dd-trace 5.132.0 → 5.134.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/ci/diagnose.js +9 -14
- package/ci/init.js +1 -2
- package/ci/test-optimization-validation/ci-discovery.js +9 -4
- package/ci/test-optimization-validation/executable.js +1 -5
- package/ci/test-optimization-validation/framework-adapters/cypress.js +1 -4
- package/ci/test-optimization-validation/framework-adapters/vitest.js +1 -1
- package/ci/test-optimization-validation/generated-files.js +6 -4
- package/ci/test-optimization-validation/generated-test-contract.js +7 -3
- package/ci/test-optimization-validation/manifest-scaffold.js +7 -2
- package/ci/test-optimization-validation/manifest-schema.js +6 -7
- package/ci/test-optimization-validation/report-writer.js +6 -2
- package/ci/test-optimization-validation/runner-command.js +2 -4
- package/ci/test-optimization-validation/runner-contract.js +1 -2
- package/ci/test-optimization-validation/scenarios/auto-test-retries.js +1 -15
- package/ci/vitest-no-worker-init-runner-setup.mjs +27 -0
- package/ci/vitest-no-worker-init-setup.mjs +10 -7
- package/index.d.ts +41 -19
- package/initialize.mjs +1 -3
- package/openfeature/rules-based.d.ts +11 -0
- package/openfeature/rules-based.js +7 -0
- package/package.json +25 -22
- package/packages/datadog-core/src/storage.js +16 -0
- package/packages/datadog-esbuild/index.js +18 -12
- package/packages/datadog-instrumentations/index.js +2 -1
- package/packages/datadog-instrumentations/src/aerospike.js +3 -3
- package/packages/datadog-instrumentations/src/ai.js +3 -3
- package/packages/datadog-instrumentations/src/aws-durable-execution-sdk-js.js +0 -6
- package/packages/datadog-instrumentations/src/aws-sdk.js +21 -13
- package/packages/datadog-instrumentations/src/cassandra-driver.js +25 -20
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +9 -23
- package/packages/datadog-instrumentations/src/cucumber.js +65 -41
- package/packages/datadog-instrumentations/src/elasticsearch.js +1 -5
- package/packages/datadog-instrumentations/src/electron.js +6 -6
- package/packages/datadog-instrumentations/src/fastify.js +13 -4
- package/packages/datadog-instrumentations/src/fs.js +2 -2
- package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +9 -5
- package/packages/datadog-instrumentations/src/grpc/client.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/bundler-register.js +28 -9
- package/packages/datadog-instrumentations/src/helpers/check-require-cache.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +1 -1
- package/packages/datadog-instrumentations/src/helpers/register.js +45 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentation-registry.js +89 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +5 -6
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/jest.js +12 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/postgres.js +48 -31
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/vitest.js +8 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +7 -7
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +5 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms/postgres.js +42 -4
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +7 -10
- package/packages/datadog-instrumentations/src/ioredis.js +7 -5
- package/packages/datadog-instrumentations/src/iovalkey.js +7 -5
- package/packages/datadog-instrumentations/src/jest.js +72 -67
- package/packages/datadog-instrumentations/src/knex.js +9 -5
- package/packages/datadog-instrumentations/src/mariadb-bundle.js +3 -3
- package/packages/datadog-instrumentations/src/mocha/common.js +20 -8
- package/packages/datadog-instrumentations/src/mocha/main.js +140 -43
- package/packages/datadog-instrumentations/src/mocha/utils.js +38 -4
- package/packages/datadog-instrumentations/src/mocha/worker.js +1 -2
- package/packages/datadog-instrumentations/src/mongodb-core.js +3 -3
- package/packages/datadog-instrumentations/src/mongoose.js +3 -3
- package/packages/datadog-instrumentations/src/nova-sonic/audio.js +173 -0
- package/packages/datadog-instrumentations/src/nova-sonic/index.js +209 -0
- package/packages/datadog-instrumentations/src/nova-sonic/session.js +492 -0
- package/packages/datadog-instrumentations/src/openai-realtime/index.js +18 -6
- package/packages/datadog-instrumentations/src/openai-realtime/session.js +1 -1
- package/packages/datadog-instrumentations/src/openai.js +7 -0
- package/packages/datadog-instrumentations/src/pino.js +5 -6
- package/packages/datadog-instrumentations/src/playwright.js +2 -0
- package/packages/datadog-instrumentations/src/redis.js +27 -13
- package/packages/datadog-instrumentations/src/router.js +30 -0
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +2 -6
- package/packages/datadog-instrumentations/src/stripe.js +23 -12
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +8 -5
- package/packages/datadog-instrumentations/src/vitest-main.js +16 -18
- package/packages/datadog-instrumentations/src/vitest-util.js +7 -4
- package/packages/datadog-instrumentations/src/vitest-worker.js +1 -2
- package/packages/datadog-instrumentations/src/vitest.js +9 -1
- package/packages/datadog-instrumentations/src/webdriverio.js +5 -8
- package/packages/datadog-instrumentations/src/ws.js +1 -4
- package/packages/datadog-plugin-amqplib/src/client.js +1 -2
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +1 -5
- package/packages/datadog-plugin-aws-durable-execution-sdk-js/src/handler.js +1 -2
- package/packages/datadog-plugin-aws-sdk/src/base.js +5 -8
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/index.js +18 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/sonic.js +45 -0
- package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +9 -3
- package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -5
- package/packages/datadog-plugin-azure-durable-functions/src/index.js +5 -4
- package/packages/datadog-plugin-azure-functions/src/index.js +5 -3
- package/packages/datadog-plugin-claude-agent-sdk/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +4 -5
- package/packages/datadog-plugin-cypress/src/index.js +6 -6
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -2
- package/packages/datadog-plugin-cypress/src/support.js +3 -4
- package/packages/datadog-plugin-express/src/code_origin.js +1 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +2 -2
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +1 -2
- package/packages/datadog-plugin-graphql/src/execute.js +5 -5
- package/packages/datadog-plugin-grpc/src/util.js +1 -2
- package/packages/datadog-plugin-kafkajs/src/producer.js +1 -2
- package/packages/datadog-plugin-mocha/src/index.js +7 -10
- package/packages/datadog-plugin-mocha/src/webdriverio-video.js +8 -4
- package/packages/datadog-plugin-mongodb-core/src/query.js +8 -5
- package/packages/datadog-plugin-next/src/index.js +1 -2
- package/packages/datadog-plugin-openai/src/tracing.js +5 -2
- package/packages/datadog-plugin-openai-agents/src/integration.js +6 -2
- package/packages/datadog-plugin-openai-agents/src/processor.js +2 -4
- package/packages/datadog-plugin-postgres/src/index.js +24 -0
- package/packages/datadog-plugin-protobufjs/src/schema_iterator.js +1 -5
- package/packages/datadog-plugin-rhea/src/consumer.js +1 -4
- package/packages/datadog-plugin-vitest/src/index.js +5 -2
- package/packages/datadog-shimmer/src/shimmer.js +5 -4
- package/packages/datadog-webpack/index.js +55 -43
- package/packages/datadog-webpack/src/loader.js +56 -8
- package/packages/dd-trace/src/aiguard/evaluation.js +143 -1
- package/packages/dd-trace/src/aiguard/integrations/vercel-ai.js +2 -4
- package/packages/dd-trace/src/aiguard/messages/utils.js +1 -2
- package/packages/dd-trace/src/aiguard/redaction.js +8 -2
- package/packages/dd-trace/src/appsec/api_security/normalized-route.js +3 -2
- package/packages/dd-trace/src/appsec/api_security/sampler.js +2 -6
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -9
- package/packages/dd-trace/src/appsec/handlers/http-request.js +3 -9
- package/packages/dd-trace/src/appsec/handlers/http-response.js +7 -2
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +4 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/set-cookies-header-interceptor.js +1 -4
- package/packages/dd-trace/src/appsec/iast/path-line.js +2 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations-taint-object.js +7 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +1 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter-esm.mjs +1 -3
- package/packages/dd-trace/src/appsec/iast/telemetry/iast-metric.js +1 -6
- package/packages/dd-trace/src/appsec/lambda.js +1 -3
- package/packages/dd-trace/src/appsec/rasp/fs-plugin.js +37 -27
- package/packages/dd-trace/src/appsec/rasp/lfi.js +9 -5
- package/packages/dd-trace/src/appsec/reporter.js +21 -1
- package/packages/dd-trace/src/appsec/stack_trace.js +4 -4
- package/packages/dd-trace/src/ci-visibility/dynamic-atr-retries.js +3 -6
- package/packages/dd-trace/src/ci-visibility/dynamic-instrumentation/worker/index.js +3 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/msgpack-to-json.js +1 -1
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +13 -7
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +2 -8
- package/packages/dd-trace/src/ci-visibility/resolve-runfile-path.js +54 -0
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +5 -8
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +2 -53
- package/packages/dd-trace/src/config/config-types.d.ts +2 -2
- package/packages/dd-trace/src/config/defaults.js +5 -5
- package/packages/dd-trace/src/config/generated-config-types.d.ts +10 -0
- package/packages/dd-trace/src/config/helper.js +34 -3
- package/packages/dd-trace/src/config/index.js +55 -9
- package/packages/dd-trace/src/config/normalize-service.js +1 -1
- package/packages/dd-trace/src/config/parsers.js +2 -2
- package/packages/dd-trace/src/config/supported-configurations.json +44 -0
- package/packages/dd-trace/src/datastreams/processor.js +3 -2
- package/packages/dd-trace/src/datastreams/schemas/schema_builder.js +1 -4
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +6 -5
- package/packages/dd-trace/src/debugger/devtools_client/condition.js +5 -5
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/collector.js +4 -6
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -0
- package/packages/dd-trace/src/debugger/guardrail-metrics.js +2 -2
- package/packages/dd-trace/src/debugger/unsupported-runtime.js +16 -0
- package/packages/dd-trace/src/dogstatsd.js +1 -1
- package/packages/dd-trace/src/encode/tags-processors.js +2 -2
- package/packages/dd-trace/src/exporters/common/request.js +1 -5
- package/packages/dd-trace/src/id.js +14 -1
- package/packages/dd-trace/src/lambda/handler.js +179 -19
- package/packages/dd-trace/src/lambda/index.js +15 -1
- package/packages/dd-trace/src/lambda/runtime/patch.js +34 -7
- package/packages/dd-trace/src/llmobs/agent-manifest.js +19 -2
- package/packages/dd-trace/src/llmobs/audio-utils.js +3 -2
- package/packages/dd-trace/src/llmobs/constants/tags.js +15 -0
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +15 -0
- package/packages/dd-trace/src/llmobs/plugins/genai/util.js +1 -2
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/chat_model.js +1 -3
- package/packages/dd-trace/src/llmobs/plugins/langgraph/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/nova-sonic.js +92 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/constants.js +5 -0
- package/packages/dd-trace/src/llmobs/plugins/openai/index.js +64 -2
- package/packages/dd-trace/src/llmobs/plugins/openai/utils.js +38 -0
- package/packages/dd-trace/src/llmobs/prompts/manager.js +5 -7
- package/packages/dd-trace/src/llmobs/prompts/prompt.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +15 -4
- package/packages/dd-trace/src/llmobs/span_processor.js +13 -2
- package/packages/dd-trace/src/llmobs/tagger.js +20 -10
- package/packages/dd-trace/src/llmobs/util.js +11 -6
- package/packages/dd-trace/src/llmobs/writers/base.js +4 -5
- package/packages/dd-trace/src/log/log.js +1 -5
- package/packages/dd-trace/src/openfeature/evaluation-telemetry-opt-out-hook.js +51 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +48 -21
- package/packages/dd-trace/src/openfeature/index.js +6 -0
- package/packages/dd-trace/src/openfeature/writers/util.js +4 -4
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +1 -2
- package/packages/dd-trace/src/opentelemetry/otlp/common.proto +1 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_transformer.js +24 -24
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +53 -13
- package/packages/dd-trace/src/otel-sampling.js +4 -5
- package/packages/dd-trace/src/otel-thread-ctx.js +79 -13
- package/packages/dd-trace/src/plugin_manager.js +1 -2
- package/packages/dd-trace/src/plugins/database.js +7 -16
- package/packages/dd-trace/src/plugins/tracing.js +0 -1
- package/packages/dd-trace/src/plugins/util/git.js +99 -59
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +1 -5
- package/packages/dd-trace/src/plugins/util/stacktrace.js +2 -1
- package/packages/dd-trace/src/plugins/util/test.js +50 -4
- package/packages/dd-trace/src/plugins/util/web.js +90 -20
- package/packages/dd-trace/src/priority_sampler.js +1 -2
- package/packages/dd-trace/src/profiling/profiler.js +4 -6
- package/packages/dd-trace/src/proxy.js +1 -2
- package/packages/dd-trace/src/ritm.js +4 -2
- package/packages/dd-trace/src/serverless.js +5 -0
- package/packages/dd-trace/src/span_processor.js +13 -17
- package/packages/dd-trace/src/span_stats.js +4 -1
- package/packages/dd-trace/src/telemetry/endpoints.js +1 -3
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +1 -1
- package/packages/dd-trace/src/util.js +37 -4
- package/packages/dd-trace/src/web-tags-cache.js +6 -2
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +8 -8
- package/vendor/dist/@datadog/openfeature-node-server/index.js +1 -1
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/LICENSE +201 -0
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.d.ts +925 -0
- package/vendor/dist/@datadog/openfeature-node-server/rules-based/index.js +1 -0
- 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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const PARAMETER = 'dd_evaluation_telemetry_opt_out'
|
|
4
|
+
|
|
5
|
+
/** Gates an owned finally-only telemetry hook without changing evaluation or exposure handling. */
|
|
6
|
+
class EvaluationTelemetryOptOutHook {
|
|
7
|
+
#delegate
|
|
8
|
+
#decisions = new WeakMap()
|
|
9
|
+
|
|
10
|
+
/** @param {import('@openfeature/server-sdk').Hook} delegate */
|
|
11
|
+
constructor (delegate) {
|
|
12
|
+
this.#delegate = delegate
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** @param {import('@openfeature/core').HookContext} hookContext */
|
|
16
|
+
before (hookContext) {
|
|
17
|
+
// Hook context identity is stable across stages, including each MultiProvider branch.
|
|
18
|
+
this.#decisions.set(hookContext, isOptedOut(hookContext.context))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @param {import('@openfeature/core').HookContext} hookContext */
|
|
22
|
+
error (hookContext) {
|
|
23
|
+
// A customer before hook can fail before this hook runs. Capture opt-out before customer error hooks change it.
|
|
24
|
+
if (!this.#decisions.has(hookContext)) {
|
|
25
|
+
this.#decisions.set(hookContext, isOptedOut(hookContext.context))
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {import('@openfeature/core').HookContext} hookContext
|
|
31
|
+
* @param {import('@openfeature/core').EvaluationDetails<import('@openfeature/core').FlagValue>} evaluationDetails
|
|
32
|
+
* @param {import('@openfeature/core').HookHints} [hints]
|
|
33
|
+
*/
|
|
34
|
+
finally (hookContext, evaluationDetails, hints) {
|
|
35
|
+
const optedOut = this.#decisions.get(hookContext) === true || isOptedOut(hookContext.context)
|
|
36
|
+
this.#decisions.delete(hookContext)
|
|
37
|
+
if (!optedOut) return this.#delegate.finally?.(hookContext, evaluationDetails, hints)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @param {import('@openfeature/core').EvaluationContext} context */
|
|
42
|
+
function isOptedOut (context) {
|
|
43
|
+
try {
|
|
44
|
+
return context?.[PARAMETER] === true
|
|
45
|
+
} catch {
|
|
46
|
+
// An unreadable attribute is not boolean true and must not change the evaluation result.
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = EvaluationTelemetryOptOutHook
|
|
@@ -9,6 +9,7 @@ const configurationSource = require('./configuration_source')
|
|
|
9
9
|
const { EXPOSURE_CHANNEL } = require('./constants/constants')
|
|
10
10
|
const DebugLoggingHook = require('./debug-logging-hook')
|
|
11
11
|
const EvalMetricsHook = require('./eval-metrics-hook')
|
|
12
|
+
const EvaluationTelemetryOptOutHook = require('./evaluation-telemetry-opt-out-hook')
|
|
12
13
|
const SpanEnrichmentHook = require('./span-enrichment-hook')
|
|
13
14
|
const FlagEvalEVPHook = require('./writers/flag-eval-evp-hook')
|
|
14
15
|
|
|
@@ -17,6 +18,9 @@ const FlagEvalEVPHook = require('./writers/flag-eval-evp-hook')
|
|
|
17
18
|
* Extends DatadogNodeServerProvider to add tracer integration and configuration management.
|
|
18
19
|
*/
|
|
19
20
|
class FlaggingProvider extends DatadogNodeServerProvider {
|
|
21
|
+
// Track this wrapper's logging lifecycle without reading the upstream provider's private state.
|
|
22
|
+
#waitingForConfiguration = false
|
|
23
|
+
|
|
20
24
|
/** @type {SpanEnrichmentHook | undefined} */
|
|
21
25
|
#spanEnrichmentHook
|
|
22
26
|
|
|
@@ -36,8 +40,13 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
36
40
|
initializationTimeoutMs: config.featureFlags.DD_EXPERIMENTAL_FLAGGING_PROVIDER_INITIALIZATION_TIMEOUT_MS,
|
|
37
41
|
})
|
|
38
42
|
|
|
43
|
+
const enableOptOut =
|
|
44
|
+
config.featureFlags.DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED === true
|
|
45
|
+
/** @param {import('@openfeature/server-sdk').Hook} hook */
|
|
46
|
+
const telemetryHook = hook => enableOptOut ? new EvaluationTelemetryOptOutHook(hook) : hook
|
|
47
|
+
|
|
39
48
|
if (config.DD_METRICS_OTEL_ENABLED === true) {
|
|
40
|
-
this.hooks.push(new EvalMetricsHook(config))
|
|
49
|
+
this.hooks.push(telemetryHook(new EvalMetricsHook(config)))
|
|
41
50
|
} else {
|
|
42
51
|
log.debug('Feature Flags: evaluation metrics disabled; set %s=true to enable', 'DD_METRICS_OTEL_ENABLED')
|
|
43
52
|
}
|
|
@@ -49,7 +58,7 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
49
58
|
if (config.featureFlags.DD_EXPERIMENTAL_FLAGGING_PROVIDER_SPAN_ENRICHMENT_ENABLED) {
|
|
50
59
|
this.#spanEnrichmentHook = new SpanEnrichmentHook(tracer)
|
|
51
60
|
// @ts-expect-error The upstream constructor always initializes its optional hooks property.
|
|
52
|
-
this.hooks.push(this.#spanEnrichmentHook)
|
|
61
|
+
this.hooks.push(telemetryHook(this.#spanEnrichmentHook))
|
|
53
62
|
log.info('%s span enrichment enabled', this.constructor.name)
|
|
54
63
|
} else {
|
|
55
64
|
log.info('%s span enrichment disabled', this.constructor.name)
|
|
@@ -60,7 +69,7 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
60
69
|
|
|
61
70
|
if (config.featureFlags?.DD_FLAGGING_EVALUATION_COUNTS_ENABLED !== false) {
|
|
62
71
|
this.#flagEvalEVPHook = new FlagEvalEVPHook(config)
|
|
63
|
-
this.hooks.push(this.#flagEvalEVPHook)
|
|
72
|
+
this.hooks.push(telemetryHook(this.#flagEvalEVPHook))
|
|
64
73
|
}
|
|
65
74
|
|
|
66
75
|
this.#configurationSource = configurationSource.create(config, this.setConfiguration.bind(this))
|
|
@@ -74,6 +83,7 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
74
83
|
initialize (context) {
|
|
75
84
|
log.debug('Feature Flags: waiting for provider initialization...')
|
|
76
85
|
|
|
86
|
+
this.#waitingForConfiguration = !this.getConfiguration()
|
|
77
87
|
const promise = super.initialize(context)
|
|
78
88
|
|
|
79
89
|
// `DatadogNodeServerProvider#initialize` starts a timer that is never unref'd, which would
|
|
@@ -82,28 +92,45 @@ class FlaggingProvider extends DatadogNodeServerProvider {
|
|
|
82
92
|
// TODO: remove once `@datadog/openfeature-node-server` unrefs this timer itself.
|
|
83
93
|
this.initController?.timeoutId?.unref?.()
|
|
84
94
|
|
|
85
|
-
|
|
86
|
-
// Guarded so a logger failure can never leave the derived promise unhandled.
|
|
87
|
-
promise.then(
|
|
88
|
-
() => {
|
|
89
|
-
try {
|
|
90
|
-
log.debug('Feature Flags: provider initialized successfully')
|
|
91
|
-
} catch { /* logging failure must not crash the process */ }
|
|
92
|
-
},
|
|
93
|
-
(error) => {
|
|
94
|
-
try {
|
|
95
|
-
// errorWithoutTelemetry avoids inflating telemetry volume for every routine init timeout.
|
|
96
|
-
log.errorWithoutTelemetry(
|
|
97
|
-
'Feature Flags: provider failed to initialize: %s',
|
|
98
|
-
error instanceof Error ? error.message : String(error)
|
|
99
|
-
)
|
|
100
|
-
} catch { /* logging failure must not crash the process */ }
|
|
101
|
-
}
|
|
102
|
-
)
|
|
95
|
+
if (this.getConfiguration()) this.#logInitialConfiguration()
|
|
103
96
|
|
|
104
97
|
return promise
|
|
105
98
|
}
|
|
106
99
|
|
|
100
|
+
/**
|
|
101
|
+
* @param {Parameters<DatadogNodeServerProvider['setConfiguration']>[0]} configuration
|
|
102
|
+
*/
|
|
103
|
+
setConfiguration (configuration) {
|
|
104
|
+
const wasWaiting = this.#waitingForConfiguration
|
|
105
|
+
super.setConfiguration(configuration)
|
|
106
|
+
this.#waitingForConfiguration = false
|
|
107
|
+
if (wasWaiting && configuration != null) this.#logInitialConfiguration()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {unknown} error
|
|
112
|
+
*/
|
|
113
|
+
setError (error) {
|
|
114
|
+
const wasWaiting = this.#waitingForConfiguration
|
|
115
|
+
super.setError(error)
|
|
116
|
+
this.#waitingForConfiguration = false
|
|
117
|
+
if (!wasWaiting) return
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
// Avoid inflating telemetry volume for routine initialization timeouts.
|
|
121
|
+
log.errorWithoutTelemetry(
|
|
122
|
+
'Feature Flags: provider failed to initialize: %s',
|
|
123
|
+
error instanceof Error ? error.message : String(error)
|
|
124
|
+
)
|
|
125
|
+
} catch { /* logging failure must not affect initialization */ }
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#logInitialConfiguration () {
|
|
129
|
+
try {
|
|
130
|
+
log.debug('Feature Flags: initial configuration available')
|
|
131
|
+
} catch { /* logging failure must not affect initialization */ }
|
|
132
|
+
}
|
|
133
|
+
|
|
107
134
|
/**
|
|
108
135
|
* Called when the provider is shut down.
|
|
109
136
|
* Cleans up resources including channel subscriptions.
|
|
@@ -33,6 +33,12 @@ function _handleFlush () {
|
|
|
33
33
|
* @param {import('../config')} config - Tracer configuration object
|
|
34
34
|
*/
|
|
35
35
|
function enable (config) {
|
|
36
|
+
if (config.featureFlags?.DD_FEATURE_FLAGS_EXPOSURES_DATADOG_LOGGING_ENABLED === false) {
|
|
37
|
+
log.debug('Feature Flags: Datadog exposure logging disabled; set %s=true to enable',
|
|
38
|
+
'DD_FEATURE_FLAGS_EXPOSURES_DATADOG_LOGGING_ENABLED')
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
if (exposuresWriter) {
|
|
37
43
|
log.warn('%s already enabled', exposuresWriter.constructor.name)
|
|
38
44
|
return
|
|
@@ -31,14 +31,14 @@ const deliveryStrategies = new WeakMap()
|
|
|
31
31
|
let missingRouteWarningLogged = false
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Logs the unavailable
|
|
34
|
+
* Logs the unavailable event-delivery warning once.
|
|
35
35
|
*
|
|
36
36
|
*/
|
|
37
|
-
function
|
|
37
|
+
function warnEventDeliveryUnavailable () {
|
|
38
38
|
if (missingRouteWarningLogged) return
|
|
39
39
|
missingRouteWarningLogged = true
|
|
40
40
|
logger.warn(
|
|
41
|
-
'Feature Flags
|
|
41
|
+
'Feature Flags event delivery is disabled because no compatible local EVP route or direct intake ' +
|
|
42
42
|
'credentials are available.'
|
|
43
43
|
)
|
|
44
44
|
}
|
|
@@ -169,7 +169,7 @@ function setAgentlessStrategy (config, setWriterEnabledValue) {
|
|
|
169
169
|
if (error) {
|
|
170
170
|
logger.debug('FFE Writer disabled - error getting local receiver info: %s', error.message)
|
|
171
171
|
}
|
|
172
|
-
|
|
172
|
+
warnEventDeliveryUnavailable()
|
|
173
173
|
markUnavailable()
|
|
174
174
|
})
|
|
175
175
|
}
|
|
@@ -52,7 +52,7 @@ function encodeHrTime (hrTime) {
|
|
|
52
52
|
* OtlpTransformer transforms log records to OTLP format.
|
|
53
53
|
*
|
|
54
54
|
* This implementation follows the OTLP Logs v1.7.0 Data Model specification:
|
|
55
|
-
* https://opentelemetry.
|
|
55
|
+
* https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/opentelemetry/proto/logs/v1/logs.proto
|
|
56
56
|
*
|
|
57
57
|
* @class OtlpTransformer
|
|
58
58
|
* @augments OtlpTransformerBase
|
|
@@ -18,7 +18,7 @@ const AGGREGATION_TEMPORALITY_CUMULATIVE = protoAggregationTemporality.values.AG
|
|
|
18
18
|
* OtlpTransformer transforms metrics to OTLP format.
|
|
19
19
|
*
|
|
20
20
|
* This implementation follows the OTLP Metrics v1.7.0 Data Model specification:
|
|
21
|
-
* https://opentelemetry.
|
|
21
|
+
* https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/opentelemetry/proto/metrics/v1/metrics.proto
|
|
22
22
|
*
|
|
23
23
|
* @class OtlpTransformer
|
|
24
24
|
* @augments OtlpTransformerBase
|
|
@@ -162,8 +162,7 @@ class PeriodicMetricReader {
|
|
|
162
162
|
addBatchObservableCallback (callback, observables) {
|
|
163
163
|
if (typeof callback !== 'function') return
|
|
164
164
|
const instruments = new Set(observables?.filter(isObservableInstrument))
|
|
165
|
-
if (instruments.size === 0) return
|
|
166
|
-
if (this.#findBatchCallback(callback, instruments) !== -1) return
|
|
165
|
+
if (instruments.size === 0 || this.#findBatchCallback(callback, instruments) !== -1) return
|
|
167
166
|
this.#batchCallbacks.push({ callback, instruments })
|
|
168
167
|
}
|
|
169
168
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Vendored from: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/opentelemetry/proto/
|
|
1
|
+
// Vendored from: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/opentelemetry/proto/common/v1/common.proto
|
|
2
2
|
// Copyright 2019, OpenTelemetry Authors
|
|
3
3
|
//
|
|
4
4
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -84,7 +84,7 @@ const DD_ERROR_META_KEYS = new Set(['error.message'])
|
|
|
84
84
|
* OtlpTraceTransformer transforms DD-formatted spans to OTLP trace JSON format.
|
|
85
85
|
*
|
|
86
86
|
* This implementation follows the OTLP trace data model:
|
|
87
|
-
* https://opentelemetry.
|
|
87
|
+
* https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/opentelemetry/proto/trace/v1/trace.proto
|
|
88
88
|
*
|
|
89
89
|
* It receives DD-formatted spans (from span_format.js) and produces
|
|
90
90
|
* an ExportTraceServiceRequest serialized as JSON (http/json protocol only).
|
|
@@ -95,6 +95,11 @@ const DD_ERROR_META_KEYS = new Set(['error.message'])
|
|
|
95
95
|
class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
96
96
|
#otelTraceSemanticsEnabled
|
|
97
97
|
|
|
98
|
+
// Span meta entries with the same key and value as a resource attribute are already carried by
|
|
99
|
+
// the resource (e.g. DD_TAGS), so they are not repeated as span attributes.
|
|
100
|
+
/** @type {import('@opentelemetry/api').Attributes} */
|
|
101
|
+
#resourceAttributes
|
|
102
|
+
|
|
98
103
|
/**
|
|
99
104
|
* Creates a new OtlpTraceTransformer instance.
|
|
100
105
|
*
|
|
@@ -104,6 +109,16 @@ class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
|
104
109
|
constructor (resourceAttributes, otelTraceSemanticsEnabled) {
|
|
105
110
|
super(resourceAttributes, 'http/json', 'traces')
|
|
106
111
|
this.#otelTraceSemanticsEnabled = otelTraceSemanticsEnabled
|
|
112
|
+
this.#resourceAttributes = resourceAttributes
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @override
|
|
117
|
+
* @param {import('@opentelemetry/api').Attributes} resourceAttributes - Resource attributes
|
|
118
|
+
*/
|
|
119
|
+
updateResourceAttributes (resourceAttributes) {
|
|
120
|
+
super.updateResourceAttributes(resourceAttributes)
|
|
121
|
+
this.#resourceAttributes = resourceAttributes
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
/**
|
|
@@ -168,8 +183,8 @@ class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
|
168
183
|
|
|
169
184
|
return {
|
|
170
185
|
traceId: span.trace_id.toTraceIdHex(traceIdHigh).padStart(32, '0'),
|
|
171
|
-
spanId: this.#
|
|
172
|
-
parentSpanId:
|
|
186
|
+
spanId: this.#spanIdToHex(span.span_id),
|
|
187
|
+
parentSpanId: parentId && !parentId.equals(ZERO_ID) ? this.#spanIdToHex(parentId) : undefined,
|
|
173
188
|
traceState: span.trace_state,
|
|
174
189
|
name: span.resource,
|
|
175
190
|
kind: this.#mapSpanKind(span.meta?.['span.kind']),
|
|
@@ -216,11 +231,13 @@ class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
|
216
231
|
}
|
|
217
232
|
}
|
|
218
233
|
|
|
219
|
-
// Add meta string tags, skipping keys that map to dedicated OTLP fields
|
|
234
|
+
// Add meta string tags, skipping keys that map to dedicated OTLP fields and tags the
|
|
235
|
+
// resource already carries with the same value (e.g. global tags from DD_TAGS)
|
|
220
236
|
if (span.meta) {
|
|
221
237
|
for (const [key, value] of Object.entries(span.meta)) {
|
|
222
238
|
if (EXCLUDED_META_KEYS.has(key)) continue
|
|
223
239
|
if (this.#otelTraceSemanticsEnabled && DD_ERROR_META_KEYS.has(key)) continue
|
|
240
|
+
if (this.#resourceAttributes[key] === value) continue
|
|
224
241
|
attributes.push({ key, value: { stringValue: value } })
|
|
225
242
|
}
|
|
226
243
|
}
|
|
@@ -338,26 +355,9 @@ class OtlpTraceTransformer extends OtlpTransformerBase {
|
|
|
338
355
|
}
|
|
339
356
|
}
|
|
340
357
|
|
|
341
|
-
/**
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
* Per the OTLP http/json spec, trace-ids and span-ids must be hex-encoded strings.
|
|
345
|
-
*
|
|
346
|
-
* @param {Identifier} identifier - DD Identifier
|
|
347
|
-
* @param {number} targetLength - Target byte length (16 for trace ID, 8 for span ID)
|
|
348
|
-
*/
|
|
349
|
-
#idToBytes (identifier, targetLength) {
|
|
350
|
-
const buffer = identifier.toBuffer()
|
|
351
|
-
if (buffer.length === targetLength) {
|
|
352
|
-
return Buffer.from(buffer).toString('hex')
|
|
353
|
-
}
|
|
354
|
-
if (buffer.length > targetLength) {
|
|
355
|
-
return Buffer.from(buffer.slice(buffer.length - targetLength)).toString('hex')
|
|
356
|
-
}
|
|
357
|
-
// Pad with leading zeros to reach target length.
|
|
358
|
-
const result = Buffer.alloc(targetLength)
|
|
359
|
-
Buffer.from(buffer).copy(result, targetLength - buffer.length)
|
|
360
|
-
return result.toString('hex')
|
|
358
|
+
/** @param {Identifier} identifier */
|
|
359
|
+
#spanIdToHex (identifier) {
|
|
360
|
+
return identifier.toString(16).slice(-16)
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
/**
|
|
@@ -38,7 +38,7 @@ const id = require('../../id')
|
|
|
38
38
|
const DatadogSpanContext = require('../span_context')
|
|
39
39
|
const log = require('../../log')
|
|
40
40
|
const tags = require('../../../../../ext/tags')
|
|
41
|
-
const {
|
|
41
|
+
const { getValidatedConfiguredEnvName } = require('../../config/helper')
|
|
42
42
|
const { setAllBaggageItems, getAllBaggageItems, removeAllBaggageItems } = require('../../baggage')
|
|
43
43
|
const { hasTraceSourcePropagationTag } = require('../../standalone/tracesource')
|
|
44
44
|
const telemetryMetrics = require('../../telemetry/metrics')
|
|
@@ -134,8 +134,7 @@ function isOptionalDatadogTraceStateField (key, injection) {
|
|
|
134
134
|
* @returns {DatadogSpanContext | undefined}
|
|
135
135
|
*/
|
|
136
136
|
function extractGenericContext (traceId, spanId, radix) {
|
|
137
|
-
if (!traceId || invalidSegment.test(traceId)) return
|
|
138
|
-
if (!spanId) return
|
|
137
|
+
if (!traceId || invalidSegment.test(traceId) || !spanId) return
|
|
139
138
|
|
|
140
139
|
return new DatadogSpanContext({
|
|
141
140
|
traceId: id(traceId, radix),
|
|
@@ -305,13 +304,25 @@ class TextMapPropagator {
|
|
|
305
304
|
/** @type {string[] | undefined} Source array that `#baggageTagKeysSet` was built from. */
|
|
306
305
|
#baggageTagKeysSetSource
|
|
307
306
|
|
|
308
|
-
/** @type {import('../../config')} */
|
|
307
|
+
/** @type {ReturnType<import('../../config')>} */
|
|
309
308
|
#config
|
|
310
309
|
|
|
311
310
|
/** @type {typeof extractB3SingleContext | typeof extractB3MultiContext} */
|
|
312
311
|
#extractB3Context
|
|
313
312
|
|
|
314
|
-
/**
|
|
313
|
+
/** Whether the `b3` injection style resolves to single-header propagation. */
|
|
314
|
+
#b3InjectIsSingleHeader
|
|
315
|
+
|
|
316
|
+
/** Cached origin used to resolve the v5 `b3` injection style. */
|
|
317
|
+
#b3InjectOrigin
|
|
318
|
+
|
|
319
|
+
/** Cached state of the v5 experimental B3 setting. */
|
|
320
|
+
#b3ExperimentalEnabled
|
|
321
|
+
|
|
322
|
+
/** Cached origin of the shared v5 propagation style. */
|
|
323
|
+
#b3SharedOrigin
|
|
324
|
+
|
|
325
|
+
/** @param {ReturnType<import('../../config')>} config */
|
|
315
326
|
constructor (config) {
|
|
316
327
|
this.#config = config
|
|
317
328
|
|
|
@@ -319,16 +330,44 @@ class TextMapPropagator {
|
|
|
319
330
|
// expect single, legacy `DD_TRACE_PROPAGATION_STYLE` callers expect multi.
|
|
320
331
|
/* istanbul ignore else: v5 fallback */
|
|
321
332
|
if (DD_MAJOR >= 6) {
|
|
333
|
+
this.#b3InjectIsSingleHeader = true
|
|
322
334
|
this.#extractB3Context = extractB3SingleContext
|
|
323
335
|
} else {
|
|
324
|
-
const envName =
|
|
336
|
+
const envName = getValidatedConfiguredEnvName('DD_TRACE_PROPAGATION_STYLE')
|
|
325
337
|
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
326
338
|
this.#extractB3Context = envName === 'OTEL_PROPAGATORS'
|
|
327
339
|
? extractB3SingleContext
|
|
328
340
|
: extractB3MultiContext
|
|
341
|
+
|
|
342
|
+
this.#refreshB3InjectionStyle()
|
|
329
343
|
}
|
|
330
344
|
}
|
|
331
345
|
|
|
346
|
+
#refreshB3InjectionStyle () {
|
|
347
|
+
const origin = this.#config.getOrigin?.('tracePropagationStyle.inject') ?? 'default'
|
|
348
|
+
const experimentalEnabled = this.#config.experimental?.b3 === true
|
|
349
|
+
const sharedOrigin = origin === 'calculated'
|
|
350
|
+
? this.#config.getOrigin?.('DD_TRACE_PROPAGATION_STYLE') ?? 'default'
|
|
351
|
+
: undefined
|
|
352
|
+
if (origin === this.#b3InjectOrigin &&
|
|
353
|
+
experimentalEnabled === this.#b3ExperimentalEnabled &&
|
|
354
|
+
sharedOrigin === this.#b3SharedOrigin) return
|
|
355
|
+
|
|
356
|
+
let envName
|
|
357
|
+
if (origin === 'calculated' && !experimentalEnabled && sharedOrigin !== 'remote_config') {
|
|
358
|
+
envName = getValidatedConfiguredEnvName('DD_TRACE_PROPAGATION_STYLE')
|
|
359
|
+
} else if (origin === 'env_var' ||
|
|
360
|
+
origin === 'local_stable_config' ||
|
|
361
|
+
origin === 'fleet_stable_config') {
|
|
362
|
+
envName = getValidatedConfiguredEnvName('DD_TRACE_PROPAGATION_STYLE_INJECT')
|
|
363
|
+
}
|
|
364
|
+
// eslint-disable-next-line eslint-rules/eslint-env-aliases
|
|
365
|
+
this.#b3InjectIsSingleHeader = envName === 'OTEL_PROPAGATORS'
|
|
366
|
+
this.#b3InjectOrigin = origin
|
|
367
|
+
this.#b3ExperimentalEnabled = experimentalEnabled
|
|
368
|
+
this.#b3SharedOrigin = sharedOrigin
|
|
369
|
+
}
|
|
370
|
+
|
|
332
371
|
/**
|
|
333
372
|
* Returns a `Set` view of `#config.baggageTagKeys` that is rebuilt only
|
|
334
373
|
* when the source array reference changes. Avoids an `O(n)` `Set` alloc
|
|
@@ -574,9 +613,8 @@ class TextMapPropagator {
|
|
|
574
613
|
* @returns {Record<string, string> | undefined}
|
|
575
614
|
*/
|
|
576
615
|
#injectB3MultipleHeaders (spanContext, carrier) {
|
|
577
|
-
// v5 also accepts the legacy `'b3'` spelling for multi; v6+ routes `'b3'` to single-header.
|
|
578
616
|
const hasB3multi = this.#hasPropagationStyle('inject', 'b3multi') ||
|
|
579
|
-
(
|
|
617
|
+
(this.#hasPropagationStyle('inject', 'b3') && !this.#usesB3SingleHeaderInjection())
|
|
580
618
|
if (!hasB3multi) return
|
|
581
619
|
|
|
582
620
|
carrier ??= {}
|
|
@@ -603,7 +641,7 @@ class TextMapPropagator {
|
|
|
603
641
|
#injectB3SingleHeader (spanContext, carrier) {
|
|
604
642
|
// v6+ keeps `'b3 single header'` as a back-compat alias for callers that bypass parser normalisation.
|
|
605
643
|
const hasB3SingleHeader = this.#hasPropagationStyle('inject', 'b3 single header') ||
|
|
606
|
-
(
|
|
644
|
+
(this.#hasPropagationStyle('inject', 'b3') && this.#usesB3SingleHeaderInjection())
|
|
607
645
|
if (!hasB3SingleHeader) return
|
|
608
646
|
|
|
609
647
|
carrier ??= {}
|
|
@@ -620,6 +658,11 @@ class TextMapPropagator {
|
|
|
620
658
|
return carrier
|
|
621
659
|
}
|
|
622
660
|
|
|
661
|
+
#usesB3SingleHeaderInjection () {
|
|
662
|
+
if (DD_MAJOR < 6) this.#refreshB3InjectionStyle()
|
|
663
|
+
return this.#b3InjectIsSingleHeader
|
|
664
|
+
}
|
|
665
|
+
|
|
623
666
|
/**
|
|
624
667
|
* @param {DatadogSpanContext} spanContext
|
|
625
668
|
* @param {Record<string, string> | undefined} carrier
|
|
@@ -982,11 +1025,8 @@ class TextMapPropagator {
|
|
|
982
1025
|
const traceparent = { version }
|
|
983
1026
|
// W3C Trace Context §3.3.1.1: multiple tracestate fields MUST be combined per RFC 7230 §3.2.2.
|
|
984
1027
|
const tracestate = TraceState.fromString(readTracestate(carrier))
|
|
985
|
-
if (invalidSegment.test(traceId)) return
|
|
986
|
-
if (invalidSegment.test(spanId)) return
|
|
987
|
-
|
|
988
1028
|
// Version ff is considered invalid
|
|
989
|
-
if (version === 'ff') return
|
|
1029
|
+
if (invalidSegment.test(traceId) || invalidSegment.test(spanId) || version === 'ff') return
|
|
990
1030
|
|
|
991
1031
|
// Version 00 should have no tail, but future versions may
|
|
992
1032
|
if (tail && version === '00') return
|
|
@@ -11,11 +11,10 @@ const UINT64_MASK = 2n ** 64n - 1n
|
|
|
11
11
|
/**
|
|
12
12
|
* @param {unknown} value
|
|
13
13
|
* @param {number} minLength
|
|
14
|
-
* @param {number} maxLength
|
|
15
14
|
* @returns {value is string}
|
|
16
15
|
*/
|
|
17
|
-
function isLowerHex (value, minLength
|
|
18
|
-
if (typeof value !== 'string' || value.length < minLength || value.length >
|
|
16
|
+
function isLowerHex (value, minLength) {
|
|
17
|
+
if (typeof value !== 'string' || value.length < minLength || value.length > 14) return false
|
|
19
18
|
|
|
20
19
|
for (let index = 0; index < value.length; index++) {
|
|
21
20
|
const code = value.charCodeAt(index)
|
|
@@ -112,11 +111,11 @@ function sanitizeFields (state) {
|
|
|
112
111
|
let randomValue = state.get('rv')
|
|
113
112
|
let threshold = state.get('th')
|
|
114
113
|
|
|
115
|
-
if (!isLowerHex(randomValue, 14
|
|
114
|
+
if (!isLowerHex(randomValue, 14)) {
|
|
116
115
|
state.delete('rv')
|
|
117
116
|
randomValue = undefined
|
|
118
117
|
}
|
|
119
|
-
if (!isLowerHex(threshold, 1
|
|
118
|
+
if (!isLowerHex(threshold, 1)) {
|
|
120
119
|
state.delete('th')
|
|
121
120
|
threshold = undefined
|
|
122
121
|
}
|