Skip to content

♻️ [js-core] Schema-driven configuration validation across browser-core, browser-logs, and browser-rum-core#4798

Draft
thomas-lebeau wants to merge 6 commits into
mainfrom
worktree-js-core-configuration
Draft

♻️ [js-core] Schema-driven configuration validation across browser-core, browser-logs, and browser-rum-core#4798
thomas-lebeau wants to merge 6 commits into
mainfrom
worktree-js-core-configuration

Conversation

@thomas-lebeau

Copy link
Copy Markdown
Collaborator

Motivation

Configuration validation in browser-core, browser-logs, and browser-rum-core was previously done imperatively — each package had its own ad-hoc validation logic with repetitive checks, inconsistent error handling, and no shared abstraction.

This PR introduces a schema-driven configuration system in @datadog/js-core that declaratively describes fields, their types, defaults, and validation rules. Browser packages then derive their Configuration types and validation functions from these schemas.

Changes

  • @datadog/js-core: Add configuration entry point with validateAndBuildConfiguration, InferredConfig, and field definition types (StringField, BooleanField, PercentageField, SiteField, MatchOptionField, EnumField, CustomField). Includes an INVALID sentinel value that custom validators can return to fail the whole configuration.
  • browser-core: Replace imperative validateAndBuildConfiguration and manual Configuration interface with BROWSER_CORE_SCHEMA + InferredConfig<typeof BROWSER_CORE_SCHEMA>. Cookie-option fields (useSecureSessionCookie, etc.) are moved into the schema. buildCookieOptions now takes a typed CookieConfiguration rather than raw init config.
  • browser-logs: Replace LogsConfiguration interface and imperative validation with LOGS_SCHEMA that spreads BROWSER_CORE_SCHEMA and adds forwardErrorsToLogs, forwardConsoleLogs, forwardReports, and requestErrorResponseLengthLimit.
  • browser-rum-core: Same pattern — RUM_SCHEMA spreads BROWSER_CORE_SCHEMA and adds all RUM-specific fields.

Test instructions

yarn test:unit
yarn typecheck
yarn lint

Checklist

  • Tested locally
  • Tested on staging
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated documentation and/or relevant AGENTS.md file

@datadog-prod-us1-3

datadog-prod-us1-3 Bot commented Jun 17, 2026

Copy link
Copy Markdown

Pipelines

Fix all issues with BitsAI

⚠️ Warnings

🚦 14 Pipeline jobs failed

DataDog/browser-sdk | build-and-lint   View in Datadog   GitLab

DataDog/browser-sdk | build-bundle   View in Datadog   GitLab

DataDog/browser-sdk | bundle-size   View in Datadog   GitLab

View all 14 failed jobs.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 65e5aaf | Docs | Datadog PR Page | Give us feedback!

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jun 17, 2026

Copy link
Copy Markdown

Bundles Sizes Evolution

📦 Bundle Name Base Size Local Size 𝚫 𝚫% Status
Rum 172.37 KiB 173.13 KiB +778 B +0.44%
Rum Profiler 8.01 KiB 8.01 KiB 0 B 0.00%
Rum Recorder 21.09 KiB 21.09 KiB 0 B 0.00%
Logs 54.43 KiB 55.51 KiB +1.08 KiB +1.98%
Rum Slim 129.94 KiB 130.73 KiB +818 B +0.61%
Worker 22.96 KiB 22.96 KiB 0 B 0.00%

@thomas-lebeau thomas-lebeau force-pushed the worktree-js-core-configuration branch 5 times, most recently from 4db0705 to f78a2c8 Compare June 18, 2026 12:44
Adds @datadog/js-core/configuration — a runtime-agnostic engine that
validates and builds typed configuration objects from a declarative schema.

Field types: string, percentage, boolean, site (Datadog domain regex),
match-option (string | RegExp | function), enum (array or object form),
custom (arbitrary validator). The multiple: true modifier normalizes a
single value to a singleton array then validates each item.

The INVALID sentinel lets validators fail the whole config rather than
fall back to a default. InferredConfig<S> derives a precise TypeScript type
from the schema so Configuration types can never drift from their validation.

An optional display function can be passed to validateAndBuildConfiguration;
each field definition may carry an errorMessage string that the engine
passes to display when that field's value is invalid.
Replaces the hand-written Configuration interface and per-field validators
with a declarative BROWSER_CORE_SCHEMA. Configuration is now inferred via
InferredConfig<typeof BROWSER_CORE_SCHEMA> — impossible to drift.

Key changes:
- validateAndBuildConfiguration is now a thin wrapper: passes display.error
  to the schema engine so all field errorMessages surface as display.error calls
- trackingConsent uses the object-form enum (INVALID on explicit invalid value)
- source uses the array-form enum (defaults to 'browser' on invalid/missing)
- sessionPersistence uses enum + multiple: true, normalising 'cookie' → ['cookie']
- allowedTrackingOrigins uses match-option + multiple: true
- cookieOptions removed from Configuration; the three boolean flags it was
  derived from are now first-class schema fields
- BROWSER_CORE_SCHEMA exported so browser-logs and browser-rum-core can extend it
…ation

validateAndBuildConfiguration is now a pure schema call with no side effects.
Two runtime checks that needed browser context move to their natural homes:

- isAllowedTrackingOrigins: moved to preStartLogs/preStartRum (init layer).
  Signature updated to accept Configuration directly. errorStack parameter
  removed from validateAndBuild* — it was only threaded through to reach
  isAllowedTrackingOrigins.

- buildCookieOptions: moved out of validateAndBuildConfiguration return value.
  sessionInCookie.ts now calls buildCookieOptions(configuration) directly.
  Signature updated to accept the three boolean fields from Configuration.

- sessionStore: normalizePersistenceList simplified — sessionPersistence is
  always SessionPersistence[] | undefined after schema validation.
Extends BROWSER_CORE_SCHEMA with three logs-specific fields:

- forwardErrorsToLogs: boolean, default true
- forwardConsoleLogs: custom validator (undefined → [], 'all' → all values,
  valid array → deduped, invalid → INVALID)
- forwardReports: same pattern as forwardConsoleLogs

LogsConfiguration is now InferredConfig<typeof LOGS_SCHEMA> & { requestErrorResponseLengthLimit }.
validateAndBuildLogsConfiguration reduces to: schema call + constant field.
Extends BROWSER_CORE_SCHEMA with ~20 RUM-specific fields covering sample
rates, booleans, enums (defaultPrivacyLevel, traceContextInjection), arrays
(excludedActivityUrls, plugins, trackFeatureFlagsForEvents), and passthroughs.

RumConfiguration is InferredConfig<typeof RUM_SCHEMA> with four additions that
require post-schema computation:
- startSessionReplayRecordingManually: conditional default on sessionReplaySampleRate
- rulePsr: derived from traceSampleRate
- allowedTracingUrls / trackResourceHeaders / allowedGraphQlUrls: complex
  normalization helpers stay unchanged

errorStack removed from validateAndBuildRumConfiguration signature — it was
only threaded through to isAllowedTrackingOrigins, which now lives in the
boot layer.
@thomas-lebeau thomas-lebeau force-pushed the worktree-js-core-configuration branch from f78a2c8 to 8341a2a Compare June 18, 2026 12:53
- Replace CustomField/INVALID sentinel with UnionField, SchemaField, and
  FunctionField types for cleaner type-safe field definitions
- Replace per-field errorMessage with auto-generated error messages and
  a strict: false flag for backward-compatible validation fallback
- Extract buildCookieOptions/CookieConfiguration from browser-core
  configuration.ts into cookie.ts
- Remove validateAndBuildConfiguration, isSampleRate, and buildCookieOptions
  from browser-core (now in js-core or cookie.ts)
- Update browser-core, browser-logs, and browser-rum-core schemas to use
  the new field types (union, schema, function)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant