dd-trace 5.118.0 → 5.120.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.
@@ -316,6 +316,9 @@ interface Plugins {
316
316
  }
317
317
 
318
318
  declare namespace tracer {
319
+ export interface PluginOptions extends Plugins {}
320
+ export type PluginName = keyof PluginOptions;
321
+
319
322
  export type SpanOptions = Omit<opentracing.SpanOptions, 'childOf'> & {
320
323
  /**
321
324
  * Set childOf to 'null' to create a root span without a parent, even when a parent span
@@ -3908,6 +3911,13 @@ declare namespace tracer {
3908
3911
  */
3909
3912
  submitEvaluation (spanContext: llmobs.ExportedLLMObsSpan, options: llmobs.EvaluationOptions): void
3910
3913
 
3914
+ /**
3915
+ * Submits end-user feedback for a span, trace, session, or customer-defined entity.
3916
+ * Exactly one target must be provided in the options.
3917
+ * @param options An object containing the label, metric type, value, submitter and target of the feedback.
3918
+ */
3919
+ submitFeedback (options: llmobs.FeedbackOptions): void
3920
+
3911
3921
 
3912
3922
  /**
3913
3923
  * Annotates all spans, including auto-instrumented spans, with the provided tags created in the context of the callback function.
@@ -3931,29 +3941,74 @@ declare namespace tracer {
3931
3941
  flush (): void
3932
3942
  }
3933
3943
 
3944
+ /** JSON-serializable value accepted by LLMObs Experiments. */
3945
+ type JSONType = string | number | boolean | null | JSONType[] | { [key: string]: JSONType }
3946
+
3934
3947
  /**
3935
3948
  * A task run over each dataset record during an experiment.
3936
3949
  */
3937
- type ExperimentTask = (input: any, config: Record<string, any>) => any | Promise<any>
3950
+ type ExperimentTask = (
3951
+ input: JSONType,
3952
+ config: Record<string, JSONType>,
3953
+ metadata?: Record<string, JSONType>
3954
+ ) => JSONType | Promise<JSONType>
3938
3955
 
3939
3956
  /**
3940
3957
  * Scores a single task output. The return type selects the metric:
3941
- * `boolean` -> boolean, `number` -> score, anything else -> categorical.
3958
+ * `boolean` -> boolean, `number` -> score, `string` -> categorical, anything else -> json.
3942
3959
  */
3943
- type ExperimentEvaluator = (input: any, output: any, expectedOutput: any) => any | Promise<any>
3960
+ type ExperimentEvaluator = (
3961
+ input: JSONType,
3962
+ output: JSONType,
3963
+ expectedOutput: JSONType
3964
+ ) => JSONType | Promise<JSONType>
3965
+
3966
+ /**
3967
+ * Scores all rows in an experiment run and emits a summary metric.
3968
+ */
3969
+ type ExperimentSummaryEvaluator = (
3970
+ inputs: any[],
3971
+ outputs: any[],
3972
+ expectedOutputs: any[],
3973
+ evaluatorResults: Record<string, any[]>,
3974
+ metadata?: Array<Record<string, any>>
3975
+ ) => any | Promise<any>
3976
+
3977
+ interface CreateDatasetOptions {
3978
+ description?: string
3979
+ records?: Array<{
3980
+ id?: string,
3981
+ inputData: JSONType,
3982
+ expectedOutput?: JSONType,
3983
+ metadata?: Record<string, JSONType>
3984
+ }>
3985
+ }
3944
3986
 
3945
3987
  interface ExperimentOptions {
3946
3988
  name: string
3947
3989
  dataset: Dataset
3948
3990
  task: ExperimentTask
3949
- /** Evaluators keyed by metric label. */
3950
- evaluators?: Record<string, ExperimentEvaluator>
3991
+ /** Evaluators keyed by metric label, or named functions. */
3992
+ evaluators?: Record<string, ExperimentEvaluator> | ExperimentEvaluator[]
3993
+ /** Summary evaluators keyed by metric label, or named functions. */
3994
+ summaryEvaluators?: Record<string, ExperimentSummaryEvaluator> | ExperimentSummaryEvaluator[]
3951
3995
  description?: string
3952
- config?: Record<string, any>
3996
+ config?: Record<string, JSONType>
3953
3997
  tags?: Record<string, string>
3954
3998
  }
3955
3999
 
4000
+ interface ExperimentRunOptions {
4001
+ /** Maximum retries for task and evaluator failures. Default 0. */
4002
+ maxRetries?: number
4003
+ /** Delay before a retry, in milliseconds. Default 100 * (attempt + 1). */
4004
+ retryDelay?: (attempt: number) => number
4005
+ /** Reject on the first task/evaluator error instead of capturing it. Default false. */
4006
+ throwOnErrors?: boolean
4007
+ }
4008
+
3956
4009
  interface PullDatasetOptions {
4010
+ /** Dataset version to pull. Defaults to latest. */
4011
+ version?: number
3957
4012
  /** Wait until at least this many records are readable (absorbs write lag). */
3958
4013
  expectedRecordCount?: number
3959
4014
  /** Maximum total time to wait, in ms. Default 30000. */
@@ -3966,19 +4021,30 @@ declare namespace tracer {
3966
4021
  traceId: string
3967
4022
  startNs: number
3968
4023
  durationNs: number
3969
- input: any
3970
- output: any
3971
- expectedOutput: any
4024
+ input: JSONType
4025
+ output: JSONType
4026
+ expectedOutput: JSONType
3972
4027
  readonly isError: boolean
3973
4028
  errorType: string | null
3974
4029
  errorMessage: string | null
3975
- evaluations: Record<string, any>
4030
+ evaluations: Record<string, JSONType>
3976
4031
  evaluationErrors: Record<string, string>
3977
4032
  }
3978
4033
 
4034
+ interface ExperimentRun {
4035
+ runId: string
4036
+ runIteration: number
4037
+ rows: ExperimentResultRow[]
4038
+ summaryEvaluations: Record<string, { value: any, error: string | null }>
4039
+ }
4040
+
3979
4041
  interface ExperimentResult {
3980
4042
  experimentId: string
3981
4043
  rows: ExperimentResultRow[]
4044
+ /** Single-run summary evaluator results. */
4045
+ summaryEvaluations: Record<string, { value: any, error: string | null }>
4046
+ /** Experiment runs. P0 Node experiments currently return one run. */
4047
+ runs: ExperimentRun[]
3982
4048
  /** Dashboard URL for the experiment. */
3983
4049
  url: string
3984
4050
  }
@@ -3991,13 +4057,20 @@ declare namespace tracer {
3991
4057
  }
3992
4058
 
3993
4059
  interface Dataset {
3994
- addRecord (input: any, expectedOutput?: any, metadata?: Record<string, any>): Dataset
4060
+ addRecord (input: JSONType, expectedOutput?: JSONType, metadata?: Record<string, JSONType>): Dataset
3995
4061
  /** Creates the dataset remotely if needed and pushes any unpushed records. */
3996
4062
  push (): Promise<DatasetPushResult>
3997
4063
  name (): string
3998
4064
  id (): string | null
3999
4065
  projectId (): string | null
4000
- records (): Array<{ input: any, expectedOutput: any, metadata: Record<string, any> }>
4066
+ version (): number | null
4067
+ latestVersion (): number | null
4068
+ records (): Array<{
4069
+ id: string | null,
4070
+ input: JSONType,
4071
+ expectedOutput: JSONType,
4072
+ metadata: Record<string, JSONType>
4073
+ }>
4001
4074
  /** Dashboard URL for the dataset, or null until pushed. */
4002
4075
  url (): string | null
4003
4076
  }
@@ -4006,12 +4079,13 @@ declare namespace tracer {
4006
4079
  name (): string
4007
4080
  experimentId (): string | null
4008
4081
  url (): string | null
4009
- run (): Promise<ExperimentResult>
4082
+ run (options?: ExperimentRunOptions): Promise<ExperimentResult>
4010
4083
  }
4011
4084
 
4012
4085
  interface Experiments {
4013
4086
  /** Create a local dataset buffer; pushed on the first experiment run. */
4014
4087
  createDataset (name: string, description?: string): Dataset
4088
+ createDataset (name: string, options?: CreateDatasetOptions): Dataset
4015
4089
  /** Pull an existing dataset (with records) by name. */
4016
4090
  pullDataset (name: string, options?: PullDatasetOptions): Promise<Dataset>
4017
4091
  /** Build an experiment to run over a dataset. */
@@ -4090,6 +4164,93 @@ declare namespace tracer {
4090
4164
  metadata?: { [key: string]: any }
4091
4165
  }
4092
4166
 
4167
+ interface FeedbackSubmitter {
4168
+ /**
4169
+ * The identifier of the end user who submitted the feedback.
4170
+ */
4171
+ id: string,
4172
+
4173
+ /**
4174
+ * The type of submitter, e.g. 'user'.
4175
+ */
4176
+ type?: string
4177
+ }
4178
+
4179
+ interface FeedbackOptions {
4180
+ /**
4181
+ * The name of the feedback metric
4182
+ */
4183
+ label: string,
4184
+
4185
+ /**
4186
+ * The type of feedback metric, one of 'categorical', 'score', 'boolean', 'json' or 'text'
4187
+ */
4188
+ metricType: 'categorical' | 'score' | 'boolean' | 'json' | 'text',
4189
+
4190
+ /**
4191
+ * The value of the feedback metric.
4192
+ * Must be string for 'categorical' and 'text' metrics, number for 'score' metrics, boolean for 'boolean' metrics and a JSON object for 'json' metrics.
4193
+ */
4194
+ value: string | number | boolean | { [key: string]: any },
4195
+
4196
+ /**
4197
+ * Who submitted the feedback.
4198
+ */
4199
+ submitter: llmobs.FeedbackSubmitter,
4200
+
4201
+ /**
4202
+ * The span context of the span to attach the feedback to, as returned by `llmobs.exportSpan()`.
4203
+ * Exactly one of `span`, `spanId`, `traceId`, `sessionId` or `feedbackJoinKey` must be provided.
4204
+ */
4205
+ span?: llmobs.ExportedLLMObsSpan,
4206
+
4207
+ /**
4208
+ * The ID of the span to attach the feedback to.
4209
+ */
4210
+ spanId?: string,
4211
+
4212
+ /**
4213
+ * The ID of the trace to attach the feedback to.
4214
+ */
4215
+ traceId?: string,
4216
+
4217
+ /**
4218
+ * The ID of the session to attach the feedback to.
4219
+ */
4220
+ sessionId?: string,
4221
+
4222
+ /**
4223
+ * A customer-defined key to attach the feedback to.
4224
+ */
4225
+ feedbackJoinKey?: string,
4226
+
4227
+ /**
4228
+ * An object of string key-value pairs to tag the feedback with.
4229
+ * A `null` or `undefined` value is sent as the string `"null"` or `"undefined"`.
4230
+ */
4231
+ tags?: { [key: string]: string | null | undefined },
4232
+
4233
+ /**
4234
+ * The name of the ML application
4235
+ */
4236
+ mlApp?: string,
4237
+
4238
+ /**
4239
+ * The timestamp in milliseconds when the feedback was generated.
4240
+ */
4241
+ timestampMs?: number,
4242
+
4243
+ /**
4244
+ * Reasoning for the feedback.
4245
+ */
4246
+ reasoning?: string,
4247
+
4248
+ /**
4249
+ * Whether the feedback passed or failed. Valid values are pass and fail.
4250
+ */
4251
+ assessment?: 'pass' | 'fail'
4252
+ }
4253
+
4093
4254
  interface Document {
4094
4255
  /**
4095
4256
  * 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": "5.118.0",
3
+ "version": "5.120.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
  })