dd-trace 5.132.0 → 5.134.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 (231) hide show
  1. package/ci/diagnose.js +9 -14
  2. package/ci/init.js +1 -2
  3. package/ci/test-optimization-validation/ci-discovery.js +9 -4
  4. package/ci/test-optimization-validation/executable.js +1 -5
  5. package/ci/test-optimization-validation/framework-adapters/cypress.js +1 -4
  6. package/ci/test-optimization-validation/framework-adapters/vitest.js +1 -1
  7. package/ci/test-optimization-validation/generated-files.js +6 -4
  8. package/ci/test-optimization-validation/generated-test-contract.js +7 -3
  9. package/ci/test-optimization-validation/manifest-scaffold.js +7 -2
  10. package/ci/test-optimization-validation/manifest-schema.js +6 -7
  11. package/ci/test-optimization-validation/report-writer.js +6 -2
  12. package/ci/test-optimization-validation/runner-command.js +2 -4
  13. package/ci/test-optimization-validation/runner-contract.js +1 -2
  14. package/ci/test-optimization-validation/scenarios/auto-test-retries.js +1 -15
  15. package/ci/vitest-no-worker-init-runner-setup.mjs +27 -0
  16. package/ci/vitest-no-worker-init-setup.mjs +10 -7
  17. package/index.d.ts +41 -19
  18. package/initialize.mjs +1 -3
  19. package/openfeature/rules-based.d.ts +11 -0
  20. package/openfeature/rules-based.js +7 -0
  21. package/package.json +25 -22
  22. package/packages/datadog-core/src/storage.js +16 -0
  23. package/packages/datadog-esbuild/index.js +18 -12
  24. package/packages/datadog-instrumentations/index.js +2 -1
  25. package/packages/datadog-instrumentations/src/aerospike.js +3 -3
  26. package/packages/datadog-instrumentations/src/ai.js +3 -3
  27. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -6
  28. package/packages/datadog-instrumentations/src/aws-sdk.js +21 -13
  29. package/packages/datadog-instrumentations/src/cassandra-driver.js +25 -20
  30. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +9 -23
  31. package/packages/datadog-instrumentations/src/cucumber.js +65 -41
  32. package/packages/datadog-instrumentations/src/elasticsearch.js +1 -5
  33. package/packages/datadog-instrumentations/src/electron.js +6 -6
  34. package/packages/datadog-instrumentations/src/fastify.js +13 -4
  35. package/packages/datadog-instrumentations/src/fs.js +2 -2
  36. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +9 -5
  37. package/packages/datadog-instrumentations/src/grpc/client.js +2 -0
  38. package/packages/datadog-instrumentations/src/helpers/bundler-register.js +28 -9
  39. package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +1 -2
  40. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  41. package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
  42. package/packages/datadog-instrumentations/src/helpers/register.js +45 -1
  43. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -0
  44. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +89 -6
  45. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +5 -6
  46. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/jest.js +12 -0
  47. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +48 -31
  48. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/vitest.js +8 -0
  49. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +7 -7
  50. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +5 -0
  51. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +42 -4
  52. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +7 -10
  53. package/packages/datadog-instrumentations/src/ioredis.js +7 -5
  54. package/packages/datadog-instrumentations/src/iovalkey.js +7 -5
  55. package/packages/datadog-instrumentations/src/jest.js +72 -67
  56. package/packages/datadog-instrumentations/src/knex.js +9 -5
  57. package/packages/datadog-instrumentations/src/mariadb-bundle.js +3 -3
  58. package/packages/datadog-instrumentations/src/mocha/common.js +20 -8
  59. package/packages/datadog-instrumentations/src/mocha/main.js +140 -43
  60. package/packages/datadog-instrumentations/src/mocha/utils.js +38 -4
  61. package/packages/datadog-instrumentations/src/mocha/worker.js +1 -2
  62. package/packages/datadog-instrumentations/src/mongodb-core.js +3 -3
  63. package/packages/datadog-instrumentations/src/mongoose.js +3 -3
  64. package/packages/datadog-instrumentations/src/nova-sonic/audio.js +173 -0
  65. package/packages/datadog-instrumentations/src/nova-sonic/index.js +209 -0
  66. package/packages/datadog-instrumentations/src/nova-sonic/session.js +492 -0
  67. package/packages/datadog-instrumentations/src/openai-realtime/index.js +18 -6
  68. package/packages/datadog-instrumentations/src/openai-realtime/session.js +1 -1
  69. package/packages/datadog-instrumentations/src/openai.js +7 -0
  70. package/packages/datadog-instrumentations/src/pino.js +5 -6
  71. package/packages/datadog-instrumentations/src/playwright.js +2 -0
  72. package/packages/datadog-instrumentations/src/redis.js +27 -13
  73. package/packages/datadog-instrumentations/src/router.js +30 -0
  74. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +2 -6
  75. package/packages/datadog-instrumentations/src/stripe.js +23 -12
  76. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +8 -5
  77. package/packages/datadog-instrumentations/src/vitest-main.js +16 -18
  78. package/packages/datadog-instrumentations/src/vitest-util.js +7 -4
  79. package/packages/datadog-instrumentations/src/vitest-worker.js +1 -2
  80. package/packages/datadog-instrumentations/src/vitest.js +9 -1
  81. package/packages/datadog-instrumentations/src/webdriverio.js +5 -8
  82. package/packages/datadog-instrumentations/src/ws.js +1 -4
  83. package/packages/datadog-plugin-amqplib/src/client.js +1 -2
  84. package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -5
  85. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -2
  86. package/packages/datadog-plugin-aws-sdk/src/base.js +5 -8
  87. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +18 -0
  88. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/sonic.js +45 -0
  89. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
  90. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -5
  91. package/packages/datadog-plugin-azure-durable-functions/src/index.js +5 -4
  92. package/packages/datadog-plugin-azure-functions/src/index.js +5 -3
  93. package/packages/datadog-plugin-claude-agent-sdk/src/index.js +0 -2
  94. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +4 -5
  95. package/packages/datadog-plugin-cypress/src/index.js +6 -6
  96. package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -2
  97. package/packages/datadog-plugin-cypress/src/support.js +3 -4
  98. package/packages/datadog-plugin-express/src/code_origin.js +1 -2
  99. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
  100. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
  101. package/packages/datadog-plugin-graphql/src/execute.js +5 -5
  102. package/packages/datadog-plugin-grpc/src/util.js +1 -2
  103. package/packages/datadog-plugin-kafkajs/src/producer.js +1 -2
  104. package/packages/datadog-plugin-mocha/src/index.js +7 -10
  105. package/packages/datadog-plugin-mocha/src/webdriverio-video.js +8 -4
  106. package/packages/datadog-plugin-mongodb-core/src/query.js +8 -5
  107. package/packages/datadog-plugin-next/src/index.js +1 -2
  108. package/packages/datadog-plugin-openai/src/tracing.js +5 -2
  109. package/packages/datadog-plugin-openai-agents/src/integration.js +6 -2
  110. package/packages/datadog-plugin-openai-agents/src/processor.js +2 -4
  111. package/packages/datadog-plugin-postgres/src/index.js +24 -0
  112. package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -5
  113. package/packages/datadog-plugin-rhea/src/consumer.js +1 -4
  114. package/packages/datadog-plugin-vitest/src/index.js +5 -2
  115. package/packages/datadog-shimmer/src/shimmer.js +5 -4
  116. package/packages/datadog-webpack/index.js +55 -43
  117. package/packages/datadog-webpack/src/loader.js +56 -8
  118. package/packages/dd-trace/src/aiguard/evaluation.js +143 -1
  119. package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -4
  120. package/packages/dd-trace/src/aiguard/messages/utils.js +1 -2
  121. package/packages/dd-trace/src/aiguard/redaction.js +8 -2
  122. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +3 -2
  123. package/packages/dd-trace/src/appsec/api_security/sampler.js +2 -6
  124. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -9
  125. package/packages/dd-trace/src/appsec/handlers/http-request.js +3 -9
  126. package/packages/dd-trace/src/appsec/handlers/http-response.js +7 -2
  127. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -3
  128. package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +1 -4
  129. package/packages/dd-trace/src/appsec/iast/path-line.js +2 -1
  130. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +7 -1
  131. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -3
  132. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -3
  133. package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +1 -6
  134. package/packages/dd-trace/src/appsec/lambda.js +1 -3
  135. package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +37 -27
  136. package/packages/dd-trace/src/appsec/rasp/lfi.js +9 -5
  137. package/packages/dd-trace/src/appsec/reporter.js +21 -1
  138. package/packages/dd-trace/src/appsec/stack_trace.js +4 -4
  139. package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +3 -6
  140. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +3 -2
  141. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +1 -1
  142. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -7
  143. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +1 -2
  144. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +2 -8
  145. package/packages/dd-trace/src/ci-visibility/resolve-runfile-path.js +54 -0
  146. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +5 -8
  147. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +2 -53
  148. package/packages/dd-trace/src/config/config-types.d.ts +2 -2
  149. package/packages/dd-trace/src/config/defaults.js +5 -5
  150. package/packages/dd-trace/src/config/generated-config-types.d.ts +10 -0
  151. package/packages/dd-trace/src/config/helper.js +34 -3
  152. package/packages/dd-trace/src/config/index.js +55 -9
  153. package/packages/dd-trace/src/config/normalize-service.js +1 -1
  154. package/packages/dd-trace/src/config/parsers.js +2 -2
  155. package/packages/dd-trace/src/config/supported-configurations.json +44 -0
  156. package/packages/dd-trace/src/datastreams/processor.js +3 -2
  157. package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -4
  158. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +6 -5
  159. package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -5
  160. package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -0
  161. package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +4 -6
  162. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -0
  163. package/packages/dd-trace/src/debugger/guardrail-metrics.js +2 -2
  164. package/packages/dd-trace/src/debugger/unsupported-runtime.js +16 -0
  165. package/packages/dd-trace/src/dogstatsd.js +1 -1
  166. package/packages/dd-trace/src/encode/tags-processors.js +2 -2
  167. package/packages/dd-trace/src/exporters/common/request.js +1 -5
  168. package/packages/dd-trace/src/id.js +14 -1
  169. package/packages/dd-trace/src/lambda/handler.js +179 -19
  170. package/packages/dd-trace/src/lambda/index.js +15 -1
  171. package/packages/dd-trace/src/lambda/runtime/patch.js +34 -7
  172. package/packages/dd-trace/src/llmobs/agent-manifest.js +19 -2
  173. package/packages/dd-trace/src/llmobs/audio-utils.js +3 -2
  174. package/packages/dd-trace/src/llmobs/constants/tags.js +15 -0
  175. package/packages/dd-trace/src/llmobs/experiments/experiment.js +1 -1
  176. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +15 -0
  177. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +1 -2
  178. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -3
  179. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
  180. package/packages/dd-trace/src/llmobs/plugins/nova-sonic.js +92 -0
  181. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +5 -0
  182. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +64 -2
  183. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +38 -0
  184. package/packages/dd-trace/src/llmobs/prompts/manager.js +5 -7
  185. package/packages/dd-trace/src/llmobs/prompts/prompt.js +1 -1
  186. package/packages/dd-trace/src/llmobs/sdk.js +15 -4
  187. package/packages/dd-trace/src/llmobs/span_processor.js +13 -2
  188. package/packages/dd-trace/src/llmobs/tagger.js +20 -10
  189. package/packages/dd-trace/src/llmobs/util.js +11 -6
  190. package/packages/dd-trace/src/llmobs/writers/base.js +4 -5
  191. package/packages/dd-trace/src/log/log.js +1 -5
  192. package/packages/dd-trace/src/openfeature/evaluation-telemetry-opt-out-hook.js +51 -0
  193. package/packages/dd-trace/src/openfeature/flagging_provider.js +48 -21
  194. package/packages/dd-trace/src/openfeature/index.js +6 -0
  195. package/packages/dd-trace/src/openfeature/writers/util.js +4 -4
  196. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -1
  197. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
  198. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -2
  199. package/packages/dd-trace/src/opentelemetry/otlp/common.proto +1 -1
  200. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +24 -24
  201. package/packages/dd-trace/src/opentracing/propagation/text_map.js +53 -13
  202. package/packages/dd-trace/src/otel-sampling.js +4 -5
  203. package/packages/dd-trace/src/otel-thread-ctx.js +79 -13
  204. package/packages/dd-trace/src/plugin_manager.js +1 -2
  205. package/packages/dd-trace/src/plugins/database.js +7 -16
  206. package/packages/dd-trace/src/plugins/tracing.js +0 -1
  207. package/packages/dd-trace/src/plugins/util/git.js +99 -59
  208. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -5
  209. package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -1
  210. package/packages/dd-trace/src/plugins/util/test.js +50 -4
  211. package/packages/dd-trace/src/plugins/util/web.js +90 -20
  212. package/packages/dd-trace/src/priority_sampler.js +1 -2
  213. package/packages/dd-trace/src/profiling/profiler.js +4 -6
  214. package/packages/dd-trace/src/proxy.js +1 -2
  215. package/packages/dd-trace/src/ritm.js +4 -2
  216. package/packages/dd-trace/src/serverless.js +5 -0
  217. package/packages/dd-trace/src/span_processor.js +13 -17
  218. package/packages/dd-trace/src/span_stats.js +4 -1
  219. package/packages/dd-trace/src/telemetry/endpoints.js +1 -3
  220. package/packages/dd-trace/src/telemetry/logs/log-collector.js +1 -1
  221. package/packages/dd-trace/src/util.js +37 -4
  222. package/packages/dd-trace/src/web-tags-cache.js +6 -2
  223. package/vendor/dist/@apm-js-collab/code-transformer/index.js +8 -8
  224. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
  225. package/vendor/dist/@datadog/openfeature-node-server/rules-based/LICENSE +201 -0
  226. package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.d.ts +925 -0
  227. package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.js +1 -0
  228. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  229. package/vendor/dist/protobufjs/index.js +1 -1
  230. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  231. package/vendor/dist/shell-quote/index.js +1 -1
@@ -1,16 +1,38 @@
1
1
  'use strict'
2
2
 
3
3
  // Activated rewrites publish their module name to the plugin manager after evaluation.
4
- // Only pure Orchestrion integrations that need this activation set activate: true.
4
+ // Integrations can also provide synchronous runtime setup before plugin activation.
5
+ // Setup must not load rewrite targets: re-entrant activations of the same group are dropped.
6
+ // activate: true covers every rewrite target in the entry; activate.modules narrows it to the packages
7
+ // that should trigger activation, leaving the rest of the entry rewrite-only.
5
8
  // Other entries use hooks or another activation path, or do not need activation from a rewrite.
9
+ /**
10
+ * @typedef {object} Activation
11
+ * @property {string} moduleName
12
+ * @property {string} [version]
13
+ *
14
+ * @typedef {object} ActivationConfig
15
+ * @property {string[]} [modules]
16
+ * @property {((activation: Activation) => void)} [setup]
17
+ *
18
+ * @typedef {object} InstrumentationRegistryEntry
19
+ * @property {true|ActivationConfig} [activate]
20
+ * @property {Array<{ module: { name: string } }>} instrumentations
21
+ */
22
+
23
+ /** @satisfies {InstrumentationRegistryEntry[]} */
6
24
  const registry = [
7
25
  { instrumentations: require('./instrumentations/ai') },
8
26
  { activate: true, instrumentations: require('./instrumentations/azure-cosmos') },
9
27
  { instrumentations: require('./instrumentations/azure-durable-functions') },
10
28
  { activate: true, instrumentations: require('./instrumentations/bullmq') },
11
- { instrumentations: require('./instrumentations/claude-agent-sdk') },
29
+ {
30
+ activate: { setup: () => require('../../claude-agent-sdk') },
31
+ instrumentations: require('./instrumentations/claude-agent-sdk'),
32
+ },
12
33
  { instrumentations: require('./instrumentations/graphql') },
13
34
  { instrumentations: require('./instrumentations/graphql-jit') },
35
+ { instrumentations: require('./instrumentations/jest') },
14
36
  { activate: true, instrumentations: require('./instrumentations/langchain') },
15
37
  { activate: true, instrumentations: require('./instrumentations/langgraph') },
16
38
  { activate: true, instrumentations: require('./instrumentations/mercurius') },
@@ -18,15 +40,68 @@ const registry = [
18
40
  { instrumentations: require('./instrumentations/openai-agents') },
19
41
  { instrumentations: require('./instrumentations/playwright') },
20
42
  { activate: true, instrumentations: require('./instrumentations/postgres') },
43
+ { instrumentations: require('./instrumentations/vitest') },
21
44
  { instrumentations: require('./instrumentations/webdriverio') },
22
- { instrumentations: require('./instrumentations/aws-durable-execution-sdk-js') },
45
+ {
46
+ activate: { setup: () => require('../../aws-durable-execution-sdk-js') },
47
+ instrumentations: require('./instrumentations/aws-durable-execution-sdk-js'),
48
+ },
23
49
  { activate: true, instrumentations: require('./instrumentations/supabase') },
24
50
  ]
25
51
 
26
52
  const activatedModules = new Set()
53
+ /** @type {Map<string, (activation: Activation) => void>} */
54
+ const activationSetups = new Map()
27
55
  for (const { activate, instrumentations } of registry) {
28
- if (!activate) continue
29
- for (const { module } of instrumentations) activatedModules.add(module.name)
56
+ if (activate === undefined) continue
57
+ if (activate !== true && (typeof activate !== 'object' || activate === null || Array.isArray(activate))) {
58
+ throw new TypeError('Instrumentation registry activate must be true or an activation config object')
59
+ }
60
+ const config = activate === true ? undefined : activate
61
+ const setup = config?.setup
62
+ if (setup !== undefined && typeof setup !== 'function') {
63
+ throw new TypeError('Instrumentation registry activate.setup must be a function')
64
+ }
65
+
66
+ const rewriteModules = new Set(instrumentations.map(({ module }) => module.name))
67
+ for (const moduleName of resolveActivationModules(config?.modules, rewriteModules)) {
68
+ if (activatedModules.has(moduleName) && activationSetups.get(moduleName) !== setup) {
69
+ throw new TypeError(`Instrumentation registry activation module "${moduleName}" has conflicting setup functions`)
70
+ }
71
+ activatedModules.add(moduleName)
72
+ if (setup) activationSetups.set(moduleName, setup)
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Activation covers every rewrite target in the entry unless it names the packages to activate. An explicit
78
+ * list keeps helper packages that share the entry rewrite-only.
79
+ * @param {string[]|undefined} modules
80
+ * @param {Set<string>} rewriteModules
81
+ * @returns {Set<string>}
82
+ */
83
+ function resolveActivationModules (modules, rewriteModules) {
84
+ if (modules === undefined) return rewriteModules
85
+ if (!Array.isArray(modules) || modules.length === 0) {
86
+ throw new TypeError('Instrumentation registry activate.modules must be a non-empty array')
87
+ }
88
+
89
+ const entryModules = new Set()
90
+ for (const moduleName of modules) {
91
+ if (typeof moduleName !== 'string' || moduleName.length === 0) {
92
+ throw new TypeError('Instrumentation registry activate.modules must contain non-empty strings')
93
+ }
94
+ if (!rewriteModules.has(moduleName)) {
95
+ throw new TypeError(
96
+ `Instrumentation registry activation module "${moduleName}" is not a rewrite target in its entry`
97
+ )
98
+ }
99
+ if (entryModules.has(moduleName)) {
100
+ throw new TypeError(`Instrumentation registry activation module "${moduleName}" is duplicated in its entry`)
101
+ }
102
+ entryModules.add(moduleName)
103
+ }
104
+ return entryModules
30
105
  }
31
106
 
32
107
  const instrumentations = registry.flatMap(entry => entry.instrumentations)
@@ -38,4 +113,12 @@ function isRewriteActivationEnabled (moduleName) {
38
113
  return activatedModules.has(moduleName)
39
114
  }
40
115
 
41
- module.exports = { isRewriteActivationEnabled, instrumentations, registry }
116
+ /**
117
+ * @param {string} moduleName
118
+ * @returns {((activation: Activation) => void)|undefined}
119
+ */
120
+ function getActivationSetup (moduleName) {
121
+ return activationSetups.get(moduleName)
122
+ }
123
+
124
+ module.exports = { getActivationSetup, isRewriteActivationEnabled, instrumentations, registry }
@@ -26,11 +26,10 @@ const COMPILE_DEFERRED_FIELD = 'FunctionDeclaration[id.name="compileDeferredFiel
26
26
  */
27
27
 
28
28
  /**
29
- * @param {GraphqlJitInstrumentation[]} instrumentations
30
29
  * @param {string} versionRange
31
30
  * @param {string} filePath
32
31
  */
33
- function addInstrumentations (instrumentations, versionRange, filePath) {
32
+ function addInstrumentations (versionRange, filePath) {
34
33
  const moduleDefinition = { name: 'graphql-jit', versionRange, filePath }
35
34
  instrumentations.push(
36
35
  {
@@ -75,9 +74,9 @@ function addInstrumentations (instrumentations, versionRange, filePath) {
75
74
  const instrumentations = []
76
75
  // graphql-jit 0.7 and 0.8.0 use this layout and remain compatible with GraphQL 15 and 16.
77
76
  // GraphQL 17 compatibility starts at 0.8.1.
78
- addInstrumentations(instrumentations, '>=0.7.0 <0.8.5 || >=0.8.7 <0.9.0', 'dist/execution.js')
79
- addInstrumentations(instrumentations, '>=0.8.5 <0.8.7', 'dist/cjs/execution.js')
80
- addInstrumentations(instrumentations, '>=0.8.5 <0.8.7', 'dist/esm/execution.js')
81
- addInstrumentations(instrumentations, '>=0.8.7 <0.9.0', 'dist/execution.mjs')
77
+ addInstrumentations('>=0.7.0 <0.8.5 || >=0.8.7 <0.9.0', 'dist/execution.js')
78
+ addInstrumentations('>=0.8.5 <0.8.7', 'dist/cjs/execution.js')
79
+ addInstrumentations('>=0.8.5 <0.8.7', 'dist/esm/execution.js')
80
+ addInstrumentations('>=0.8.7 <0.9.0', 'dist/execution.mjs')
82
81
 
83
82
  module.exports = instrumentations
@@ -0,0 +1,12 @@
1
+ 'use strict'
2
+
3
+ module.exports = [
4
+ ['>=24.8.0 <30.0.0', 'build/runTest.js'],
5
+ ['>=30.0.0', 'build/index.js'],
6
+ ['>=30.0.0', 'build/testWorker.js'],
7
+ ].map(([versionRange, filePath]) => ({
8
+ module: { name: 'jest-runner', versionRange, filePath },
9
+ // Wrap the returned promise so completion covers both successful and failed teardown.
10
+ functionQuery: { functionName: 'runTestInternal', kind: 'Sync' },
11
+ channelName: 'runTestInternal',
12
+ }))
@@ -1,36 +1,53 @@
1
1
  'use strict'
2
2
 
3
- const handlers = ['src/index.js', 'cjs/src/index.js'].map(filePath => ({
4
- module: {
5
- name: 'postgres',
6
- versionRange: '>=3.0.0',
7
- filePath,
8
- },
9
- astQuery: 'Program',
10
- transform: 'postgresQueryHandlers',
11
- channelName: 'query',
12
- }))
3
+ const instrumentations = []
13
4
 
14
- const preparations = ['src/connection.js', 'cjs/src/connection.js'].map(filePath => ({
15
- module: {
16
- name: 'postgres',
17
- versionRange: '>=3.0.0',
18
- filePath,
19
- },
20
- astQuery: 'Program',
21
- transform: 'postgresQueryPreparation',
22
- channelName: 'query:prepare',
23
- }))
5
+ for (const filePath of ['src/index.js', 'cjs/src/index.js']) {
6
+ instrumentations.push({
7
+ module: {
8
+ name: 'postgres',
9
+ versionRange: '>=3.0.0',
10
+ filePath,
11
+ },
12
+ astQuery: 'Program',
13
+ transform: 'postgresQueryHandlers',
14
+ channelName: 'query',
15
+ })
16
+ }
24
17
 
25
- const lifecycles = ['src/query.js', 'cjs/src/query.js'].map(filePath => ({
26
- module: {
27
- name: 'postgres',
28
- versionRange: '>=3.0.0',
29
- filePath,
30
- },
31
- astQuery: 'Program',
32
- transform: 'postgresQueryLifecycle',
33
- channelName: 'query',
34
- }))
18
+ for (const filePath of ['src/connection.js', 'cjs/src/connection.js']) {
19
+ instrumentations.push({
20
+ module: {
21
+ name: 'postgres',
22
+ versionRange: '>=3.0.0',
23
+ filePath,
24
+ },
25
+ astQuery: 'Program',
26
+ transform: 'postgresQueryAcquire',
27
+ channelName: 'query:acquire',
28
+ }, {
29
+ module: {
30
+ name: 'postgres',
31
+ versionRange: '>=3.0.0',
32
+ filePath,
33
+ },
34
+ astQuery: 'Program',
35
+ transform: 'postgresQueryPreparation',
36
+ channelName: 'query:prepare',
37
+ })
38
+ }
35
39
 
36
- module.exports = [...handlers, ...preparations, ...lifecycles]
40
+ for (const filePath of ['src/query.js', 'cjs/src/query.js']) {
41
+ instrumentations.push({
42
+ module: {
43
+ name: 'postgres',
44
+ versionRange: '>=3.0.0',
45
+ filePath,
46
+ },
47
+ astQuery: 'Program',
48
+ transform: 'postgresQueryLifecycle',
49
+ channelName: 'query',
50
+ })
51
+ }
52
+
53
+ module.exports = instrumentations
@@ -0,0 +1,8 @@
1
+ 'use strict'
2
+
3
+ module.exports = ['dist/index.js', 'dist/chunk-hooks.js'].map(filePath => ({
4
+ module: { name: '@vitest/runner', versionRange: '>=1.6.0 <4.1.0', filePath },
5
+ astQuery: 'FunctionDeclaration[id.name="createSuiteCollector"] ' +
6
+ 'VariableDeclarator[id.name="task"] > FunctionExpression',
7
+ channelName: 'createTestTask',
8
+ }))
@@ -506,9 +506,8 @@ module.exports = [
506
506
  versionRange: '>=9.0.0',
507
507
  filePath: 'build/index.js',
508
508
  },
509
- astQuery: 'TryStatement:has(CatchClause IfStatement[test.operator=">"]' +
510
- '[test.left.object.name="retries"][test.left.property.name="limit"]' +
511
- '[test.right.object.name="retries"][test.right.property.name="attempts"]) > BlockStatement',
509
+ astQuery: 'FunctionDeclaration[id.name="executeAsync"] TryStatement:has(CatchClause ' +
510
+ 'CallExpression[callee.object.name="executeAsync"][callee.property.name="call"]) > BlockStatement',
512
511
  channelName: 'executeAsync',
513
512
  transform: 'awaitContextCallback',
514
513
  transformOptions: {
@@ -521,10 +520,8 @@ module.exports = [
521
520
  versionRange: '>=9.0.0',
522
521
  filePath: 'build/index.js',
523
522
  },
524
- astQuery: 'FunctionDeclaration[id.name="executeAsync"] CatchClause ' +
525
- 'IfStatement[test.operator=">"][test.left.object.name="retries"]' +
526
- '[test.left.property.name="limit"][test.right.object.name="retries"]' +
527
- '[test.right.property.name="attempts"]',
523
+ astQuery: 'FunctionDeclaration[id.name="executeAsync"] CatchClause > BlockStatement > ' +
524
+ 'IfStatement:has(CallExpression[callee.object.name="executeAsync"][callee.property.name="call"])',
528
525
  channelName: 'executeAsync',
529
526
  transform: 'awaitContextCallback',
530
527
  transformOptions: {
@@ -540,7 +537,10 @@ module.exports = [
540
537
  },
541
538
  astQuery: 'AssignmentExpression[left.object.object.name="Spec"]' +
542
539
  '[left.object.property.name="prototype"][left.property.name="execute"] > FunctionExpression',
540
+ // A method name keeps the original function expression, so the start context
541
+ // carries `self` (the legacy Spec) that the WebdriverIO Jasmine lifecycle reads.
543
542
  functionQuery: {
543
+ methodName: 'execute',
544
544
  kind: 'Sync',
545
545
  },
546
546
  channelName: 'Spec_execute',
@@ -41,6 +41,8 @@
41
41
  "@supabase/realtime-js/dist/module/RealtimeChannel.js": "@supabase/realtime-js",
42
42
  "@supabase/storage-js/dist/index.cjs": "@supabase/storage-js",
43
43
  "@supabase/storage-js/dist/index.mjs": "@supabase/storage-js",
44
+ "@vitest/runner/dist/chunk-hooks.js": "@vitest/runner",
45
+ "@vitest/runner/dist/index.js": "@vitest/runner",
44
46
  "@wdio/cli/build/index.js": "@wdio/cli",
45
47
  "@wdio/config/build/node/index.js": "@wdio/config",
46
48
  "@wdio/jasmine-framework/build/index.js": "@wdio/jasmine-framework",
@@ -76,6 +78,9 @@
76
78
  "graphql/validation/validate.js": "graphql",
77
79
  "graphql/validation/validate.mjs": "graphql",
78
80
  "jasmine-core/lib/jasmine-core/jasmine.js": "jasmine-core",
81
+ "jest-runner/build/index.js": "jest-runner",
82
+ "jest-runner/build/runTest.js": "jest-runner",
83
+ "jest-runner/build/testWorker.js": "jest-runner",
79
84
  "mercurius/index.js": "mercurius",
80
85
  "playwright-core/lib/coreBundle.js": "playwright-core",
81
86
  "playwright/lib/common/config.js": "playwright",
@@ -12,11 +12,37 @@ const POSTGRES_SIMPLE_DBM_QUERIES = '__ddTracePostgresSimpleDbmQueries'
12
12
  const POSTGRES_STATEMENT = 'this.string ?? (this.tagged && this.strings?.length !== 1 ? undefined : this.strings?.[0])'
13
13
 
14
14
  module.exports = {
15
+ postgresQueryAcquire,
15
16
  postgresQueryHandlers,
16
17
  postgresQueryLifecycle,
17
18
  postgresQueryPreparation,
18
19
  }
19
20
 
21
+ /**
22
+ * @param {object} state
23
+ * @param {import('estree').Program} program
24
+ */
25
+ function postgresQueryAcquire (state, program) {
26
+ const channelVariable = injectPostgresTracingChannel(state, program)
27
+ const executeFunctions = query(program, 'FunctionDeclaration[id.name="execute"]')
28
+ assert(executeFunctions.length === 1, 'postgresQueryAcquire: unexpected execute function count')
29
+
30
+ const execute = executeFunctions[0]
31
+ const queryParameter = execute.params[0]
32
+ assert(queryParameter?.type === 'Identifier', 'postgresQueryAcquire: execute query parameter changed')
33
+ assert(execute.body.type === 'BlockStatement', 'postgresQueryAcquire: execute body changed')
34
+
35
+ const body = execute.body.body
36
+ const executeIndex = body.findIndex(statement => statement.type === 'TryStatement')
37
+ assert(executeIndex !== -1, 'postgresQueryAcquire: execute try block changed')
38
+
39
+ body.splice(executeIndex, 0, ...parse(`
40
+ if (${channelVariable}.start.hasSubscribers) {
41
+ ${channelVariable}.start.publish({ query: ${queryParameter.name} });
42
+ }
43
+ `).body)
44
+ }
45
+
20
46
  /**
21
47
  * Starts a Postgres.js query at the pool handler that owns its connection options.
22
48
  *
@@ -154,6 +180,7 @@ function wrapPostgresHandler (handler, queryParameter, channelVariable) {
154
180
  assert(handler.body.type === 'BlockStatement', 'postgresQueryHandlers: handler body changed')
155
181
  assert(!handler.async && !handler.generator, 'postgresQueryHandlers: unsupported handler kind')
156
182
 
183
+ // Direct handoffs publish before the handler returns, so they record zero pool wait.
157
184
  const originalBody = handler.body.body
158
185
  const wrapperBody = parse(`
159
186
  function wrapper () {
@@ -167,12 +194,18 @@ function wrapPostgresHandler (handler, queryParameter, channelVariable) {
167
194
  __ddTraceContext.host = ${POSTGRES_OPTIONS}.host[0];
168
195
  __ddTraceContext.port = ${POSTGRES_OPTIONS}.port[0];
169
196
  }
170
- return ${channelVariable}.start.runStores(__ddTraceContext, () => {});
197
+ const __ddTraceResult = ${channelVariable}.start.runStores(__ddTraceContext, () => {});
198
+ if (!__ddTraceContext.poolWaitFinished) {
199
+ __ddTraceContext.poolWaitStartMs = performance.now();
200
+ }
201
+ return __ddTraceResult;
171
202
  }
172
203
  }
173
204
  `).body[0].body.body
174
205
 
175
- wrapperBody[0].consequent.body.at(-1).argument.arguments[1].body.body = originalBody
206
+ const tracingCalls = query(wrapperBody[0], 'CallExpression[callee.property.name="runStores"]')
207
+ assert(tracingCalls.length === 1, 'postgresQueryHandlers: runStores call changed')
208
+ tracingCalls[0].arguments[1].body.body = originalBody
176
209
  handler.body.body = [...wrapperBody, ...originalBody]
177
210
  }
178
211
 
@@ -272,8 +305,13 @@ function findPostgresQueryIdentifier (program) {
272
305
 
273
306
  const declarations = query(program, 'VariableDeclarator[id.type="ObjectPattern"]')
274
307
  for (const declaration of declarations) {
275
- if (declaration.init?.type !== 'CallExpression' || declaration.init.callee.name !== 'require') continue
276
- if (declaration.init.arguments[0]?.value !== './query.js') continue
308
+ if (
309
+ declaration.init?.type !== 'CallExpression' ||
310
+ declaration.init.callee.name !== 'require' ||
311
+ declaration.init.arguments[0]?.value !== './query.js'
312
+ ) {
313
+ continue
314
+ }
277
315
 
278
316
  for (const property of declaration.id.properties) {
279
317
  if (property.type === 'Property' && property.key.name === 'Query' && property.value.type === 'Identifier') {
@@ -140,8 +140,7 @@ function awaitContextCallback (state, node, _parent, ancestry) {
140
140
  const generatedCallback = createAwaitedContextCallback(
141
141
  state,
142
142
  insertionTarget,
143
- callbackAncestry,
144
- 'awaitContextCallback'
143
+ callbackAncestry
145
144
  )
146
145
  if (!generatedCallback) return
147
146
 
@@ -158,8 +157,7 @@ function awaitContextCallback (state, node, _parent, ancestry) {
158
157
  const generatedCallback = createAwaitedContextCallback(
159
158
  state,
160
159
  node.consequent,
161
- ancestry,
162
- 'awaitContextCallback'
160
+ ancestry
163
161
  )
164
162
  if (!generatedCallback) return
165
163
 
@@ -181,18 +179,17 @@ function awaitContextCallback (state, node, _parent, ancestry) {
181
179
  * @param {Parameters<typeof awaitContextCallback>[0]} state
182
180
  * @param {import('estree').BlockStatement} insertionTarget
183
181
  * @param {import('estree').Node[]} ancestry
184
- * @param {string} transformName
185
182
  * @returns {{
186
183
  * callbackStatements: import('estree').Statement[],
187
184
  * callbackVariable: string
188
185
  * }|undefined}
189
186
  */
190
- function createAwaitedContextCallback (state, insertionTarget, ancestry, transformName) {
187
+ function createAwaitedContextCallback (state, insertionTarget, ancestry) {
191
188
  const { callbackArgumentNames = [], callbackName, callbackThis = false } = state.transformOptions ?? {}
192
189
 
193
- assert(identifierPattern.test(callbackName), `${transformName}: callbackName must be an identifier`)
190
+ assert(identifierPattern.test(callbackName), 'awaitContextCallback: callbackName must be an identifier')
194
191
  assert(Array.isArray(callbackArgumentNames) && callbackArgumentNames.every(name => identifierPattern.test(name)),
195
- `${transformName}: callbackArgumentNames must be identifiers`)
192
+ 'awaitContextCallback: callbackArgumentNames must be identifiers')
196
193
 
197
194
  let enclosingFunction
198
195
  let hasTraceWrapper = false
@@ -215,8 +212,8 @@ function createAwaitedContextCallback (state, insertionTarget, ancestry, transfo
215
212
  hasTraceWrapper ||= hasContextBinding && hasTracedBinding
216
213
  }
217
214
 
218
- assert(enclosingFunction?.async, `${transformName}: expected an enclosing async function`)
219
- assert(hasTraceWrapper, `${transformName}: expected an enclosing trace wrapper`)
215
+ assert(enclosingFunction?.async, 'awaitContextCallback: expected an enclosing async function')
216
+ assert(hasTraceWrapper, 'awaitContextCallback: expected an enclosing trace wrapper')
220
217
 
221
218
  const callbackVariable = `__apm$${callbackName}`
222
219
  if (query(insertionTarget, `[id.name="${callbackVariable}"]`).length > 0) return
@@ -14,9 +14,7 @@ const connectionOptionsCache = new WeakMap()
14
14
 
15
15
  function wrapRedis (Redis) {
16
16
  shimmer.wrap(Redis.prototype, 'sendCommand', sendCommand => function (command, stream) {
17
- if (!startCh.hasSubscribers) return sendCommand.call(this, command, stream)
18
-
19
- if (!command?.promise) return sendCommand.call(this, command, stream)
17
+ if (!startCh.hasSubscribers || !command?.promise) return sendCommand.call(this, command, stream)
20
18
 
21
19
  const options = this.options || {}
22
20
  let connectionOptions = connectionOptionsCache.get(this)
@@ -32,7 +30,7 @@ function wrapRedis (Redis) {
32
30
  connectionName: options.connectionName,
33
31
  }
34
32
  return startCh.runStores(ctx, () => {
35
- command.promise.then(() => finish(finishCh, errorCh, ctx), err => finish(finishCh, errorCh, ctx, err))
33
+ command.promise.then(() => finish(ctx), err => finish(ctx, err))
36
34
 
37
35
  return sendCommand.call(this, command, stream)
38
36
  })
@@ -51,7 +49,11 @@ addHook({ name: 'ioredis', versions: ['>=4.11.0 <5'], file: 'built/redis/index.j
51
49
 
52
50
  addHook({ name: 'ioredis', versions: ['>=5'] }, wrapRedis)
53
51
 
54
- function finish (finishCh, errorCh, ctx, error) {
52
+ /**
53
+ * @param {Record<string, unknown> & { error?: Error }} ctx
54
+ * @param {Error} [error]
55
+ */
56
+ function finish (ctx, error) {
55
57
  if (error) {
56
58
  ctx.error = error
57
59
  errorCh.publish(ctx)
@@ -12,9 +12,7 @@ const errorCh = channel('apm:iovalkey:command:error')
12
12
 
13
13
  addHook({ name: 'iovalkey', versions: ['>=0.0.1'] }, Valkey => {
14
14
  shimmer.wrap(Valkey.prototype, 'sendCommand', sendCommand => function (command, stream) {
15
- if (!startCh.hasSubscribers) return sendCommand.apply(this, arguments)
16
-
17
- if (!command?.promise) return sendCommand.apply(this, arguments)
15
+ if (!startCh.hasSubscribers || !command?.promise) return sendCommand.apply(this, arguments)
18
16
 
19
17
  const options = this.options || {}
20
18
  const connectionName = options.connectionName
@@ -22,7 +20,7 @@ addHook({ name: 'iovalkey', versions: ['>=0.0.1'] }, Valkey => {
22
20
 
23
21
  const ctx = { command: command.name, args: command.args, connectionOptions, connectionName }
24
22
  return startCh.runStores(ctx, () => {
25
- command.promise.then(() => finish(finishCh, errorCh, ctx), err => finish(finishCh, errorCh, ctx, err))
23
+ command.promise.then(() => finish(ctx), err => finish(ctx, err))
26
24
 
27
25
  try {
28
26
  return sendCommand.apply(this, arguments)
@@ -37,7 +35,11 @@ addHook({ name: 'iovalkey', versions: ['>=0.0.1'] }, Valkey => {
37
35
  return Valkey
38
36
  })
39
37
 
40
- function finish (finishCh, errorCh, ctx, error) {
38
+ /**
39
+ * @param {Record<string, unknown> & { error?: Error }} ctx
40
+ * @param {Error} [error]
41
+ */
42
+ function finish (ctx, error) {
41
43
  if (error) {
42
44
  ctx.error = error
43
45
  errorCh.publish(ctx)