Skip to content

[Openapi] Product metadata in extension #4511

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 6 commits into from
Jun 17, 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
22 changes: 17 additions & 5 deletions compiler-rs/clients_schema_to_openapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub struct OpenApiConversion {
}

/// 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<OpenApiConversion> {
pub fn convert_schema(mut schema: IndexedModel, config: Configuration, product_meta: IndexMap<String,String>) -> anyhow::Result<OpenApiConversion> {
// Expand generics
schema = clients_schema::transform::expand_generics(schema, ExpandConfig::default())?;

Expand All @@ -73,7 +73,7 @@ pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow
schema = clients_schema::transform::filter_availability(schema, filter)?;
}

convert_expanded_schema(&schema, &config)
convert_expanded_schema(&schema, &config, &product_meta)
}

/// Convert an API model into an OpenAPI v3 schema. The input model must have all generics expanded, conversion
Expand All @@ -82,7 +82,7 @@ pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow
/// Note: there are ways to represent [generics in JSON Schema], but its unlikely that tooling will understand it.
///
/// [generics in JSON Schema]: https://json-schema.org/blog/posts/dynamicref-and-generics
pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) -> anyhow::Result<OpenApiConversion> {
pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration, product_meta: &IndexMap<String,String>) -> anyhow::Result<OpenApiConversion> {
let mut openapi = OpenAPI {
openapi: "3.0.3".into(),
info: info(model),
Expand Down Expand Up @@ -120,7 +120,7 @@ pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) ->
continue;
}
}
paths::add_endpoint(endpoint, &mut tac, &mut openapi.paths)?;
paths::add_endpoint(endpoint, &mut tac, &mut openapi.paths, product_meta)?;
}

// // Sort maps to ensure output stability
Expand Down Expand Up @@ -180,7 +180,19 @@ fn info(model: &IndexedModel) -> openapiv3::Info {
}
}

pub fn availability_as_extensions(availabilities: &Option<Availabilities>, flavor: &Option<Flavor>) -> IndexMap<String, serde_json::Value> {
pub fn product_meta_as_extensions(namespace: &str, product_meta: &IndexMap<String,String>) -> IndexMap<String, Value> {
let mut result = IndexMap::new();
let mut additional_namespace= "".to_string();
if let Some(meta) = product_meta.get(namespace) {
additional_namespace = format!(", {meta}");
}

let product_str = format!("elasticsearch{additional_namespace}");
result.insert("x-product-feature".to_string(), Value::String(product_str));
result
}

pub fn availability_as_extensions(availabilities: &Option<Availabilities>, flavor: &Option<Flavor>) -> IndexMap<String, Value> {
let mut result = IndexMap::new();
convert_availabilities(availabilities, flavor, &mut result);
result
Expand Down
7 changes: 5 additions & 2 deletions compiler-rs/clients_schema_to_openapi/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
// under the License.

use std::fs::File;
use clients_schema::IndexedModel;
use indexmap::IndexMap;
use clients_schema::{IndexedModel};
use tracing::Level;
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::FmtSubscriber;
Expand All @@ -32,10 +33,12 @@ fn main() -> anyhow::Result<()> {
.finish();
tracing::subscriber::set_global_default(subscriber)?;

let product_meta: IndexMap<String, String> = serde_json::from_reader(File::open("../../specification/_doc_ids/product-meta.json")?)?;
let schema = IndexedModel::from_reader(File::open(&cli.schema)?)?;
let output = cli.output.clone();
let redirect_path = cli.redirect_path(&cli.output);
let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into())?;
let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into(), product_meta)?;
serde_json::to_writer_pretty(File::create(&output)?, &openapi.openapi)?;
serde_json::to_writer_pretty(File::create(&output)?, &openapi.openapi)?;

if let Some(redirects) = openapi.redirects {
Expand Down
6 changes: 3 additions & 3 deletions compiler-rs/clients_schema_to_openapi/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ use crate::convert_availabilities;
pub fn add_endpoint(
endpoint: &clients_schema::Endpoint,
tac: &mut TypesAndComponents,
out: &mut Paths
out: &mut Paths,
product_meta: &IndexMap<String,String>
) -> anyhow::Result<()> {
if endpoint.request.is_none() {
// tracing::warn!("Endpoint {} is missing a request -- ignored", &endpoint.name);
Expand Down Expand Up @@ -371,8 +372,7 @@ pub fn add_endpoint(
if !code_samples.is_empty() {
extensions.insert("x-codeSamples".to_string(), serde_json::json!(code_samples));
}
let mut ext_availability = crate::availability_as_extensions(&endpoint.availability, &tac.config.flavor);
extensions.append(&mut ext_availability);
extensions.append(&mut crate::product_meta_as_extensions(namespace, product_meta));

// Create the operation, it will be repeated if we have several methods
let operation = openapiv3::Operation {
Expand Down
Binary file modified compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm
Binary file not shown.
14 changes: 11 additions & 3 deletions compiler-rs/compiler-wasm-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
// specific language governing permissions and limitations
// under the License.

use std::path::PathBuf;
use std::path::{PathBuf};
use argh::FromArgs;
use clients_schema::IndexedModel;
use clients_schema::{IndexedModel};
use wasm_bindgen::prelude::*;
use clients_schema::indexmap::IndexMap;
use clients_schema_to_openapi::cli::Cli;

/// Minimal bindings to Node's `fs` module.
Expand Down Expand Up @@ -63,8 +64,15 @@ pub fn convert0(cli: Cli, cwd: Option<String>) -> anyhow::Result<()> {

let json = node_fs::read_file_sync_to_string(&input.to_string_lossy(), "utf8");
let schema = IndexedModel::from_reader(json.as_bytes())?;

let product_meta_path = match cwd {
Some(ref cwd) => format!("{cwd}/specification/_doc_ids/product-meta.json"),
None => "specification/_doc_ids/product-meta.json".to_string(),
};
let json_product_map = node_fs::read_file_sync_to_string(&product_meta_path, "utf8");
let product_meta: IndexMap<String, String> = serde_json::from_str(&json_product_map).expect("Cannot parse product metadata file");

let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into())?;
let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into(), product_meta)?;

let result = serde_json::to_string_pretty(&openapi.openapi)?;
node_fs::write_file_sync(&output.to_string_lossy(), &result);
Expand Down
Loading
Loading