Parses ATProto lexicon JSON files into a normalized schema IR.
Unlike a flat extractor, this walks schema nodes recursively, preserving every node type the lexicon spec defines:
- Primitives:
string(withformat/maxLength/maxGraphemes/enum),integer(minimum/maximum),boolean,bytes,unknown - Containers:
object(properties/required),array(items) - Links:
ref(#def,nsid,nsid#def),union(refs),cid-link,blob - Records:
record(key+ embedded object)
Nodes are plain maps tagged with :kind. Refs are kept symbolic; the
generator resolves them against the full set of parsed lexicons.
Examples
{:ok, lexicons} = Parser.parse_dir("priv/lexicons")
%{id: "app.bsky.feed.post", defs: %{"main" => %{kind: :record, ...}}} =
lexicons["app.bsky.feed.post"]
Summary
Functions
Parse a decoded lexicon JSON map.
Parse every lexicon JSON file under dir (recursively).
Parse a single lexicon JSON file.
Parse a single schema node (e.g. an XRPC parameters block or a
property) into the IR. Public for the endpoint generator.
Types
@type lexicon() :: %{ id: String.t(), description: String.t() | nil, defs: %{required(String.t()) => schema_node()} }
@type node_kind() ::
:string
| :token
| :integer
| :boolean
| :bytes
| :unknown
| :cid_link
| :blob
| :array
| :object
| :record
| :ref
| :union
| :params
| :query
| :procedure
| :permission_set
| :subscription
Functions
Parse a decoded lexicon JSON map.
Parse every lexicon JSON file under dir (recursively).
Returns {:ok, %{nsid => lexicon}} or {:error, {path, reason}} for the
first file that fails.
Parse a single lexicon JSON file.
@spec parse_schema_node(map()) :: {:ok, schema_node()} | {:error, term()}
Parse a single schema node (e.g. an XRPC parameters block or a
property) into the IR. Public for the endpoint generator.