dd-trace 6.16.0 → 6.17.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 (334) hide show
  1. package/ci/diagnose.js +0 -23
  2. package/ci/test-optimization-validation/approval-artifacts.js +0 -3
  3. package/ci/test-optimization-validation/approval.js +0 -6
  4. package/ci/test-optimization-validation/artifact-id.js +0 -1
  5. package/ci/test-optimization-validation/bounded-json.js +0 -1
  6. package/ci/test-optimization-validation/cli.js +0 -12
  7. package/ci/test-optimization-validation/command-output-policy.js +0 -1
  8. package/ci/test-optimization-validation/command-runner.js +0 -3
  9. package/ci/test-optimization-validation/environment.js +0 -4
  10. package/ci/test-optimization-validation/executable-approval.js +0 -1
  11. package/ci/test-optimization-validation/executable.js +0 -5
  12. package/ci/test-optimization-validation/framework-adapters/cucumber.js +0 -6
  13. package/ci/test-optimization-validation/framework-adapters/cypress.js +0 -3
  14. package/ci/test-optimization-validation/framework-adapters/playwright.js +0 -6
  15. package/ci/test-optimization-validation/framework-adapters/vitest.js +0 -4
  16. package/ci/test-optimization-validation/generated-test-contract.js +0 -5
  17. package/ci/test-optimization-validation/generated-verifier.js +0 -1
  18. package/ci/test-optimization-validation/literal-environment.js +0 -1
  19. package/ci/test-optimization-validation/manifest-scaffold.js +0 -17
  20. package/ci/test-optimization-validation/manifest-schema.js +0 -21
  21. package/ci/test-optimization-validation/offline-fixtures.js +0 -4
  22. package/ci/test-optimization-validation/plan-writer.js +0 -11
  23. package/ci/test-optimization-validation/preflight-runner.js +0 -1
  24. package/ci/test-optimization-validation/redaction.js +0 -4
  25. package/ci/test-optimization-validation/report-writer.js +0 -16
  26. package/ci/test-optimization-validation/runner-command.js +0 -3
  27. package/ci/test-optimization-validation/runner-contract.js +0 -4
  28. package/ci/test-optimization-validation/safe-files.js +0 -1
  29. package/ci/test-optimization-validation/scenarios/basic-reporting.js +0 -1
  30. package/ci/test-optimization-validation/scenarios/ci-wiring.js +0 -1
  31. package/ci/test-optimization-validation/source-text.js +0 -3
  32. package/ci/vitest-no-worker-init-setup.mjs +41 -16
  33. package/index.d.ts +165 -0
  34. package/package.json +17 -16
  35. package/packages/datadog-esbuild/src/utils.js +0 -2
  36. package/packages/datadog-instrumentations/src/aerospike.js +28 -6
  37. package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -2
  38. package/packages/datadog-instrumentations/src/aws-sdk.js +0 -2
  39. package/packages/datadog-instrumentations/src/claude-agent-sdk.js +0 -2
  40. package/packages/datadog-instrumentations/src/console.js +97 -0
  41. package/packages/datadog-instrumentations/src/cucumber.js +72 -12
  42. package/packages/datadog-instrumentations/src/cypress-config.js +0 -23
  43. package/packages/datadog-instrumentations/src/helpers/channel.js +0 -2
  44. package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +0 -5
  45. package/packages/datadog-instrumentations/src/helpers/hooks.js +8 -0
  46. package/packages/datadog-instrumentations/src/helpers/instrumentation-utils.js +0 -3
  47. package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +0 -6
  48. package/packages/datadog-instrumentations/src/helpers/register.js +4 -0
  49. package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +72 -24
  50. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +39 -0
  51. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +3 -17
  52. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +12 -0
  53. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +36 -0
  54. package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/supabase.js +128 -0
  55. package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +16 -0
  56. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +388 -0
  57. package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +0 -5
  58. package/packages/datadog-instrumentations/src/helpers/router-helper.js +0 -1
  59. package/packages/datadog-instrumentations/src/jest.js +141 -51
  60. package/packages/datadog-instrumentations/src/knex.js +0 -1
  61. package/packages/datadog-instrumentations/src/mariadb-bundle.js +0 -24
  62. package/packages/datadog-instrumentations/src/mariadb.js +0 -2
  63. package/packages/datadog-instrumentations/src/mocha/common.js +0 -1
  64. package/packages/datadog-instrumentations/src/mocha/main.js +22 -25
  65. package/packages/datadog-instrumentations/src/mocha/utils.js +119 -49
  66. package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +0 -6
  67. package/packages/datadog-instrumentations/src/mocha/worker.js +14 -17
  68. package/packages/datadog-instrumentations/src/mysql2.js +0 -2
  69. package/packages/datadog-instrumentations/src/openai-realtime/audio-accumulator.js +241 -0
  70. package/packages/datadog-instrumentations/src/openai-realtime/events.js +76 -0
  71. package/packages/datadog-instrumentations/src/openai-realtime/index.js +301 -0
  72. package/packages/datadog-instrumentations/src/openai-realtime/session.js +998 -0
  73. package/packages/datadog-instrumentations/src/openai-realtime/turns.js +211 -0
  74. package/packages/datadog-instrumentations/src/openai.js +51 -12
  75. package/packages/datadog-instrumentations/src/oracledb.js +9 -3
  76. package/packages/datadog-instrumentations/src/playwright-reporter.js +3 -16
  77. package/packages/datadog-instrumentations/src/playwright.js +238 -55
  78. package/packages/datadog-instrumentations/src/postgres.js +7 -0
  79. package/packages/datadog-instrumentations/src/router.js +0 -2
  80. package/packages/datadog-instrumentations/src/rum-browser-scripts.js +0 -2
  81. package/packages/datadog-instrumentations/src/sequelize.js +0 -1
  82. package/packages/datadog-instrumentations/src/supabase.js +15 -0
  83. package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +18 -18
  84. package/packages/datadog-instrumentations/src/vitest-main.js +37 -17
  85. package/packages/datadog-instrumentations/src/vitest-util.js +7 -1
  86. package/packages/datadog-instrumentations/src/vitest-worker.js +49 -13
  87. package/packages/datadog-instrumentations/src/webdriverio.js +23 -42
  88. package/packages/datadog-instrumentations/src/ws.js +0 -1
  89. package/packages/datadog-plugin-ai/src/utils.js +0 -2
  90. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/trace-checkpoint.js +0 -1
  91. package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +0 -2
  92. package/packages/datadog-plugin-aws-sdk/src/base.js +0 -1
  93. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +0 -1
  94. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +0 -1
  95. package/packages/datadog-plugin-aws-sdk/src/util.js +0 -1
  96. package/packages/datadog-plugin-azure-durable-functions/src/index.js +0 -1
  97. package/packages/datadog-plugin-cucumber/src/index.js +10 -0
  98. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +171 -75
  99. package/packages/datadog-plugin-cypress/src/finalization.js +0 -3
  100. package/packages/datadog-plugin-cypress/src/source-map-utils.js +0 -4
  101. package/packages/datadog-plugin-cypress/src/support.js +52 -7
  102. package/packages/datadog-plugin-graphql/src/resolve-error.js +1 -2
  103. package/packages/datadog-plugin-graphql/src/utils.js +0 -5
  104. package/packages/datadog-plugin-jest/src/index.js +13 -0
  105. package/packages/datadog-plugin-kafkajs/src/producer.js +0 -1
  106. package/packages/datadog-plugin-mocha/src/index.js +39 -11
  107. package/packages/datadog-plugin-mongodb-core/src/query.js +0 -1
  108. package/packages/datadog-plugin-openai/src/index.js +16 -1
  109. package/packages/datadog-plugin-openai/src/realtime.js +144 -0
  110. package/packages/datadog-plugin-openai-agents/src/integration.js +0 -4
  111. package/packages/datadog-plugin-openai-agents/src/util.js +0 -1
  112. package/packages/datadog-plugin-playwright/src/index.js +76 -9
  113. package/packages/datadog-plugin-postgres/src/index.js +167 -0
  114. package/packages/datadog-plugin-prisma/src/datadog-tracing-helper.js +0 -1
  115. package/packages/datadog-plugin-redis/src/index.js +15 -1
  116. package/packages/datadog-plugin-supabase/src/error.js +18 -0
  117. package/packages/datadog-plugin-supabase/src/index.js +21 -0
  118. package/packages/datadog-plugin-supabase/src/supabase-auth-js-gotrueclient-getuser.js +69 -0
  119. package/packages/datadog-plugin-supabase/src/supabase-functions-js-functionsclient-invoke.js +70 -0
  120. package/packages/datadog-plugin-supabase/src/supabase-postgrest-js-postgrestbuilder-then.js +122 -0
  121. package/packages/datadog-plugin-supabase/src/supabase-realtime-js-realtimechannel-send.js +66 -0
  122. package/packages/datadog-plugin-supabase/src/supabase-storage-js-handle-request.js +93 -0
  123. package/packages/datadog-plugin-supabase/src/url.js +17 -0
  124. package/packages/datadog-plugin-vitest/src/index.js +10 -0
  125. package/packages/datadog-plugin-ws/src/util.js +0 -4
  126. package/packages/datadog-turbopack/index.js +0 -6
  127. package/packages/datadog-turbopack/src/loader.js +0 -16
  128. package/packages/datadog-webpack/src/loader.js +0 -1
  129. package/packages/dd-trace/src/aiguard/client.js +2 -3
  130. package/packages/dd-trace/src/aiguard/evaluation.js +6 -12
  131. package/packages/dd-trace/src/aiguard/index.js +2 -2
  132. package/packages/dd-trace/src/aiguard/integrations/index.js +1 -1
  133. package/packages/dd-trace/src/aiguard/integrations/openai.js +81 -7
  134. package/packages/dd-trace/src/aiguard/messages/anthropic.js +0 -2
  135. package/packages/dd-trace/src/aiguard/messages/openai.js +64 -1
  136. package/packages/dd-trace/src/aiguard/messages/utils.js +0 -1
  137. package/packages/dd-trace/src/aiguard/redaction.js +0 -1
  138. package/packages/dd-trace/src/aiguard/sdk.js +1 -1
  139. package/packages/dd-trace/src/appsec/activation.js +1 -1
  140. package/packages/dd-trace/src/appsec/api_security/normalized-route.js +0 -5
  141. package/packages/dd-trace/src/appsec/api_security/sampler.js +0 -4
  142. package/packages/dd-trace/src/appsec/blocking/index.js +3 -3
  143. package/packages/dd-trace/src/appsec/downstream_requests.js +1 -4
  144. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  145. package/packages/dd-trace/src/appsec/iast/overhead-controller.js +5 -5
  146. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +1 -1
  147. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -1
  148. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +3 -3
  149. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +8 -10
  150. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +2 -2
  151. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +4 -1
  152. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +7 -7
  153. package/packages/dd-trace/src/appsec/index.js +2 -2
  154. package/packages/dd-trace/src/appsec/lambda.js +71 -2
  155. package/packages/dd-trace/src/appsec/rasp/utils.js +5 -1
  156. package/packages/dd-trace/src/appsec/remote_config.js +8 -6
  157. package/packages/dd-trace/src/appsec/reporter.js +10 -6
  158. package/packages/dd-trace/src/appsec/rule_manager.js +3 -3
  159. package/packages/dd-trace/src/appsec/sdk/track_event.js +0 -2
  160. package/packages/dd-trace/src/appsec/waf/index.js +2 -2
  161. package/packages/dd-trace/src/appsec/waf/waf_manager.js +8 -5
  162. package/packages/dd-trace/src/carrier.js +0 -5
  163. package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +104 -0
  164. package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +0 -2
  165. package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +34 -3
  166. package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +0 -1
  167. package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +0 -1
  168. package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +0 -1
  169. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +0 -4
  170. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +0 -1
  171. package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +0 -2
  172. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +37 -15
  173. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +0 -3
  174. package/packages/dd-trace/src/ci-visibility/exporters/request.js +0 -11
  175. package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +0 -1
  176. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +0 -1
  177. package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +0 -6
  178. package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +2 -2
  179. package/packages/dd-trace/src/ci-visibility/requests/rate-limit.js +0 -1
  180. package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +0 -5
  181. package/packages/dd-trace/src/ci-visibility/requests/video-request.js +0 -1
  182. package/packages/dd-trace/src/ci-visibility/telemetry.js +13 -0
  183. package/packages/dd-trace/src/ci-visibility/test-optimization-cache.js +0 -1
  184. package/packages/dd-trace/src/ci-visibility/test-screenshot.js +0 -2
  185. package/packages/dd-trace/src/ci-visibility/test-video.js +0 -1
  186. package/packages/dd-trace/src/config/defaults.js +3 -2
  187. package/packages/dd-trace/src/config/generated-config-types.d.ts +73 -67
  188. package/packages/dd-trace/src/config/helper.js +0 -1
  189. package/packages/dd-trace/src/config/index.js +24 -24
  190. package/packages/dd-trace/src/config/parsers.js +34 -6
  191. package/packages/dd-trace/src/config/remote_config.js +25 -109
  192. package/packages/dd-trace/src/config/supported-configurations.json +139 -10
  193. package/packages/dd-trace/src/datastreams/encoding.js +0 -1
  194. package/packages/dd-trace/src/datastreams/pathway.js +0 -1
  195. package/packages/dd-trace/src/debugger/constants.js +10 -0
  196. package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +62 -10
  197. package/packages/dd-trace/src/debugger/devtools_client/config.js +2 -0
  198. package/packages/dd-trace/src/debugger/devtools_client/guardrail-metrics.js +15 -0
  199. package/packages/dd-trace/src/debugger/devtools_client/index.js +103 -27
  200. package/packages/dd-trace/src/debugger/devtools_client/json-buffer.js +50 -7
  201. package/packages/dd-trace/src/debugger/devtools_client/log.js +3 -1
  202. package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +21 -8
  203. package/packages/dd-trace/src/debugger/devtools_client/send.js +40 -14
  204. package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +53 -13
  205. package/packages/dd-trace/src/debugger/devtools_client/snapshot/processor.js +118 -71
  206. package/packages/dd-trace/src/debugger/devtools_client/snapshot-pruner.js +0 -3
  207. package/packages/dd-trace/src/debugger/devtools_client/status.js +20 -6
  208. package/packages/dd-trace/src/debugger/guardrail-metrics.js +167 -0
  209. package/packages/dd-trace/src/debugger/index.js +50 -2
  210. package/packages/dd-trace/src/debugger/inspect-segment.js +0 -3
  211. package/packages/dd-trace/src/debugger/probe_sampler.js +133 -9
  212. package/packages/dd-trace/src/debugger/probe_sampler_constants.js +31 -1
  213. package/packages/dd-trace/src/dogstatsd.js +0 -23
  214. package/packages/dd-trace/src/encode/0.4-cross-payload.js +0 -3
  215. package/packages/dd-trace/src/encode/0.4.js +0 -7
  216. package/packages/dd-trace/src/encode/0.5.js +0 -2
  217. package/packages/dd-trace/src/encode/tags-processors.js +0 -1
  218. package/packages/dd-trace/src/evp_proxy/discovery.js +0 -1
  219. package/packages/dd-trace/src/evp_proxy/path.js +0 -2
  220. package/packages/dd-trace/src/exporters/agent/writer.js +0 -1
  221. package/packages/dd-trace/src/exporters/agentless/index.js +0 -1
  222. package/packages/dd-trace/src/exporters/agentless/intake.js +0 -1
  223. package/packages/dd-trace/src/exporters/agentless/writer.js +0 -3
  224. package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +0 -6
  225. package/packages/dd-trace/src/exporters/common/request.js +1 -0
  226. package/packages/dd-trace/src/exporters/common/url.js +0 -2
  227. package/packages/dd-trace/src/exporters/common/writer.js +0 -2
  228. package/packages/dd-trace/src/id.js +0 -11
  229. package/packages/dd-trace/src/llmobs/audio-codec.js +192 -0
  230. package/packages/dd-trace/src/llmobs/audio-utils.js +121 -0
  231. package/packages/dd-trace/src/llmobs/constants/audio.js +35 -0
  232. package/packages/dd-trace/src/llmobs/constants/prompts.js +14 -0
  233. package/packages/dd-trace/src/llmobs/constants/tags.js +17 -0
  234. package/packages/dd-trace/src/llmobs/eval-metric.js +0 -6
  235. package/packages/dd-trace/src/llmobs/experiments/dataset.js +0 -4
  236. package/packages/dd-trace/src/llmobs/experiments/experiment.js +0 -3
  237. package/packages/dd-trace/src/llmobs/experiments/index.js +7 -6
  238. package/packages/dd-trace/src/llmobs/experiments/util.js +1 -11
  239. package/packages/dd-trace/src/llmobs/index.js +1 -3
  240. package/packages/dd-trace/src/llmobs/noop.js +10 -0
  241. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +0 -4
  242. package/packages/dd-trace/src/llmobs/plugins/anthropic/util.js +0 -1
  243. package/packages/dd-trace/src/llmobs/plugins/genai/util.js +0 -4
  244. package/packages/dd-trace/src/llmobs/plugins/modelcontextprotocol-sdk/utils.js +0 -2
  245. package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +0 -2
  246. package/packages/dd-trace/src/llmobs/plugins/openai/index.js +4 -6
  247. package/packages/dd-trace/src/llmobs/plugins/openai/realtime.js +285 -0
  248. package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +16 -3
  249. package/packages/dd-trace/src/llmobs/prompts/cache.js +272 -0
  250. package/packages/dd-trace/src/llmobs/prompts/manager.js +639 -0
  251. package/packages/dd-trace/src/llmobs/prompts/noop.js +29 -0
  252. package/packages/dd-trace/src/llmobs/prompts/prompt.js +92 -0
  253. package/packages/dd-trace/src/llmobs/sdk.js +21 -6
  254. package/packages/dd-trace/src/llmobs/span_processor.js +81 -2
  255. package/packages/dd-trace/src/llmobs/tagger.js +30 -7
  256. package/packages/dd-trace/src/llmobs/telemetry.js +36 -4
  257. package/packages/dd-trace/src/llmobs/util.js +0 -34
  258. package/packages/dd-trace/src/llmobs/writers/base.js +0 -1
  259. package/packages/dd-trace/src/llmobs/writers/util.js +1 -2
  260. package/packages/dd-trace/src/log/channels.js +3 -0
  261. package/packages/dd-trace/src/log/index.js +23 -5
  262. package/packages/dd-trace/src/log-submission/log-submission-plugin.js +74 -6
  263. package/packages/dd-trace/src/msgpack/chunk.js +0 -1
  264. package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +0 -12
  265. package/packages/dd-trace/src/openfeature/encoding.js +0 -2
  266. package/packages/dd-trace/src/openfeature/eval-metrics-hook.js +0 -1
  267. package/packages/dd-trace/src/openfeature/index.js +0 -4
  268. package/packages/dd-trace/src/openfeature/span-enrichment-hook.js +0 -1
  269. package/packages/dd-trace/src/openfeature/span-enrichment.js +0 -4
  270. package/packages/dd-trace/src/openfeature/writers/base.js +0 -6
  271. package/packages/dd-trace/src/openfeature/writers/exposures.js +0 -5
  272. package/packages/dd-trace/src/openfeature/writers/util.js +0 -4
  273. package/packages/dd-trace/src/opentelemetry/logs/logger.js +0 -1
  274. package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +0 -1
  275. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +0 -1
  276. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +0 -2
  277. package/packages/dd-trace/src/opentelemetry/metrics/meter_provider.js +0 -1
  278. package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_transformer.js +0 -1
  279. package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +0 -1
  280. package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -14
  281. package/packages/dd-trace/src/opentelemetry/metrics/time.js +0 -1
  282. package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +30 -13
  283. package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +0 -1
  284. package/packages/dd-trace/src/opentelemetry/span-helpers.js +0 -1
  285. package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +0 -1
  286. package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +0 -3
  287. package/packages/dd-trace/src/opentracing/propagation/text_map.js +0 -6
  288. package/packages/dd-trace/src/opentracing/span_context.js +0 -1
  289. package/packages/dd-trace/src/otel-thread-ctx.js +38 -11
  290. package/packages/dd-trace/src/payload-tagging/tagging.js +15 -3
  291. package/packages/dd-trace/src/plugins/ci_plugin.js +0 -1
  292. package/packages/dd-trace/src/plugins/database.js +2 -6
  293. package/packages/dd-trace/src/plugins/index.js +7 -0
  294. package/packages/dd-trace/src/plugins/plugin.js +0 -4
  295. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  296. package/packages/dd-trace/src/plugins/util/git.js +1 -3
  297. package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +0 -1
  298. package/packages/dd-trace/src/plugins/util/llm.js +0 -2
  299. package/packages/dd-trace/src/plugins/util/status-validator.js +0 -1
  300. package/packages/dd-trace/src/plugins/util/test.js +21 -20
  301. package/packages/dd-trace/src/plugins/util/url.js +0 -5
  302. package/packages/dd-trace/src/priority_sampler.js +0 -6
  303. package/packages/dd-trace/src/process-tags/index.js +0 -1
  304. package/packages/dd-trace/src/profiler.js +132 -35
  305. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +0 -1
  306. package/packages/dd-trace/src/profiling/profiler.js +101 -41
  307. package/packages/dd-trace/src/profiling/ssi-heuristics.js +29 -15
  308. package/packages/dd-trace/src/propagation-hash/index.js +0 -1
  309. package/packages/dd-trace/src/proxy.js +21 -45
  310. package/packages/dd-trace/src/random_sampler.js +0 -4
  311. package/packages/dd-trace/src/rate_limiter.js +0 -4
  312. package/packages/dd-trace/src/remote_config/capabilities.js +1 -9
  313. package/packages/dd-trace/src/remote_config/index.js +0 -1
  314. package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +0 -3
  315. package/packages/dd-trace/src/sampler.js +0 -4
  316. package/packages/dd-trace/src/sampling_rule.js +0 -7
  317. package/packages/dd-trace/src/serverless/vercel.js +0 -1
  318. package/packages/dd-trace/src/serverless.js +0 -1
  319. package/packages/dd-trace/src/service-naming/index.js +0 -1
  320. package/packages/dd-trace/src/service-naming/schemas/util.js +0 -1
  321. package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +7 -0
  322. package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +5 -0
  323. package/packages/dd-trace/src/span_processor.js +2 -2
  324. package/packages/dd-trace/src/span_sampler.js +0 -1
  325. package/packages/dd-trace/src/standalone/product.js +2 -2
  326. package/packages/dd-trace/src/standalone/tracesource.js +0 -1
  327. package/packages/dd-trace/src/startup-log.js +1 -1
  328. package/packages/dd-trace/src/telemetry/endpoints.js +0 -8
  329. package/packages/dd-trace/src/telemetry/logs/index.js +16 -5
  330. package/packages/dd-trace/src/telemetry/logs/log-collector.js +16 -6
  331. package/packages/dd-trace/src/telemetry/metrics.js +0 -2
  332. package/packages/dd-trace/src/telemetry/telemetry.js +4 -1
  333. package/packages/dd-trace/src/util.js +13 -1
  334. package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
@@ -11,6 +11,8 @@ const waf = require('./waf')
11
11
 
12
12
  const activeInvocations = new WeakMap()
13
13
 
14
+ const MAX_RESPONSE_BODY_SIZE = 16 * 1024 * 1024
15
+
14
16
  /**
15
17
  * Maps pre-extracted HTTP data from the Lambda event to WAF addresses,
16
18
  * runs the WAF, and reports results on the span.
@@ -86,11 +88,12 @@ function onLambdaStartInvocation (data) {
86
88
  * WAF pass, disposes the WAF context, and finishes the request report.
87
89
  *
88
90
  * @param {{ span: object, statusCode: string | undefined,
89
- * responseHeaders: Record<string, string> | undefined }} data
91
+ * responseHeaders: Record<string, string> | undefined,
92
+ * responseBody: unknown, isBase64Encoded: boolean | undefined }} data
90
93
  */
91
94
  function onLambdaEndInvocation (data) {
92
95
  try {
93
- const { span, statusCode, responseHeaders } = data
96
+ const { span, statusCode, responseHeaders, responseBody, isBase64Encoded } = data
94
97
 
95
98
  if (!span) {
96
99
  log.warn('[ASM] No span provided in Lambda end invocation')
@@ -127,6 +130,11 @@ function onLambdaEndInvocation (data) {
127
130
 
128
131
  if (samplingDecision === apiSecurity.SamplingDecision.SAMPLE) {
129
132
  persistent[addresses.WAF_CONTEXT_PROCESSOR] = { 'extract-schema': true }
133
+
134
+ const parsedBody = parseResponseBody(responseBody, responseHeaders, isBase64Encoded)
135
+ if (parsedBody !== undefined) {
136
+ persistent[addresses.HTTP_INCOMING_RESPONSE_BODY] = parsedBody
137
+ }
130
138
  }
131
139
 
132
140
  let wafResult
@@ -147,6 +155,67 @@ function onLambdaEndInvocation (data) {
147
155
  }
148
156
  }
149
157
 
158
+ /**
159
+ * Turns the raw response body published by the Lambda layer into the object the WAF expects
160
+ *
161
+ * @param {unknown} rawBody
162
+ * @param {Record<string, string> | undefined} headers Already lowercased by the Lambda layer
163
+ * @param {boolean | undefined} isBase64Encoded
164
+ * @returns {object | undefined} The parsed body, or `undefined` when it cannot be used
165
+ */
166
+ function parseResponseBody (rawBody, headers, isBase64Encoded) {
167
+ if (!rawBody) return
168
+
169
+ // A handler that answered with the payload itself needs no parsing, and no content type either.
170
+ if (typeof rawBody === 'object') return rawBody
171
+
172
+ if (typeof rawBody !== 'string') return
173
+
174
+ if (!isJsonContentType(headers?.['content-type'])) return
175
+
176
+ if (isOverSizeCap(rawBody, isBase64Encoded)) {
177
+ log.debug('[ASM] Lambda response body larger than %d bytes, skipping schema extraction',
178
+ MAX_RESPONSE_BODY_SIZE)
179
+ return
180
+ }
181
+
182
+ const contentEncoding = headers?.['content-encoding']?.toLowerCase()
183
+ if (contentEncoding && contentEncoding !== 'identity') return
184
+
185
+ try {
186
+ const parsed = JSON.parse(isBase64Encoded ? Buffer.from(rawBody, 'base64').toString('utf8') : rawBody)
187
+
188
+ // A JSON scalar carries no schema worth extracting.
189
+ if (parsed === null || typeof parsed !== 'object') return
190
+
191
+ return parsed
192
+ } catch {
193
+ // The SyntaxError message embeds a fragment of the body, which is customer data.
194
+ log.debug('[ASM] Failed to parse Lambda response body')
195
+ }
196
+ }
197
+
198
+ /**
199
+ * @param {string | undefined} contentType
200
+ */
201
+ function isJsonContentType (contentType) {
202
+ return typeof contentType === 'string' && contentType.toLowerCase().includes('json')
203
+ }
204
+
205
+ /**
206
+ * Tells whether a raw body exceeds the size cap, without decoding or measuring it when avoidable
207
+ *
208
+ * @param {string} rawBody
209
+ * @param {boolean | undefined} isBase64Encoded
210
+ */
211
+ function isOverSizeCap (rawBody, isBase64Encoded) {
212
+ if (isBase64Encoded) return Math.floor(rawBody.length * 3 / 4) >= MAX_RESPONSE_BODY_SIZE
213
+ if (rawBody.length >= MAX_RESPONSE_BODY_SIZE) return true
214
+ if (rawBody.length * 3 < MAX_RESPONSE_BODY_SIZE) return false
215
+
216
+ return Buffer.byteLength(rawBody, 'utf8') >= MAX_RESPONSE_BODY_SIZE
217
+ }
218
+
150
219
  module.exports = {
151
220
  onLambdaStartInvocation,
152
221
  onLambdaEndInvocation,
@@ -45,7 +45,11 @@ class DatadogRaspAbortError extends Error {
45
45
  function handleResult (result, req, res, abortController, config, raspRule) {
46
46
  const generateStackTraceAction = result?.actions?.generate_stack
47
47
 
48
- const { enabled, maxDepth, maxStackTraces } = config.appsec.stackTrace
48
+ const {
49
+ DD_APPSEC_STACK_TRACE_ENABLED: enabled,
50
+ DD_APPSEC_MAX_STACK_TRACE_DEPTH: maxDepth,
51
+ DD_APPSEC_MAX_STACK_TRACES: maxStackTraces,
52
+ } = config.appsec
49
53
 
50
54
  const rootSpan = web.root(req)
51
55
 
@@ -43,7 +43,7 @@ function enable (rcInstance, config, appsec) {
43
43
  setCollectionMode(rcConfig.auto_user_instrum.mode)
44
44
  autoUserInstrumModeId = configId
45
45
  } else if (configId === autoUserInstrumModeId) {
46
- setCollectionMode(config.appsec.eventTracking.mode)
46
+ setCollectionMode(config.appsec.DD_APPSEC_AUTO_USER_INSTRUMENTATION_MODE)
47
47
  autoUserInstrumModeId = null
48
48
  }
49
49
  }
@@ -68,7 +68,7 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
68
68
  const isRemoteConfigControlling = action === 'apply' || action === 'modify'
69
69
  const shouldEnable = isRemoteConfigControlling
70
70
  ? rcConfig.asm.enabled // take control
71
- : config.appsec.enabled // give back control to local config
71
+ : config.appsec.DD_APPSEC_ENABLED // give back control to local config
72
72
 
73
73
  if (shouldEnable) {
74
74
  appsec.enable(config)
@@ -79,8 +79,10 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
79
79
  // TODO: Use configWithOrigin /generateTelemetry instead of manually constructing the change.
80
80
  updateConfig([
81
81
  {
82
- name: 'appsec.enabled',
83
- origin: isRemoteConfigControlling ? 'remote_config' : config.getOrigin('appsec.enabled'),
82
+ name: 'DD_APPSEC_ENABLED',
83
+ origin: isRemoteConfigControlling
84
+ ? 'remote_config'
85
+ : config.getOrigin('appsec.DD_APPSEC_ENABLED'),
84
86
  value: shouldEnable,
85
87
  },
86
88
  ], config)
@@ -93,7 +95,7 @@ function enableOrDisableAppsec (action, rcConfig, config, appsec) {
93
95
  * @param {object} appsecConfig - Appsec config
94
96
  */
95
97
  function enableWafUpdate (appsecConfig) {
96
- if (rc && appsecConfig && !appsecConfig.rules) {
98
+ if (rc && appsecConfig && !appsecConfig.DD_APPSEC_RULES) {
97
99
  // dirty require to make startup faster for serverless
98
100
  const { ASM_WAF_PRODUCTS } = require('./rc-products')
99
101
  const RuleManager = require('./rule_manager')
@@ -119,7 +121,7 @@ function enableWafUpdate (appsecConfig) {
119
121
  rc.updateCapabilities(RemoteConfigCapabilities.ASM_TRACE_TAGGING_RULES, true)
120
122
  rc.updateCapabilities(RemoteConfigCapabilities.ASM_EXTENDED_DATA_COLLECTION, true)
121
123
 
122
- if (appsecConfig.rasp?.enabled) {
124
+ if (appsecConfig.DD_APPSEC_RASP_ENABLED) {
123
125
  rc.updateCapabilities(RemoteConfigCapabilities.ASM_RASP_SQLI, true)
124
126
  rc.updateCapabilities(RemoteConfigCapabilities.ASM_RASP_SSRF, true)
125
127
  rc.updateCapabilities(RemoteConfigCapabilities.ASM_RASP_LFI, true)
@@ -8,7 +8,7 @@ const web = require('../plugins/util/web')
8
8
  const { ipHeaderList } = require('../plugins/util/ip_extractor')
9
9
  const { keepTrace } = require('../priority_sampler')
10
10
  const { ASM } = require('../standalone/product')
11
- const { isEmpty } = require('../util')
11
+ const { isEmpty, truncateString } = require('../util')
12
12
  const { getActiveRequest } = require('./store')
13
13
  const {
14
14
  incrementWafInitMetric,
@@ -114,11 +114,15 @@ const NON_EXTENDED_REQUEST_HEADERS = new Set([...requestHeadersList, ...eventHea
114
114
  const NON_EXTENDED_RESPONSE_HEADERS = new Set(responseHeaderList)
115
115
  const REDACTED_HEADERS = new Set(redactedHeadersList)
116
116
 
117
+ /**
118
+ * @param {import('../config/config-types').ConfigProperties['appsec']} _config
119
+ * @param {boolean} [inferredProxyServicesEnabled]
120
+ */
117
121
  function init (_config, inferredProxyServicesEnabled) {
118
- config.headersExtendedCollectionEnabled = _config.extendedHeadersCollection.enabled
119
- config.maxHeadersCollected = _config.extendedHeadersCollection.maxHeaders
120
- config.headersRedaction = _config.extendedHeadersCollection.redaction
121
- config.raspBodyCollection = _config.rasp.bodyCollection
122
+ config.headersExtendedCollectionEnabled = _config.DD_APPSEC_COLLECT_ALL_HEADERS
123
+ config.maxHeadersCollected = _config.DD_APPSEC_MAX_COLLECTED_HEADERS
124
+ config.headersRedaction = _config.DD_APPSEC_HEADER_COLLECTION_REDACTION_ENABLED
125
+ config.raspBodyCollection = _config.DD_APPSEC_RASP_COLLECT_REQUEST_BODY
122
126
  config.inferredProxyServicesEnabled = inferredProxyServicesEnabled
123
127
  }
124
128
 
@@ -431,7 +435,7 @@ function truncateRequestBody (target, depth = 0) {
431
435
  switch (typeof target) {
432
436
  case 'string':
433
437
  if (target.length > COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH) {
434
- return { value: target.slice(0, COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH), truncated: true }
438
+ return { value: truncateString(target, COLLECTED_REQUEST_BODY_MAX_STRING_LENGTH), truncated: true }
435
439
  }
436
440
  return { value: target, truncated: false }
437
441
  case 'object': {
@@ -20,15 +20,15 @@ let appliedActions = new Map()
20
20
  */
21
21
 
22
22
  /**
23
- * @typedef {import('./waf').WAFConfig & { rules?: string }} AppSecConfig
23
+ * @typedef {import('./waf').WAFConfig & { DD_APPSEC_RULES?: string }} AppSecConfig
24
24
  */
25
25
 
26
26
  /**
27
27
  * @param {AppSecConfig} config
28
28
  */
29
29
  function loadRules (config) {
30
- const defaultRules = config.rules
31
- ? JSON.parse(readFileSync(config.rules, 'utf8'))
30
+ const defaultRules = config.DD_APPSEC_RULES
31
+ ? JSON.parse(readFileSync(config.DD_APPSEC_RULES, 'utf8'))
32
32
  : require('./recommended.json')
33
33
 
34
34
  waf.init(defaultRules, config)
@@ -14,7 +14,6 @@ const { getRootSpan } = require('./utils')
14
14
  * @param {import('../../tracer')} tracer
15
15
  * @param {import('../../../../../index').User} user
16
16
  * @param {Record<string, string>} [metadata]
17
- * @returns {void}
18
17
  */
19
18
  function trackUserLoginSuccessEvent (tracer, user, metadata) {
20
19
  // TODO: better user check here and in _setUser() ?
@@ -48,7 +47,6 @@ function trackUserLoginSuccessEvent (tracer, user, metadata) {
48
47
  * @param {string} userId
49
48
  * @param {boolean} exists
50
49
  * @param {Record<string, string>} [metadata]
51
- * @returns {void}
52
50
  */
53
51
  function trackUserLoginFailureEvent (tracer, userId, exists, metadata) {
54
52
  if (!userId || typeof userId !== 'string') {
@@ -25,7 +25,7 @@ let limiter = new Limiter(100)
25
25
  let WAFManager = null
26
26
 
27
27
  /**
28
- * @typedef {import('./waf_manager').WAFManagerConfig & { rateLimit: number }} WAFConfig
28
+ * @typedef {import('./waf_manager').WAFManagerConfig & { DD_APPSEC_TRACE_RATE_LIMIT: number }} WAFConfig
29
29
  */
30
30
 
31
31
  const waf = {
@@ -48,7 +48,7 @@ const waf = {
48
48
  function init (rules, config) {
49
49
  destroy()
50
50
 
51
- limiter = new Limiter(config.rateLimit)
51
+ limiter = new Limiter(config.DD_APPSEC_TRACE_RATE_LIMIT)
52
52
 
53
53
  // Lazy loading improves the startup time
54
54
  WAFManager = require('./waf_manager')
@@ -8,9 +8,9 @@ const contexts = new WeakMap()
8
8
 
9
9
  /**
10
10
  * @typedef {object} WAFManagerConfig
11
- * @property {number} wafTimeout - Maximum time in microseconds for WAF execution
12
- * @property {string} obfuscatorKeyRegex - Regex to redact sensitive data by key
13
- * @property {string} obfuscatorValueRegex - Regex to redact sensitive data by value
11
+ * @property {number} DD_APPSEC_WAF_TIMEOUT - Maximum time in microseconds for WAF execution
12
+ * @property {string} DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP - Regex to redact sensitive data by key
13
+ * @property {string} DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP - Regex to redact sensitive data by value
14
14
  */
15
15
 
16
16
  class WAFManager {
@@ -22,7 +22,7 @@ class WAFManager {
22
22
  */
23
23
  constructor (rules, config) {
24
24
  this.config = config
25
- this.wafTimeout = config.wafTimeout
25
+ this.wafTimeout = config.DD_APPSEC_WAF_TIMEOUT
26
26
  this.ddwaf = this._loadDDWAF(rules)
27
27
  this.rulesVersion = this.ddwaf.diagnostics.ruleset_version
28
28
  this.defaultRules = rules
@@ -36,7 +36,10 @@ class WAFManager {
36
36
  const { DDWAF } = require('@datadog/native-appsec')
37
37
  this.ddwafVersion = DDWAF.version()
38
38
 
39
- const { obfuscatorKeyRegex, obfuscatorValueRegex } = this.config
39
+ const {
40
+ DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP: obfuscatorKeyRegex,
41
+ DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP: obfuscatorValueRegex,
42
+ } = this.config
40
43
  return new DDWAF(rules, WAFManager.defaultWafConfigPath, { obfuscatorKeyRegex, obfuscatorValueRegex })
41
44
  } catch (err) {
42
45
  this.ddwafVersion ||= 'unknown'
@@ -81,7 +81,6 @@ function defineField (fieldName, headerName, read, operations) {
81
81
  /**
82
82
  * @param {Carrier} carrier
83
83
  * @param {Value} value
84
- * @returns {void}
85
84
  */
86
85
  write (carrier, value) {
87
86
  carrier[headerName] = value
@@ -89,7 +88,6 @@ function defineField (fieldName, headerName, read, operations) {
89
88
 
90
89
  /**
91
90
  * @param {Carrier} carrier
92
- * @returns {boolean}
93
91
  */
94
92
  has (carrier) {
95
93
  return headerName in carrier
@@ -97,7 +95,6 @@ function defineField (fieldName, headerName, read, operations) {
97
95
 
98
96
  /**
99
97
  * @param {Carrier} carrier
100
- * @returns {void}
101
98
  */
102
99
  delete (carrier) {
103
100
  delete carrier[headerName]
@@ -106,7 +103,6 @@ function defineField (fieldName, headerName, read, operations) {
106
103
  /**
107
104
  * @param {Carrier} carrier
108
105
  * @param {Carrier} target
109
- * @returns {void}
110
106
  */
111
107
  copy (carrier, target) {
112
108
  if (Object.hasOwn(carrier, headerName)) target[headerName] = carrier[headerName]
@@ -308,7 +304,6 @@ defineCapability('legacyBaggage', FIELD_READ | FIELD_WRITE, {
308
304
  /**
309
305
  * @param {Carrier} carrier
310
306
  * @param {Record<string, string>} target
311
- * @returns {void}
312
307
  */
313
308
  read (carrier, target) {
314
309
  for (const name of Object.keys(carrier)) {
@@ -0,0 +1,104 @@
1
+ 'use strict'
2
+
3
+ const log = require('../log')
4
+
5
+ const {
6
+ retriesForDuration,
7
+ retryBucketIndexForDuration,
8
+ } = require('./efd-retry-policy')
9
+
10
+ const DYNAMIC_ATR_ENABLED_ENV = 'DD_CIVISIBILITY_DYNAMIC_ATR_ENABLED'
11
+ const DYNAMIC_ATR_BUCKETS_ENV = 'DD_CIVISIBILITY_DYNAMIC_ATR_BUCKETS'
12
+
13
+ const RETRY_BUCKET_COUNT = 5
14
+ const MAX_RETRIES_PER_BUCKET = 20
15
+
16
+ /**
17
+ * Returns whether duration-based ATR retry budgets are enabled.
18
+ *
19
+ * @param {unknown} value A parsed test-optimization configuration value.
20
+ */
21
+ function isDynamicAtrEnabled (value) {
22
+ return value === true
23
+ }
24
+
25
+ /**
26
+ * Parses and validates custom ATR retry buckets from the parsed
27
+ * test-optimization configuration.
28
+ *
29
+ * Returns a frozen array of 5 positive integers in [1, 20], or `null`
30
+ * when the value is unset/empty or invalid (in which case the EFD retry
31
+ * settings from the backend are used).
32
+ *
33
+ * @param {unknown} value A parsed test-optimization configuration value.
34
+ * @returns {number[] | null}
35
+ */
36
+ function getDynamicAtrBuckets (value) {
37
+ if (!Array.isArray(value) || value.length === 0) {
38
+ return null
39
+ }
40
+
41
+ const parts = value
42
+ const raw = parts.join(',')
43
+ if (parts.length !== RETRY_BUCKET_COUNT) {
44
+ log.warn(
45
+ 'Invalid %s value %o; expected five comma-separated integers in [1, %d]',
46
+ DYNAMIC_ATR_BUCKETS_ENV, raw, MAX_RETRIES_PER_BUCKET
47
+ )
48
+ return null
49
+ }
50
+
51
+ const buckets = []
52
+ for (const part of parts) {
53
+ const trimmedPart = typeof part === 'string' ? part.trim() : ''
54
+ if (!/^\d+$/.test(trimmedPart)) {
55
+ log.warn(
56
+ 'Invalid %s value %o; expected five comma-separated integers in [1, %d]',
57
+ DYNAMIC_ATR_BUCKETS_ENV, raw, MAX_RETRIES_PER_BUCKET
58
+ )
59
+ return null
60
+ }
61
+ const value = Number(trimmedPart)
62
+ if (!Number.isSafeInteger(value) || value < 1 || value > MAX_RETRIES_PER_BUCKET) {
63
+ log.warn(
64
+ 'Invalid %s value %o; expected five comma-separated integers in [1, %d]',
65
+ DYNAMIC_ATR_BUCKETS_ENV, raw, MAX_RETRIES_PER_BUCKET
66
+ )
67
+ return null
68
+ }
69
+ buckets.push(value)
70
+ }
71
+
72
+ return Object.freeze(buckets)
73
+ }
74
+
75
+ /**
76
+ * Computes the dynamic ATR retry count for a test based on its initial-attempt
77
+ * duration.
78
+ *
79
+ * When `customBuckets` is provided, the bucket at the duration index is used.
80
+ * Otherwise, the EFD retry policy's `retriesForDuration` is used.
81
+ *
82
+ * The result is clamped to a minimum of 1.
83
+ *
84
+ * @param {number} durationMs - Initial-attempt duration in milliseconds.
85
+ * @param {import('./efd-retry-policy').EfdRetryPolicy} efdRetryPolicy
86
+ * @param {number[] | null} customBuckets
87
+ */
88
+ function getDynamicAtrRetryCount (durationMs, efdRetryPolicy, customBuckets) {
89
+ let retryCount
90
+ if (customBuckets) {
91
+ retryCount = customBuckets[retryBucketIndexForDuration(durationMs)]
92
+ } else {
93
+ retryCount = retriesForDuration(durationMs, efdRetryPolicy)
94
+ }
95
+ return Math.max(1, retryCount)
96
+ }
97
+
98
+ module.exports = {
99
+ DYNAMIC_ATR_BUCKETS_ENV,
100
+ DYNAMIC_ATR_ENABLED_ENV,
101
+ getDynamicAtrBuckets,
102
+ getDynamicAtrRetryCount,
103
+ isDynamicAtrEnabled,
104
+ }
@@ -52,7 +52,6 @@ const limits = {
52
52
 
53
53
  /**
54
54
  * @param {object} value - Snapshot object or sub-object.
55
- * @returns {boolean}
56
55
  */
57
56
  function isCapturedValue (value) {
58
57
  return typeof value.type === 'string'
@@ -62,7 +61,6 @@ function isCapturedValue (value) {
62
61
  * Remove empty capture containers before sending snapshots through the Test Optimization logs path.
63
62
  *
64
63
  * @param {object} value - Snapshot object or sub-object.
65
- * @returns {void}
66
64
  */
67
65
  function removeEmptyCaptureProperties (value) {
68
66
  const stack = [value]
@@ -23,12 +23,43 @@ const EARLY_FLAKE_DETECTION_RETRY_BUCKETS =
23
23
  * @property {number} schedulingRetryCount
24
24
  */
25
25
 
26
+ /**
27
+ * Returns the zero-based dynamic ATR retry-bucket index for a test duration.
28
+ *
29
+ * Bucket boundaries (ms): 5 000, 10 000, 30 000, 300 000.
30
+ * Durations at a boundary remain in that bucket.
31
+ *
32
+ * @param {number} durationMs
33
+ */
34
+ function retryBucketIndexForDuration (durationMs) {
35
+ for (let index = 0; index < EARLY_FLAKE_DETECTION_RETRY_THRESHOLDS.length; index++) {
36
+ if (durationMs <= EARLY_FLAKE_DETECTION_RETRY_THRESHOLDS[index].limitMs) {
37
+ return index
38
+ }
39
+ }
40
+ return EARLY_FLAKE_DETECTION_RETRY_THRESHOLDS.length // > 5 m bucket
41
+ }
42
+
43
+ /**
44
+ * Returns the backend retry budget using dynamic ATR's inclusive duration cutoffs.
45
+ *
46
+ * @param {number} durationMs
47
+ * @param {EfdRetryPolicy} retryPolicy
48
+ */
49
+ function retriesForDuration (durationMs, retryPolicy) {
50
+ const index = retryBucketIndexForDuration(durationMs)
51
+ if (index < retryPolicy.durationRetryCounts.length) {
52
+ return retryPolicy.durationRetryCounts[index].retryCount
53
+ }
54
+ return 0
55
+ }
56
+
26
57
  /**
27
58
  * @param {number} durationMs
28
59
  * @param {EfdRetryPolicy} retryPolicy
29
- * @returns {number}
30
60
  */
31
61
  function getEfdRetryCountForDuration (durationMs, retryPolicy) {
62
+ // EFD retains exclusive cutoffs, including no retries at exactly five minutes.
32
63
  for (const { durationLimitMs, retryCount } of retryPolicy.durationRetryCounts) {
33
64
  if (durationMs < durationLimitMs) {
34
65
  return retryCount
@@ -62,7 +93,6 @@ function createEfdRetryPolicy (retriesByDuration = {}) {
62
93
 
63
94
  /**
64
95
  * @param {EfdRetryPolicy | undefined} retryPolicy
65
- * @returns {boolean}
66
96
  */
67
97
  function hasEfdRetries (retryPolicy) {
68
98
  return (retryPolicy?.schedulingRetryCount ?? 0) > 0
@@ -71,7 +101,6 @@ function hasEfdRetries (retryPolicy) {
71
101
  /**
72
102
  * @param {number} retryIndex
73
103
  * @param {number | undefined} retryCount
74
- * @returns {boolean}
75
104
  */
76
105
  function shouldSkipEfdRetry (retryIndex, retryCount) {
77
106
  return retryCount !== undefined && retryIndex > retryCount
@@ -85,5 +114,7 @@ module.exports = {
85
114
  createEfdRetryPolicy,
86
115
  getEfdRetryCountForDuration,
87
116
  hasEfdRetries,
117
+ retriesForDuration,
118
+ retryBucketIndexForDuration,
88
119
  shouldSkipEfdRetry,
89
120
  }
@@ -36,7 +36,6 @@ class Writer extends BaseWriter {
36
36
  *
37
37
  * @param {(error?: Error) => void} [done]
38
38
  * @param {{ deadline?: number }} [options]
39
- * @returns {void}
40
39
  */
41
40
  flush (done, options) {
42
41
  this.#requestTracker.flush(done, options)
@@ -37,7 +37,6 @@ class DynamicInstrumentationLogsWriter extends BaseWriter {
37
37
  *
38
38
  * @param {(error?: Error) => void} [done]
39
39
  * @param {{ deadline?: number }} [options]
40
- * @returns {void}
41
40
  */
42
41
  flush (done, options) {
43
42
  this.#requestTracker.flush(done, options)
@@ -36,7 +36,6 @@ class Writer extends BaseWriter {
36
36
  *
37
37
  * @param {(error?: Error) => void} [done]
38
38
  * @param {{ deadline?: number }} [options]
39
- * @returns {void}
40
39
  */
41
40
  flush (done, options) {
42
41
  this.#requestTracker.flush(done, options)
@@ -105,7 +105,6 @@ class CiValidationExporter extends CiVisibilityExporter {
105
105
  /**
106
106
  * Resolves the inherited git-upload gate without performing an upload.
107
107
  *
108
- * @returns {void}
109
108
  */
110
109
  sendGitMetadata () {
111
110
  this._resolveGit()
@@ -114,14 +113,12 @@ class CiValidationExporter extends CiVisibilityExporter {
114
113
  /**
115
114
  * Drops debugger logs in offline validation mode.
116
115
  *
117
- * @returns {void}
118
116
  */
119
117
  exportDiLogs () {}
120
118
 
121
119
  /**
122
120
  * Reports that code coverage is outside the offline validator's scope.
123
121
  *
124
- * @returns {boolean} always false
125
122
  */
126
123
  canReportCodeCoverage () {
127
124
  return false
@@ -140,7 +137,6 @@ class CiValidationExporter extends CiVisibilityExporter {
140
137
  /**
141
138
  * Reports that screenshot upload is unavailable.
142
139
  *
143
- * @returns {boolean} always false
144
140
  */
145
141
  canUploadTestScreenshots () {
146
142
  return false
@@ -257,7 +257,6 @@ class MsgpackJsonConverter {
257
257
  }
258
258
  }
259
259
 
260
- /** @returns {number} unsigned 8-bit integer */
261
260
  #readUInt8 () {
262
261
  this.#assertAvailable(1)
263
262
  return this.#input[this.#offset++]
@@ -179,7 +179,6 @@ class CiValidationSink {
179
179
  /**
180
180
  * Atomically publishes this process's bounded completion evidence.
181
181
  *
182
- * @returns {boolean} whether the record was published
183
182
  */
184
183
  #writeCompletionRecord () {
185
184
  const directoryPath = path.join(this.#outputRoot, 'completions')
@@ -215,7 +214,6 @@ class CiValidationSink {
215
214
  * Writes one completed JSON payload to a unique file.
216
215
  *
217
216
  * @param {Buffer} payload JSON payload
218
- * @returns {boolean} whether the payload was written
219
217
  */
220
218
  #writePayloadFile (payload) {
221
219
  if (this.#fileCount >= MAX_OUTPUT_FILES) {