Skip to content

[OpenAPI] Add a CLI to configure export parameters #4426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -234,5 +234,6 @@ dist/* binary

output/** linguist-generated=true
output/schema/validation-errors.json linguist-generated=false
compiler-rs/compiler-wasm-lib/pkg/* linguist-generated=true

####################################################################################################
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ transform-expand-generics: ## Create a new schema with all generics expanded
@npm run transform-expand-generics --prefix compiler

transform-to-openapi: ## Generate the OpenAPI definition from the compiled schema
@npm run transform-to-openapi --prefix compiler
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor stack --output output/openapi/elasticsearch-openapi.json
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor serverless --output output/openapi/elasticsearch-serverless-openapi.json

filter-for-serverless: ## Generate the serverless version from the compiled schema
@npm run --prefix compiler filter-by-availability -- --serverless --visibility=public --input ../output/schema/schema.json --output ../output/schema/schema-serverless.json
@npm run --prefix compiler filter-by-availability -- --serverless --visibility=public --input ../output/schema/schema.json --output ../output/output/openapi/elasticsearch-serverless-openapi.json

dump-routes: ## Create a new schema with all generics expanded
@npm run dump-routes --prefix compiler
Expand Down
66 changes: 63 additions & 3 deletions compiler-rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ members = [
[workspace.dependencies]
anyhow = "1"
arcstr = "1"
argh = "0.1"
clap = "4"
console_error_panic_hook = "0.1"
convert_case = "0.6"
Expand Down
4 changes: 2 additions & 2 deletions compiler-rs/clients_schema_to_openapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ publish = false
[dependencies]
clients_schema = {path="../clients_schema"}

argh = { workspace = true }
derive_more = { version = "2", features = ["from_str"] }
serde_json = { workspace = true }
serde_ignored = { workspace = true }
icu_segmenter = { workspace = true }
Expand All @@ -16,5 +18,3 @@ indexmap = { workspace = true }

tracing = { workspace = true }
tracing-subscriber = { workspace = true }
clap = { workspace = true, features = ["derive"] }

62 changes: 62 additions & 0 deletions compiler-rs/clients_schema_to_openapi/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use std::path::PathBuf;
use argh::FromArgs;
use clients_schema::Flavor;
use crate::Configuration;

/// Convert schema.json to an OpenAPI schema
#[derive(Debug, FromArgs)]
pub struct Cli {
/// schema file to transform.
#[argh(option)]
pub schema: PathBuf,

/// output file.
#[argh(option)]
pub output: PathBuf,

//---- Fields from lib::Configuration

/// the flavor to generate [all, stack, serverless - default = all]
#[argh(option, default = "SchemaFlavor::All")]
pub flavor: SchemaFlavor,

/// add enum descriptions to property descriptions [default = true]
#[argh(option, default = "true")]
pub lift_enum_descriptions: bool,

/// generate only this namespace (can be repeated)
#[argh(option)]
pub namespace: Vec<String>,
}

use derive_more::FromStr;

#[derive(Debug, Clone, PartialEq, FromStr)]
pub enum SchemaFlavor {
/// No schema filtering
All,
/// Stack (stateful) flavor
Stack,
/// Serverless flavor
Serverless,
}

impl From<Cli> for Configuration {
fn from(val: Cli) -> Configuration {
let flavor = match val.flavor {
SchemaFlavor::All => None,
SchemaFlavor::Serverless => Some(Flavor::Serverless),
SchemaFlavor::Stack => Some(Flavor::Stack),
};

Configuration {
flavor,
lift_enum_descriptions: val.lift_enum_descriptions,
namespaces: if val.namespace.is_empty() {
None
} else {
Some(val.namespace)
},
}
}
}
16 changes: 7 additions & 9 deletions compiler-rs/clients_schema_to_openapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod components;
mod paths;
mod schemas;
mod utils;
pub mod cli;

use indexmap::IndexMap;

Expand All @@ -29,18 +30,10 @@ use crate::components::TypesAndComponents;

pub struct Configuration {
pub flavor: Option<Flavor>,
pub namespaces: Option<Vec<String>>,
pub lift_enum_descriptions: bool,
}

impl Default for Configuration {
fn default() -> Self {
Self {
flavor: None,
lift_enum_descriptions: true,
}
}
}

/// Convert an API model into an OpenAPI v3 schema, optionally filtered for a given flavor
pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow::Result<OpenAPI> {
// Expand generics
Expand Down Expand Up @@ -105,6 +98,11 @@ pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) ->

// Endpoints
for endpoint in &model.endpoints {
if let Some(namespaces) = &config.namespaces {
if !namespaces.contains(&endpoint.name) {
continue;
}
}
paths::add_endpoint(endpoint, &mut tac, &mut openapi.paths)?;
}

Expand Down
Loading
Loading