nori

OpenAPI library for Gleam.

Supports OpenAPI 3.0.x and 3.1.x. Provides:

Quick Start

Parsing an OpenAPI document

import nori

pub fn main() {
  let json = "{\"openapi\": \"3.1.0\", \"info\": {\"title\": \"My API\", \"version\": \"1.0.0\"}}"
  let assert Ok(doc) = nori.parse_json(json)
  io.println("API: " <> doc.info.title)
}

Building an OpenAPI document

import nori
import nori/document
import nori/paths
import nori/operation
import nori/server

pub fn main() {
  let doc =
    document.v3_1_0("My API", "1.0.0")
    |> document.add_server(server.new("https://api.example.com"))
    |> document.add_path("/users", paths.get(operation.with_id("listUsers")))

  let json = nori.to_json(doc)
}

Types

Error types for parsing OpenAPI documents.

pub type ParseError {
  JsonParseError(message: String)
  DecodeError(errors: List(decode.DecodeError))
  UnsupportedVersion(version: String)
}

Constructors

  • JsonParseError(message: String)

    JSON parsing failed

  • DecodeError(errors: List(decode.DecodeError))

    Document decoding failed

  • UnsupportedVersion(version: String)

    Unsupported OpenAPI version

Values

pub fn api_version(doc: document.Document) -> String

Gets the version from an OpenAPI document’s info.

pub fn build_ir(doc: document.Document) -> ir.CodegenIR

Build a language-agnostic codegen intermediate representation from a parsed document.

CodegenIR is the contract between the parser and any code generator (built-in Gleam/TypeScript, or third-party satellite packages). Walk it directly to drive your own emitters.

Examples

let assert Ok(doc) = nori.parse_file("api.yaml")
let codegen_ir = nori.build_ir(doc)
// pass codegen_ir to your own generator
pub fn check_capabilities(
  doc: document.Document,
) -> Result(document.Document, List(capability.Issue))

Walk a parsed document and collect any OpenAPI features nori does not yet support. Returns the document unchanged when nothing is flagged, otherwise a list of Issues sorted with blocking severity first.

Use this before build_ir if you want to fail fast instead of producing degraded codegen output.

Examples

let assert Ok(doc) = nori.parse_file("api.yaml")
case nori.check_capabilities(doc) {
  Ok(_) -> generate(doc)
  Error(issues) -> {
    list.each(issues, fn(i) { io.println(capability.issue_to_string(i)) })
  }
}
pub fn parse_file(
  path: String,
) -> Result(document.Document, ParseError)

Loads and parses an OpenAPI spec file (YAML or JSON).

Detects format by file extension (.yaml/.yml → YAML, .json → JSON).

Examples

let assert Ok(doc) = nori.parse_file("./nori.yaml")
pub fn parse_json(
  input: String,
) -> Result(document.Document, ParseError)

Parses an OpenAPI document from a JSON string.

Examples

let json = "{ \"openapi\": \"3.1.0\", \"info\": { \"title\": \"My API\", \"version\": \"1.0.0\" } }"
let assert Ok(doc) = nori.parse_json(json)
pub fn parse_schema(
  dyn: dynamic.Dynamic,
) -> Result(schema.Schema, List(decode.DecodeError))

Decode a single JSON Schema fragment into nori’s Schema type.

Stable seam for satellite generators (e.g. AsyncAPI) that carry their own spec structure but whose payloads are plain JSON Schema. Feed the decoded Schema to schema_to_typedef / schema_to_typeref to reach the IR.

Examples

let assert Ok(dyn) = json.parse(payload_json, decode.dynamic)
let assert Ok(s) = nori.parse_schema(dyn)
pub fn parse_yaml(
  input: String,
) -> Result(document.Document, ParseError)

Parses an OpenAPI document from a YAML string.

Examples

let yaml = "openapi: '3.1.0'\ninfo:\n  title: My API\n  version: '1.0.0'"
let assert Ok(doc) = nori.parse_yaml(yaml)
pub fn schema_to_typedef(
  name: String,
  s: schema.Schema,
) -> ir.TypeDef

Convert a named Schema into a codegen TypeDef — the same record / enum / union / alias the built-in generators consume. Use for top-level named schemas (message payloads, component schemas).

pub fn schema_to_typeref(s: schema.Schema) -> ir.TypeRef

Convert a Schema into a TypeRef — the field-level reference form (named ref, primitive, array, nullable, …). Use for inline / property schemas.

pub fn spec_version(doc: document.Document) -> String

Gets the OpenAPI specification version as a string.

pub fn title(doc: document.Document) -> String

Gets the title from an OpenAPI document.

pub fn to_json(doc: document.Document) -> String

Serializes an OpenAPI document to a JSON string.

Examples

let json = nori.to_json(doc)
pub fn to_json_pretty(doc: document.Document) -> String

Serializes an OpenAPI document to a pretty-printed JSON string.

Examples

let json = nori.to_json_pretty(doc)
Search Document