Selecto.Domain (Selecto v0.4.6)

Copy Markdown

Compatibility-safe normalization entry point for Selecto domains.

This module does not participate in Selecto.configure/3 yet. It provides a read-only normalization boundary for callers that want a stable, diagnostic view of authored domain maps while existing runtime behavior remains unchanged.

Summary

Functions

compose(domain, overlays \\ [])

@spec compose(term(), term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}

Composes an authored domain with one or more domain overlays.

This is the Stage 2 composition boundary. It is opt-in and does not participate in Selecto.configure/3 yet. Composition uses explicit, deterministic merge semantics:

  • maps deep-merge by section
  • redact_fields, including source.redact_fields, are unioned
  • extensions are appended uniquely
  • other lists and scalar values are replaced by later overlays

After overlays are merged, declared extension merge_domain/2 callbacks are applied in declaration order and the result is normalized again.

describe(normalized)

@spec describe(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}

Returns structured inspection output for an authored or normalized domain.

The inspection map is intentionally compact and deterministic so generators, Studio, docs, and tests can reason about the normalized contract without walking the whole domain map directly.

domain_fingerprint(domain)

domain_fingerprint?(value)

domain_version(domain)

domain_version?(value)

invalid_schema_version_warning(version)

invalid_section_shape_warning(section, expected, value)

maybe_put_domain_fingerprint(domain, domain_fingerprint)

maybe_put_domain_version(domain, domain_version)

name?(value)

normalize(domain)

@spec normalize(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}

Normalizes an authored domain map into a compatibility-safe contract.

The normalizer currently:

  • infers schema_version as 1 when it is missing
  • preserves optional domain_version metadata as an opaque authored-domain version label
  • preserves optional domain_fingerprint metadata as an opaque authored-domain content identity label
  • expands supported field-level choice-source shorthand into canonical source_relationships, choice_sources, and field reference bindings
  • classifies authored top-level sections as canonical, projection, proposed, or unknown
  • exposes current query, write, action, capability, relationship, and choice registries without rewriting existing runtime behavior

Returns {:ok, normalized, diagnostics} for maps and {:error, diagnostics} for non-map inputs.

normalize_schema_version(version)

normalized_domain(authored_domain, canonical_domain, schema_version, domain_version, domain_fingerprint, sections)

parse_schema_version(version)

project(normalized, projection)

@spec project(map(), :query | :write | :ui | :api | :query_contract) :: map()

Projects a normalized domain into a read-only consumer view.

Projection helpers are intentionally conservative in this slice. They reshape the normalized map for future consumers, but no existing runtime path calls them yet.

Supported projections:

  • :query - query/runtime-facing sections
  • :write - write/action/reference sections
  • :ui - display defaults, choices, actions, and detail actions
  • :api - read/write/action contract for API-style consumers
  • :query_contract - constrained query metadata for tools, Components, and AI

query_contract(normalized)

@spec query_contract(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}

Returns the constrained query contract projection for an authored or normalized domain.

This is a convenience wrapper around normalize/1 and project(normalized, :query_contract) for Components, AI tooling, and other consumers that should not need to walk the normalized domain map directly.

schema_version(domain)

section_shape_warnings(domain)

shape_warnings(domain, sections, expected, valid?)

unsupported_schema_version_warning(version)

validate(domain)

@spec validate(term()) ::
  {:ok, map(), Selecto.Domain.Diagnostics.t()}
  | {:error, Selecto.Domain.Diagnostics.t()}

Normalizes an authored domain and validates it against the first-wave canonical contract.

This is still a compatibility-safe entry point: it does not participate in Selecto.configure/3 unless a caller opts in elsewhere.