Docket.Schema (docket v0.1.0-dev)

Copy Markdown View Source

Serializable schema IR used by graph fields and node contracts.

validate/2 implements the validation engine used by the compiler for field defaults and node config, and later by the runtime for input payloads and state writes.

Types

:string, :float (accepts any number), :integer, :boolean, :map (any string-keyed map), :object (declared fields), :enum (closed value set), and :list (per-item schema in item).

Constraints

Constraints are stored as a string-keyed map (the constructors normalize atom option keys) and enforced by validate/2:

  • numbers (:float, :integer) — min, max (inclusive)
  • strings — min_length, max_length, pattern (Elixir/PCRE regex source string)
  • lists — min_items, max_items

Unknown constraint keys are stored but ignored. Objects accept an open: true option (stored in constraints) that permits unknown keys; by default unknown object keys are rejected.

Shorthand

Everywhere the constructors and the graph editing API expect a schema, terse literals normalize (via normalize/1) into real schemas:

:string                          # bare primitive type
{:integer, min: 0}               # type + options
{:list, :string}                 # list + item shorthand
{:list, :string, max_items: 10}
{:enum, ["low", "high"]}
{:object, %{"name" => :string}, open: true}

Object field values and list items normalize recursively, so Docket.Schema.object(%{age: {:integer, min: 0}, tags: {:list, :string}}) is fully shorthand. Values that match no shorthand pass through unchanged and are reported by the compiler.

Summary

Types

primitive_type()

@type primitive_type() :: :boolean | :float | :integer | :map | :string

t()

@type t() :: %Docket.Schema{
  constraints: map(),
  default: term(),
  fields: %{optional(String.t() | atom()) => t()},
  item: t() | nil,
  metadata: map(),
  required: boolean(),
  type: type(),
  values: [term()]
}

type()

@type type() :: primitive_type() | :enum | :list | :object

Functions

boolean(opts \\ [])

@spec boolean(keyword()) :: t()

enum(values, opts \\ [])

@spec enum(
  [term()],
  keyword()
) :: t()

float(opts \\ [])

@spec float(keyword()) :: t()

integer(opts \\ [])

@spec integer(keyword()) :: t()

list(item, opts \\ [])

@spec list(
  t() | term(),
  keyword()
) :: t()

map(opts \\ [])

@spec map(keyword()) :: t()

normalize(schema)

@spec normalize(term()) :: term()

Normalizes schema shorthand (see the module documentation) into a Docket.Schema struct.

Real schemas and values matching no shorthand pass through unchanged; the compiler reports the latter as invalid schemas.

object(fields, opts \\ [])

@spec object(
  map(),
  keyword()
) :: t()

string(opts \\ [])

@spec string(keyword()) :: t()

validate(schema, value)

@spec validate(t(), term()) :: :ok | {:error, [String.t()]}

Validates a value against a schema.

Checks primitive types, enum membership, required object fields, unknown object keys (unless the object is open), list items against item, and the stored constraints listed in the module documentation. nil is valid unless the schema is required.

Returns :ok or {:error, reasons} with human-readable reason strings.