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.
- package/README.electron.md +7 -0
- package/README.md +17 -0
- package/ci/diagnose.js +2100 -0
- package/ci/init.js +23 -2
- package/ci/runbook.md +198 -0
- package/ci/test-optimization-validation/approval-artifacts.js +143 -0
- package/ci/test-optimization-validation/approval.js +299 -0
- package/ci/test-optimization-validation/artifact-id.js +20 -0
- package/ci/test-optimization-validation/bounded-json.js +121 -0
- package/ci/test-optimization-validation/ci-command-candidate.js +83 -0
- package/ci/test-optimization-validation/ci-discovery.js +181 -0
- package/ci/test-optimization-validation/ci-remediation.js +210 -0
- package/ci/test-optimization-validation/cli.js +903 -0
- package/ci/test-optimization-validation/command-blocker.js +81 -0
- package/ci/test-optimization-validation/command-output-policy.js +206 -0
- package/ci/test-optimization-validation/command-runner.js +707 -0
- package/ci/test-optimization-validation/command-suitability.js +471 -0
- package/ci/test-optimization-validation/executable-approval.js +48 -0
- package/ci/test-optimization-validation/executable.js +480 -0
- package/ci/test-optimization-validation/generated-file-policy.js +63 -0
- package/ci/test-optimization-validation/generated-files.js +351 -0
- package/ci/test-optimization-validation/generated-verifier.js +196 -0
- package/ci/test-optimization-validation/init-probe-preload.js +163 -0
- package/ci/test-optimization-validation/init-probe.js +246 -0
- package/ci/test-optimization-validation/late-initialization.js +63 -0
- package/ci/test-optimization-validation/local-command.js +163 -0
- package/ci/test-optimization-validation/manifest-loader.js +133 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +738 -0
- package/ci/test-optimization-validation/manifest-schema.js +862 -0
- package/ci/test-optimization-validation/offline-fixtures.js +327 -0
- package/ci/test-optimization-validation/offline-output.js +406 -0
- package/ci/test-optimization-validation/payload-normalizer.js +72 -0
- package/ci/test-optimization-validation/plan-writer.js +1120 -0
- package/ci/test-optimization-validation/preflight-runner.js +114 -0
- package/ci/test-optimization-validation/redaction.js +331 -0
- package/ci/test-optimization-validation/report-writer.js +1508 -0
- package/ci/test-optimization-validation/safe-files.js +203 -0
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +159 -0
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +657 -0
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +780 -0
- package/ci/test-optimization-validation/scenarios/early-flake-detection.js +141 -0
- package/ci/test-optimization-validation/scenarios/helpers.js +539 -0
- package/ci/test-optimization-validation/scenarios/test-management.js +218 -0
- package/ci/test-optimization-validation/setup-runner.js +97 -0
- package/ci/test-optimization-validation/static-diagnosis.js +159 -0
- package/ci/test-optimization-validation/test-output.js +129 -0
- package/ci/test-optimization-validation-manifest.schema.json +1 -0
- package/ci/validate-test-optimization.js +3 -0
- package/ext/exporters.js +1 -0
- package/index.d.ts +121 -8
- package/init.js +18 -0
- package/initialize.mjs +1 -1
- package/loader-hook.mjs +28 -18
- package/openfeature.d.ts +1 -0
- package/openfeature.js +4 -0
- package/package.json +11 -8
- package/packages/datadog-instrumentations/src/ai.js +8 -2
- package/packages/datadog-instrumentations/src/child_process.js +1 -1
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +1 -1
- package/packages/datadog-instrumentations/src/cucumber-worker-threads.js +9 -3
- package/packages/datadog-instrumentations/src/cucumber.js +31 -19
- package/packages/datadog-instrumentations/src/cypress-config.js +398 -52
- package/packages/datadog-instrumentations/src/fastify.js +7 -11
- package/packages/datadog-instrumentations/src/helpers/channel.js +74 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +27 -6
- package/packages/datadog-instrumentations/src/helpers/optional-peer-bundler.js +8 -8
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +28 -2
- package/packages/datadog-instrumentations/src/jest.js +44 -17
- package/packages/datadog-instrumentations/src/mariadb.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/main.js +79 -32
- package/packages/datadog-instrumentations/src/mocha/utils.js +0 -4
- package/packages/datadog-instrumentations/src/mongodb.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/mquery.js +2 -2
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +24 -0
- package/packages/datadog-instrumentations/src/nyc.js +0 -2
- package/packages/datadog-instrumentations/src/oracledb.js +2 -2
- package/packages/datadog-instrumentations/src/pg.js +2 -2
- package/packages/datadog-instrumentations/src/playwright.js +162 -46
- package/packages/datadog-instrumentations/src/process.js +3 -0
- package/packages/datadog-instrumentations/src/router.js +18 -8
- package/packages/datadog-instrumentations/src/selenium.js +52 -26
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +3 -3
- package/packages/datadog-instrumentations/src/vitest-main.js +14 -28
- package/packages/datadog-instrumentations/src/vitest-util.js +0 -7
- package/packages/datadog-instrumentations/src/vitest-worker.js +5 -8
- package/packages/datadog-instrumentations/src/ws.js +2 -1
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/context.js +2 -2
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/util.js +2 -1
- package/packages/datadog-plugin-aws-sdk/src/util.js +2 -2
- package/packages/datadog-plugin-cucumber/src/index.js +3 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +19 -57
- package/packages/datadog-plugin-cypress/src/index.js +6 -1
- package/packages/datadog-plugin-cypress/src/support.js +92 -26
- package/packages/datadog-plugin-electron/src/ipc.js +1 -1
- package/packages/datadog-plugin-graphql/src/execute.js +87 -45
- package/packages/datadog-plugin-graphql/src/validate.js +2 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-langchain/src/handlers/embedding.js +2 -1
- package/packages/datadog-plugin-langchain/src/handlers/language_models.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -1
- package/packages/datadog-plugin-playwright/src/index.js +181 -65
- package/packages/datadog-plugin-router/src/index.js +11 -2
- package/packages/datadog-plugin-selenium/src/index.js +5 -36
- package/packages/datadog-plugin-vitest/src/index.js +5 -5
- package/packages/datadog-plugin-ws/src/close.js +2 -1
- package/packages/datadog-plugin-ws/src/producer.js +2 -1
- package/packages/datadog-plugin-ws/src/receiver.js +2 -1
- package/packages/datadog-plugin-ws/src/server.js +2 -1
- package/packages/dd-trace/src/aiguard/sdk.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -2
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +3 -1
- package/packages/dd-trace/src/azure_metadata.js +2 -1
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/index.js +93 -28
- package/packages/dd-trace/src/ci-visibility/early-flake-detection/get-known-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/index.js +160 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +288 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/payload-projection.js +84 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +369 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +60 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +41 -3
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +7 -2
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +1 -1
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +6 -2
- package/packages/dd-trace/src/ci-visibility/rum.js +7 -0
- package/packages/dd-trace/src/ci-visibility/test-api-manual/test-api-manual-plugin.js +4 -0
- package/packages/dd-trace/src/ci-visibility/test-management/get-test-management-tests.js +1 -1
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +137 -9
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +168 -8
- package/packages/dd-trace/src/ci-visibility/test-screenshot.js +90 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +16 -0
- package/packages/dd-trace/src/config/helper.js +1 -0
- package/packages/dd-trace/src/config/index.js +10 -0
- package/packages/dd-trace/src/config/supported-configurations.json +66 -0
- package/packages/dd-trace/src/exporter.js +2 -0
- package/packages/dd-trace/src/exporters/common/client-library-headers.js +21 -0
- package/packages/dd-trace/src/exporters/common/request.js +59 -30
- package/packages/dd-trace/src/exporters/common/url.js +15 -1
- package/packages/dd-trace/src/feature-registry.js +10 -3
- package/packages/dd-trace/src/llmobs/experiments/client.js +113 -0
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +154 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +283 -0
- package/packages/dd-trace/src/llmobs/experiments/index.js +152 -0
- package/packages/dd-trace/src/llmobs/experiments/noop.js +30 -0
- package/packages/dd-trace/src/llmobs/experiments/result.js +34 -0
- package/packages/dd-trace/src/llmobs/noop.js +6 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +20 -3
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +2 -2
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +8 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +48 -14
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +43 -0
- package/packages/dd-trace/src/llmobs/sdk.js +17 -0
- package/packages/dd-trace/src/llmobs/tagger.js +68 -0
- package/packages/dd-trace/src/llmobs/telemetry.js +2 -1
- package/packages/dd-trace/src/llmobs/util.js +32 -0
- package/packages/dd-trace/src/openfeature/agentless_configuration_source.js +322 -0
- package/packages/dd-trace/src/openfeature/configuration_source.js +90 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +14 -23
- package/packages/dd-trace/src/openfeature/index.js +0 -2
- package/packages/dd-trace/src/openfeature/noop.js +1 -28
- package/packages/dd-trace/src/openfeature/register.js +16 -27
- package/packages/dd-trace/src/openfeature/remote_config.js +15 -18
- package/packages/dd-trace/src/openfeature/require-provider.js +18 -0
- package/packages/dd-trace/src/opentelemetry/span-ending-hook.js +10 -0
- package/packages/dd-trace/src/opentelemetry/span.js +5 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +20 -6
- package/packages/dd-trace/src/plugins/util/git.js +3 -2
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +29 -5
- package/packages/dd-trace/src/plugins/util/test.js +56 -4
- package/packages/dd-trace/src/profiling/profilers/space.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/wall.js +1 -0
- package/packages/dd-trace/src/proxy.js +84 -7
- package/packages/dd-trace/src/span_processor.js +5 -0
- package/packages/dd-trace/src/standalone/index.js +0 -14
- package/packages/dd-trace/src/telemetry/send-data.js +2 -2
- package/packages/dd-trace/src/util.js +26 -0
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +1 -1
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/vendor/dist/shell-quote/index.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/require-optional-peer.js +0 -17
package/index.d.ts
CHANGED
|
@@ -156,12 +156,12 @@ interface Tracer extends opentracing.Tracer {
|
|
|
156
156
|
llmobs: tracer.llmobs.LLMObs;
|
|
157
157
|
|
|
158
158
|
/**
|
|
159
|
-
* OpenFeature Provider with Remote Config
|
|
159
|
+
* OpenFeature Provider with agentless and Agent Remote Config delivery.
|
|
160
160
|
*
|
|
161
|
-
*
|
|
162
|
-
* Enable with DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED=true.
|
|
161
|
+
* Agentless delivery is enabled by default and starts when the provider is first accessed.
|
|
163
162
|
*
|
|
164
|
-
* @env
|
|
163
|
+
* @env DD_FEATURE_FLAGS_ENABLED
|
|
164
|
+
* @env DD_FEATURE_FLAGS_CONFIGURATION_SOURCE
|
|
165
165
|
* @beta This feature is in preview and not ready for production use
|
|
166
166
|
*/
|
|
167
167
|
openfeature: tracer.OpenFeatureProvider;
|
|
@@ -799,9 +799,9 @@ declare namespace tracer {
|
|
|
799
799
|
*/
|
|
800
800
|
flaggingProvider?: {
|
|
801
801
|
/**
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
*
|
|
802
|
+
* Legacy feature flagging provider switch.
|
|
803
|
+
* When the stable Feature Flags configuration is unset, true selects Agent Remote Config and false disables
|
|
804
|
+
* the provider.
|
|
805
805
|
*
|
|
806
806
|
* @default false
|
|
807
807
|
* @env DD_EXPERIMENTAL_FLAGGING_PROVIDER_ENABLED
|
|
@@ -1620,7 +1620,7 @@ declare namespace tracer {
|
|
|
1620
1620
|
/**
|
|
1621
1621
|
* Flagging Provider (OpenFeature-compatible).
|
|
1622
1622
|
*
|
|
1623
|
-
* Wraps @datadog/openfeature-node-server with
|
|
1623
|
+
* Wraps @datadog/openfeature-node-server with agentless and Agent Remote Config delivery.
|
|
1624
1624
|
* Implements the OpenFeature Provider interface for flag evaluation.
|
|
1625
1625
|
*
|
|
1626
1626
|
* @beta This feature is in preview and not ready for production use
|
|
@@ -3568,6 +3568,12 @@ declare namespace tracer {
|
|
|
3568
3568
|
*/
|
|
3569
3569
|
enabled: boolean,
|
|
3570
3570
|
|
|
3571
|
+
/**
|
|
3572
|
+
* Datasets & Experiments API. Requires LLM Observability to be enabled and
|
|
3573
|
+
* `DD_API_KEY` / `DD_APP_KEY` to be set.
|
|
3574
|
+
*/
|
|
3575
|
+
experiments: Experiments,
|
|
3576
|
+
|
|
3571
3577
|
/**
|
|
3572
3578
|
* Enable LLM Observability tracing.
|
|
3573
3579
|
*
|
|
@@ -3721,6 +3727,93 @@ declare namespace tracer {
|
|
|
3721
3727
|
flush (): void
|
|
3722
3728
|
}
|
|
3723
3729
|
|
|
3730
|
+
/**
|
|
3731
|
+
* A task run over each dataset record during an experiment.
|
|
3732
|
+
*/
|
|
3733
|
+
type ExperimentTask = (input: any, config: Record<string, any>) => any | Promise<any>
|
|
3734
|
+
|
|
3735
|
+
/**
|
|
3736
|
+
* Scores a single task output. The return type selects the metric:
|
|
3737
|
+
* `boolean` -> boolean, `number` -> score, anything else -> categorical.
|
|
3738
|
+
*/
|
|
3739
|
+
type ExperimentEvaluator = (input: any, output: any, expectedOutput: any) => any | Promise<any>
|
|
3740
|
+
|
|
3741
|
+
interface ExperimentOptions {
|
|
3742
|
+
name: string
|
|
3743
|
+
dataset: Dataset
|
|
3744
|
+
task: ExperimentTask
|
|
3745
|
+
/** Evaluators keyed by metric label. */
|
|
3746
|
+
evaluators?: Record<string, ExperimentEvaluator>
|
|
3747
|
+
description?: string
|
|
3748
|
+
config?: Record<string, any>
|
|
3749
|
+
tags?: Record<string, string>
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
interface PullDatasetOptions {
|
|
3753
|
+
/** Wait until at least this many records are readable (absorbs write lag). */
|
|
3754
|
+
expectedRecordCount?: number
|
|
3755
|
+
/** Maximum total time to wait, in ms. Default 30000. */
|
|
3756
|
+
maxWaitMs?: number
|
|
3757
|
+
}
|
|
3758
|
+
|
|
3759
|
+
interface ExperimentResultRow {
|
|
3760
|
+
index: number
|
|
3761
|
+
spanId: string
|
|
3762
|
+
traceId: string
|
|
3763
|
+
startNs: number
|
|
3764
|
+
durationNs: number
|
|
3765
|
+
input: any
|
|
3766
|
+
output: any
|
|
3767
|
+
expectedOutput: any
|
|
3768
|
+
readonly isError: boolean
|
|
3769
|
+
errorType: string | null
|
|
3770
|
+
errorMessage: string | null
|
|
3771
|
+
evaluations: Record<string, any>
|
|
3772
|
+
evaluationErrors: Record<string, string>
|
|
3773
|
+
}
|
|
3774
|
+
|
|
3775
|
+
interface ExperimentResult {
|
|
3776
|
+
experimentId: string
|
|
3777
|
+
rows: ExperimentResultRow[]
|
|
3778
|
+
/** Dashboard URL for the experiment. */
|
|
3779
|
+
url: string
|
|
3780
|
+
}
|
|
3781
|
+
|
|
3782
|
+
interface DatasetPushResult {
|
|
3783
|
+
/** Number of records from this push that were confirmed with a record id. */
|
|
3784
|
+
pushedCount: number
|
|
3785
|
+
/** Number of records attempted in this push. */
|
|
3786
|
+
totalCount: number
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
interface Dataset {
|
|
3790
|
+
addRecord (input: any, expectedOutput?: any, metadata?: Record<string, any>): Dataset
|
|
3791
|
+
/** Creates the dataset remotely if needed and pushes any unpushed records. */
|
|
3792
|
+
push (): Promise<DatasetPushResult>
|
|
3793
|
+
name (): string
|
|
3794
|
+
id (): string | null
|
|
3795
|
+
projectId (): string | null
|
|
3796
|
+
records (): Array<{ input: any, expectedOutput: any, metadata: Record<string, any> }>
|
|
3797
|
+
/** Dashboard URL for the dataset, or null until pushed. */
|
|
3798
|
+
url (): string | null
|
|
3799
|
+
}
|
|
3800
|
+
|
|
3801
|
+
interface Experiment {
|
|
3802
|
+
name (): string
|
|
3803
|
+
experimentId (): string | null
|
|
3804
|
+
url (): string | null
|
|
3805
|
+
run (): Promise<ExperimentResult>
|
|
3806
|
+
}
|
|
3807
|
+
|
|
3808
|
+
interface Experiments {
|
|
3809
|
+
/** Create a local dataset buffer; pushed on the first experiment run. */
|
|
3810
|
+
createDataset (name: string, description?: string): Dataset
|
|
3811
|
+
/** Pull an existing dataset (with records) by name. */
|
|
3812
|
+
pullDataset (name: string, options?: PullDatasetOptions): Promise<Dataset>
|
|
3813
|
+
/** Build an experiment to run over a dataset. */
|
|
3814
|
+
experiment (options: ExperimentOptions): Experiment
|
|
3815
|
+
}
|
|
3816
|
+
|
|
3724
3817
|
interface LLMObservabilitySpan {
|
|
3725
3818
|
/**
|
|
3726
3819
|
* The span kind
|
|
@@ -3833,6 +3926,26 @@ declare namespace tracer {
|
|
|
3833
3926
|
* Tool calls of the message
|
|
3834
3927
|
*/
|
|
3835
3928
|
toolCalls?: ToolCall[],
|
|
3929
|
+
|
|
3930
|
+
/**
|
|
3931
|
+
* Audio segments attached to the message (e.g. speech input/output)
|
|
3932
|
+
*/
|
|
3933
|
+
audioParts?: AudioPart[],
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3936
|
+
/**
|
|
3937
|
+
* Represents an audio segment attached to an LLM chat model message.
|
|
3938
|
+
*/
|
|
3939
|
+
interface AudioPart {
|
|
3940
|
+
/**
|
|
3941
|
+
* The MIME type of the audio (e.g. "audio/wav", "audio/mpeg")
|
|
3942
|
+
*/
|
|
3943
|
+
mimeType: string,
|
|
3944
|
+
|
|
3945
|
+
/**
|
|
3946
|
+
* The audio content as a base64-encoded string
|
|
3947
|
+
*/
|
|
3948
|
+
content: string,
|
|
3836
3949
|
}
|
|
3837
3950
|
|
|
3838
3951
|
/**
|
package/init.js
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
// In PM2 cluster mode, per-app env vars arrive as a `pm2_env`
|
|
4
|
+
// JSON string after --require has already run so we extract them
|
|
5
|
+
// manually if present.
|
|
6
|
+
var pm2EnvStr = process.env.pm2_env
|
|
7
|
+
if (typeof pm2EnvStr === 'string') {
|
|
8
|
+
try {
|
|
9
|
+
var pm2Config = JSON.parse(pm2EnvStr)
|
|
10
|
+
var pm2Keys = Object.keys(pm2Config)
|
|
11
|
+
for (var i = 0; i < pm2Keys.length; i++) {
|
|
12
|
+
var k = pm2Keys[i]
|
|
13
|
+
var v = pm2Config[k]
|
|
14
|
+
if (v != null) {
|
|
15
|
+
process.env[k] = String(v)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
} catch (e) {}
|
|
19
|
+
}
|
|
20
|
+
|
|
3
21
|
var guard = require('./packages/dd-trace/src/guardrails')
|
|
4
22
|
|
|
5
23
|
module.exports = guard(function () {
|
package/initialize.mjs
CHANGED
package/loader-hook.mjs
CHANGED
|
@@ -2,24 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Module from 'node:module'
|
|
4
4
|
import { pathToFileURL } from 'node:url'
|
|
5
|
+
import { isMainThread } from 'node:worker_threads'
|
|
5
6
|
|
|
6
7
|
import { createHook, supportsSyncHooks } from 'import-in-the-middle/create-hook.mjs'
|
|
7
|
-
import { initialize as origInitialize, load as origLoad
|
|
8
|
-
import regexpEscapeModule from './vendor/dist/escape-string-regexp/index.js'
|
|
9
|
-
import hooks from './packages/datadog-instrumentations/src/helpers/hooks.js'
|
|
10
|
-
import configHelper from './packages/dd-trace/src/config/helper.js'
|
|
8
|
+
import { initialize as origInitialize, load as origLoad } from 'import-in-the-middle/hook.mjs'
|
|
11
9
|
import * as rewriterLoader from './packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs'
|
|
12
|
-
import { isRelativeRequire } from './packages/datadog-instrumentations/src/helpers/shared-utils.js'
|
|
13
10
|
|
|
14
11
|
// This file must support Node.js 12.0.0 syntax
|
|
15
12
|
|
|
16
13
|
const { builtinModules } = Module
|
|
17
|
-
const regexpEscape = regexpEscapeModule.default
|
|
18
14
|
const require = Module.createRequire(import.meta.url)
|
|
15
|
+
// The query marks initialize.mjs's application-thread preload; loader workers use the full graph.
|
|
16
|
+
const isInitializeMainThread = isMainThread && import.meta.url.endsWith('?initialize')
|
|
19
17
|
let syncImportInTheMiddleHook
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
let getValueFromEnvSources
|
|
20
|
+
let regexpEscape
|
|
23
21
|
|
|
24
22
|
// Substrings of resolved URLs that import-in-the-middle must never wrap: re-export
|
|
25
23
|
// shims and internal helper graphs that break when proxied, plus iitm's own files
|
|
@@ -32,15 +30,26 @@ export const iitmExclusionRegExp = /middle|langsmith|openai\/_shims|openai\/reso
|
|
|
32
30
|
// against a regex metacharacter entering a package name.
|
|
33
31
|
const includeModuleNames = new Set()
|
|
34
32
|
let moduleNameAlternation = ''
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
|
|
34
|
+
if (!isInitializeMainThread) {
|
|
35
|
+
const regexpEscapeModule = require('./vendor/dist/escape-string-regexp/index.js')
|
|
36
|
+
const hooks = require('./packages/datadog-instrumentations/src/helpers/hooks.js')
|
|
37
|
+
const configHelper = require('./packages/dd-trace/src/config/helper.js')
|
|
38
|
+
const { isRelativeRequire } = require('./packages/datadog-instrumentations/src/helpers/shared-utils.js')
|
|
39
|
+
|
|
40
|
+
regexpEscape = regexpEscapeModule.default
|
|
41
|
+
getValueFromEnvSources = configHelper.getValueFromEnvSources
|
|
42
|
+
|
|
43
|
+
for (const moduleName of Object.keys(hooks)) {
|
|
44
|
+
// Relative hooks resolve outside node_modules and are not instrumented here.
|
|
45
|
+
if (isRelativeRequire(moduleName)) continue
|
|
46
|
+
includeModuleNames.add(moduleName)
|
|
47
|
+
// iitm matches a built-in by its node: specifier too, so mirror that and
|
|
48
|
+
// wrap `import 'node:crypto'` as well as `import 'crypto'`.
|
|
49
|
+
if (builtinModules.includes(moduleName)) includeModuleNames.add(`node:${moduleName}`)
|
|
50
|
+
if (moduleNameAlternation !== '') moduleNameAlternation += '|'
|
|
51
|
+
moduleNameAlternation += regexpEscape(moduleName)
|
|
52
|
+
}
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
const nodeModulesIncludeSource = `node_modules/(?:${moduleNameAlternation})/(?!node_modules).+`
|
|
@@ -181,4 +190,5 @@ function registerSyncLoaderHooks (data = {}) {
|
|
|
181
190
|
return true
|
|
182
191
|
}
|
|
183
192
|
|
|
184
|
-
export {
|
|
193
|
+
export { resolve } from 'import-in-the-middle/hook.mjs'
|
|
194
|
+
export { initialize, load, registerSyncLoaderHooks }
|
package/openfeature.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/openfeature.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -153,6 +153,8 @@
|
|
|
153
153
|
"LICENSE.Apache",
|
|
154
154
|
"LICENSE.BSD3",
|
|
155
155
|
"loader-hook.mjs",
|
|
156
|
+
"openfeature.d.ts",
|
|
157
|
+
"openfeature.js",
|
|
156
158
|
"packages/*/index.js",
|
|
157
159
|
"packages/*/index.electron.js",
|
|
158
160
|
"packages/*/lib/**/*",
|
|
@@ -168,7 +170,7 @@
|
|
|
168
170
|
],
|
|
169
171
|
"dependencies": {
|
|
170
172
|
"dc-polyfill": "^0.1.11",
|
|
171
|
-
"import-in-the-middle": "^3.3.
|
|
173
|
+
"import-in-the-middle": "^3.3.2",
|
|
172
174
|
"opentracing": ">=0.14.7"
|
|
173
175
|
},
|
|
174
176
|
"optionalDependencies": {
|
|
@@ -177,7 +179,7 @@
|
|
|
177
179
|
"@datadog/native-iast-taint-tracking": "4.2.0",
|
|
178
180
|
"@datadog/native-metrics": "3.1.2",
|
|
179
181
|
"@datadog/openfeature-node-server": "2.0.0",
|
|
180
|
-
"@datadog/pprof": "5.
|
|
182
|
+
"@datadog/pprof": "5.17.0",
|
|
181
183
|
"@datadog/wasm-js-rewriter": "5.0.1",
|
|
182
184
|
"@opentelemetry/api": ">=1.0.0 <1.10.0",
|
|
183
185
|
"@opentelemetry/api-logs": "<1.0.0",
|
|
@@ -188,7 +190,7 @@
|
|
|
188
190
|
"@actions/github": "^9.1.1",
|
|
189
191
|
"@babel/helpers": "^8.0.0",
|
|
190
192
|
"@eslint/eslintrc": "^3.3.5",
|
|
191
|
-
"@eslint/js": "^
|
|
193
|
+
"@eslint/js": "^10.0.1",
|
|
192
194
|
"@msgpack/msgpack": "^3.1.3",
|
|
193
195
|
"@openfeature/core": "^1.11.0",
|
|
194
196
|
"@openfeature/server-sdk": "~1.22.0",
|
|
@@ -196,21 +198,22 @@
|
|
|
196
198
|
"@types/mocha": "^10.0.10",
|
|
197
199
|
"@types/node": "^18.19.106",
|
|
198
200
|
"@types/sinon": "^22.0.0",
|
|
201
|
+
"@vercel/nft": "^0.29.4",
|
|
199
202
|
"axios": "^1.18.1",
|
|
200
203
|
"benchmark": "^2.1.4",
|
|
201
204
|
"body-parser": "^2.3.0",
|
|
202
205
|
"bun": "1.3.14",
|
|
203
|
-
"c8": "^
|
|
206
|
+
"c8": "^12.0.0",
|
|
204
207
|
"codeowners-audit": "^2.9.0",
|
|
205
|
-
"eslint": "^
|
|
208
|
+
"eslint": "^10.5.0",
|
|
206
209
|
"eslint-plugin-cypress": "^6.4.2",
|
|
207
|
-
"eslint-plugin-import": "^
|
|
210
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
208
211
|
"eslint-plugin-jsdoc": "^63.0.12",
|
|
209
212
|
"eslint-plugin-mocha": "^11.3.0",
|
|
210
213
|
"eslint-plugin-n": "^18.2.1",
|
|
211
214
|
"eslint-plugin-promise": "^7.3.0",
|
|
212
215
|
"eslint-plugin-sonarjs": "^4.2.0",
|
|
213
|
-
"eslint-plugin-unicorn": "^
|
|
216
|
+
"eslint-plugin-unicorn": "^68.0.0",
|
|
214
217
|
"express": "^5.1.0",
|
|
215
218
|
"glob": "^10.4.5",
|
|
216
219
|
"globals": "^17.7.0",
|
|
@@ -127,7 +127,7 @@ function wrapTracer (tracer) {
|
|
|
127
127
|
return function (...args) {
|
|
128
128
|
const name = args[0]
|
|
129
129
|
const options = args.length > 2 ? (args[1] ?? {}) : {} // startActiveSpan(name, fn)
|
|
130
|
-
const cb = args
|
|
130
|
+
const cb = args.at(-1)
|
|
131
131
|
|
|
132
132
|
const ctx = {
|
|
133
133
|
name,
|
|
@@ -230,7 +230,13 @@ for (const hook of getHooks('ai')) {
|
|
|
230
230
|
// generateObject, streamObject)
|
|
231
231
|
tracingChannel('orchestrion:ai:resolveLanguageModel').subscribe({
|
|
232
232
|
end (ctx) {
|
|
233
|
-
|
|
233
|
+
const model = ctx.arguments[0]
|
|
234
|
+
if (typeof model !== 'string' && model !== ctx.result) {
|
|
235
|
+
wrapModelWithLifecycle(model)
|
|
236
|
+
wrappedModels.add(ctx.result)
|
|
237
|
+
} else {
|
|
238
|
+
wrapModelWithLifecycle(ctx.result)
|
|
239
|
+
}
|
|
234
240
|
},
|
|
235
241
|
})
|
|
236
242
|
|
|
@@ -190,7 +190,7 @@ function wrapChildProcessAsyncMethod (ChildProcess, shell = false) {
|
|
|
190
190
|
const error = context.abortController.signal.reason || new Error('Aborted')
|
|
191
191
|
childProcess.emit('error', error)
|
|
192
192
|
|
|
193
|
-
const cb = context.callArgs
|
|
193
|
+
const cb = context.callArgs.at(-1)
|
|
194
194
|
if (typeof cb === 'function') {
|
|
195
195
|
cb(error)
|
|
196
196
|
}
|
|
@@ -496,7 +496,7 @@ function finishStream (chunks, ctx, error) {
|
|
|
496
496
|
|
|
497
497
|
let processError
|
|
498
498
|
if (chunks.length > 0) {
|
|
499
|
-
const lastChunk = chunks
|
|
499
|
+
const lastChunk = chunks.at(-1)
|
|
500
500
|
if (lastChunk?.type === 'result') ctx.output = lastChunk.result
|
|
501
501
|
|
|
502
502
|
try {
|
|
@@ -9,11 +9,17 @@ const appRequire = createRequire(path.join(process.cwd(), 'package.json'))
|
|
|
9
9
|
|
|
10
10
|
try {
|
|
11
11
|
// Cucumber v13 parallel workers start from an ESM worker.mjs entrypoint, which
|
|
12
|
-
// statically imports the internal runtime Worker before it runs support-code
|
|
12
|
+
// statically imports the internal runtime Worker/Executor before it runs support-code
|
|
13
13
|
// requireModules. The regular module hook does not patch that internal worker
|
|
14
|
-
// import, so this preload is injected into requireModules to patch the cached
|
|
14
|
+
// import, so this preload is injected into requireModules to patch the cached class
|
|
15
15
|
// prototype before Cucumber constructs the worker instance.
|
|
16
|
-
|
|
16
|
+
let runtimeExecutorPackage
|
|
17
|
+
try {
|
|
18
|
+
runtimeExecutorPackage = appRequire('@cucumber/cucumber/lib/runtime/executor')
|
|
19
|
+
} catch {
|
|
20
|
+
runtimeExecutorPackage = appRequire('@cucumber/cucumber/lib/runtime/worker')
|
|
21
|
+
}
|
|
22
|
+
patchCucumberWorkerRunTestCase(runtimeExecutorPackage, true)
|
|
17
23
|
} catch {
|
|
18
24
|
// Ignore preload failures so cucumber can keep running if its internals change.
|
|
19
25
|
}
|
|
@@ -28,6 +28,7 @@ const {
|
|
|
28
28
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
29
29
|
const { writeCoverageBackfillToCache } = require('../../dd-trace/src/ci-visibility/test-optimization-cache')
|
|
30
30
|
const satisfies = require('../../../vendor/dist/semifies')
|
|
31
|
+
const { getChannelPromise } = require('./helpers/channel')
|
|
31
32
|
const { addHook, channel } = require('./helpers/instrument')
|
|
32
33
|
|
|
33
34
|
const cucumberWorkerThreadsPatchModule = require.resolve('./cucumber-worker-threads')
|
|
@@ -563,12 +564,6 @@ function getErrorFromCucumberResult (cucumberResult) {
|
|
|
563
564
|
return error
|
|
564
565
|
}
|
|
565
566
|
|
|
566
|
-
function getChannelPromise (channelToPublishTo, frameworkVersion = null) {
|
|
567
|
-
return new Promise(resolve => {
|
|
568
|
-
channelToPublishTo.publish({ onDone: resolve, frameworkVersion })
|
|
569
|
-
})
|
|
570
|
-
}
|
|
571
|
-
|
|
572
567
|
function getShouldBeSkippedSuite (pickle, suitesToSkip) {
|
|
573
568
|
const testSuitePath = getTestSuitePath(pickle.uri, process.cwd())
|
|
574
569
|
const isUnskippable = isMarkedAsUnskippable(pickle)
|
|
@@ -1036,7 +1031,9 @@ function testCaseHook (TestCaseRunner, version) {
|
|
|
1036
1031
|
// Valid for old and new cucumber versions
|
|
1037
1032
|
function getCucumberOptions (adapterOrCoordinator) {
|
|
1038
1033
|
if (adapterOrCoordinator.adapter) {
|
|
1039
|
-
return adapterOrCoordinator.adapter.worker?.options ||
|
|
1034
|
+
return adapterOrCoordinator.adapter.worker?.options ||
|
|
1035
|
+
adapterOrCoordinator.adapter.executor?.options ||
|
|
1036
|
+
adapterOrCoordinator.adapter.options
|
|
1040
1037
|
}
|
|
1041
1038
|
return adapterOrCoordinator.options
|
|
1042
1039
|
}
|
|
@@ -1054,7 +1051,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1054
1051
|
}
|
|
1055
1052
|
let errorSkippableRequest
|
|
1056
1053
|
|
|
1057
|
-
const configurationResponse = await getChannelPromise(libraryConfigurationCh, frameworkVersion)
|
|
1054
|
+
const configurationResponse = await getChannelPromise(libraryConfigurationCh, { frameworkVersion }) || {}
|
|
1058
1055
|
|
|
1059
1056
|
repositoryRoot = configurationResponse.repositoryRoot
|
|
1060
1057
|
isItrEnabled = configurationResponse.libraryConfig?.isItrEnabled
|
|
@@ -1087,7 +1084,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1087
1084
|
|
|
1088
1085
|
if (isKnownTestsEnabled) {
|
|
1089
1086
|
const currentKnownTestsResponse = knownTestsResponse || await getChannelPromise(knownTestsCh)
|
|
1090
|
-
if (currentKnownTestsResponse.err) {
|
|
1087
|
+
if (!currentKnownTestsResponse || currentKnownTestsResponse.err) {
|
|
1091
1088
|
isEarlyFlakeDetectionEnabled = false
|
|
1092
1089
|
isKnownTestsEnabled = false
|
|
1093
1090
|
} else {
|
|
@@ -1096,7 +1093,9 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1096
1093
|
}
|
|
1097
1094
|
|
|
1098
1095
|
if (isSuitesSkippingEnabled) {
|
|
1099
|
-
const skippableResponse = skippableSuitesResponse ||
|
|
1096
|
+
const skippableResponse = skippableSuitesResponse ||
|
|
1097
|
+
await getChannelPromise(skippableSuitesCh) ||
|
|
1098
|
+
{ err: true }
|
|
1100
1099
|
|
|
1101
1100
|
errorSkippableRequest = skippableResponse.err
|
|
1102
1101
|
skippableSuites = skippableResponse.skippableSuites ?? []
|
|
@@ -1145,7 +1144,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1145
1144
|
if (isTestManagementTestsEnabled) {
|
|
1146
1145
|
const currentTestManagementTestsResponse =
|
|
1147
1146
|
testManagementTestsResponse || await getChannelPromise(testManagementTestsCh)
|
|
1148
|
-
if (currentTestManagementTestsResponse.err) {
|
|
1147
|
+
if (!currentTestManagementTestsResponse || currentTestManagementTestsResponse.err) {
|
|
1149
1148
|
isTestManagementTestsEnabled = false
|
|
1150
1149
|
} else {
|
|
1151
1150
|
testManagementTests = currentTestManagementTestsResponse.testManagementTests
|
|
@@ -1154,7 +1153,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1154
1153
|
|
|
1155
1154
|
if (isImpactedTestsEnabled) {
|
|
1156
1155
|
const impactedTestsResponse = await getChannelPromise(modifiedFilesCh)
|
|
1157
|
-
if (!impactedTestsResponse.err) {
|
|
1156
|
+
if (impactedTestsResponse && !impactedTestsResponse.err) {
|
|
1158
1157
|
modifiedFiles = impactedTestsResponse.modifiedFiles
|
|
1159
1158
|
}
|
|
1160
1159
|
}
|
|
@@ -1213,7 +1212,7 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1213
1212
|
global.__coverage__ = fromCoverageMapToCoverage(originalCoverageMap)
|
|
1214
1213
|
}
|
|
1215
1214
|
|
|
1216
|
-
sessionFinishCh
|
|
1215
|
+
const flushPromise = getChannelPromise(sessionFinishCh, {
|
|
1217
1216
|
status: success ? 'pass' : 'fail',
|
|
1218
1217
|
isSuitesSkipped,
|
|
1219
1218
|
testCodeCoverageLinesTotal,
|
|
@@ -1226,9 +1225,11 @@ function getWrappedStart (start, frameworkVersion, isParallel = false, isCoordin
|
|
|
1226
1225
|
isTestManagementTestsEnabled,
|
|
1227
1226
|
isParallel,
|
|
1228
1227
|
})
|
|
1228
|
+
|
|
1229
1229
|
logTestOptimizationSummary({ attemptToFixExecutions })
|
|
1230
1230
|
loggedAttemptToFixTests.clear()
|
|
1231
1231
|
eventDataCollector = null
|
|
1232
|
+
await flushPromise
|
|
1232
1233
|
return result
|
|
1233
1234
|
}
|
|
1234
1235
|
}
|
|
@@ -1434,13 +1435,14 @@ function getWrappedRunTestCase (runTestCaseFunction, isNewerCucumberVersion = fa
|
|
|
1434
1435
|
}
|
|
1435
1436
|
}
|
|
1436
1437
|
|
|
1437
|
-
function patchCucumberWorkerRunTestCase (
|
|
1438
|
-
const
|
|
1439
|
-
|
|
1438
|
+
function patchCucumberWorkerRunTestCase (runtimeExecutorPackage, isWorker) {
|
|
1439
|
+
const runtimeExecutorPrototype =
|
|
1440
|
+
runtimeExecutorPackage?.Worker?.prototype || runtimeExecutorPackage?.Executor?.prototype
|
|
1441
|
+
if (!runtimeExecutorPrototype || patchedCucumberWorkers.has(runtimeExecutorPrototype)) return
|
|
1440
1442
|
|
|
1441
|
-
patchedCucumberWorkers.add(
|
|
1443
|
+
patchedCucumberWorkers.add(runtimeExecutorPrototype)
|
|
1442
1444
|
shimmer.wrap(
|
|
1443
|
-
|
|
1445
|
+
runtimeExecutorPrototype,
|
|
1444
1446
|
'runTestCase',
|
|
1445
1447
|
runTestCase => getWrappedRunTestCase(runTestCase, true, isWorker)
|
|
1446
1448
|
)
|
|
@@ -1572,15 +1574,25 @@ addHook({
|
|
|
1572
1574
|
// `getWrappedRunTestCase` does two things:
|
|
1573
1575
|
// - generates suite start and finish events in the main process,
|
|
1574
1576
|
// - handles EFD in both the main process and the worker process.
|
|
1577
|
+
// Shimmer is required because this wrapper may invoke the original test case multiple times and mutate runtime options.
|
|
1575
1578
|
addHook({
|
|
1576
1579
|
name: '@cucumber/cucumber',
|
|
1577
|
-
versions: ['>=11.0.0'],
|
|
1580
|
+
versions: ['>=11.0.0 <13.2.0'],
|
|
1578
1581
|
file: 'lib/runtime/worker.js',
|
|
1579
1582
|
}, (workerPackage) => {
|
|
1580
1583
|
patchCucumberWorkerRunTestCase(workerPackage, !!getEnvironmentVariable('CUCUMBER_WORKER_ID'))
|
|
1581
1584
|
return workerPackage
|
|
1582
1585
|
})
|
|
1583
1586
|
|
|
1587
|
+
addHook({
|
|
1588
|
+
name: '@cucumber/cucumber',
|
|
1589
|
+
versions: ['>=13.2.0'],
|
|
1590
|
+
file: 'lib/runtime/executor.js',
|
|
1591
|
+
}, (executorPackage) => {
|
|
1592
|
+
patchCucumberWorkerRunTestCase(executorPackage, !!getEnvironmentVariable('CUCUMBER_WORKER_ID'))
|
|
1593
|
+
return executorPackage
|
|
1594
|
+
})
|
|
1595
|
+
|
|
1584
1596
|
// `getWrappedStart` generates session start and finish events
|
|
1585
1597
|
addHook({
|
|
1586
1598
|
name: '@cucumber/cucumber',
|