Current section
Files
Jump to
Current section
Files
src/atproto_openapi.gleam
//// Public API: turn a set of parsed `atproto_lexicon/ast.LexiconDoc`
//// values into a single OpenAPI 3.1.0 document. See
//// `docs/lexicon-openapi.md` for the mapping this implements and
//// `atproto_openapi/emit` for the assembly logic this delegates to.
//// `main` runs the CLI (`atproto_openapi/cli`), which walks a directory of
//// lexicon JSON files and writes the generated document to disk.
import atproto_lexicon/ast.{type LexiconDoc}
import atproto_openapi/cli
import atproto_openapi/emit
import atproto_openapi/refs
import gleam/json
import gleam/result
/// Per-run document metadata. A CLI invocation fills this from flags with
/// sane defaults; a library caller builds it directly.
pub type Options {
Options(title: String, version: String, servers: List(String))
}
pub type Generated {
Generated(
json: String,
operation_count: Int,
schema_count: Int,
subscriptions_skipped: List(String),
)
}
pub type Error {
RefError(refs.RefError)
}
/// Assemble `docs` into one OpenAPI 3.1.0 document. Fails only when a ref
/// is malformed or two distinct lexicon refs derive the same
/// `components/schemas` key; see `atproto_openapi/refs`. Every other input
/// shape has a defined mapping per the design doc.
pub fn generate(
docs: List(LexiconDoc),
options: Options,
) -> Result(Generated, Error) {
emit.assemble(docs, options.title, options.version, options.servers)
|> result.map(fn(document) {
Generated(
json: json.to_string(document.json),
operation_count: document.operation_count,
schema_count: document.schema_count,
subscriptions_skipped: document.subscriptions_skipped,
)
})
|> result.map_error(RefError)
}
/// `gleam run -m atproto_openapi -- <lexicons-dir> <out-file> [--title T]
/// [--version V] [--server URL]`. See `atproto_openapi/cli`.
pub fn main() -> Nil {
cli.main()
}