AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
A C++ CLI for generating source code from OpenAPI specifications with JavaScript and Inja templates.
Developer toolsJavaScript · C++GitHub @openapi-yagenOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Yet another OpenAPI generator
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
title: openapi-yagen overview
sidebar_label: Overview and CLI
slug: /docs/overview
description: Install openapi-yagen, explore its features, and use the generate and convert commands.Read the full README ↗Main features:
curl tool is required.convert below, and
generator-format.md)Statically-linked binaries are published on the
releases page: openapi-yagen for
Linux x86_64, openapi-yagen-linux-arm64 for Linux arm64, and openapi-yagen-macos (a universal
binary - runs on both Intel and Apple Silicon Macs). Install one to ~/.local/bin - the standard
per-user executable location (see
file-hierarchy(7)),
already on PATH on most modern distributions - no root/sudo needed:
mkdir -p ~/.local/bin && curl -L https://github.com/openapi-yagen/openapi-yagen/releases/latest/download/openapi-yagen -o ~/.local/bin/openapi-yagen && chmod +x ~/.local/bin/openapi-yagen
If ~/.local/bin isn't already on your PATH, add this to your shell's startup file (e.g.
~/.bashrc, ~/.zshrc) and restart your shell:
export PATH="$HOME/.local/bin:$PATH"
Grab the universal binary instead, and clear its quarantine flag - it isn't code-signed or notarized (no Apple Developer account behind this project), so Gatekeeper otherwise refuses to run it:
mkdir -p ~/.local/bin && curl -L https://github.com/openapi-yagen/openapi-yagen/releases/latest/download/openapi-yagen-macos -o ~/.local/bin/openapi-yagen && chmod +x ~/.local/bin/openapi-yagen && xattr -d com.apple.quarantine ~/.local/bin/openapi-yagen
Unlike on Linux, ~/.local/bin is never on PATH by default on macOS - don't skip the export PATH step above (/usr/local/bin, the one macOS location that is on PATH out of the box, is
normally root-owned and needs sudo to write to, unless Homebrew already claimed it).
Or skip both the quarantine step and the PATH setup with the Docker image below.
A runtime image is published to the GitHub Container Registry as
ghcr.io/openapi-yagen/openapi-yagen,
for linux/amd64 and linux/arm64 - the latter runs natively (no emulation) on Apple Silicon under
Docker Desktop, making this the easiest route on macOS: no Gatekeeper quarantine step, and no local
build toolchain either. Mount the directory holding your spec (and any --override-dir/generator
files) as /workspace, its working directory:
docker run --rm -v "$PWD":/workspace ghcr.io/openapi-yagen/openapi-yagen \
generate openapi.yaml -g builtin:kotlin_ktor_client -o out
Every subcommand below (generate, convert, list-generators, extract, info) works the same
way - append it and its options after the image name exactly as you would after the
openapi-yagen binary itself. -g/--override-dir/-o/spec-file paths are resolved inside
the container, so keep them relative to the directory you mounted. Loading a generator from an
HTTP(S) URL (-g https://...) works too - the image bundles curl for that.
An alias makes it behave like a locally installed binary for the rest of a shell session:
alias openapi-yagen='docker run --rm -v "$PWD":/workspace ghcr.io/openapi-yagen/openapi-yagen'
Supported CLI root options and subcommands:
Usage: ./openapi-yagen [OPTIONS] [SUBCOMMAND]
Options:
-h,--help Print this help message and exit
-v,--version Print version and exit
Subcommands:
generate, g Generate sources from openapi specification
convert, c Convert an OpenAPI spec from one version to another
list-generators, l List built-in generators bundled with this binary (use with -g builtin:<name>)
extract, e Extract a built-in generator's files to a directory, e.g. to customize it further without starting from scratch
info, i Show a generator's metadata: name, description, OpenAPI version, and declared variables
Generate sources from openapi specification
Usage: ./openapi-yagen generate [OPTIONS] [spec-file]
Positionals:
spec-file TEXT [openapi.yaml]
Specification file
Options:
-h,--help Print this help message and exit
--override-dir TEXT Directory with overridden generator files
-o,--out-dir TEXT [.] Output directory for generated code
-g,--generator TEXT REQUIRED
Path to generator. It can be a directory, zip archive, HTTP URL, or a built-in generator (builtin:<name> - see the list-generators command)
-p,--post-process TEXT ... Post process file with specified tool for extension
-c,--clear Clear output directory before generating
-v,--var TEXT ... Set variable. Syntax is: -v (var_name)=(var_value)
-t,--tags TEXT ... Only generate operations/models tagged with one of these tags (default: generate everything)
--header TEXT Override the auto-generated "do not edit" header text prepended to every generated file (default: names the generator; wrapped in whichever comment syntax the file's own extension/generator.yml commentStyle resolves to)
--no-header Disable the auto-generated "do not edit" header entirely
Every file written via renderTemplate/copyFile (see generator-format.md)
gets a "do not edit" header prepended automatically, wrapped in whatever comment syntax that
file's own extension uses (# for .rb/.py/.yml, // for .kt/.go/.ts/.h/..., and so
on - see lib/generator/file_header.cpp for the full table). An
extension the table doesn't recognize (e.g. a hypothetical .json output, which has no comment
syntax at all) is left untouched rather than corrupted with a guess. renderTemplateToString's
output never gets one, since it's an in-memory fragment (e.g. for a {% include %}-style
partial), not a real output file.
The default header names the specific generator that produced the file:
// Code generated by openapi-yagen (kotlin_ktor_server). DO NOT EDIT.
// https://openapi-yagen.github.io
--header "<text>" replaces the message itself (still auto-wrapped in the resolved comment
syntax); --no-header disables the header entirely for that run. A generator can also override
which comment style the engine picks for its own output, regardless of extension, via
generator.yml's commentStyle field (see generator-format.md) -
useful if the built-in extension table guesses wrong for an unusual output format.
-c/--clear deletes everything inside --out-dir before generating; without it existing files
are kept and only overwritten. As a safeguard, clearing is refused when the output directory is
the current directory (the default -o .) or one of its parents - point --out-dir at a
dedicated directory for generated code.
-p/--post-process <spec> runs an external command on each generated file, keyed by extension:
-p "ts:prettier --write %file%"
%file% is replaced with the generated file's path. The ext1,ext2: prefix is optional - a
-p value with no prefix (just a bare command) runs on every generated file, regardless of
extension. Pass -p more than once to chain multiple tools (e.g. one for .kt files, a different
one for everything else).
-t/--tags <tag>... restricts generation to a subset of the spec's OpenAPI tags. With no -t
flag (the default), everything in the spec is generated, unchanged from before this option existed.
openapi-yagen generate openapi.yaml -g builtin:kotlin_ktor_client -o out -t pets -t orders
An operation is kept if it declares any of the given tags (an operation with several tags
needs only one to match); an untagged operation is dropped as soon as -t is used at all. This is
an engine-level filter, applied before the spec ever reaches the generator's JavaScript: a
generator doesn't need to know tag filtering exists to support it. Filtering happens in three
steps:
paths and webhooks alike; a path left
with none of its operations remaining is dropped entirely.components.schemas (and parameters/requestBodies/responses/headers) are
pruned down to whatever's still reachable from a surviving operation's parameters, request body,
or responses (following $refs, properties, items, allOf/oneOf/anyOf, and so on) - a
model only ever used by a filtered-out operation is dropped along with it; one used by both a
surviving and a filtered-out operation is kept.tags: list is trimmed to the tags actually passed to -t.Convert an OpenAPI spec from one version to another
Usage: ./openapi-yagen convert [OPTIONS] spec-file
Positionals:
spec-file TEXT REQUIRED Specification file to convert
Options:
-h,--help Print this help message and exit
--from TEXT Source OpenAPI version (e.g. 2.0, 3.0, 3.1, 3.2) - auto-detected from the spec's own "openapi"/"swagger" field if omitted
--to TEXT REQUIRED Target OpenAPI version (e.g. 2.0, 3.0, 3.1, 3.2)
-o,--out TEXT REQUIRED Output file path
--format TEXT Output format: "yaml" or "json" - inferred from --out's extension if omitted
openapi-yagen convert openapi-3.1.yaml --to 3.0 -o openapi-3.0.yaml
List built-in generators bundled with this binary (use with -g builtin:<name>)
Usage: ./openapi-yagen list-generators [OPTIONS]
Options:
-h,--help Print this help message and exit
-d,--describe Also print each generator's description
Extract a built-in generator's files to a directory, e.g. to customize it further without starting from scratch
Usage: ./openapi-yagen extract [OPTIONS] name
Positionals:
name TEXT REQUIRED Built-in generator name, with or without a "builtin:" prefix (see the list-generators command)
Options:
-h,--help Print this help message and exit
-o,--out-dir TEXT REQUIRED Output directory
Show a generator's metadata: name, description, OpenAPI version, and declared variables
Usage: ./openapi-yagen info [OPTIONS] generator
Positionals:
generator TEXT REQUIRED Path to generator. It can be a directory, zip archive, HTTP URL, or a built-in generator (builtin:<name> - see the list-generators command)
Options:
-h,--help Print this help message and exit
openapi-yagen info builtin:kotlin_ktor_client
This is the same version conversion generate runs automatically when a spec's version doesn't
match a generator's declared openApiVersion (see
generator-format.md), exposed as a
standalone tool - useful to inspect what a spec looks like in another version, or to pin a spec to
one version before checking it in. It's scoped to the constructs the engine itself models (see the
same doc section) rather than a fully lossless converter for every possible spec field.
The output's top-level keys (openapi/info/paths/... or swagger/info/host/... for a 2.0
target) are written in the specification's own documented order, not alphabetical - nested objects
still come out alphabetical. String values that would otherwise be ambiguous when read back
(a response status code like 200, or a string that happens to look like a bool/float/null, e.g.
"true"/"1.5") are always quoted, so they round-trip as strings rather than being silently
misread as a different YAML type by another tool.
-g also accepts an HTTP/S URL pointing at a generator's source folder, so you can run a
generator straight from GitHub without cloning it. openapi-yagen fetches the generator's files
(generator.yml, scripts, templates) over HTTP/S as it needs them, so the URL must point at the
raw folder contents (curl is required). For example, using this repo's own
sample_cpp_models_generator:
openapi-yagen generate openapi.yaml \
-g https://raw.githubusercontent.com/openapi-yagen/openapi-yagen/master/generators/sample_cpp_models_generator/src \
-o out
A handful of the generators in generators/ are embedded directly into the
openapi-yagen binary at build time, so they work offline with no local checkout, zip, or network
access:
openapi-yagen list-generators
openapi-yagen generate openapi.yaml -g builtin:kotlin_ktor_client -o out -v packageName=com.example.petstore
To fork a built-in generator and customize it, extract its files to a directory first:
openapi-yagen extract kotlin_ktor_client -o my-kotlin-client-generator
See docs/ for the full generator-writing documentation: a step-by-step
tutorial building a small generator from scratch, the
generator format (folder layout, generator.yml), the
JavaScript API (globals, built-in functions), and
templating (Inja syntax, calling functions from templates).
Generators are located in the generators folder. See generators/README.md
for the full list - which ones are built into the openapi-yagen binary itself (usable via
-g builtin:<name>, see "Using a built-in generator" above) and which need -g pointed at a
directory/zip/URL - plus a link to each generator's own documentation.
The project is a CMake + Conan 2 C++20 codebase (core in lib/, CLI in cli/, tests in
test/). See AGENTS.md and
docs/develop/ for build/test commands, project architecture, and coding
conventions - it's the entry point for working on the openapi-yagen engine itself (as opposed to
writing a generator, which docs/ covers).