dd-trace 6.7.0 → 6.9.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 (272) hide show
  1. package/ci/diagnose.js +27 -25
  2. package/ci/init.js +6 -6
  3. package/ci/runbook.md +114 -20
  4. package/ci/test-optimization-validation/approval-artifacts.js +36 -3
  5. package/ci/test-optimization-validation/approval.js +78 -22
  6. package/ci/test-optimization-validation/blocker-category.js +24 -0
  7. package/ci/test-optimization-validation/ci-discovery.js +23 -17
  8. package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
  9. package/ci/test-optimization-validation/ci-remediation.js +1 -1
  10. package/ci/test-optimization-validation/cli.js +280 -52
  11. package/ci/test-optimization-validation/command-blocker.js +159 -20
  12. package/ci/test-optimization-validation/command-output-policy.js +14 -8
  13. package/ci/test-optimization-validation/command-runner.js +9 -7
  14. package/ci/test-optimization-validation/environment.js +4 -2
  15. package/ci/test-optimization-validation/executable.js +15 -13
  16. package/ci/test-optimization-validation/execution-lock.js +70 -0
  17. package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
  18. package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
  19. package/ci/test-optimization-validation/framework-adapters/playwright.js +5 -5
  20. package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
  21. package/ci/test-optimization-validation/generated-files.js +47 -37
  22. package/ci/test-optimization-validation/generated-test-contract.js +9 -7
  23. package/ci/test-optimization-validation/generated-verifier.js +24 -17
  24. package/ci/test-optimization-validation/literal-glob.js +52 -0
  25. package/ci/test-optimization-validation/manifest-loader.js +3 -0
  26. package/ci/test-optimization-validation/manifest-scaffold.js +301 -52
  27. package/ci/test-optimization-validation/manifest-schema.js +80 -17
  28. package/ci/test-optimization-validation/offline-fixtures.js +13 -4
  29. package/ci/test-optimization-validation/offline-output.js +6 -6
  30. package/ci/test-optimization-validation/package-check.js +94 -0
  31. package/ci/test-optimization-validation/plan-writer.js +183 -10
  32. package/ci/test-optimization-validation/preflight-runner.js +110 -31
  33. package/ci/test-optimization-validation/project-build-artifact.js +31 -0
  34. package/ci/test-optimization-validation/redaction.js +18 -27
  35. package/ci/test-optimization-validation/report-writer.js +182 -48
  36. package/ci/test-optimization-validation/result-semantics.js +20 -3
  37. package/ci/test-optimization-validation/runner-command.js +41 -21
  38. package/ci/test-optimization-validation/runner-contract.js +79 -43
  39. package/ci/test-optimization-validation/safe-files.js +4 -4
  40. package/ci/test-optimization-validation/scenarios/basic-reporting.js +60 -6
  41. package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
  42. package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
  43. package/ci/test-optimization-validation/scenarios/test-management.js +2 -2
  44. package/ci/test-optimization-validation/static-diagnosis.js +10 -3
  45. package/ci/test-optimization-validation/test-output.js +2 -1
  46. package/ci/test-optimization-validation/validation-blocker.js +21 -0
  47. package/ci/vitest-no-worker-init-setup.mjs +377 -84
  48. package/index.d.ts +175 -14
  49. package/init.js +1 -17
  50. package/initialize.mjs +11 -0
  51. package/loader-hook.mjs +6 -4
  52. package/package.json +12 -4
  53. package/packages/datadog-core/src/utils/src/kebabcase.js +8 -2
  54. package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
  55. package/packages/datadog-esbuild/index.js +4 -2
  56. package/packages/datadog-esbuild/src/utils.js +17 -2
  57. package/packages/datadog-instrumentations/src/ai.js +61 -34
  58. package/packages/datadog-instrumentations/src/bluebird.js +6 -6
  59. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +85 -9
  60. package/packages/datadog-instrumentations/src/cucumber.js +131 -51
  61. package/packages/datadog-instrumentations/src/dns.js +21 -2
  62. package/packages/datadog-instrumentations/src/electron.js +1 -0
  63. package/packages/datadog-instrumentations/src/fastify.js +3 -1
  64. package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
  65. package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
  66. package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +10 -0
  67. package/packages/datadog-instrumentations/src/helpers/hook.js +19 -2
  68. package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
  69. package/packages/datadog-instrumentations/src/helpers/register.js +9 -3
  70. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
  71. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
  72. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +175 -0
  73. package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
  74. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
  75. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +61 -0
  76. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +50 -18
  77. package/packages/datadog-instrumentations/src/helpers/router-helper.js +38 -7
  78. package/packages/datadog-instrumentations/src/helpers/shared-utils.js +39 -0
  79. package/packages/datadog-instrumentations/src/http/client.js +1 -3
  80. package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
  81. package/packages/datadog-instrumentations/src/jest.js +986 -246
  82. package/packages/datadog-instrumentations/src/mocha/common.js +1 -3
  83. package/packages/datadog-instrumentations/src/mocha/main.js +109 -51
  84. package/packages/datadog-instrumentations/src/mocha/utils.js +120 -32
  85. package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +44 -0
  86. package/packages/datadog-instrumentations/src/mocha/worker.js +441 -43
  87. package/packages/datadog-instrumentations/src/moleculer/client.js +1 -1
  88. package/packages/datadog-instrumentations/src/mysql.js +1 -1
  89. package/packages/datadog-instrumentations/src/next.js +155 -23
  90. package/packages/datadog-instrumentations/src/openai.js +14 -0
  91. package/packages/datadog-instrumentations/src/pg.js +180 -6
  92. package/packages/datadog-instrumentations/src/playwright.js +176 -81
  93. package/packages/datadog-instrumentations/src/promise-js.js +4 -4
  94. package/packages/datadog-instrumentations/src/promise.js +3 -3
  95. package/packages/datadog-instrumentations/src/rhea.js +1 -1
  96. package/packages/datadog-instrumentations/src/router.js +195 -19
  97. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +567 -65
  98. package/packages/datadog-instrumentations/src/vitest-main.js +438 -54
  99. package/packages/datadog-instrumentations/src/vitest-util.js +42 -7
  100. package/packages/datadog-instrumentations/src/vitest-worker.js +234 -17
  101. package/packages/datadog-instrumentations/src/webdriverio.js +1090 -0
  102. package/packages/datadog-instrumentations/src/when.js +3 -3
  103. package/packages/datadog-instrumentations/src/ws.js +5 -1
  104. package/packages/datadog-plugin-aerospike/src/index.js +1 -3
  105. package/packages/datadog-plugin-amqplib/src/client.js +1 -1
  106. package/packages/datadog-plugin-amqplib/src/producer.js +1 -1
  107. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
  108. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
  109. package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +2 -2
  110. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -3
  111. package/packages/datadog-plugin-azure-service-bus/src/producer.js +5 -3
  112. package/packages/datadog-plugin-bullmq/src/producer.js +3 -3
  113. package/packages/datadog-plugin-child_process/src/index.js +3 -3
  114. package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -11
  115. package/packages/datadog-plugin-cucumber/src/index.js +5 -1
  116. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +50 -46
  117. package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -1
  118. package/packages/datadog-plugin-cypress/src/support.js +7 -4
  119. package/packages/datadog-plugin-electron/src/net.js +10 -4
  120. package/packages/datadog-plugin-fastify/src/tracing.js +1 -1
  121. package/packages/datadog-plugin-fs/src/index.js +0 -4
  122. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +14 -7
  123. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +19 -10
  124. package/packages/datadog-plugin-graphql/src/execute.js +1 -0
  125. package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -1
  126. package/packages/datadog-plugin-http/src/client.js +3 -2
  127. package/packages/datadog-plugin-http2/src/client.js +1 -1
  128. package/packages/datadog-plugin-jest/src/index.js +3 -21
  129. package/packages/datadog-plugin-jest/src/util.js +4 -1
  130. package/packages/datadog-plugin-kafkajs/src/producer.js +2 -1
  131. package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
  132. package/packages/datadog-plugin-mocha/src/index.js +342 -6
  133. package/packages/datadog-plugin-next/src/index.js +57 -9
  134. package/packages/datadog-plugin-openai/src/tracing.js +4 -0
  135. package/packages/datadog-plugin-pg/src/index.js +65 -1
  136. package/packages/datadog-plugin-playwright/src/index.js +1 -1
  137. package/packages/datadog-plugin-prisma/src/index.js +5 -1
  138. package/packages/datadog-plugin-rhea/src/consumer.js +16 -13
  139. package/packages/datadog-plugin-rhea/src/producer.js +1 -1
  140. package/packages/datadog-plugin-undici/src/index.js +2 -1
  141. package/packages/datadog-plugin-vitest/src/index.js +179 -18
  142. package/packages/datadog-shimmer/src/shimmer.js +6 -2
  143. package/packages/datadog-webpack/index.js +2 -2
  144. package/packages/dd-trace/src/aiguard/sdk.js +3 -0
  145. package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
  146. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -1
  147. package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
  148. package/packages/dd-trace/src/appsec/handlers/http-request.js +215 -0
  149. package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
  150. package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
  151. package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
  152. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +1 -1
  153. package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-analyzer.js +1 -1
  154. package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
  155. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
  156. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -3
  157. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +2 -2
  158. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +2 -2
  159. package/packages/dd-trace/src/appsec/index.js +48 -476
  160. package/packages/dd-trace/src/appsec/sdk/track_event.js +10 -1
  161. package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
  162. package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
  163. package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
  164. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +7 -6
  165. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +29 -15
  166. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +19 -1
  167. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +25 -1
  168. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/webdriverio.js +26 -0
  169. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -1
  170. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
  171. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
  172. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -3
  173. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
  174. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +2 -2
  175. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
  176. package/packages/dd-trace/src/config/defaults.js +14 -6
  177. package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -2
  178. package/packages/dd-trace/src/config/helper.js +2 -0
  179. package/packages/dd-trace/src/config/index.js +31 -5
  180. package/packages/dd-trace/src/config/parsers.js +19 -1
  181. package/packages/dd-trace/src/config/remote_config.js +1 -1
  182. package/packages/dd-trace/src/config/supported-configurations.json +13 -6
  183. package/packages/dd-trace/src/datastreams/encoding.js +3 -4
  184. package/packages/dd-trace/src/debugger/devtools_client/log.js +2 -1
  185. package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +1 -4
  186. package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -2
  187. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +2 -2
  188. package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +16 -2
  189. package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
  190. package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
  191. package/packages/dd-trace/src/encode/tags-processors.js +2 -2
  192. package/packages/dd-trace/src/exporters/common/url.js +3 -5
  193. package/packages/dd-trace/src/exporters/electron/index.js +4 -1
  194. package/packages/dd-trace/src/external-logger/src/index.js +1 -2
  195. package/packages/dd-trace/src/flare/index.js +2 -2
  196. package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
  197. package/packages/dd-trace/src/guardrails/log.js +1 -10
  198. package/packages/dd-trace/src/id.js +1 -1
  199. package/packages/dd-trace/src/llmobs/constants/tags.js +1 -1
  200. package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
  201. package/packages/dd-trace/src/llmobs/experiments/client.js +4 -2
  202. package/packages/dd-trace/src/llmobs/experiments/dataset.js +66 -14
  203. package/packages/dd-trace/src/llmobs/experiments/experiment.js +289 -95
  204. package/packages/dd-trace/src/llmobs/experiments/index.js +66 -19
  205. package/packages/dd-trace/src/llmobs/experiments/noop.js +95 -10
  206. package/packages/dd-trace/src/llmobs/experiments/result.js +13 -2
  207. package/packages/dd-trace/src/llmobs/experiments/util.js +220 -0
  208. package/packages/dd-trace/src/llmobs/noop.js +2 -0
  209. package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
  210. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
  211. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +1 -1
  212. package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
  213. package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +1 -1
  214. package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
  215. package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
  216. package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
  217. package/packages/dd-trace/src/llmobs/sdk.js +152 -78
  218. package/packages/dd-trace/src/llmobs/span_processor.js +9 -7
  219. package/packages/dd-trace/src/llmobs/tagger.js +1 -2
  220. package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
  221. package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
  222. package/packages/dd-trace/src/llmobs/writers/spans.js +12 -6
  223. package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
  224. package/packages/dd-trace/src/log/channels.js +1 -9
  225. package/packages/dd-trace/src/log/levels.js +12 -0
  226. package/packages/dd-trace/src/noop/proxy.js +2 -2
  227. package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
  228. package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
  229. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
  230. package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
  231. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
  232. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +3 -2
  233. package/packages/dd-trace/src/opentelemetry/span.js +4 -0
  234. package/packages/dd-trace/src/opentracing/span.js +1 -1
  235. package/packages/dd-trace/src/opentracing/span_context.js +1 -1
  236. package/packages/dd-trace/src/plugins/ci_plugin.js +124 -23
  237. package/packages/dd-trace/src/plugins/index.js +2 -0
  238. package/packages/dd-trace/src/plugins/plugin.js +1 -1
  239. package/packages/dd-trace/src/plugins/tracing.js +1 -0
  240. package/packages/dd-trace/src/plugins/util/ci.js +13 -6
  241. package/packages/dd-trace/src/plugins/util/git.js +7 -5
  242. package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +3 -3
  243. package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
  244. package/packages/dd-trace/src/plugins/util/llm.js +2 -2
  245. package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
  246. package/packages/dd-trace/src/plugins/util/tags.js +2 -0
  247. package/packages/dd-trace/src/plugins/util/test.js +356 -86
  248. package/packages/dd-trace/src/plugins/util/url.js +5 -5
  249. package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
  250. package/packages/dd-trace/src/plugins/util/web.js +24 -2
  251. package/packages/dd-trace/src/priority_sampler.js +6 -3
  252. package/packages/dd-trace/src/profiler.js +1 -1
  253. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
  254. package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
  255. package/packages/dd-trace/src/profiling/profilers/poisson.js +1 -1
  256. package/packages/dd-trace/src/profiling/profilers/shared.js +2 -2
  257. package/packages/dd-trace/src/proxy.js +1 -0
  258. package/packages/dd-trace/src/ritm.js +10 -20
  259. package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
  260. package/packages/dd-trace/src/sampling_rule.js +4 -2
  261. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
  262. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
  263. package/packages/dd-trace/src/startup-log.js +3 -0
  264. package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
  265. package/packages/dd-trace/src/telemetry/logs/log-collector.js +3 -1
  266. package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
  267. package/packages/dd-trace/src/util.js +16 -0
  268. package/vendor/dist/@apm-js-collab/code-transformer/index.js +12 -12
  269. package/vendor/dist/pprof-format/index.js +1 -1
  270. package/vendor/dist/source-map/index.js +1 -1
  271. package/version.js +10 -8
  272. /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
package/index.d.ts CHANGED
@@ -71,7 +71,7 @@ interface Tracer extends opentracing.Tracer {
71
71
  * @param plugin The name of a built-in plugin.
72
72
  * @param config Configuration options. Can also be `false` to disable the plugin.
73
73
  */
74
- use<P extends keyof Plugins> (plugin: P, config?: Plugins[P] | boolean): this;
74
+ use<P extends tracer.PluginName> (plugin: P, config?: tracer.PluginOptions[P] | boolean): this;
75
75
 
76
76
  /**
77
77
  * Returns a reference to the current scope.
@@ -314,6 +314,9 @@ interface Plugins {
314
314
  }
315
315
 
316
316
  declare namespace tracer {
317
+ export interface PluginOptions extends Plugins {}
318
+ export type PluginName = keyof PluginOptions;
319
+
317
320
  export type SpanOptions = Omit<opentracing.SpanOptions, 'childOf'> & {
318
321
  /**
319
322
  * Set childOf to 'null' to create a root span without a parent, even when a parent span
@@ -3711,6 +3714,13 @@ declare namespace tracer {
3711
3714
  */
3712
3715
  submitEvaluation (spanContext: llmobs.ExportedLLMObsSpan, options: llmobs.EvaluationOptions): void
3713
3716
 
3717
+ /**
3718
+ * Submits end-user feedback for a span, trace, session, or customer-defined entity.
3719
+ * Exactly one target must be provided in the options.
3720
+ * @param options An object containing the label, metric type, value, submitter and target of the feedback.
3721
+ */
3722
+ submitFeedback (options: llmobs.FeedbackOptions): void
3723
+
3714
3724
 
3715
3725
  /**
3716
3726
  * Annotates all spans, including auto-instrumented spans, with the provided tags created in the context of the callback function.
@@ -3734,29 +3744,74 @@ declare namespace tracer {
3734
3744
  flush (): void
3735
3745
  }
3736
3746
 
3747
+ /** JSON-serializable value accepted by LLMObs Experiments. */
3748
+ type JSONType = string | number | boolean | null | JSONType[] | { [key: string]: JSONType }
3749
+
3737
3750
  /**
3738
3751
  * A task run over each dataset record during an experiment.
3739
3752
  */
3740
- type ExperimentTask = (input: any, config: Record<string, any>) => any | Promise<any>
3753
+ type ExperimentTask = (
3754
+ input: JSONType,
3755
+ config: Record<string, JSONType>,
3756
+ metadata?: Record<string, JSONType>
3757
+ ) => JSONType | Promise<JSONType>
3741
3758
 
3742
3759
  /**
3743
3760
  * Scores a single task output. The return type selects the metric:
3744
- * `boolean` -> boolean, `number` -> score, anything else -> categorical.
3761
+ * `boolean` -> boolean, `number` -> score, `string` -> categorical, anything else -> json.
3745
3762
  */
3746
- type ExperimentEvaluator = (input: any, output: any, expectedOutput: any) => any | Promise<any>
3763
+ type ExperimentEvaluator = (
3764
+ input: JSONType,
3765
+ output: JSONType,
3766
+ expectedOutput: JSONType
3767
+ ) => JSONType | Promise<JSONType>
3768
+
3769
+ /**
3770
+ * Scores all rows in an experiment run and emits a summary metric.
3771
+ */
3772
+ type ExperimentSummaryEvaluator = (
3773
+ inputs: any[],
3774
+ outputs: any[],
3775
+ expectedOutputs: any[],
3776
+ evaluatorResults: Record<string, any[]>,
3777
+ metadata?: Array<Record<string, any>>
3778
+ ) => any | Promise<any>
3779
+
3780
+ interface CreateDatasetOptions {
3781
+ description?: string
3782
+ records?: Array<{
3783
+ id?: string,
3784
+ inputData: JSONType,
3785
+ expectedOutput?: JSONType,
3786
+ metadata?: Record<string, JSONType>
3787
+ }>
3788
+ }
3747
3789
 
3748
3790
  interface ExperimentOptions {
3749
3791
  name: string
3750
3792
  dataset: Dataset
3751
3793
  task: ExperimentTask
3752
- /** Evaluators keyed by metric label. */
3753
- evaluators?: Record<string, ExperimentEvaluator>
3794
+ /** Evaluators keyed by metric label, or named functions. */
3795
+ evaluators?: Record<string, ExperimentEvaluator> | ExperimentEvaluator[]
3796
+ /** Summary evaluators keyed by metric label, or named functions. */
3797
+ summaryEvaluators?: Record<string, ExperimentSummaryEvaluator> | ExperimentSummaryEvaluator[]
3754
3798
  description?: string
3755
- config?: Record<string, any>
3799
+ config?: Record<string, JSONType>
3756
3800
  tags?: Record<string, string>
3757
3801
  }
3758
3802
 
3803
+ interface ExperimentRunOptions {
3804
+ /** Maximum retries for task and evaluator failures. Default 0. */
3805
+ maxRetries?: number
3806
+ /** Delay before a retry, in milliseconds. Default 100 * (attempt + 1). */
3807
+ retryDelay?: (attempt: number) => number
3808
+ /** Reject on the first task/evaluator error instead of capturing it. Default false. */
3809
+ throwOnErrors?: boolean
3810
+ }
3811
+
3759
3812
  interface PullDatasetOptions {
3813
+ /** Dataset version to pull. Defaults to latest. */
3814
+ version?: number
3760
3815
  /** Wait until at least this many records are readable (absorbs write lag). */
3761
3816
  expectedRecordCount?: number
3762
3817
  /** Maximum total time to wait, in ms. Default 30000. */
@@ -3769,19 +3824,30 @@ declare namespace tracer {
3769
3824
  traceId: string
3770
3825
  startNs: number
3771
3826
  durationNs: number
3772
- input: any
3773
- output: any
3774
- expectedOutput: any
3827
+ input: JSONType
3828
+ output: JSONType
3829
+ expectedOutput: JSONType
3775
3830
  readonly isError: boolean
3776
3831
  errorType: string | null
3777
3832
  errorMessage: string | null
3778
- evaluations: Record<string, any>
3833
+ evaluations: Record<string, JSONType>
3779
3834
  evaluationErrors: Record<string, string>
3780
3835
  }
3781
3836
 
3837
+ interface ExperimentRun {
3838
+ runId: string
3839
+ runIteration: number
3840
+ rows: ExperimentResultRow[]
3841
+ summaryEvaluations: Record<string, { value: any, error: string | null }>
3842
+ }
3843
+
3782
3844
  interface ExperimentResult {
3783
3845
  experimentId: string
3784
3846
  rows: ExperimentResultRow[]
3847
+ /** Single-run summary evaluator results. */
3848
+ summaryEvaluations: Record<string, { value: any, error: string | null }>
3849
+ /** Experiment runs. P0 Node experiments currently return one run. */
3850
+ runs: ExperimentRun[]
3785
3851
  /** Dashboard URL for the experiment. */
3786
3852
  url: string
3787
3853
  }
@@ -3794,13 +3860,20 @@ declare namespace tracer {
3794
3860
  }
3795
3861
 
3796
3862
  interface Dataset {
3797
- addRecord (input: any, expectedOutput?: any, metadata?: Record<string, any>): Dataset
3863
+ addRecord (input: JSONType, expectedOutput?: JSONType, metadata?: Record<string, JSONType>): Dataset
3798
3864
  /** Creates the dataset remotely if needed and pushes any unpushed records. */
3799
3865
  push (): Promise<DatasetPushResult>
3800
3866
  name (): string
3801
3867
  id (): string | null
3802
3868
  projectId (): string | null
3803
- records (): Array<{ input: any, expectedOutput: any, metadata: Record<string, any> }>
3869
+ version (): number | null
3870
+ latestVersion (): number | null
3871
+ records (): Array<{
3872
+ id: string | null,
3873
+ input: JSONType,
3874
+ expectedOutput: JSONType,
3875
+ metadata: Record<string, JSONType>
3876
+ }>
3804
3877
  /** Dashboard URL for the dataset, or null until pushed. */
3805
3878
  url (): string | null
3806
3879
  }
@@ -3809,12 +3882,13 @@ declare namespace tracer {
3809
3882
  name (): string
3810
3883
  experimentId (): string | null
3811
3884
  url (): string | null
3812
- run (): Promise<ExperimentResult>
3885
+ run (options?: ExperimentRunOptions): Promise<ExperimentResult>
3813
3886
  }
3814
3887
 
3815
3888
  interface Experiments {
3816
3889
  /** Create a local dataset buffer; pushed on the first experiment run. */
3817
3890
  createDataset (name: string, description?: string): Dataset
3891
+ createDataset (name: string, options?: CreateDatasetOptions): Dataset
3818
3892
  /** Pull an existing dataset (with records) by name. */
3819
3893
  pullDataset (name: string, options?: PullDatasetOptions): Promise<Dataset>
3820
3894
  /** Build an experiment to run over a dataset. */
@@ -3893,6 +3967,93 @@ declare namespace tracer {
3893
3967
  metadata?: { [key: string]: any }
3894
3968
  }
3895
3969
 
3970
+ interface FeedbackSubmitter {
3971
+ /**
3972
+ * The identifier of the end user who submitted the feedback.
3973
+ */
3974
+ id: string,
3975
+
3976
+ /**
3977
+ * The type of submitter, e.g. 'user'.
3978
+ */
3979
+ type?: string
3980
+ }
3981
+
3982
+ interface FeedbackOptions {
3983
+ /**
3984
+ * The name of the feedback metric
3985
+ */
3986
+ label: string,
3987
+
3988
+ /**
3989
+ * The type of feedback metric, one of 'categorical', 'score', 'boolean', 'json' or 'text'
3990
+ */
3991
+ metricType: 'categorical' | 'score' | 'boolean' | 'json' | 'text',
3992
+
3993
+ /**
3994
+ * The value of the feedback metric.
3995
+ * Must be string for 'categorical' and 'text' metrics, number for 'score' metrics, boolean for 'boolean' metrics and a JSON object for 'json' metrics.
3996
+ */
3997
+ value: string | number | boolean | { [key: string]: any },
3998
+
3999
+ /**
4000
+ * Who submitted the feedback.
4001
+ */
4002
+ submitter: llmobs.FeedbackSubmitter,
4003
+
4004
+ /**
4005
+ * The span context of the span to attach the feedback to, as returned by `llmobs.exportSpan()`.
4006
+ * Exactly one of `span`, `spanId`, `traceId`, `sessionId` or `feedbackJoinKey` must be provided.
4007
+ */
4008
+ span?: llmobs.ExportedLLMObsSpan,
4009
+
4010
+ /**
4011
+ * The ID of the span to attach the feedback to.
4012
+ */
4013
+ spanId?: string,
4014
+
4015
+ /**
4016
+ * The ID of the trace to attach the feedback to.
4017
+ */
4018
+ traceId?: string,
4019
+
4020
+ /**
4021
+ * The ID of the session to attach the feedback to.
4022
+ */
4023
+ sessionId?: string,
4024
+
4025
+ /**
4026
+ * A customer-defined key to attach the feedback to.
4027
+ */
4028
+ feedbackJoinKey?: string,
4029
+
4030
+ /**
4031
+ * An object of string key-value pairs to tag the feedback with.
4032
+ * A `null` or `undefined` value is sent as the string `"null"` or `"undefined"`.
4033
+ */
4034
+ tags?: { [key: string]: string | null | undefined },
4035
+
4036
+ /**
4037
+ * The name of the ML application
4038
+ */
4039
+ mlApp?: string,
4040
+
4041
+ /**
4042
+ * The timestamp in milliseconds when the feedback was generated.
4043
+ */
4044
+ timestampMs?: number,
4045
+
4046
+ /**
4047
+ * Reasoning for the feedback.
4048
+ */
4049
+ reasoning?: string,
4050
+
4051
+ /**
4052
+ * Whether the feedback passed or failed. Valid values are pass and fail.
4053
+ */
4054
+ assessment?: 'pass' | 'fail'
4055
+ }
4056
+
3896
4057
  interface Document {
3897
4058
  /**
3898
4059
  * Document text
package/init.js CHANGED
@@ -1,22 +1,6 @@
1
1
  'use strict'
2
2
 
3
- // In PM2 cluster mode, per-app env vars arrive as a `pm2_env`
4
- // JSON string after --require has already run so we extract them
5
- // manually if present.
6
- var pm2EnvStr = process.env.pm2_env
7
- if (typeof pm2EnvStr === 'string') {
8
- try {
9
- var pm2Config = JSON.parse(pm2EnvStr)
10
- var pm2Keys = Object.keys(pm2Config)
11
- for (var i = 0; i < pm2Keys.length; i++) {
12
- var k = pm2Keys[i]
13
- var v = pm2Config[k]
14
- if (v != null) {
15
- process.env[k] = String(v)
16
- }
17
- }
18
- } catch (e) {}
19
- }
3
+ require('./packages/dd-trace/src/guardrails/apply-pm2-env')
20
4
 
21
5
  var guard = require('./packages/dd-trace/src/guardrails')
22
6
 
package/initialize.mjs CHANGED
@@ -20,6 +20,7 @@ import { isMainThread } from 'worker_threads'
20
20
 
21
21
  import {
22
22
  iitmExclusionRegExp,
23
+ initialize as hookInitialize,
23
24
  load as hookLoad,
24
25
  resolve as hookResolve,
25
26
  } from './loader-hook.mjs?initialize'
@@ -66,7 +67,17 @@ const [NODE_MAJOR, NODE_MINOR] = process.versions.node.split('.').map(Number)
66
67
 
67
68
  const brokenLoaders = NODE_MAJOR === 18 && NODE_MINOR === 0
68
69
 
70
+ // Node calls `initialize` only through `module.register`, never for `--loader`; without it
71
+ // import-in-the-middle keeps its default matcher and proxies every application module. Loaders
72
+ // before Node 18.19 share the application thread, where `loader-hook.mjs` builds no matcher.
73
+ let needsHookInitialize = !isMainThread && !brokenLoaders
74
+
69
75
  export async function load (url, context, nextLoad) {
76
+ if (needsHookInitialize) {
77
+ needsHookInitialize = false
78
+ hookInitialize()
79
+ }
80
+
70
81
  const loadHook = (brokenLoaders || iitmExclusionRegExp.test(url)) ? nextLoad : hookLoad
71
82
  return insertInit(await loadHook(url, context, nextLoad), url, context)
72
83
  }
package/loader-hook.mjs CHANGED
@@ -16,7 +16,6 @@ const require = Module.createRequire(import.meta.url)
16
16
  const isInitializeMainThread = isMainThread && import.meta.url.endsWith('?initialize')
17
17
  let syncImportInTheMiddleHook
18
18
 
19
- let getValueFromEnvSources
20
19
  let regexpEscape
21
20
 
22
21
  // Substrings of resolved URLs that import-in-the-middle must never wrap: re-export
@@ -32,13 +31,12 @@ const includeModuleNames = new Set()
32
31
  let moduleNameAlternation = ''
33
32
 
34
33
  if (!isInitializeMainThread) {
34
+ require('./packages/dd-trace/src/guardrails/apply-pm2-env.js')
35
35
  const regexpEscapeModule = require('./vendor/dist/escape-string-regexp/index.js')
36
36
  const hooks = require('./packages/datadog-instrumentations/src/helpers/hooks.js')
37
- const configHelper = require('./packages/dd-trace/src/config/helper.js')
38
37
  const { isRelativeRequire } = require('./packages/datadog-instrumentations/src/helpers/shared-utils.js')
39
38
 
40
39
  regexpEscape = regexpEscapeModule.default
41
- getValueFromEnvSources = configHelper.getValueFromEnvSources
42
40
 
43
41
  for (const moduleName of Object.keys(hooks)) {
44
42
  // Relative hooks resolve outside node_modules and are not instrumented here.
@@ -63,7 +61,11 @@ function prepareImportInTheMiddleOptions (data = {}) {
63
61
  // A consumer-owned shouldInclude predicate takes over the wrapping decision, so
64
62
  // iitm ignores the include/exclude arrays. Building the matcher here keeps the
65
63
  // synchronous and asynchronous loaders on one matching implementation.
66
- data.shouldInclude = createShouldInclude(getValueFromEnvSources('DD_IAST_SECURITY_CONTROLS_CONFIGURATION'))
64
+ // Lazily required and read without its registered default so a loader worker
65
+ // never loads the configuration defaults table. The default is unset regardless.
66
+ const { getValueFromEnvSources } = require('./packages/dd-trace/src/config/helper.js')
67
+
68
+ data.shouldInclude = createShouldInclude(getValueFromEnvSources('DD_IAST_SECURITY_CONTROLS_CONFIGURATION', true))
67
69
 
68
70
  return data
69
71
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "6.7.0",
3
+ "version": "6.9.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -15,6 +15,8 @@
15
15
  "generate:electron-package": "node scripts/generate-electron-package.js",
16
16
  "verify:config:types": "node scripts/generate-config-types.js --check",
17
17
  "verify:electron-package": "node scripts/generate-electron-package.js --check",
18
+ "generate:rewriter:targets": "node scripts/generate-rewriter-targets.js",
19
+ "verify:rewriter:targets": "node scripts/generate-rewriter-targets.js --check",
18
20
  "generate:supported-integrations": "node scripts/generate-supported-integrations.js",
19
21
  "verify:supported-integrations": "node scripts/generate-supported-integrations.js --check",
20
22
  "type:check": "tsc --noEmit -p tsconfig.dev.json",
@@ -24,7 +26,7 @@
24
26
  "lint:fix": "node scripts/check_licenses.js && node scripts/check-no-coverage-artifacts.js && node scripts/check-no-mcr-images.js && node scripts/check-docker-image-shas.js && eslint . --concurrency=auto --max-warnings 0 --fix",
25
27
  "lint:inspect": "npx @eslint/config-inspector@latest",
26
28
  "lint:codeowners": "codeowners-audit",
27
- "lint:codeowners:ci": "codeowners-audit --glob='**/*.spec.js' --glob='benchmark/sirun/**' --glob='.agents/**' --glob='.claude/**' --glob='integration-tests/**'",
29
+ "lint:codeowners:ci": "codeowners-audit --glob='**/*.spec.js' --glob='benchmark/sirun/**' --glob='.agents/**' --glob='.claude/**' --glob='integration-tests/**' --glob='packages/dd-trace/src/guardrails/**'",
28
30
  "lint:editorconfig": "docker build -q -t ec .github/editorconfig-checker && docker run --rm --volume=$PWD:/check ec",
29
31
  "release:proposal": "node scripts/release/proposal",
30
32
  "services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
@@ -96,6 +98,9 @@
96
98
  "test:integration:playwright:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/playwright/${SPEC:-playwright-*}.spec.js\"",
97
99
  "test:integration:selenium": "mocha --timeout 60000 \"integration-tests/selenium/*.spec.js\"",
98
100
  "test:integration:selenium:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/selenium/*.spec.js\"",
101
+ "test:integration:test-optimization:helpers": "mocha \"integration-tests/cypress/*dependencies.spec.js\" \"integration-tests/jest/*dependencies.spec.js\" \"integration-tests/playwright/version*.spec.js\"",
102
+ "test:integration:webdriverio": "mocha --timeout 60000 \"integration-tests/webdriverio/*.spec.js\"",
103
+ "test:integration:webdriverio:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/webdriverio/*.spec.js\"",
99
104
  "test:integration:vitest": "mocha --timeout 60000 \"integration-tests/vitest/${SPEC:-vitest*}.spec.js\"",
100
105
  "test:integration:vitest:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/vitest/${SPEC:-vitest*}.spec.js\"",
101
106
  "test:integration:testopt": "mocha --timeout 120000 \"integration-tests/ci-visibility/*.spec.js\"",
@@ -178,7 +183,7 @@
178
183
  "@datadog/native-appsec": "11.0.1",
179
184
  "@datadog/native-iast-taint-tracking": "4.2.0",
180
185
  "@datadog/native-metrics": "3.1.2",
181
- "@datadog/openfeature-node-server": "2.0.0",
186
+ "@datadog/openfeature-node-server": "2.0.2",
182
187
  "@datadog/pprof": "5.17.0",
183
188
  "@datadog/wasm-js-rewriter": "5.0.1",
184
189
  "@opentelemetry/api": ">=1.0.0 <1.10.0",
@@ -199,6 +204,7 @@
199
204
  "@types/node": "^18.19.106",
200
205
  "@types/sinon": "^22.0.0",
201
206
  "@vercel/nft": "^1.10.2",
207
+ "@yarnpkg/lockfile": "^1.1.0",
202
208
  "axios": "^1.18.1",
203
209
  "benchmark": "^2.1.4",
204
210
  "body-parser": "^2.3.0",
@@ -213,7 +219,7 @@
213
219
  "eslint-plugin-n": "^18.2.1",
214
220
  "eslint-plugin-promise": "^7.3.0",
215
221
  "eslint-plugin-sonarjs": "^4.2.0",
216
- "eslint-plugin-unicorn": "^68.0.0",
222
+ "eslint-plugin-unicorn": "^73.0.0",
217
223
  "express": "^5.1.0",
218
224
  "glob": "^10.4.5",
219
225
  "globals": "^17.7.0",
@@ -221,7 +227,9 @@
221
227
  "husky": "^9.1.7",
222
228
  "istanbul-lib-report": "^3.0.0",
223
229
  "istanbul-reports": "^3.0.2",
230
+ "jsonc-parser": "^3.3.1",
224
231
  "jszip": "^3.10.1",
232
+ "minimatch": "^10.2.5",
225
233
  "mocha": "^11.7.6",
226
234
  "mocha-junit-reporter": "^2.2.1",
227
235
  "mocha-multi-reporters": "^1.5.1",
@@ -5,10 +5,16 @@ module.exports = function kebabcase (str) {
5
5
  throw new TypeError('Expected a string')
6
6
  }
7
7
 
8
- return str
8
+ const kebab = str
9
9
  .trim()
10
10
  .replaceAll(/([a-z])([A-Z])/g, '$1-$2') // Convert camelCase to kebab-case
11
11
  .replaceAll(/[\s_]+/g, '-') // Replace spaces and underscores with a single dash
12
- .replaceAll(/^-+|-+$/g, '') // Trim leading and trailing dashes
13
12
  .toLowerCase()
13
+
14
+ // Trim by index; a `/-+$/` regex re-examines the dash run once per start position.
15
+ let start = 0
16
+ let end = kebab.length
17
+ while (kebab.charCodeAt(start) === 45) start++ // '-'
18
+ while (end > start && kebab.charCodeAt(end - 1) === 45) end--
19
+ return kebab.slice(start, end)
14
20
  }
@@ -9,7 +9,6 @@ const digitRegex = /^\d+$/
9
9
  * { 'a.0.b': 'value' } -> { a: [{ b: 'value' }] }
10
10
  *
11
11
  * @param {object} tags - Key/value pairs of tags
12
- * @returns Object - Parsed tags
13
12
  */
14
13
  module.exports = function parseTags (tags) {
15
14
  const parsedTags = {}
@@ -265,10 +265,12 @@ ${build.initialOptions.banner.js}`
265
265
  }
266
266
  }
267
267
  // The file namespace is used when requiring files from disk in userland
268
+ if (extracted.pkg === null) return
269
+
268
270
  let pathToPackageJson
269
271
  try {
270
272
  // we can't use require.resolve('pkg/package.json') as ESM modules don't make the file available
271
- pathToPackageJson = require.resolve(`${extracted.pkg}`, { paths: [args.resolveDir] })
273
+ pathToPackageJson = require.resolve(extracted.pkg, { paths: [args.resolveDir] })
272
274
  pathToPackageJson = extractPackageAndModulePath(pathToPackageJson).pkgJson
273
275
  } catch (err) {
274
276
  if (err.code === 'MODULE_NOT_FOUND') {
@@ -340,7 +342,7 @@ ${build.initialOptions.banner.js}`
340
342
 
341
343
  if (data.isESM) {
342
344
  if (args.path.endsWith(ESM_INTERCEPTED_SUFFIX)) {
343
- args.path = args.path.slice(0, -1 * ESM_INTERCEPTED_SUFFIX.length)
345
+ args.path = args.path.slice(0, -ESM_INTERCEPTED_SUFFIX.length)
344
346
 
345
347
  if (data.internal) {
346
348
  args.path = args.path.slice(INTERNAL_ESM_INTERCEPTED_PREFIX.length)
@@ -85,10 +85,25 @@ function getSource (url, { format }) {
85
85
  }
86
86
  }
87
87
 
88
+ /**
89
+ * @typedef {[typeof LOAD_OPERATION, URL, object] | [typeof RESOLVE_OPERATION, string, object]} GetExportsOperation
90
+ */
91
+
92
+ /**
93
+ * @typedef {{ done: false, value: GetExportsOperation } | { done: true, value: Set<string> }} GetExportsResult
94
+ */
95
+
96
+ /**
97
+ * @typedef {{
98
+ * next: (value?: unknown) => GetExportsResult,
99
+ * throw: (error?: unknown) => GetExportsResult,
100
+ * }} GetExportsGenerator
101
+ */
102
+
88
103
  /**
89
104
  * Drives the generator returned by import-in-the-middle >=3.1.0 export discovery.
90
105
  *
91
- * @param {Generator<Array, Set<string>>} exportsGenerator Generator returned by getExports
106
+ * @param {GetExportsGenerator} exportsGenerator Generator returned by getExports
92
107
  * @param {(url: URL, context: object) => { source: string, format: string }} getSource
93
108
  * Function that loads module source
94
109
  * @returns {Set<string>}
@@ -174,7 +189,7 @@ async function processModule ({ path, internal = false, context, excludeDefault
174
189
  for (const n of exportNames) {
175
190
  if (n === 'default' && excludeDefault) continue
176
191
 
177
- if (isStarExportLine(n) === true) {
192
+ if (isStarExportLine(n)) {
178
193
  // export * from 'wherever'
179
194
  const [, modFile] = n.split('* from ')
180
195
 
@@ -116,6 +116,66 @@ function wrapModelWithLifecycle (model) {
116
116
  }
117
117
  }
118
118
 
119
+ /**
120
+ * Wraps an OTel span without changing its method receivers.
121
+ *
122
+ * OTel spans may use private fields, so methods must run against the original
123
+ * span. A per-invocation wrapper also preserves `ctx` without mutating the AI
124
+ * SDK's shared no-op span.
125
+ *
126
+ * @param {import('@opentelemetry/api').Span} span
127
+ * @param {object} ctx
128
+ * @returns {import('@opentelemetry/api').Span}
129
+ */
130
+ function createDelegatingSpan (span, ctx) {
131
+ return {
132
+ spanContext () {
133
+ return span.spanContext.apply(span, arguments)
134
+ },
135
+ setAttribute () {
136
+ span.setAttribute.apply(span, arguments)
137
+ return this
138
+ },
139
+ setAttributes (attributes) {
140
+ vercelAiSpanSetAttributesChannel.publish({ ctx, attributes })
141
+ span.setAttributes.apply(span, arguments)
142
+ return this
143
+ },
144
+ addEvent () {
145
+ span.addEvent.apply(span, arguments)
146
+ return this
147
+ },
148
+ addLink () {
149
+ span.addLink.apply(span, arguments)
150
+ return this
151
+ },
152
+ addLinks () {
153
+ span.addLinks.apply(span, arguments)
154
+ return this
155
+ },
156
+ setStatus () {
157
+ span.setStatus.apply(span, arguments)
158
+ return this
159
+ },
160
+ updateName () {
161
+ span.updateName.apply(span, arguments)
162
+ return this
163
+ },
164
+ isRecording () {
165
+ return span.isRecording.apply(span, arguments)
166
+ },
167
+ recordException (exception) {
168
+ ctx.error = exception
169
+ vercelAiTracingChannel.error.publish(ctx)
170
+ return span.recordException.apply(span, arguments)
171
+ },
172
+ end () {
173
+ vercelAiTracingChannel.asyncEnd.publish(ctx)
174
+ return span.end.apply(span, arguments)
175
+ },
176
+ }
177
+ }
178
+
119
179
  function wrapTracer (tracer) {
120
180
  if (tracers.has(tracer)) {
121
181
  return
@@ -136,40 +196,7 @@ function wrapTracer (tracer) {
136
196
 
137
197
  args[args.length - 1] = shimmer.wrapFunction(cb, function (originalCb) {
138
198
  return function (span) {
139
- // A plain delegating wrapper is used instead of Object.create(span) because
140
- // Object.create (and Proxy) cannot cross private-field brand checks — any span
141
- // method that reads a private field (e.g. BridgeSpanBase#statusCode) would throw
142
- // "Cannot read private member" on a prototype clone. Every method here calls
143
- // through to the real span instance so private fields always resolve correctly.
144
- const freshSpan = {
145
- spanContext () { return span.spanContext() },
146
- setAttribute (key, value) { span.setAttribute(key, value); return freshSpan },
147
- setAttributes (attributes) {
148
- vercelAiSpanSetAttributesChannel.publish({ ctx, attributes })
149
- span.setAttributes(attributes)
150
- return freshSpan
151
- },
152
- addEvent (name, attributesOrStartTime, startTime) {
153
- span.addEvent(name, attributesOrStartTime, startTime)
154
- return freshSpan
155
- },
156
- addLink (link, attrs) { span.addLink(link, attrs); return freshSpan },
157
- addLinks (links) { span.addLinks(links); return freshSpan },
158
- setStatus (status) { span.setStatus(status); return freshSpan },
159
- updateName (spanName) { span.updateName(spanName); return freshSpan },
160
- isRecording () { return span.isRecording() },
161
- recordException (exception, timeInput) {
162
- ctx.error = exception
163
- vercelAiTracingChannel.error.publish(ctx)
164
- span.recordException(exception, timeInput)
165
- },
166
- end (...endArgs) {
167
- vercelAiTracingChannel.asyncEnd.publish(ctx)
168
- span.end(...endArgs)
169
- },
170
- }
171
-
172
- return originalCb.call(this, freshSpan)
199
+ return originalCb.call(this, createDelegatingSpan(span, ctx))
173
200
  }
174
201
  })
175
202
 
@@ -15,12 +15,12 @@ function createGetNewLibraryCopyWrap (originalLib) {
15
15
  }
16
16
  }
17
17
 
18
- addHook({ name: 'bluebird', versions: ['>=2.0.2'] }, Promise => {
19
- shimmer.wrap(Promise.prototype, '_then', wrapThen)
20
- return Promise
18
+ addHook({ name: 'bluebird', versions: ['>=2.0.2'] }, LibraryPromise => {
19
+ shimmer.wrap(LibraryPromise.prototype, '_then', wrapThen)
20
+ return LibraryPromise
21
21
  })
22
22
 
23
- addHook({ name: 'bluebird', versions: ['^2.11.0', '^3.4.1'] }, Promise => {
24
- shimmer.wrap(Promise, 'getNewLibraryCopy', createGetNewLibraryCopyWrap(Promise))
25
- return Promise
23
+ addHook({ name: 'bluebird', versions: ['^2.11.0', '^3.4.1'] }, LibraryPromise => {
24
+ shimmer.wrap(LibraryPromise, 'getNewLibraryCopy', createGetNewLibraryCopyWrap(LibraryPromise))
25
+ return LibraryPromise
26
26
  })