Current section
Files
Jump to
Current section
Files
atproto_codegen
README.md
README.md
# atproto_codegen
> **Alpha, pre-release.** Pre-1.0 and evolving alongside
> [at-record](https://tangled.org/@mokkenstorm.dev/at-record); expect breaking
> changes between 0.x releases.
Generate Gleam types, JSON codecs, and a typed XRPC client from
[atproto lexicon](https://atproto.com/specs/lexicon) files. Parses through the
full-fidelity [`atproto_lexicon`](https://hex.pm/packages/atproto_lexicon)
AST, lowers to a codegen-friendly view, and runs a small plugin pipeline
(`types`, `decode-json`, optional `xrpc-client`) over it. Unsupported defs are
reported and skipped, never emitted wrong.
## Usage
```sh
gleam run -m atproto_codegen -- <lexicons_dir> <out_dir> <out_module> <nsid_prefix>[,...] [client_module]
# types + codecs only:
gleam run -m atproto_codegen -- ./lexicons ./src/my_app/gen my_app/gen com.example.myapp.,com.atproto.
# additionally generate a typed XRPC client module:
gleam run -m atproto_codegen -- ./lexicons ./src/my_app/gen my_app/gen com.example.myapp.,com.atproto. client
```
- `lexicons_dir` is walked recursively for `*.json` lexicon files. Vendor any
external lexicons you reference (e.g. `com.atproto.repo.strongRef`) into it.
- `out_module` is the module prefix the generated code imports itself under;
it must match where `out_dir` sits in your `src/`.
- `nsid_prefixes` are stripped from NSIDs when deriving module paths, so
`com.example.myapp.shelf.entry` emits `<out_dir>/shelf/entry.gleam`.
- `client_module` (optional) enables the `xrpc-client` plugin: one module of
typed query/procedure functions over
[`atproto_client`](https://hex.pm/packages/atproto_client)'s primitives,
with a params record, generated encoders/decoders, and a per-method error
union (one variant per lexicon-declared error plus transport/unknown
catch-alls). Omit it and output is exactly the pre-0.2 shape.
The generated client requires `atproto_client >= 0.2.0`: it constructs its
xrpc error variants (`RequestFailed`, `DecodeFailed`, `BadStatus`) through
`atproto_core/xrpc`, which has owned them since that release. Add both
`atproto_client` and `atproto_core` as direct dependencies, since the
generated module imports each.
Generated `blob` fields use `atproto/blob` from `atproto_client`, so projects
consuming generated code with blobs need that dependency.
## Lexicon coverage
`record` and `object` defs for codecs; `query` and `procedure` defs for the
client plugin (subscriptions are skipped). Refs resolve across lexicons (a
bare NSID ref points at that lexicon's `main` def). `knownValues` string sets
map to plain `String`; `unknown` round-trips through a `Dynamic` passthrough.