Registering, type-checking, and publishing lexicons.
This module is the entry point for the lexicon workflow; the pieces live in their own modules:
Lexicon.Parser— lexicon JSON → normalized IRLexicon.Schema— thecom.atproto.lexicon.schemarecord typeLexicon.Validator— runtime validation of values against schemasLexicon.Registry— runtime NSID → lexicon registryLexicon.Resolver— fetching published lexicons from a PDSLexicon.Generator+mix exosphere.gen.lexicons— compile-time typed modules
The workflow
# 1. Define (or fetch) a lexicon document
{:ok, schema} = Exosphere.Lexicon.Schema.new(%{
"lexicon" => 1,
"id" => "com.example.post",
"defs" => %{"main" => %{
"type" => "record", "key" => "tid",
"record" => %{"type" => "object",
"required" => ["text"],
"properties" => %{"text" => %{"type" => "string", "maxGraphemes" => 100}}}
}}
})
# 2. Type-check records against it — now, and at runtime
:ok = Exosphere.Lexicon.register(schema)
:ok = Exosphere.Lexicon.validate("com.example.post", %{
"$type" => "com.example.post", "text" => "hello"
})
# 3. Publish it to a PDS (record key = the NSID)
{:ok, %{uri: uri, cid: cid}} =
Exosphere.Lexicon.publish(session, pds_url, did, schema)Publishing and updating
publish/4 writes to com.atproto.lexicon.schema with the lexicon's
NSID as the record key, so publishing an updated document for the same
NSID overwrites the previous version.
Summary
Functions
Delete a published lexicon record by NSID.
Publish a lexicon to a PDS as a com.atproto.lexicon.schema record.
Register a lexicon (parsed, or a raw JSON document) in the runtime
Lexicon.Registry. See Exosphere.Lexicon.Registry.register/1.
Register many lexicons at once. See Exosphere.Lexicon.Registry.register_all/1.
Type-check a value against a registered lexicon.
Type-check a value against a schema without registering it.
Functions
Delete a published lexicon record by NSID.
Like publish/2, delete(session, nsid) reads the PDS URL and DID
from the session.
@spec publish(map(), Exosphere.Lexicon.Schema.t() | map()) :: {:ok, %{uri: String.t(), cid: String.t()}} | {:error, term()}
Publish a lexicon to a PDS as a com.atproto.lexicon.schema record.
publish(session, schema) takes the PDS URL and DID from the session
(session.pds / session.sub); publish(session, pds_url, did, schema) overrides them explicitly.
The record key is the lexicon's NSID, so the record lands at
at://<did>/com.atproto.lexicon.schema/<nsid> and re-publishing an
updated document updates it in place.
Register a lexicon (parsed, or a raw JSON document) in the runtime
Lexicon.Registry. See Exosphere.Lexicon.Registry.register/1.
Register many lexicons at once. See Exosphere.Lexicon.Registry.register_all/1.
Type-check a value against a registered lexicon.
type is an NSID or NSID with fragment; value is the wire-format
map. Options are forwarded to Validator.validate/4 (notably
strict: true to reject unknown fields, open-union variants, and
refs whose target lexicon is not registered).
See Exosphere.Lexicon.Registry.validate/3.
@spec validate_with( Exosphere.Lexicon.Schema.t() | Exosphere.Lexicon.Parser.lexicon(), term(), String.t(), [Exosphere.Lexicon.Validator.opt()] ) :: :ok | {:error, [{path :: String.t(), message :: String.t()}]}
Type-check a value against a schema without registering it.
Takes a %Lexicon.Schema{} (or its parsed IR) — for checking a
fetched document without touching global registry state. Options are
forwarded to Validator.validate/4.