//// 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 -- [--title T] /// [--version V] [--server URL]`. See `atproto_openapi/cli`. pub fn main() -> Nil { cli.main() }