Validates and canonicalizes Letterpress variable schemas.
A schema declares every template variable's type, phase, output context, required/default behavior, description, and sensitivity. Object and list definitions may describe nested values. The normalized form is deliberately JSON-native so it can cross runtimes without serializing Elixir terms.
Atom keys are accepted at the Elixir boundary. Normalization converts them to strings, fills contract defaults, sorts variables, and rejects unknown fields or values that do not match the generated contract.
Example
iex> schema = %{version: 1, variables: %{name: %{type: "string"}}}
iex> {:ok, normalized} = Letterpress.Schema.normalize(schema)
iex> definition = normalized["variables"]["name"]
iex> {definition["phase"], definition["context"], definition["required"]}
{"delivery", "text", true}
Summary
Functions
Returns the lowercase SHA-256 digest of a normalized schema.
Normalizes a version-1 schema or returns diagnostics.
Functions
Returns the lowercase SHA-256 digest of a normalized schema.
Call normalize/1 first when the map came from an external caller. This
function hashes the value it receives and does not validate it again.
Example
iex> schema = %{"version" => 1, "variables" => %{}}
iex> byte_size(Letterpress.Schema.hash(schema))
64
@spec normalize(map()) :: {:ok, map()} | {:error, [Letterpress.Diagnostic.t()]}
Normalizes a version-1 schema or returns diagnostics.
Successful output has exactly the "version" and "variables" top-level
keys. Expected user-authored failures return one or more
Letterpress.Diagnostic structs rather than raising.
Example
iex> {:error, [diagnostic]} =
...> Letterpress.Schema.normalize(%{"version" => 2, "variables" => %{}})
iex> diagnostic.code
"LP_SCHEMA_VERSION"