···2626 [publication and resolution spec](https://atproto.com/specs/lexicon#lexicon-publication-and-resolution).
2727- `mix atex.lexicons.resolve` task for resolving one or more lexicons by NSID
2828 and writing to a JSON file.
2929+- Sigils for `Atex.AtURI` and `Atex.TID`, `~AT"at://..."` and `~TID"..."`
3030+ respectively.
29313032## [0.8.0] - 2026-03-29
3133
+34
lib/atex/aturi.ex
···140140 |> String.trim_trailing("/")
141141 end
142142143143+ @doc """
144144+ Sigil for constructing an `Atex.AtURI` struct from a string literal.
145145+ Raises `ArgumentError` if the string is not a valid `at://` URI.
146146+147147+ ## Examples
148148+149149+ iex> import Atex.AtURI
150150+ iex> ~AT"at://did:plc:44ybard66vv44zksje25o7dz/app.bsky.feed.post/3jwdwj2ctlk26"
151151+ ~AT"at://did:plc:44ybard66vv44zksje25o7dz/app.bsky.feed.post/3jwdwj2ctlk26"
152152+153153+ """
154154+ defmacro sigil_AT({:<<>>, _meta, [value]}, _modifiers) when is_binary(value) do
155155+ case Atex.AtURI.new(value) do
156156+ {:ok, uri} ->
157157+ Macro.escape(uri)
158158+159159+ :error ->
160160+ raise ArgumentError, "invalid at:// URI: #{inspect(value)}"
161161+ end
162162+ end
163163+164164+ defmacro sigil_AT({:<<>>, _meta, _parts} = ast, _modifiers) do
165165+ quote do
166166+ case Atex.AtURI.new(unquote(ast)) do
167167+ {:ok, uri} -> uri
168168+ :error -> raise ArgumentError, "invalid at:// URI: #{inspect(unquote(ast))}"
169169+ end
170170+ end
171171+ end
172172+143173 defp from_named_captures(%{"authority" => authority, "collection" => "", "rkey" => ""}),
144174 do: %__MODULE__{authority: authority}
145175···157187defimpl String.Chars, for: Atex.AtURI do
158188 def to_string(uri), do: Atex.AtURI.to_string(uri)
159189end
190190+191191+defimpl Inspect, for: Atex.AtURI do
192192+ def inspect(uri, _opts), do: ~s(~AT"#{Atex.AtURI.to_string(uri)}")
193193+end
+35
lib/atex/tid.ex
···182182 """
183183 @spec match?(String.t()) :: boolean()
184184 def match?(value), do: Regex.match?(@re, value)
185185+186186+ @doc """
187187+ Sigil for constructing a `Atex.TID` struct from a string literal at
188188+ compile-time or runtime. Raises `ArgumentError` if the string is not a valid
189189+ TID.
190190+191191+ ## Examples
192192+193193+ iex> import Atex.TID
194194+ iex> ~TID"3jzfcijpj2z2a"
195195+ ~TID"3jzfcijpj2z2a"
196196+197197+ """
198198+ defmacro sigil_TID({:<<>>, _meta, [value]}, _modifiers) when is_binary(value) do
199199+ case Atex.TID.decode(value) do
200200+ {:ok, tid} ->
201201+ Macro.escape(tid)
202202+203203+ :error ->
204204+ raise ArgumentError, "invalid TID: #{inspect(value)}"
205205+ end
206206+ end
207207+208208+ defmacro sigil_TID({:<<>>, _meta, _parts} = ast, _modifiers) do
209209+ quote do
210210+ case Atex.TID.decode(unquote(ast)) do
211211+ {:ok, tid} -> tid
212212+ :error -> raise ArgumentError, "invalid TID: #{inspect(unquote(ast))}"
213213+ end
214214+ end
215215+ end
185216end
186217187218defimpl String.Chars, for: Atex.TID do
188219 def to_string(tid), do: Atex.TID.encode(tid)
189220end
221221+222222+defimpl Inspect, for: Atex.TID do
223223+ def inspect(tid, _opts), do: ~s(~TID"#{Atex.TID.encode(tid)}")
224224+end