dd-trace 6.4.0 → 6.6.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 (185) hide show
  1. package/README.electron.md +7 -0
  2. package/README.md +17 -0
  3. package/ci/diagnose.js +2100 -0
  4. package/ci/init.js +23 -2
  5. package/ci/runbook.md +198 -0
  6. package/ci/test-optimization-validation/approval-artifacts.js +143 -0
  7. package/ci/test-optimization-validation/approval.js +299 -0
  8. package/ci/test-optimization-validation/artifact-id.js +20 -0
  9. package/ci/test-optimization-validation/bounded-json.js +121 -0
  10. package/ci/test-optimization-validation/ci-command-candidate.js +83 -0
  11. package/ci/test-optimization-validation/ci-discovery.js +181 -0
  12. package/ci/test-optimization-validation/ci-remediation.js +210 -0
  13. package/ci/test-optimization-validation/cli.js +903 -0
  14. package/ci/test-optimization-validation/command-blocker.js +81 -0
  15. package/ci/test-optimization-validation/command-output-policy.js +206 -0
  16. package/ci/test-optimization-validation/command-runner.js +707 -0
  17. package/ci/test-optimization-validation/command-suitability.js +471 -0
  18. package/ci/test-optimization-validation/executable-approval.js +48 -0
  19. package/ci/test-optimization-validation/executable.js +480 -0
  20. package/ci/test-optimization-validation/generated-file-policy.js +63 -0
  21. package/ci/test-optimization-validation/generated-files.js +351 -0
  22. package/ci/test-optimization-validation/generated-verifier.js +196 -0
  23. package/ci/test-optimization-validation/init-probe-preload.js +163 -0
  24. package/ci/test-optimization-validation/init-probe.js +246 -0
  25. package/ci/test-optimization-validation/late-initialization.js +63 -0
  26. package/ci/test-optimization-validation/local-command.js +163 -0
  27. package/ci/test-optimization-validation/manifest-loader.js +133 -0
  28. package/ci/test-optimization-validation/manifest-scaffold.js +738 -0
  29. package/ci/test-optimization-validation/manifest-schema.js +862 -0
  30. package/ci/test-optimization-validation/offline-fixtures.js +327 -0
  31. package/ci/test-optimization-validation/offline-output.js +406 -0
  32. package/ci/test-optimization-validation/payload-normalizer.js +72 -0
  33. package/ci/test-optimization-validation/plan-writer.js +1120 -0
  34. package/ci/test-optimization-validation/preflight-runner.js +114 -0
  35. package/ci/test-optimization-validation/redaction.js +331 -0
  36. package/ci/test-optimization-validation/report-writer.js +1508 -0
  37. package/ci/test-optimization-validation/safe-files.js +203 -0
  38. package/ci/test-optimization-validation/scenarios/auto-test-retries.js +159 -0
  39. package/ci/test-optimization-validation/scenarios/basic-reporting.js +657 -0
  40. package/ci/test-optimization-validation/scenarios/ci-wiring.js +780 -0
  41. package/ci/test-optimization-validation/scenarios/early-flake-detection.js +141 -0
  42. package/ci/test-optimization-validation/scenarios/helpers.js +539 -0
  43. package/ci/test-optimization-validation/scenarios/test-management.js +218 -0
  44. package/ci/test-optimization-validation/setup-runner.js +97 -0
  45. package/ci/test-optimization-validation/static-diagnosis.js +159 -0
  46. package/ci/test-optimization-validation/test-output.js +129 -0
  47. package/ci/test-optimization-validation-manifest.schema.json +1 -0
  48. package/ci/validate-test-optimization.js +3 -0
  49. package/ext/exporters.js +1 -0
  50. package/index.d.ts +121 -8
  51. package/init.js +18 -0
  52. package/initialize.mjs +1 -1
  53. package/loader-hook.mjs +28 -18
  54. package/openfeature.d.ts +1 -0
  55. package/openfeature.js +4 -0
  56. package/package.json +11 -8
  57. package/packages/datadog-instrumentations/src/ai.js +8 -2
  58. package/packages/datadog-instrumentations/src/child_process.js +1 -1
  59. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -1
  60. package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +9 -3
  61. package/packages/datadog-instrumentations/src/cucumber.js +31 -19
  62. package/packages/datadog-instrumentations/src/cypress-config.js +398 -52
  63. package/packages/datadog-instrumentations/src/fastify.js +7 -11
  64. package/packages/datadog-instrumentations/src/helpers/channel.js +74 -0
  65. package/packages/datadog-instrumentations/src/helpers/hook.js +27 -6
  66. package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +8 -8
  67. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +28 -2
  68. package/packages/datadog-instrumentations/src/jest.js +44 -17
  69. package/packages/datadog-instrumentations/src/mariadb.js +1 -1
  70. package/packages/datadog-instrumentations/src/mocha/main.js +79 -32
  71. package/packages/datadog-instrumentations/src/mocha/utils.js +0 -4
  72. package/packages/datadog-instrumentations/src/mongodb.js +3 -3
  73. package/packages/datadog-instrumentations/src/mongoose.js +3 -3
  74. package/packages/datadog-instrumentations/src/mquery.js +2 -2
  75. package/packages/datadog-instrumentations/src/mysql.js +1 -1
  76. package/packages/datadog-instrumentations/src/next.js +24 -0
  77. package/packages/datadog-instrumentations/src/nyc.js +0 -2
  78. package/packages/datadog-instrumentations/src/oracledb.js +2 -2
  79. package/packages/datadog-instrumentations/src/pg.js +2 -2
  80. package/packages/datadog-instrumentations/src/playwright.js +162 -46
  81. package/packages/datadog-instrumentations/src/process.js +3 -0
  82. package/packages/datadog-instrumentations/src/router.js +18 -8
  83. package/packages/datadog-instrumentations/src/selenium.js +52 -26
  84. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +3 -3
  85. package/packages/datadog-instrumentations/src/vitest-main.js +14 -28
  86. package/packages/datadog-instrumentations/src/vitest-util.js +0 -7
  87. package/packages/datadog-instrumentations/src/vitest-worker.js +5 -8
  88. package/packages/datadog-instrumentations/src/ws.js +2 -1
  89. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +2 -2
  90. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +2 -1
  91. package/packages/datadog-plugin-aws-sdk/src/util.js +2 -2
  92. package/packages/datadog-plugin-cucumber/src/index.js +3 -2
  93. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -57
  94. package/packages/datadog-plugin-cypress/src/index.js +6 -1
  95. package/packages/datadog-plugin-cypress/src/support.js +92 -26
  96. package/packages/datadog-plugin-electron/src/ipc.js +1 -1
  97. package/packages/datadog-plugin-graphql/src/execute.js +87 -45
  98. package/packages/datadog-plugin-graphql/src/validate.js +2 -2
  99. package/packages/datadog-plugin-http2/src/client.js +1 -1
  100. package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -1
  101. package/packages/datadog-plugin-langchain/src/handlers/language_models.js +2 -1
  102. package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
  103. package/packages/datadog-plugin-mocha/src/index.js +2 -1
  104. package/packages/datadog-plugin-playwright/src/index.js +181 -65
  105. package/packages/datadog-plugin-router/src/index.js +11 -2
  106. package/packages/datadog-plugin-selenium/src/index.js +5 -36
  107. package/packages/datadog-plugin-vitest/src/index.js +5 -5
  108. package/packages/datadog-plugin-ws/src/close.js +2 -1
  109. package/packages/datadog-plugin-ws/src/producer.js +2 -1
  110. package/packages/datadog-plugin-ws/src/receiver.js +2 -1
  111. package/packages/datadog-plugin-ws/src/server.js +2 -1
  112. package/packages/dd-trace/src/aiguard/sdk.js +1 -1
  113. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -2
  114. package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +3 -1
  115. package/packages/dd-trace/src/azure_metadata.js +2 -1
  116. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +93 -28
  117. package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
  118. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +160 -0
  119. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +288 -0
  120. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/payload-projection.js +84 -0
  121. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +369 -0
  122. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +60 -0
  123. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +41 -3
  124. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -2
  125. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -1
  126. package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +6 -2
  127. package/packages/dd-trace/src/ci-visibility/rum.js +7 -0
  128. package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
  129. package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
  130. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +137 -9
  131. package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +168 -8
  132. package/packages/dd-trace/src/ci-visibility/test-screenshot.js +90 -0
  133. package/packages/dd-trace/src/config/generated-config-types.d.ts +16 -0
  134. package/packages/dd-trace/src/config/helper.js +1 -0
  135. package/packages/dd-trace/src/config/index.js +10 -0
  136. package/packages/dd-trace/src/config/supported-configurations.json +66 -0
  137. package/packages/dd-trace/src/exporter.js +2 -0
  138. package/packages/dd-trace/src/exporters/common/client-library-headers.js +21 -0
  139. package/packages/dd-trace/src/exporters/common/request.js +59 -30
  140. package/packages/dd-trace/src/exporters/common/url.js +15 -1
  141. package/packages/dd-trace/src/feature-registry.js +10 -3
  142. package/packages/dd-trace/src/llmobs/experiments/client.js +113 -0
  143. package/packages/dd-trace/src/llmobs/experiments/dataset.js +154 -0
  144. package/packages/dd-trace/src/llmobs/experiments/experiment.js +283 -0
  145. package/packages/dd-trace/src/llmobs/experiments/index.js +152 -0
  146. package/packages/dd-trace/src/llmobs/experiments/noop.js +30 -0
  147. package/packages/dd-trace/src/llmobs/experiments/result.js +34 -0
  148. package/packages/dd-trace/src/llmobs/noop.js +6 -0
  149. package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +20 -3
  150. package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +2 -2
  151. package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
  152. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +8 -0
  153. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +48 -14
  154. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +43 -0
  155. package/packages/dd-trace/src/llmobs/sdk.js +17 -0
  156. package/packages/dd-trace/src/llmobs/tagger.js +68 -0
  157. package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
  158. package/packages/dd-trace/src/llmobs/util.js +32 -0
  159. package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +322 -0
  160. package/packages/dd-trace/src/openfeature/configuration_source.js +90 -0
  161. package/packages/dd-trace/src/openfeature/flagging_provider.js +14 -23
  162. package/packages/dd-trace/src/openfeature/index.js +0 -2
  163. package/packages/dd-trace/src/openfeature/noop.js +1 -28
  164. package/packages/dd-trace/src/openfeature/register.js +16 -27
  165. package/packages/dd-trace/src/openfeature/remote_config.js +15 -18
  166. package/packages/dd-trace/src/openfeature/require-provider.js +18 -0
  167. package/packages/dd-trace/src/opentelemetry/span-ending-hook.js +10 -0
  168. package/packages/dd-trace/src/opentelemetry/span.js +5 -0
  169. package/packages/dd-trace/src/plugins/ci_plugin.js +20 -6
  170. package/packages/dd-trace/src/plugins/util/git.js +3 -2
  171. package/packages/dd-trace/src/plugins/util/inferred_proxy.js +29 -5
  172. package/packages/dd-trace/src/plugins/util/test.js +56 -4
  173. package/packages/dd-trace/src/profiling/profilers/space.js +1 -1
  174. package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
  175. package/packages/dd-trace/src/proxy.js +84 -7
  176. package/packages/dd-trace/src/span_processor.js +5 -0
  177. package/packages/dd-trace/src/standalone/index.js +0 -14
  178. package/packages/dd-trace/src/telemetry/send-data.js +2 -2
  179. package/packages/dd-trace/src/util.js +26 -0
  180. package/vendor/dist/@apm-js-collab/code-transformer/index.js +1 -1
  181. package/vendor/dist/@datadog/sketches-js/index.js +1 -1
  182. package/vendor/dist/protobufjs/index.js +1 -1
  183. package/vendor/dist/protobufjs/minimal/index.js +1 -1
  184. package/vendor/dist/shell-quote/index.js +1 -1
  185. package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +0 -17
@@ -4,6 +4,7 @@ const NoopProxy = require('./noop/proxy')
4
4
  const { features } = require('./feature-registry')
5
5
  const DatadogTracer = require('./tracer')
6
6
  const getConfig = require('./config')
7
+ const { getEnvironmentVariable } = require('./config/helper')
7
8
  const runtimeMetrics = require('./runtime_metrics')
8
9
  const log = require('./log')
9
10
  const { setStartupLogPluginManager, startupLog } = require('./startup-log')
@@ -14,6 +15,7 @@ const PluginManager = require('./plugin_manager')
14
15
  const NoopDogStatsDClient = require('./noop/dogstatsd')
15
16
  const { IS_SERVERLESS } = require('./serverless')
16
17
  const processTags = require('./process-tags')
18
+ const { isTrue } = require('./util')
17
19
  const {
18
20
  setBaggageItem,
19
21
  getBaggageItem,
@@ -22,6 +24,24 @@ const {
22
24
  removeAllBaggageItems,
23
25
  } = require('./baggage')
24
26
 
27
+ const VALIDATION_MANIFEST_ENV = '_DD_TEST_OPTIMIZATION_VALIDATION_MANIFEST_FILE'
28
+ const VALIDATION_MODE_ENV = '_DD_TEST_OPTIMIZATION_VALIDATION_MODE'
29
+ const VALIDATION_OUTPUT_ENV = '_DD_TEST_OPTIMIZATION_VALIDATION_OUTPUT_DIR'
30
+ const ORDINARY_TRACING_DISABLED_MESSAGE =
31
+ 'Ordinary dd-trace application tracing initialization is disabled during offline Test Optimization validation. ' +
32
+ 'The CI test process must initialize through dd-trace/ci/init.'
33
+ const OFFLINE_VALIDATION_EXPORTERS = new Set([
34
+ 'ci_validation',
35
+ 'cucumber_worker',
36
+ 'jest_worker',
37
+ 'mocha_worker',
38
+ 'playwright_worker',
39
+ 'vitest_worker',
40
+ ])
41
+ const FEATURE_STATE_NOOP = 0
42
+ const FEATURE_STATE_LAZY = 1
43
+ const FEATURE_STATE_ACTIVE = 2
44
+
25
45
  class LazyModule {
26
46
  constructor (provider) {
27
47
  this.provider = provider
@@ -70,6 +90,9 @@ function defineLazily (obj, property, getClass, ...args) {
70
90
  }
71
91
 
72
92
  class Tracer extends NoopProxy {
93
+ /** @type {Record<string, number> | undefined} */
94
+ #featureStates
95
+
73
96
  constructor () {
74
97
  super()
75
98
 
@@ -107,6 +130,11 @@ class Tracer extends NoopProxy {
107
130
 
108
131
  this._initialized = true
109
132
 
133
+ if (isOfflineTestOptimizationValidation() && !isOfflineValidationExporter(options)) {
134
+ process.stderr.write(`${ORDINARY_TRACING_DISABLED_MESSAGE}\n`)
135
+ return this
136
+ }
137
+
110
138
  try {
111
139
  const config = getConfig(options) // TODO: support dynamic code config
112
140
 
@@ -131,7 +159,7 @@ class Tracer extends NoopProxy {
131
159
 
132
160
  telemetry.start(config, this._pluginManager)
133
161
 
134
- if (config.dogstatsd) {
162
+ if (config.dogstatsd && !isOfflineTestOptimizationValidation()) {
135
163
  // Custom Metrics
136
164
  lazyProxy(this, 'dogstatsd', () => require('./dogstatsd').CustomMetrics, config)
137
165
  }
@@ -275,6 +303,36 @@ class Tracer extends NoopProxy {
275
303
  }
276
304
  }
277
305
 
306
+ /**
307
+ * @param {(typeof features)[string]} feature
308
+ * @param {import('./config/config-base')} config
309
+ */
310
+ #enableFeature (feature, config) {
311
+ const states = this.#featureStates ??= {}
312
+ const state = states[feature.name] ?? FEATURE_STATE_NOOP
313
+
314
+ if (state === FEATURE_STATE_ACTIVE || state === FEATURE_STATE_LAZY) return
315
+ states[feature.name] = FEATURE_STATE_LAZY
316
+
317
+ Reflect.defineProperty(this, feature.name, {
318
+ get: () => {
319
+ const Provider = feature.provider()
320
+ const provider = new Provider(this._tracer, config)
321
+
322
+ this._modules[feature.name].enable(config)
323
+ Reflect.defineProperty(this, feature.name, {
324
+ value: provider,
325
+ configurable: true,
326
+ enumerable: true,
327
+ })
328
+ states[feature.name] = FEATURE_STATE_ACTIVE
329
+ return provider
330
+ },
331
+ configurable: true,
332
+ enumerable: true,
333
+ })
334
+ }
335
+
278
336
  /**
279
337
  * @param {import('./config/config-base')} config - Tracer configuration
280
338
  */
@@ -300,9 +358,6 @@ class Tracer extends NoopProxy {
300
358
  }
301
359
  this._tracingInitialized = true
302
360
  }
303
- for (const feature of Object.values(features)) {
304
- feature.enable?.(config, this._tracer, this, lazyProxy)
305
- }
306
361
  if (config.experimental?.aiguard?.enabled) {
307
362
  this._modules.aiguard.enable(this._tracer, config)
308
363
  }
@@ -315,9 +370,10 @@ class Tracer extends NoopProxy {
315
370
  this._modules.aiguard.disable()
316
371
  this._modules.iast.disable()
317
372
  this._modules.llmobs.disable()
318
- for (const feature of Object.values(features)) {
319
- this._modules[feature.name].disable()
320
- }
373
+ }
374
+
375
+ for (const feature of Object.values(features)) {
376
+ if (feature.isEnabled(config)) this.#enableFeature(feature, config)
321
377
  }
322
378
 
323
379
  if (this._tracingInitialized) {
@@ -400,4 +456,25 @@ class Tracer extends NoopProxy {
400
456
  }
401
457
  }
402
458
 
459
+ /**
460
+ * Checks the private filesystem-only Test Optimization validation mode.
461
+ *
462
+ * @returns {boolean} whether network-capable tracer side channels must stay disabled
463
+ */
464
+ function isOfflineTestOptimizationValidation () {
465
+ return isTrue(getEnvironmentVariable(VALIDATION_MODE_ENV)) &&
466
+ Boolean(getEnvironmentVariable(VALIDATION_MANIFEST_ENV)) &&
467
+ Boolean(getEnvironmentVariable(VALIDATION_OUTPUT_ENV))
468
+ }
469
+
470
+ /**
471
+ * Checks whether initialization selected a filesystem-only Test Optimization exporter.
472
+ *
473
+ * @param {import('../../../index').TracerOptions} [options] tracer initialization options
474
+ * @returns {boolean} whether the selected exporter is safe for offline validation
475
+ */
476
+ function isOfflineValidationExporter (options) {
477
+ return OFFLINE_VALIDATION_EXPORTERS.has(options?.experimental?.exporter)
478
+ }
479
+
403
480
  module.exports = Tracer
@@ -6,6 +6,7 @@ const SpanSampler = require('./span_sampler')
6
6
  const GitMetadataTagger = require('./git_metadata_tagger')
7
7
  const processTags = require('./process-tags')
8
8
  const { applyHttpOtelSemantics } = require('./plugins/util/http-otel-semantics')
9
+ const { APM_TRACING_ENABLED_KEY } = require('./constants')
9
10
 
10
11
  const startedSpans = new WeakSet()
11
12
  const finishedSpans = new WeakSet()
@@ -54,12 +55,16 @@ class SpanProcessor {
54
55
  this._gitMetadataTagger.tagGitMetadata(spanContext)
55
56
 
56
57
  let isFirstSpanInChunk = true
58
+ const stampApmDisabled = this._config.apmTracingEnabled === false
57
59
 
58
60
  for (const span of started) {
59
61
  if (span._duration === undefined) {
60
62
  active.push(span)
61
63
  } else {
62
64
  const formattedSpan = spanFormat(span, isFirstSpanInChunk, this._processTags)
65
+ if (isFirstSpanInChunk && stampApmDisabled) {
66
+ formattedSpan.metrics[APM_TRACING_ENABLED_KEY] = 0
67
+ }
63
68
  isFirstSpanInChunk = false
64
69
  // Span stats read Datadog HTTP tag names from the formatted span, so
65
70
  // record them before the OTel rename — an export-only transform.
@@ -2,38 +2,24 @@
2
2
 
3
3
  const { channel } = require('dc-polyfill')
4
4
  const { USER_KEEP } = require('../../../../ext/priority')
5
- const { APM_TRACING_ENABLED_KEY } = require('../constants')
6
5
  const TraceSourcePrioritySampler = require('./tracesource_priority_sampler')
7
6
  const { hasTraceSourcePropagationTag } = require('./tracesource')
8
7
 
9
- const startCh = channel('dd-trace:span:start')
10
8
  const extractCh = channel('dd-trace:span:extract')
11
9
 
12
10
  /**
13
11
  * @param {import('../config/config-base')} config - Tracer configuration
14
12
  */
15
13
  function configure (config) {
16
- if (startCh.hasSubscribers) startCh.unsubscribe(onSpanStart)
17
14
  if (extractCh.hasSubscribers) extractCh.unsubscribe(onSpanExtract)
18
15
 
19
16
  if (config.apmTracingEnabled !== false) return
20
17
 
21
- startCh.subscribe(onSpanStart)
22
18
  extractCh.subscribe(onSpanExtract)
23
19
 
24
20
  return new TraceSourcePrioritySampler(config.env)
25
21
  }
26
22
 
27
- function onSpanStart ({ span, fields }) {
28
- const context = span.context?.()
29
- if (!context) return
30
-
31
- const { parent } = fields
32
- if (!parent || parent._isRemote) {
33
- context.setTag(APM_TRACING_ENABLED_KEY, 0)
34
- }
35
- }
36
-
37
23
  function onSpanExtract ({ spanContext = {} }) {
38
24
  if (!spanContext._trace?.tags || !spanContext._sampling) return
39
25
 
@@ -77,11 +77,11 @@ let agentTelemetry = true
77
77
  */
78
78
  function getHeaders (config, application, reqType) {
79
79
  const headers = {
80
+ 'DD-Client-Library-Language': application.language_name,
81
+ 'DD-Client-Library-Version': application.tracer_version,
80
82
  'content-type': 'application/json',
81
83
  'dd-telemetry-api-version': 'v2',
82
84
  'dd-telemetry-request-type': reqType,
83
- 'dd-client-library-language': application.language_name,
84
- 'dd-client-library-version': application.tracer_version,
85
85
  'dd-session-id': config.tags['runtime-id'],
86
86
  }
87
87
  if (config.DD_ROOT_JS_SESSION_ID) {
@@ -77,6 +77,31 @@ function globMatch (pattern, subject) {
77
77
  return true
78
78
  }
79
79
 
80
+ /**
81
+ * Return the segment at {index} when splitting {string} on {separator}, without
82
+ * allocating the intermediate array. Equivalent to
83
+ * `string.split(separator, index + 1)[index]`, but `split` with a limit forces
84
+ * V8 off its constant-limit fast path (per-call ToUint32 plus an array
85
+ * allocation), making it 60-170% slower than this scan for the small inputs
86
+ * tracer code splits (paths, request lines, version strings).
87
+ *
88
+ * @param {string} string
89
+ * @param {string} separator
90
+ * @param {number} index
91
+ * @param {string} [fallback] returned when fewer than {index} + 1 segments exist
92
+ * @returns {string | undefined}
93
+ */
94
+ function getSegment (string, separator, index, fallback) {
95
+ let start = 0
96
+ for (let i = 0; i < index; i++) {
97
+ const next = string.indexOf(separator, start)
98
+ if (next === -1) return fallback
99
+ start = next + separator.length
100
+ }
101
+ const end = string.indexOf(separator, start)
102
+ return end === -1 ? string.slice(start) : string.slice(start, end)
103
+ }
104
+
80
105
  function calculateDDBasePath (dirname) {
81
106
  const dirSteps = dirname.split(path.sep)
82
107
  const packagesIndex = dirSteps.lastIndexOf('packages')
@@ -110,6 +135,7 @@ module.exports = {
110
135
  isFalse,
111
136
  isError,
112
137
  globMatch,
138
+ getSegment,
113
139
  ddBasePath: globalThis.__DD_ESBUILD_BASEPATH || calculateDDBasePath(__dirname),
114
140
  normalizePluginEnvName,
115
141
  formatKnuthRate,
@@ -1,4 +1,4 @@
1
- (()=>{var i={"./@apm-js-collab/code-transformer/index.js"(i,s,k){"use strict";i.exports=k("./@apm-js-collab/code-transformer/lib/index.js")},"./@apm-js-collab/code-transformer/lib/index.js"(i,s,k){"use strict";let{InstrumentationMatcher:S}=k("./@apm-js-collab/code-transformer/lib/matcher.js");i.exports={create:function(i,s){return new S(i,s)}}},"./@apm-js-collab/code-transformer/lib/matcher.js"(i,s,k){"use strict";let S=k("./semifies/index.js"),{Transformer:E}=k("./@apm-js-collab/code-transformer/lib/transformer.js");let InstrumentationMatcher=class InstrumentationMatcher{#e=[];#t=null;#r={};#n={};constructor(i,s){this.#e=i,this.#t=s||"diagnostics_channel"}free(){this.#r={}}addTransform(i,s){this.#n[i]=s}getTransformer(i,s,k){k=k.replace(/\\/g,"/");let w=`${i}/${k}@${s}`;if(this.#r[w])return this.#r[w];let C=this.#e.filter(({module:E})=>E.name===i&&E.filePath===k&&S(s,E.versionRange));if(0!==C.length)return this.#r[w]=new E(i,s,k,C,this.#t,this.#n),this.#r[w]}};i.exports={InstrumentationMatcher}},"./@apm-js-collab/code-transformer/lib/transformer.js"(i,s,k){"use strict";let S,E,w=k("./esquery/dist/esquery.min.js"),{parse:C}=k("./meriyah/dist/meriyah.cjs"),{generate:T}=k("./astring/dist/astring.js"),_=k("./@apm-js-collab/code-transformer/lib/transforms.js");let Transformer=class Transformer{#a=null;#o=null;#i=null;#e=[];#t=null;#n={};constructor(i,s,k,S,E,w={}){this.#a=i,this.#o=s,this.#i=k,this.#e=S,this.#t=E,this.#n=w}free(){}get moduleName(){return this.#a}get filePath(){return this.#i}transform(i,s,_){let O;if(Buffer.isBuffer(i)&&(i=i.toString()),!i)return{code:i};let N={},D=0;for(let k of this.#e){let{astQuery:S,functionQuery:E={}}=k;if(!O){let k={loc:!0,ranges:!0,raw:!0,module:"esm"===s};try{O=C(i,k)}catch{O=C(i,{...k,module:!k.module})}"esm"===s&&(N=this.#s(O))}let T=this.#l(E,N),_=S||this.#c(T),q={...k,dcModule:this.#t,moduleType:s,moduleVersion:this.#o,functionQuery:T};q.operator=this.#u(q),w.traverse(O,w.parse(_),(...i)=>{D++,this.#p(q,...i)})}if(0===D&&this.#e.length>0){let i=this.#e.map(({functionQuery:i={}})=>{let s=this.#l(i,N),k=i.methodName||i.privateMethodName||i.functionName||i.expressionName||"constructor",S=i.className||i.functionName||i.expressionName,E=s.className||s.functionName||s.expressionName;return S&&S!==E?`${S} (local name: ${E})`:k});throw Error(`Failed to find injection points for: ${JSON.stringify(i)}`)}if(O){let i;S??=k("./@apm-js-collab/code-transformer/node_modules/source-map/source-map.js").SourceMapConsumer,E??=k("./@apm-js-collab/code-transformer/node_modules/source-map/source-map.js").SourceMapGenerator;let s=`${this.#a}/${this.#i}`;if(_){let k=new S(_);k.file=s,i=E.fromSourceMap(k)}else i=new E({file:s});return{code:T(O,{sourceMap:i}),map:i.toString()}}return{code:i}}#p(i,...s){let k=this.#n[i.operator]??_[i.operator],{index:S=0}=i.functionQuery,[E]=s,w=E.init?.type||E.type;if("ClassDeclaration"===w||"ClassExpression"===w||"VariableDeclarator"!==E.type&&(i.functionIndex=++i.functionIndex||0,null===S||S===i.functionIndex))k(i,...s)}#u({transform:i,functionQuery:{kind:s}}){if(i)return i;switch(s){case"Async":return"tracePromise";case"Auto":return"traceAuto";case"Callback":return"traceCallback";default:return"traceSync"}}#s(i){let s={};for(let k of i.body)if("ExportNamedDeclaration"===k.type&&!k.source){for(let i of k.specifiers)if(i.exported&&i.local){let k=i.exported.name??i.exported.value,S=i.local.name??i.local.value;k&&S&&(s[k]=S)}}return s}#l(i,s){if(!i.isExportAlias)return i;let{functionName:k,expressionName:S,className:E}=i;return k&&s[k]?{...i,functionName:s[k]}:S&&s[S]?{...i,expressionName:s[S]}:E&&s[E]?{...i,className:s[E]}:i}#c(i){let{functionName:s,expressionName:k,className:S,objectName:E,propertyName:w}=i,C=i.privateMethodName?"PrivateIdentifier":"Identifier",T=[],_=i.methodName||i.privateMethodName;if(S?(_??="constructor",T.push(`[id.name="${S}"]`,`[id.name="${S}"] > ClassExpression`,`[id.name="${S}"] > ClassBody > [key.name="${_}"][key.type=${C}] > [async]`,`[id.name="${S}"] > ClassExpression > ClassBody > [key.name="${_}"][key.type=${C}] > [async]`)):_&&T.push(`ClassBody > [key.name="${_}"][key.type=${C}] > [async]`,`Property[key.name="${_}"][key.type=${C}] > [async]`),s?T.push(`FunctionDeclaration[id.name="${s}"][async]`):k&&T.push(`FunctionExpression[id.name="${k}"][async]`,`ArrowFunctionExpression[id.name="${k}"][async]`,`VariableDeclarator[id.name="${k}"] > FunctionExpression[async]`,`VariableDeclarator[id.name="${k}"] > ArrowFunctionExpression[async]`,`AssignmentExpression[left.property.name="${k}"] > FunctionExpression[async]`,`AssignmentExpression[left.property.name="${k}"] > ArrowFunctionExpression[async]`,`AssignmentExpression[left.name="${k}"] > FunctionExpression[async]`,`AssignmentExpression[left.name="${k}"] > ArrowFunctionExpression[async]`),E||w){if(!E||!w)throw Error(`functionQuery: 'objectName' and 'propertyName' must be used together (got objectName=${E}, propertyName=${w})`);let i="this"===E?"left.object.type=ThisExpression":`left.object.name="${E}"`;T.push(`AssignmentExpression[${i}][left.property.name="${w}"] > [async]`)}return T.join(", ")}};i.exports={Transformer}},"./@apm-js-collab/code-transformer/lib/transforms.js"(i,s,k){"use strict";let S=k("./esquery/dist/esquery.min.js"),{parse:E}=k("./meriyah/dist/meriyah.cjs"),tracingChannelPredicate=i=>i.declarations?.[0]?.id?.properties?.[0]?.value?.name==="tr_ch_apm_tracingChannel",w=/[^\w]/g,formatChannelVariable=i=>`tr_ch_apm$${i.replace(w,"_")}`,C=i.exports={tracingChannelImport({dcModule:i,moduleType:s},k){if(k.body.some(tracingChannelPredicate))return;let S={module:"esm"===s},w=k.body.findIndex(i=>"use strict"===i.directive),C="esm"===s?`import tr_ch_apm_dc from "${i}"`:`const tr_ch_apm_dc = require("${i}")`,T=`const tr_ch_apm_hasSubscribers = ch => ch.start.hasSubscribers
1
+ (()=>{var i={"./@apm-js-collab/code-transformer/index.js"(i,s,k){"use strict";i.exports=k("./@apm-js-collab/code-transformer/lib/index.js")},"./@apm-js-collab/code-transformer/lib/index.js"(i,s,k){"use strict";let{InstrumentationMatcher:S}=k("./@apm-js-collab/code-transformer/lib/matcher.js");i.exports={create:function(i,s){return new S(i,s)}}},"./@apm-js-collab/code-transformer/lib/matcher.js"(i,s,k){"use strict";let S=k("./semifies/index.js"),{Transformer:E}=k("./@apm-js-collab/code-transformer/lib/transformer.js");let InstrumentationMatcher=class InstrumentationMatcher{#e=[];#t=null;#r={};#n={};constructor(i,s){this.#e=i,this.#t=s||"diagnostics_channel"}free(){this.#r={}}addTransform(i,s){this.#n[i]=s}getTransformer(i,s,k){k=k.replace(/\\/g,"/");let w=`${i}/${k}@${s}`;if(this.#r[w])return this.#r[w];let C=this.#e.filter(({module:E})=>E.name===i&&("string"==typeof E.filePath?E.filePath===k:E.filePath.test(k))&&S(s,E.versionRange));if(0!==C.length)return this.#r[w]=new E(i,s,k,C,this.#t,this.#n),this.#r[w]}};i.exports={InstrumentationMatcher}},"./@apm-js-collab/code-transformer/lib/transformer.js"(i,s,k){"use strict";let S,E,w=k("./esquery/dist/esquery.min.js"),{parse:C}=k("./meriyah/dist/meriyah.cjs"),{generate:T}=k("./astring/dist/astring.js"),_=k("./@apm-js-collab/code-transformer/lib/transforms.js");let Transformer=class Transformer{#a=null;#o=null;#i=null;#e=[];#t=null;#n={};constructor(i,s,k,S,E,w={}){this.#a=i,this.#o=s,this.#i=k,this.#e=S,this.#t=E,this.#n=w}free(){}get moduleName(){return this.#a}get filePath(){return this.#i}transform(i,s,_){let O;if(Buffer.isBuffer(i)&&(i=i.toString()),!i)return{code:i};let N={},D=0;for(let k of this.#e){let{astQuery:S,functionQuery:E={}}=k;if(!O){let k={loc:!0,ranges:!0,raw:!0,module:"esm"===s};try{O=C(i,k)}catch{O=C(i,{...k,module:!k.module})}"esm"===s&&(N=this.#s(O))}let T=this.#l(E,N),_=S||this.#c(T),q={...k,dcModule:this.#t,moduleType:s,moduleVersion:this.#o,functionQuery:T};q.operator=this.#u(q),w.traverse(O,w.parse(_),(...i)=>{D++,this.#p(q,...i)})}if(0===D&&this.#e.length>0){let i=this.#e.map(({astQuery:i,functionQuery:s={}})=>{if(i)return i;let k=this.#l(s,N),S=s.methodName||s.privateMethodName||s.functionName||s.expressionName||"constructor",E=s.className||s.functionName||s.expressionName,w=k.className||k.functionName||k.expressionName;return E&&E!==w?`${E} (local name: ${w})`:S});throw Error(`Failed to find injection points for: ${JSON.stringify(i)}`)}if(O){let i;S??=k("./@apm-js-collab/code-transformer/node_modules/source-map/source-map.js").SourceMapConsumer,E??=k("./@apm-js-collab/code-transformer/node_modules/source-map/source-map.js").SourceMapGenerator;let s=`${this.#a}/${this.#i}`;if(_){let k=new S(_);k.file=s,i=E.fromSourceMap(k)}else i=new E({file:s});return{code:T(O,{sourceMap:i}),map:i.toString()}}return{code:i}}#p(i,...s){let k=this.#n[i.operator]??_[i.operator],{index:S=0}=i.functionQuery,[E]=s,w=E.init?.type||E.type;if("ClassDeclaration"===w||"ClassExpression"===w||"VariableDeclarator"!==E.type&&(i.functionIndex=++i.functionIndex||0,null===S||S===i.functionIndex))k(i,...s)}#u({transform:i,functionQuery:{kind:s}}){if(i)return i;switch(s){case"Async":return"tracePromise";case"Auto":return"traceAuto";case"Callback":return"traceCallback";default:return"traceSync"}}#s(i){let s={};for(let k of i.body)if("ExportNamedDeclaration"===k.type&&!k.source){for(let i of k.specifiers)if(i.exported&&i.local){let k=i.exported.name??i.exported.value,S=i.local.name??i.local.value;k&&S&&(s[k]=S)}}return s}#l(i,s){if(!i.isExportAlias)return i;let{functionName:k,expressionName:S,className:E}=i;return k&&s[k]?{...i,functionName:s[k]}:S&&s[S]?{...i,expressionName:s[S]}:E&&s[E]?{...i,className:s[E]}:i}#c(i){let{functionName:s,expressionName:k,className:S,objectName:E,propertyName:w}=i,C=i.privateMethodName?"PrivateIdentifier":"Identifier",T=[],_=i.methodName||i.privateMethodName;if(S?(_??="constructor",T.push(`[id.name="${S}"]`,`[id.name="${S}"] > ClassExpression`,`[id.name="${S}"] > ClassBody > [key.name="${_}"][key.type=${C}] > [async]`,`[id.name="${S}"] > ClassExpression > ClassBody > [key.name="${_}"][key.type=${C}] > [async]`)):_&&T.push(`ClassBody > [key.name="${_}"][key.type=${C}] > [async]`,`Property[key.name="${_}"][key.type=${C}] > [async]`),s?T.push(`FunctionDeclaration[id.name="${s}"][async]`):k&&T.push(`FunctionExpression[id.name="${k}"][async]`,`ArrowFunctionExpression[id.name="${k}"][async]`,`VariableDeclarator[id.name="${k}"] > FunctionExpression[async]`,`VariableDeclarator[id.name="${k}"] > ArrowFunctionExpression[async]`,`AssignmentExpression[left.property.name="${k}"] > FunctionExpression[async]`,`AssignmentExpression[left.property.name="${k}"] > ArrowFunctionExpression[async]`,`AssignmentExpression[left.name="${k}"] > FunctionExpression[async]`,`AssignmentExpression[left.name="${k}"] > ArrowFunctionExpression[async]`),E||w){if(!E||!w)throw Error(`functionQuery: 'objectName' and 'propertyName' must be used together (got objectName=${E}, propertyName=${w})`);let i="this"===E?"left.object.type=ThisExpression":`left.object.name="${E}"`;T.push(`AssignmentExpression[${i}][left.property.name="${w}"] > [async]`)}return T.join(", ")}};i.exports={Transformer}},"./@apm-js-collab/code-transformer/lib/transforms.js"(i,s,k){"use strict";let S=k("./esquery/dist/esquery.min.js"),{parse:E}=k("./meriyah/dist/meriyah.cjs"),tracingChannelPredicate=i=>i.declarations?.[0]?.id?.properties?.[0]?.value?.name==="tr_ch_apm_tracingChannel",w=/[^\w]/g,formatChannelVariable=i=>`tr_ch_apm$${i.replace(w,"_")}`,C=i.exports={tracingChannelImport({dcModule:i,moduleType:s},k){if(k.body.some(tracingChannelPredicate))return;let S={module:"esm"===s},w=k.body.findIndex(i=>"use strict"===i.directive),C="esm"===s?`import tr_ch_apm_dc from "${i}"`:`const tr_ch_apm_dc = require("${i}")`,T=`const tr_ch_apm_hasSubscribers = ch => ch.start.hasSubscribers
2
2
  || ch.end.hasSubscribers
3
3
  || ch.asyncStart.hasSubscribers
4
4
  || ch.asyncEnd.hasSubscribers