dd-trace 6.9.0 → 6.11.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 (175) hide show
  1. package/README.md +0 -17
  2. package/ci/vitest-no-worker-init-setup.mjs +112 -10
  3. package/index.d.ts +150 -3
  4. package/initialize.mjs +28 -17
  5. package/openfeature.js +2 -2
  6. package/package.json +14 -10
  7. package/packages/datadog-esbuild/index.js +0 -34
  8. package/packages/datadog-instrumentations/src/anthropic.js +210 -15
  9. package/packages/datadog-instrumentations/src/aws-sdk.js +9 -1
  10. package/packages/datadog-instrumentations/src/browser-bunyan.js +11 -0
  11. package/packages/datadog-instrumentations/src/bunyan.js +3 -16
  12. package/packages/datadog-instrumentations/src/confluentinc-kafka-javascript.js +111 -6
  13. package/packages/datadog-instrumentations/src/cucumber.js +26 -11
  14. package/packages/datadog-instrumentations/src/cypress-config.js +182 -16
  15. package/packages/datadog-instrumentations/src/cypress-legacy-finalizers.js +30 -0
  16. package/packages/datadog-instrumentations/src/cypress.js +2 -0
  17. package/packages/datadog-instrumentations/src/fastify.js +2 -0
  18. package/packages/datadog-instrumentations/src/helpers/bunyan.js +22 -0
  19. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -1
  20. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +634 -0
  21. package/packages/datadog-instrumentations/src/helpers/register.js +10 -8
  22. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -1
  23. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +81 -0
  24. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +1 -0
  25. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +83 -1
  26. package/packages/datadog-instrumentations/src/jest.js +26 -18
  27. package/packages/datadog-instrumentations/src/mariadb.js +278 -21
  28. package/packages/datadog-instrumentations/src/mocha/main.js +540 -56
  29. package/packages/datadog-instrumentations/src/mocha/utils.js +132 -25
  30. package/packages/datadog-instrumentations/src/mysql.js +45 -15
  31. package/packages/datadog-instrumentations/src/mysql2.js +119 -18
  32. package/packages/datadog-instrumentations/src/path-to-regexp.js +67 -1
  33. package/packages/datadog-instrumentations/src/pg.js +116 -92
  34. package/packages/datadog-instrumentations/src/playwright-reporter.js +99 -0
  35. package/packages/datadog-instrumentations/src/playwright.js +149 -2
  36. package/packages/datadog-instrumentations/src/router.js +2 -0
  37. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +43 -4
  38. package/packages/datadog-instrumentations/src/vitest-main.js +180 -20
  39. package/packages/datadog-instrumentations/src/vitest-util.js +64 -5
  40. package/packages/datadog-instrumentations/src/vitest-worker.js +150 -25
  41. package/packages/datadog-instrumentations/src/webdriverio.js +31 -17
  42. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +12 -6
  43. package/packages/datadog-plugin-aws-sdk/src/base.js +1 -0
  44. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +163 -44
  45. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +4 -13
  46. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +1 -5
  47. package/packages/datadog-plugin-azure-functions/src/index.js +1 -1
  48. package/packages/datadog-plugin-browser-bunyan/src/index.js +9 -0
  49. package/packages/datadog-plugin-bunyan/src/index.js +5 -8
  50. package/packages/datadog-plugin-cucumber/src/index.js +11 -0
  51. package/packages/datadog-plugin-cypress/src/after-run.js +5 -1
  52. package/packages/datadog-plugin-cypress/src/after-spec.js +5 -1
  53. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +82 -30
  54. package/packages/datadog-plugin-cypress/src/finalization.js +76 -0
  55. package/packages/datadog-plugin-cypress/src/index.js +12 -6
  56. package/packages/datadog-plugin-cypress/src/plugin.js +16 -3
  57. package/packages/datadog-plugin-dd-trace-api/src/index.js +4 -0
  58. package/packages/datadog-plugin-electron/src/index.js +2 -0
  59. package/packages/datadog-plugin-fs/src/index.js +1 -1
  60. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +31 -17
  61. package/packages/datadog-plugin-jest/src/index.js +11 -4
  62. package/packages/datadog-plugin-kafkajs/src/batch-consumer.js +2 -3
  63. package/packages/datadog-plugin-kafkajs/src/consumer.js +2 -3
  64. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -2
  65. package/packages/datadog-plugin-kafkajs/src/utils.js +65 -7
  66. package/packages/datadog-plugin-mocha/src/index.js +606 -40
  67. package/packages/datadog-plugin-mysql/src/index.js +37 -0
  68. package/packages/datadog-plugin-nats/src/index.js +1 -1
  69. package/packages/datadog-plugin-next/src/index.js +1 -19
  70. package/packages/datadog-plugin-openai/src/tracing.js +41 -30
  71. package/packages/datadog-plugin-openai-agents/src/integration.js +279 -69
  72. package/packages/datadog-plugin-openai-agents/src/processor.js +16 -4
  73. package/packages/datadog-plugin-pg/src/index.js +1 -0
  74. package/packages/datadog-plugin-playwright/src/index.js +42 -13
  75. package/packages/datadog-plugin-vitest/src/index.js +14 -20
  76. package/packages/datadog-plugin-ws/src/util.js +2 -1
  77. package/packages/datadog-webpack/index.js +0 -11
  78. package/packages/dd-trace/index.js +0 -1
  79. package/packages/dd-trace/src/agent/info.js +6 -5
  80. package/packages/dd-trace/src/aiguard/client.js +100 -1
  81. package/packages/dd-trace/src/aiguard/errors.js +41 -0
  82. package/packages/dd-trace/src/aiguard/evaluation.js +357 -0
  83. package/packages/dd-trace/src/aiguard/integrations/anthropic.js +70 -0
  84. package/packages/dd-trace/src/aiguard/integrations/index.js +4 -0
  85. package/packages/dd-trace/src/aiguard/messages/anthropic.js +423 -0
  86. package/packages/dd-trace/src/aiguard/messages/openai.js +1 -24
  87. package/packages/dd-trace/src/aiguard/messages/utils.js +28 -0
  88. package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +1 -11
  89. package/packages/dd-trace/src/aiguard/sdk.js +22 -278
  90. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +453 -0
  91. package/packages/dd-trace/src/appsec/handlers/http-request.js +13 -0
  92. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +9 -12
  93. package/packages/dd-trace/src/carrier.js +356 -0
  94. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +1 -0
  95. package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +27 -3
  96. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +22 -6
  97. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +21 -5
  98. package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +164 -0
  99. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +22 -6
  100. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +365 -32
  101. package/packages/dd-trace/src/ci-visibility/exporters/request.js +201 -0
  102. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +5 -3
  103. package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -5
  104. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +2 -1
  105. package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +39 -0
  106. package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -6
  107. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +6 -2
  108. package/packages/dd-trace/src/config/generated-config-types.d.ts +7 -0
  109. package/packages/dd-trace/src/config/index.js +13 -2
  110. package/packages/dd-trace/src/config/major-overrides.js +7 -0
  111. package/packages/dd-trace/src/config/supported-configurations.json +24 -0
  112. package/packages/dd-trace/src/datastreams/context.js +6 -1
  113. package/packages/dd-trace/src/datastreams/index.js +2 -0
  114. package/packages/dd-trace/src/datastreams/manager.js +14 -3
  115. package/packages/dd-trace/src/datastreams/pathway.js +23 -22
  116. package/packages/dd-trace/src/datastreams/processor.js +16 -13
  117. package/packages/dd-trace/src/datastreams/size.js +5 -0
  118. package/packages/dd-trace/src/debugger/devtools_client/index.js +3 -2
  119. package/packages/dd-trace/src/exporters/agent/writer.js +49 -9
  120. package/packages/dd-trace/src/exporters/common/buffering-exporter.js +6 -4
  121. package/packages/dd-trace/src/exporters/common/writer.js +11 -6
  122. package/packages/dd-trace/src/llmobs/constants/tags.js +5 -0
  123. package/packages/dd-trace/src/llmobs/experiments/client.js +163 -5
  124. package/packages/dd-trace/src/llmobs/experiments/dataset.js +241 -87
  125. package/packages/dd-trace/src/llmobs/experiments/experiment.js +280 -20
  126. package/packages/dd-trace/src/llmobs/experiments/index.js +58 -59
  127. package/packages/dd-trace/src/llmobs/experiments/noop.js +71 -3
  128. package/packages/dd-trace/src/llmobs/experiments/result.js +1 -0
  129. package/packages/dd-trace/src/llmobs/experiments/util.js +41 -5
  130. package/packages/dd-trace/src/llmobs/index.js +34 -2
  131. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +12 -3
  132. package/packages/dd-trace/src/llmobs/plugins/base.js +4 -2
  133. package/packages/dd-trace/src/llmobs/span_processor.js +16 -0
  134. package/packages/dd-trace/src/llmobs/tagger.js +96 -0
  135. package/packages/dd-trace/src/llmobs/util.js +78 -0
  136. package/packages/dd-trace/src/noop/proxy.js +3 -4
  137. package/packages/dd-trace/src/openfeature/flagging_provider.js +18 -2
  138. package/packages/dd-trace/src/openfeature/remote_config.js +1 -1
  139. package/packages/dd-trace/src/opentelemetry/context_manager.js +7 -7
  140. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +2 -1
  141. package/packages/dd-trace/src/opentelemetry/logs/logger.js +67 -11
  142. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +14 -3
  143. package/packages/dd-trace/src/opentelemetry/metrics/index.js +25 -12
  144. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +2 -5
  145. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +96 -43
  146. package/packages/dd-trace/src/opentracing/propagation/text_map.js +126 -120
  147. package/packages/dd-trace/src/opentracing/propagation/text_map_dsm.js +4 -8
  148. package/packages/dd-trace/src/opentracing/tracer.js +5 -2
  149. package/packages/dd-trace/src/otel-thread-ctx.js +387 -0
  150. package/packages/dd-trace/src/plugin_manager.js +5 -3
  151. package/packages/dd-trace/src/plugins/ci_plugin.js +6 -1
  152. package/packages/dd-trace/src/plugins/index.js +1 -0
  153. package/packages/{datadog-plugin-jest/src/util.js → dd-trace/src/plugins/util/jest.js} +5 -65
  154. package/packages/dd-trace/src/plugins/util/test.js +93 -14
  155. package/packages/dd-trace/src/plugins/util/web.js +56 -2
  156. package/packages/dd-trace/src/profiling/profiler.js +1 -1
  157. package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
  158. package/packages/dd-trace/src/profiling/profilers/wall.js +37 -90
  159. package/packages/dd-trace/src/profiling/webspan-utils.js +45 -0
  160. package/packages/dd-trace/src/proxy.js +38 -29
  161. package/packages/dd-trace/src/ritm.js +9 -2
  162. package/packages/dd-trace/src/serverless.js +37 -0
  163. package/packages/dd-trace/src/span_format.js +1 -0
  164. package/packages/dd-trace/src/span_stats.js +30 -3
  165. package/packages/dd-trace/src/storage-channels.js +86 -0
  166. package/packages/dd-trace/src/tracer.js +9 -2
  167. package/packages/dd-trace/src/tracer_metadata.js +14 -1
  168. package/packages/dd-trace/src/web-tags-cache.js +132 -0
  169. package/vendor/dist/@datadog/openfeature-node-server/LICENSE +201 -0
  170. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -0
  171. package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +0 -65
  172. package/packages/datadog-webpack/src/optional-peer-loader.js +0 -17
  173. package/packages/dd-trace/src/feature-registry.js +0 -29
  174. package/packages/dd-trace/src/openfeature/register.js +0 -35
  175. package/packages/dd-trace/src/openfeature/require-provider.js +0 -18
package/README.md CHANGED
@@ -93,23 +93,6 @@ Regardless of where you open the issue, someone at Datadog will try to help.
93
93
 
94
94
  If you would like to trace your bundled application then please read this page on [bundling and dd-trace](https://docs.datadoghq.com/tracing/trace_collection/automatic_instrumentation/dd_libraries/nodejs/#bundling). It includes information on how to use our ESBuild plugin and includes caveats for other bundlers.
95
95
 
96
- When using the experimental OpenFeature provider, file-traced deployments can force the optional provider and
97
- its dependencies into the output with a side-effect import before accessing `tracer.openfeature`:
98
-
99
- CommonJS:
100
-
101
- ```js
102
- require('dd-trace/openfeature')
103
- ```
104
-
105
- ES modules:
106
-
107
- ```js
108
- import 'dd-trace/openfeature.js'
109
- ```
110
-
111
- This is a fallback for build tools that do not recognize the provider's optional-require wrapper.
112
-
113
96
 
114
97
  ## Security Vulnerabilities
115
98
 
@@ -3,16 +3,19 @@ import { afterEach, beforeAll, beforeEach, inject } from 'vitest'
3
3
  // Instrumentation-less setup for DD_EXPERIMENTAL_TEST_OPT_VITEST_NO_WORKER_INIT.
4
4
  // It applies Test Optimization execution changes without initializing dd-trace and also supports Browser Mode.
5
5
  const VITEST_NO_WORKER_INIT_ACTIVE_ENV = 'DD_TEST_OPT_VITEST_NO_WORKER_INIT_ACTIVE'
6
+ const SERIALIZED_CONTEXT_PREFIX = '\u0000dd-vitest-context:'
6
7
  const providedContext = getProvidedContext()
7
8
  const isNoWorkerInitActive = providedContext.isActive ?? getIsNoWorkerInitActive()
8
9
  const attemptToFixTests = providedContext.attemptToFixTests || {}
9
10
  const attemptToFixRetries = providedContext.attemptToFixRetries || 0
10
11
  const disabledTests = providedContext.disabledTests || {}
12
+ const efdSuiteAdmissionBrowserCommand = providedContext.efdSuiteAdmissionBrowserCommand
11
13
  const earlyFlakeDetectionRetryPolicy = providedContext.earlyFlakeDetectionRetryPolicy || {
12
14
  durationRetryCounts: [],
13
15
  schedulingRetryCount: 0,
14
16
  }
15
17
  const earlyFlakeDetectionRetries = earlyFlakeDetectionRetryPolicy.schedulingRetryCount
18
+ const isEfdSuiteAdmissionEnabled = providedContext.isEfdSuiteAdmissionEnabled === true
16
19
  const isEarlyFlakeDetectionEnabled = providedContext.isEarlyFlakeDetectionEnabled === true
17
20
  const knownTests = providedContext.knownTests || {}
18
21
  const modifiedFiles = providedContext.modifiedFiles || {}
@@ -34,6 +37,7 @@ const earlyFlakeDetectionStartByTask = new WeakMap()
34
37
  const nextAttemptIndexByTask = new WeakMap()
35
38
  const retryAttemptIndexByTask = new WeakMap()
36
39
  const usedRumTestExecutionIds = new Set()
40
+ let browserCommands
37
41
  let now
38
42
  let timeOrigin
39
43
  // Use an unfaked monotonic clock in Node and Vitest's parent frame in Browser Mode.
@@ -48,18 +52,42 @@ if (typeof globalThis.process?.uptime === 'function') {
48
52
  timeOrigin = Number.isFinite(clock?.timeOrigin) ? clock.timeOrigin : Date.now() - now()
49
53
  }
50
54
 
55
+ /**
56
+ * Requests permission from the Vitest main process to schedule Browser Mode EFD retries for one suite.
57
+ *
58
+ * @param {string} testSuite
59
+ * @param {boolean} hasNewTest
60
+ * @returns {Promise<boolean>}
61
+ */
62
+ async function requestBrowserEfdSuiteAdmission (testSuite, hasNewTest) {
63
+ try {
64
+ if (!browserCommands) {
65
+ const vitestBrowser = await import('@vitest/browser/context')
66
+ browserCommands = vitestBrowser.commands
67
+ }
68
+ return await browserCommands[efdSuiteAdmissionBrowserCommand](testSuite, hasNewTest) === true
69
+ } catch (error) {
70
+ // Browser Mode setup runs without dd-trace, so the tracer logger is unavailable.
71
+ globalThis.console?.error('Datadog Test Optimization could not request Vitest EFD suite admission.', error)
72
+ return false
73
+ }
74
+ }
75
+
51
76
  if (isNoWorkerInitActive) {
52
77
  // eslint-disable-next-line no-empty-pattern
53
- beforeAll(function ({}, suite) {
78
+ beforeAll(async function ({}, suite) {
54
79
  suite ||= arguments[0]
55
- applyExecutionChanges(suite)
80
+ const efdSuiteCandidate = getEarlyFlakeDetectionSuiteCandidate(suite)
81
+ const isEfdSuiteAdmissionAllowed = !efdSuiteCandidate || !isEfdSuiteAdmissionEnabled ||
82
+ await requestBrowserEfdSuiteAdmission(efdSuiteCandidate.testSuite, efdSuiteCandidate.hasNewTest)
83
+ applyExecutionChanges(suite, isEfdSuiteAdmissionAllowed)
56
84
  })
57
85
 
58
86
  beforeEach(function ({ onTestFinished, task, skip }) {
59
87
  const testSuite = getTestSuite(task)
60
88
  const testName = getTestName(task)
61
89
  const isAttemptToFixTest = attemptToFixTests[testSuite]?.[testName]
62
- const isEarlyFlakeDetectionTestAttempt = isEarlyFlakeDetectionTest(testSuite, testName)
90
+ const isEarlyFlakeDetectionTestAttempt = isEarlyFlakeDetectionTask(task)
63
91
  const isQuarantinedTest = quarantinedTests[testSuite]?.[testName] && !isAttemptToFixTest
64
92
  const attemptIndex = getNextAttemptIndex(task)
65
93
  const attemptStart = now()
@@ -108,12 +136,12 @@ if (isNoWorkerInitActive) {
108
136
  })
109
137
  }
110
138
 
111
- function applyExecutionChanges (suite) {
139
+ function applyExecutionChanges (suite, isEfdSuiteAdmissionAllowed) {
112
140
  const tasks = suite?.tasks
113
141
  if (tasks) {
114
142
  for (const task of tasks) {
115
143
  if (task.type === 'suite') {
116
- applyExecutionChanges(task)
144
+ applyExecutionChanges(task, isEfdSuiteAdmissionAllowed)
117
145
  continue
118
146
  }
119
147
 
@@ -125,7 +153,7 @@ function applyExecutionChanges (suite) {
125
153
  task.meta.__ddTestOptAtfRetries = attemptToFixRetries
126
154
  } else if (disabledTests[testSuite]?.[testName]) {
127
155
  task.mode = 'skip'
128
- } else if (isEarlyFlakeDetectionTest(testSuite, testName)) {
156
+ } else if (isEfdSuiteAdmissionAllowed && isEarlyFlakeDetectionTest(testSuite, testName)) {
129
157
  task.retry = 0
130
158
  task.repeats = earlyFlakeDetectionRetries
131
159
  task.meta.__ddTestOptEfdRetries = earlyFlakeDetectionRetries
@@ -333,7 +361,7 @@ function recordTestOptimizationStatus (task, attemptIndex = task.result?.repeatC
333
361
 
334
362
  if (attemptToFixTests[testSuite]?.[testName]) {
335
363
  recordAttemptToFixStatus(task, attemptIndex, onlyIfNewErrors)
336
- } else if (isEarlyFlakeDetectionTest(testSuite, testName)) {
364
+ } else if (isEarlyFlakeDetectionTask(task)) {
337
365
  recordEarlyFlakeDetectionStatus(task, attemptIndex, onlyIfNewErrors)
338
366
  } else if (task.repeats > 0) {
339
367
  recordManualRepeatStatus(task, attemptIndex)
@@ -510,7 +538,7 @@ function getFinalAttemptIndex (task) {
510
538
  if (attemptToFixTests[testSuite]?.[testName]) {
511
539
  return getAttemptToFixRetryCount(task)
512
540
  }
513
- if (isEarlyFlakeDetectionTest(testSuite, testName)) {
541
+ if (isEarlyFlakeDetectionTask(task)) {
514
542
  return getEarlyFlakeDetectionRetryCountForTask(task)
515
543
  }
516
544
 
@@ -671,6 +699,64 @@ function isEarlyFlakeDetectionTest (testSuite, testName) {
671
699
  return !testsForSuite.includes(testName)
672
700
  }
673
701
 
702
+ /**
703
+ * Returns whether Datadog admitted this task for EFD retries.
704
+ *
705
+ * @param {object} task
706
+ * @returns {boolean}
707
+ */
708
+ function isEarlyFlakeDetectionTask (task) {
709
+ return task.meta.__ddTestOptEfdRetries !== undefined
710
+ }
711
+
712
+ /**
713
+ * Returns suite admission data when a collected suite contains an EFD candidate.
714
+ *
715
+ * @param {object} suite
716
+ * @returns {{ hasNewTest: boolean, testSuite: string }|undefined}
717
+ */
718
+ function getEarlyFlakeDetectionSuiteCandidate (suite) {
719
+ const tasks = suite?.tasks
720
+ if (!tasks) return
721
+
722
+ let candidate
723
+ for (const task of tasks) {
724
+ if (task.type === 'suite') {
725
+ const nestedCandidate = getEarlyFlakeDetectionSuiteCandidate(task)
726
+ if (nestedCandidate) {
727
+ candidate ||= nestedCandidate
728
+ candidate.hasNewTest ||= nestedCandidate.hasNewTest
729
+ }
730
+ continue
731
+ }
732
+
733
+ if (task.mode === 'skip' || task.mode === 'todo') continue
734
+
735
+ const testSuite = getTestSuite(task)
736
+ const testName = getTestName(task)
737
+ if (attemptToFixTests[testSuite]?.[testName] || disabledTests[testSuite]?.[testName]) continue
738
+ if (!isEarlyFlakeDetectionTest(testSuite, testName)) continue
739
+
740
+ candidate ||= {
741
+ hasNewTest: false,
742
+ testSuite,
743
+ }
744
+ candidate.hasNewTest ||= isNewTest(testSuite, testName)
745
+ }
746
+ return candidate
747
+ }
748
+
749
+ /**
750
+ * Returns whether a collected test is absent from the known-tests response.
751
+ *
752
+ * @param {string} testSuite
753
+ * @param {string} testName
754
+ * @returns {boolean}
755
+ */
756
+ function isNewTest (testSuite, testName) {
757
+ return !(knownTests[testSuite] || []).includes(testName)
758
+ }
759
+
674
760
  function isModifiedTest (testSuite) {
675
761
  return modifiedFiles[testSuite]?.length > 0
676
762
  }
@@ -712,12 +798,28 @@ function getIsNoWorkerInitActive () {
712
798
 
713
799
  function getProvidedContext () {
714
800
  try {
715
- return inject('_ddVitestWorkerSetup') || {}
801
+ return parseProvidedContextValue(inject('_ddVitestWorkerSetup'))
716
802
  } catch {
717
803
  try {
718
- return globalThis.__vitest_worker__.providedContext._ddVitestWorkerSetup || {}
804
+ return parseProvidedContextValue(globalThis.__vitest_worker__.providedContext._ddVitestWorkerSetup)
719
805
  } catch {
720
806
  return {}
721
807
  }
722
808
  }
723
809
  }
810
+
811
+ /**
812
+ * Restore context serialized to keep Vitest's inline browser bootstrap script valid.
813
+ *
814
+ * @param {object|string|undefined} value
815
+ * @returns {object}
816
+ */
817
+ function parseProvidedContextValue (value) {
818
+ if (typeof value !== 'string' || !value.startsWith(SERIALIZED_CONTEXT_PREFIX)) return value || {}
819
+
820
+ try {
821
+ return JSON.parse(value.slice(SERIALIZED_CONTEXT_PREFIX.length))
822
+ } catch {
823
+ return {}
824
+ }
825
+ }
package/index.d.ts CHANGED
@@ -243,6 +243,7 @@ interface Plugins {
243
243
  "azure-functions": tracer.plugins.azure_functions;
244
244
  "azure-service-bus": tracer.plugins.azure_service_bus;
245
245
  "azure-durable-functions": tracer.plugins.azure_durable_functions
246
+ "browser-bunyan": tracer.plugins.browser_bunyan;
246
247
  "bullmq": tracer.plugins.bullmq;
247
248
  "bunyan": tracer.plugins.bunyan;
248
249
  "cassandra-driver": tracer.plugins.cassandra_driver;
@@ -1940,6 +1941,18 @@ declare namespace tracer {
1940
1941
  /** @hidden */
1941
1942
  interface Instrumentation extends Integration, Analyzable {}
1942
1943
 
1944
+ /** @hidden */
1945
+ interface LLMObsIntegration extends Integration {
1946
+ /**
1947
+ * Whether to capture LLM Observability spans for this integration. When set to `false`,
1948
+ * the integration keeps emitting APM spans and propagating trace context, but no LLM
1949
+ * Observability spans are produced. Useful when another integration already captures the
1950
+ * same operation and the payloads would otherwise be stored twice.
1951
+ * @default true
1952
+ */
1953
+ llmobs?: boolean;
1954
+ }
1955
+
1943
1956
  /** @hidden */
1944
1957
  interface DatabaseInstrumentation extends Instrumentation {
1945
1958
  /**
@@ -2333,11 +2346,13 @@ declare namespace tracer {
2333
2346
  interface azure_durable_functions extends Integration {}
2334
2347
 
2335
2348
  /**
2336
- * This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
2349
+ * This plugin patches the [browser-bunyan](https://github.com/philmander/browser-bunyan)
2337
2350
  * to automatically inject trace identifiers in log records when the
2338
2351
  * [logInjection](interfaces/traceroptions.html#logInjection) option is enabled
2339
2352
  * on the tracer.
2340
2353
  */
2354
+ interface browser_bunyan extends Integration {}
2355
+
2341
2356
  /**
2342
2357
  * This plugin automatically instruments the
2343
2358
  * [bullmq](https://github.com/npmjs/package/bullmq) message queue library.
@@ -2358,6 +2373,12 @@ declare namespace tracer {
2358
2373
  producerFilter?: (job: { name?: string; data?: unknown; opts?: unknown; queueName?: string }) => boolean;
2359
2374
  }
2360
2375
 
2376
+ /**
2377
+ * This plugin patches the [bunyan](https://github.com/trentm/node-bunyan)
2378
+ * to automatically inject trace identifiers in log records when the
2379
+ * [logInjection](interfaces/traceroptions.html#logInjection) option is enabled
2380
+ * on the tracer.
2381
+ */
2361
2382
  interface bunyan extends Integration {}
2362
2383
 
2363
2384
  /**
@@ -2804,7 +2825,7 @@ declare namespace tracer {
2804
2825
  * This plugin automatically instruments the
2805
2826
  * [langchain](https://js.langchain.com/) module
2806
2827
  */
2807
- interface langchain extends Instrumentation {}
2828
+ interface langchain extends Instrumentation, LLMObsIntegration {}
2808
2829
 
2809
2830
  /**
2810
2831
  * This plugin automatically instruments the
@@ -2846,7 +2867,7 @@ declare namespace tracer {
2846
2867
  * This plugin automatically instruments the
2847
2868
  * [modelcontextprotocol-sdk](https://github.com/npmjs/package/@modelcontextprotocol/sdk) library.
2848
2869
  */
2849
- interface modelcontextprotocol_sdk extends Instrumentation {}
2870
+ interface modelcontextprotocol_sdk extends Instrumentation, LLMObsIntegration {}
2850
2871
 
2851
2872
  /**
2852
2873
  * This plugin automatically instruments the
@@ -3852,6 +3873,79 @@ declare namespace tracer {
3852
3873
  url: string
3853
3874
  }
3854
3875
 
3876
+ type ExternalExperimentTimestamp = number | string | Date
3877
+
3878
+ interface StartExperimentDatasetOptions {
3879
+ /** Existing dataset id. When omitted, a placeholder dataset is created. */
3880
+ id?: string
3881
+ /** Dataset version to associate with the experiment. */
3882
+ version?: number
3883
+ /** Placeholder dataset name. Defaults to `<experiment name> dataset`. */
3884
+ name?: string
3885
+ /** Placeholder dataset description. */
3886
+ description?: string
3887
+ }
3888
+
3889
+ interface StartExperimentOptions {
3890
+ name: string
3891
+ description?: string
3892
+ /** Override the configured project name for this external experiment. */
3893
+ projectName?: string
3894
+ dataset?: StartExperimentDatasetOptions
3895
+ config?: Record<string, JSONType>
3896
+ metadata?: Record<string, JSONType>
3897
+ tags?: Record<string, string>
3898
+ }
3899
+
3900
+ interface ExternalExperimentSpanInput {
3901
+ name?: string
3902
+ input?: JSONType
3903
+ output?: JSONType
3904
+ expectedOutput?: JSONType
3905
+ metadata?: Record<string, JSONType>
3906
+ tags?: Record<string, string>
3907
+ startedAt?: ExternalExperimentTimestamp
3908
+ completedAt?: ExternalExperimentTimestamp
3909
+ durationMs?: number
3910
+ error?: string | Error | { type?: string, name?: string, message?: string, stack?: string }
3911
+ datasetRecordId?: string
3912
+ runId?: string
3913
+ runIteration?: number
3914
+ }
3915
+
3916
+ interface ExternalExperimentSpan {
3917
+ experimentId: string
3918
+ spanId: string
3919
+ traceId: string
3920
+ url: string | null
3921
+ }
3922
+
3923
+ interface ExternalExperimentMetric {
3924
+ label: string
3925
+ value?: JSONType
3926
+ error?: string | Error
3927
+ timestamp?: ExternalExperimentTimestamp
3928
+ tags?: Record<string, string>
3929
+ source?: string
3930
+ }
3931
+
3932
+ interface ExternalExperimentCloseOptions {
3933
+ status?: string
3934
+ error?: string | Error
3935
+ }
3936
+
3937
+ interface ExternalExperiment {
3938
+ experimentId (): string
3939
+ name (): string
3940
+ url (): string | null
3941
+ submitSpan (input?: ExternalExperimentSpanInput): Promise<ExternalExperimentSpan>
3942
+ submitEvaluationMetrics (
3943
+ span: { experimentId?: string, spanId: string, traceId: string },
3944
+ metrics: ExternalExperimentMetric[]
3945
+ ): Promise<void>
3946
+ close (options?: ExternalExperimentCloseOptions): Promise<void>
3947
+ }
3948
+
3855
3949
  interface DatasetPushResult {
3856
3950
  /** Number of records from this push that were confirmed with a record id. */
3857
3951
  pushedCount: number
@@ -3861,9 +3955,18 @@ declare namespace tracer {
3861
3955
 
3862
3956
  interface Dataset {
3863
3957
  addRecord (input: JSONType, expectedOutput?: JSONType, metadata?: Record<string, JSONType>): Dataset
3958
+ /** Update fields on an existing dataset record. */
3959
+ update (index: number, fields: {
3960
+ input?: JSONType
3961
+ expectedOutput?: JSONType
3962
+ metadata?: Record<string, JSONType>
3963
+ }): Dataset
3964
+ /** Delete an existing dataset record. */
3965
+ delete (index: number): Dataset
3864
3966
  /** Creates the dataset remotely if needed and pushes any unpushed records. */
3865
3967
  push (): Promise<DatasetPushResult>
3866
3968
  name (): string
3969
+ description (): string
3867
3970
  id (): string | null
3868
3971
  projectId (): string | null
3869
3972
  version (): number | null
@@ -3893,6 +3996,8 @@ declare namespace tracer {
3893
3996
  pullDataset (name: string, options?: PullDatasetOptions): Promise<Dataset>
3894
3997
  /** Build an experiment to run over a dataset. */
3895
3998
  experiment (options: ExperimentOptions): Experiment
3999
+ /** Start an externally-driven experiment. */
4000
+ startExperiment (options: StartExperimentOptions): Promise<ExternalExperiment>
3896
4001
  }
3897
4002
 
3898
4003
  interface LLMObservabilitySpan {
@@ -4099,6 +4204,11 @@ declare namespace tracer {
4099
4204
  * Audio segments attached to the message (e.g. speech input/output)
4100
4205
  */
4101
4206
  audioParts?: AudioPart[],
4207
+
4208
+ /**
4209
+ * Images attached to the message (e.g. vision input, generated output)
4210
+ */
4211
+ imageParts?: ImagePart[],
4102
4212
  }
4103
4213
 
4104
4214
  /**
@@ -4116,6 +4226,43 @@ declare namespace tracer {
4116
4226
  content: string,
4117
4227
  }
4118
4228
 
4229
+ /**
4230
+ * Represents an image attached to an LLM chat model message, carrying exactly
4231
+ * one of inline `content` or an `attachmentKey`. Supplying neither or both is
4232
+ * rejected by the tagger, and the union keeps both shapes from type-checking.
4233
+ */
4234
+ type ImagePart = {
4235
+ /**
4236
+ * The MIME type of the image (e.g. "image/png", "image/jpeg")
4237
+ */
4238
+ mimeType: string,
4239
+
4240
+ /**
4241
+ * The image content as a base64-encoded string
4242
+ */
4243
+ content: string,
4244
+
4245
+ /**
4246
+ * Explicitly excluded when inline content is present to maintain type safety.
4247
+ */
4248
+ attachmentKey?: never,
4249
+ } | {
4250
+ /**
4251
+ * The MIME type of the image (e.g. "image/png", "image/jpeg")
4252
+ */
4253
+ mimeType: string,
4254
+
4255
+ /**
4256
+ * Key of an already-uploaded image, in place of inline content
4257
+ */
4258
+ attachmentKey: string,
4259
+
4260
+ /**
4261
+ * Explicitly excluded when an attachment key is present to maintain type safety.
4262
+ */
4263
+ content?: never,
4264
+ }
4265
+
4119
4266
  /**
4120
4267
  * Represents a single tool call for an LLM chat model message
4121
4268
  */
package/initialize.mjs CHANGED
@@ -16,19 +16,28 @@ import * as Module from 'module'
16
16
  import { types } from 'util'
17
17
  import { isMainThread } from 'worker_threads'
18
18
 
19
- // This file must support Node.js 12.0.0 syntax
19
+ // This file must support Node.js 14.13.1 syntax
20
20
 
21
- import {
22
- iitmExclusionRegExp,
23
- initialize as hookInitialize,
24
- load as hookLoad,
25
- resolve as hookResolve,
26
- } from './loader-hook.mjs?initialize'
21
+ const NODE_VERSION = process.versions.node
22
+
23
+ const brokenLoaders = NODE_VERSION.startsWith('18.0')
24
+ const isNode20LoaderWorker = !isMainThread && NODE_VERSION.startsWith('20.0')
25
+ const useDefaultLoader = brokenLoaders || isNode20LoaderWorker
26
+ // Avoid CommonJS in the loader worker on Node 20.0: https://github.com/nodejs/node/issues/47566
27
+ const loaderHook = useDefaultLoader ? undefined : await import('./loader-hook.mjs?initialize')
27
28
 
28
29
  let hasInsertedInit = false
29
30
  const initJsUrl = new URL('init.js', import.meta.url).href
30
31
  // `--loader` only reliably influences ESM entrypoints; for CJS apps use `--import`/`--require`.
31
32
 
33
+ // `globalPreload` is deprecated in favor of the `initialize` hook, but `initialize` only exists
34
+ // from Node 20.6 on, so it is the only way to run code in the application realm on Node 20.0.
35
+ export const globalPreload = isNode20LoaderWorker
36
+ ? () => `if (getBuiltin('module').createRequire(${JSON.stringify(import.meta.url)})('./init.js')) {
37
+ process.emitWarning('dd-trace cannot instrument ES modules on Node.js 20.0.0. Upgrade to Node.js 20.1.0 or newer.')
38
+ }`
39
+ : undefined
40
+
32
41
  /**
33
42
  * @param {{ source?: string|Buffer|Uint8Array, format?: string }} result
34
43
  * @param {unknown} _url_
@@ -63,26 +72,28 @@ function insertInit (result, _url_, context) {
63
72
  return result
64
73
  }
65
74
 
66
- const [NODE_MAJOR, NODE_MINOR] = process.versions.node.split('.').map(Number)
67
-
68
- const brokenLoaders = NODE_MAJOR === 18 && NODE_MINOR === 0
69
-
70
75
  // Node calls `initialize` only through `module.register`, never for `--loader`; without it
71
76
  // import-in-the-middle keeps its default matcher and proxies every application module. Loaders
72
77
  // before Node 18.19 share the application thread, where `loader-hook.mjs` builds no matcher.
73
- let needsHookInitialize = !isMainThread && !brokenLoaders
78
+ let needsHookInitialize = !isMainThread && !useDefaultLoader
74
79
 
75
- export async function load (url, context, nextLoad) {
80
+ /**
81
+ * @param {string} url
82
+ * @param {import('node:module').LoadHookContext & { isMain?: boolean }} context
83
+ * @param {Parameters<import('node:module').LoadHook>[2]} nextLoad
84
+ */
85
+ async function loadWithInit (url, context, nextLoad) {
76
86
  if (needsHookInitialize) {
77
87
  needsHookInitialize = false
78
- hookInitialize()
88
+ loaderHook.initialize()
79
89
  }
80
90
 
81
- const loadHook = (brokenLoaders || iitmExclusionRegExp.test(url)) ? nextLoad : hookLoad
82
- return insertInit(await loadHook(url, context, nextLoad), url, context)
91
+ const load = (useDefaultLoader || loaderHook.iitmExclusionRegExp.test(url)) ? nextLoad : loaderHook.load
92
+ return insertInit(await load(url, context, nextLoad), url, context)
83
93
  }
84
94
 
85
- export const resolve = brokenLoaders ? undefined : hookResolve
95
+ export const load = isNode20LoaderWorker ? undefined : loadWithInit
96
+ export const resolve = useDefaultLoader ? undefined : loaderHook.resolve
86
97
 
87
98
  if (isMainThread) {
88
99
  const require = Module.createRequire(import.meta.url)
package/openfeature.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use strict'
2
2
 
3
- // Static fallback for file tracers that do not recognize the optional-peer wrapper.
4
- require('@datadog/openfeature-node-server')
3
+ // Static fallback for file tracers that do not recognize the vendored provider's lazy require.
4
+ require('./vendor/dist/@datadog/openfeature-node-server')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "6.9.0",
3
+ "version": "6.11.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -22,8 +22,9 @@
22
22
  "type:check": "tsc --noEmit -p tsconfig.dev.json",
23
23
  "type:doc:build": "cd docs && yarn && yarn build",
24
24
  "type:doc:test": "cd docs && yarn && yarn test",
25
- "lint": "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 && npm run lint:codeowners:ci && npm run verify-exercised-tests",
25
+ "lint": "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 && npm run verify:carrier-fields && npm run lint:codeowners:ci && npm run verify-exercised-tests",
26
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",
27
+ "verify:carrier-fields": "node scripts/verify-carrier-fields.mjs",
27
28
  "lint:inspect": "npx @eslint/config-inspector@latest",
28
29
  "lint:codeowners": "codeowners-audit",
29
30
  "lint:codeowners:ci": "codeowners-audit --glob='**/*.spec.js' --glob='benchmark/sirun/**' --glob='.agents/**' --glob='.claude/**' --glob='integration-tests/**' --glob='packages/dd-trace/src/guardrails/**'",
@@ -39,7 +40,7 @@
39
40
  "test:appsec:plugins:ci": "yarn services && node scripts/c8-ci.js test:appsec:plugins",
40
41
  "test:debugger": "mocha \"packages/dd-trace/test/debugger/**/*.spec.js\"",
41
42
  "test:debugger:ci": "node scripts/c8-ci.js test:debugger",
42
- "test:eslint-rules": "node eslint-rules/*.test.mjs",
43
+ "test:eslint-rules": "node scripts/run-eslint-rule-tests.mjs eslint-rules/*.test.mjs",
43
44
  "test:trace:core": "node scripts/mocha-parallel-files.js --expose-gc --timeout 30000 -- \"packages/dd-trace/test/*.spec.js\" \"packages/dd-trace/test/{agent,ci-visibility,config,crashtracking,datastreams,encode,exporters,msgpack,opentelemetry,opentracing,payload-tagging,plugins,remote_config,service-naming,standalone,telemetry,external-logger}/**/*.spec.js\"",
44
45
  "test:trace:core:ci": "node scripts/c8-ci.js test:trace:core",
45
46
  "test:trace:guardrails": "mocha \"packages/dd-trace/test/guardrails/**/*.spec.js\"",
@@ -48,7 +49,7 @@
48
49
  "test:esbuild:ci": "node scripts/c8-ci.js test:esbuild",
49
50
  "test:webpack": "mocha \"packages/datadog-webpack/test/**/*.spec.js\"",
50
51
  "test:webpack:ci": "node scripts/c8-ci.js test:webpack",
51
- "test:instrumentations": "mocha \"packages/datadog-instrumentations/test/@(${PLUGINS}).spec.js\"",
52
+ "test:instrumentations": "mocha --fail-zero \"packages/datadog-instrumentations/test/@(${PLUGINS}).spec.js\"",
52
53
  "test:instrumentations:ci": "yarn services && node scripts/c8-ci.js test:instrumentations",
53
54
  "test:instrumentations:misc": "mocha \"packages/datadog-instrumentations/test/*/**/*.spec.{js,mjs}\"",
54
55
  "test:instrumentations:misc:ci": "node scripts/c8-ci.js test:instrumentations:misc",
@@ -64,12 +65,14 @@
64
65
  "test:llmobs:plugins:ci": "yarn services && node scripts/c8-ci.js test:llmobs:plugins",
65
66
  "test:openfeature": "mocha \"packages/dd-trace/test/openfeature/**/*.spec.js\"",
66
67
  "test:openfeature:ci": "node scripts/c8-ci.js test:openfeature",
67
- "test:plugins": "node --expose-gc ./node_modules/mocha/bin/mocha.js \"packages/datadog-plugin-@(${PLUGINS})/test/**/${SPEC:-*}*.spec.js\"",
68
+ "test:plugins": "node --expose-gc ./node_modules/mocha/bin/mocha.js --fail-zero \"packages/datadog-plugin-@(${PLUGINS})/test/**/${SPEC:-*}*.spec.js\"",
68
69
  "test:plugins:ci": "yarn services && node scripts/c8-ci.js test:plugins",
69
70
  "test:plugins:ci:flaky": "yarn services && node scripts/c8-ci.js test:plugins --bail --retries 2",
70
71
  "test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
71
72
  "test:profiler": "node scripts/mocha-parallel-files.js --expose-gc --timeout 30000 -- \"packages/dd-trace/test/profiling/**/*.spec.js\"",
72
73
  "test:profiler:ci": "node scripts/c8-ci.js test:profiler",
74
+ "test:otel-thread-ctx": "mocha --timeout 60000 packages/dd-trace/test/otel-thread-ctx.spec.js",
75
+ "test:docker:otel-thread-ctx": "./scripts/docker/run-otel-thread-ctx-spec.sh",
73
76
  "test:integration": "mocha --timeout 60000 \"integration-tests/*.spec.js\"",
74
77
  "test:integration:coverage": "node ./integration-tests/coverage/run-suite.js --timeout 60000 \"integration-tests/*.spec.js\"",
75
78
  "test:integration:aiguard": "mocha --timeout 60000 \"integration-tests/aiguard/*.spec.js\"",
@@ -111,7 +114,7 @@
111
114
  "test:integration:plugins:coverage": "yarn services && node ./integration-tests/coverage/run-suite.js \"packages/datadog-plugin-@(${PLUGINS})/test/integration-test/**/${SPEC:-*}*.spec.js\"",
112
115
  "test:unit:plugins": "mocha \"packages/datadog-instrumentations/test/@(${PLUGINS}).spec.js\" \"packages/datadog-plugin-@(${PLUGINS})/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@(${PLUGINS})/test/integration-test/**/*.spec.js\"",
113
116
  "test:release": "mocha \"scripts/release/**/*.spec.js\"",
114
- "test:scripts": "mocha \"scripts/helpers/**/*.spec.js\" \"scripts/*.spec.mjs\"",
117
+ "test:scripts": "mocha \"benchmark/sirun/*.spec.js\" \"scripts/helpers/**/*.spec.js\" \"scripts/*.spec.mjs\"",
115
118
  "test:shimmer": "mocha \"packages/datadog-shimmer/test/**/*.spec.js\"",
116
119
  "test:shimmer:ci": "node scripts/c8-ci.js test:shimmer",
117
120
  "verify:workflow-job-names": "node scripts/verify-workflow-job-names.js",
@@ -179,13 +182,12 @@
179
182
  "opentracing": ">=0.14.7"
180
183
  },
181
184
  "optionalDependencies": {
182
- "@datadog/libdatadog": "0.9.4",
185
+ "@datadog/libdatadog": "0.12.1",
183
186
  "@datadog/native-appsec": "11.0.1",
184
187
  "@datadog/native-iast-taint-tracking": "4.2.0",
185
188
  "@datadog/native-metrics": "3.1.2",
186
- "@datadog/openfeature-node-server": "2.0.2",
187
- "@datadog/pprof": "5.17.0",
188
- "@datadog/wasm-js-rewriter": "5.0.1",
189
+ "@datadog/pprof": "5.18.0",
190
+ "@datadog/wasm-js-rewriter": "5.0.3",
189
191
  "@opentelemetry/api": ">=1.0.0 <1.10.0",
190
192
  "@opentelemetry/api-logs": "<1.0.0",
191
193
  "oxc-parser": "^0.132.0"
@@ -196,6 +198,8 @@
196
198
  "@babel/helpers": "^8.0.0",
197
199
  "@eslint/eslintrc": "^3.3.5",
198
200
  "@eslint/js": "^10.0.1",
201
+ "@eslint/plugin-kit": "^0.7.2",
202
+ "@datadog/openfeature-node-server": "2.1.0",
199
203
  "@msgpack/msgpack": "^3.1.3",
200
204
  "@openfeature/core": "^1.11.0",
201
205
  "@openfeature/server-sdk": "~1.22.0",