Exosphere.Bsky.Runtime (Exosphere v0.6.0)

Copy Markdown View Source

Shared runtime helpers used by the generated Exosphere.Bsky.* modules.

This module is hand-written, not generated. It provides the coercion and validation primitives that generated record modules call with their lexicon-derived constraints, so the generated files stay lean.

All validators return {value, errors} where errors is a list of {field_path, message} tuples. nil values for optional fields are skipped (or replaced by the lexicon default).

Summary

Functions

Split a wire-format map into known atom-keyed attrs and unknown extras.

Encode validated params (atom- or string-keyed map) into string values suitable for an XRPC query string: booleans and integers become strings, arrays are comma-joined, nil values are dropped.

Fetch a field of any shape (unknown, blob, cid-link, bytes, unresolved ref).

Fetch and validate an array field, checking each item with item_fn.

Fetch and validate a boolean field.

Fetch and validate an integer field.

Fetch a field referencing another lexicon object.

Fetch and validate a string field.

Fetch a union field. variants is a list of {nsid, module} pairs.

Validate one ref item: struct of mod or a map coerced through mod.new/1.

Validate one string item; opts as for get_string/4 constraints.

Validate one union item against known variants.

Put a field into the wire map, skipping nil values.

Put an encoded field into the wire map, skipping nil values.

Validate a single union value against known variants.

Types

error()

@type error() :: {String.t(), String.t()}

Functions

atomize(attrs, fields)

@spec atomize(map() | keyword(), %{required(atom()) => String.t()}) :: {map(), map()}

Split a wire-format map into known atom-keyed attrs and unknown extras.

Accepts atom or string keys. String keys are translated through fields (atom key => wire name); "$type" is dropped; unknown keys land in extra keyed by their original string name.

encode_query_params(params, fields \\ %{})

@spec encode_query_params(map(), %{required(atom()) => String.t()}) :: %{
  required(String.t()) => String.t()
}

Encode validated params (atom- or string-keyed map) into string values suitable for an XRPC query string: booleans and integers become strings, arrays are comma-joined, nil values are dropped.

get_any(attrs, key, path, opts \\ [])

@spec get_any(map(), atom(), String.t(), keyword()) :: {term(), [error()]}

Fetch a field of any shape (unknown, blob, cid-link, bytes, unresolved ref).

get_array(attrs, key, path, opts, item_fn)

@spec get_array(map(), atom(), String.t(), keyword(), (term(), String.t() ->
                                                   {:ok, term()}
                                                   | {:error, String.t()})) ::
  {term(), [error()]}

Fetch and validate an array field, checking each item with item_fn.

item_fn receives (value, path) and returns {:ok, value} or {:error, message}.

get_boolean(attrs, key, path, opts \\ [])

@spec get_boolean(map(), atom(), String.t(), keyword()) :: {term(), [error()]}

Fetch and validate a boolean field.

get_integer(attrs, key, path, opts \\ [])

@spec get_integer(map(), atom(), String.t(), keyword()) :: {term(), [error()]}

Fetch and validate an integer field.

get_ref(attrs, key, path, opts, mod)

@spec get_ref(map(), atom(), String.t(), keyword(), module()) :: {term(), [error()]}

Fetch a field referencing another lexicon object.

Accepts a struct built by mod/new/1 directly, or a map which is coerced through mod.new/1.

get_string(attrs, key, path, opts \\ [])

@spec get_string(map(), atom(), String.t(), keyword()) :: {term(), [error()]}

Fetch and validate a string field.

get_union(attrs, key, path, opts, variants)

@spec get_union(map(), atom(), String.t(), keyword(), [{String.t(), module()}]) ::
  {term(), [error()]}

Fetch a union field. variants is a list of {nsid, module} pairs.

Discriminates on $type for maps; unknown $types pass through as maps (unions are open-world). Structs of a known variant module pass as-is.

item_ref(value, path, mod)

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

Validate one ref item: struct of mod or a map coerced through mod.new/1.

item_string(value, path, opts)

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

Validate one string item; opts as for get_string/4 constraints.

item_union(value, path, variants, closed \\ false)

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

Validate one union item against known variants.

put_field(map, name, value)

@spec put_field(map(), String.t(), term()) :: map()

Put a field into the wire map, skipping nil values.

put_field(map, name, value, encoder)

@spec put_field(map(), String.t(), term(), (term() -> term())) :: map()

Put an encoded field into the wire map, skipping nil values.

union_item(value, path, variants, closed \\ false)

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

Validate a single union value against known variants.