Skip to content

[9.0] Only add x-codeSamples extensions to docs builds of openapi (#4582) #4598

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 1 commit 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
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ validate-no-cache: ## Validate a given endpoint request or response without loca

generate: ## Generate the output spec
@echo ">> generating the spec .."
@make generate-language-examples
@npm run generate-schema --prefix compiler -- --spec ../specification/ --output ../output/
@npm run start --prefix typescript-generator

Expand Down Expand Up @@ -55,7 +54,9 @@ transform-to-openapi: ## Generate the OpenAPI definition from the compiled schem
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor serverless --output output/openapi/elasticsearch-serverless-openapi.json

transform-to-openapi-for-docs: ## Generate the OpenAPI definition tailored for API docs generation
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor stack --lift-enum-descriptions --merge-multipath-endpoints --multipath-redirects --output output/openapi/elasticsearch-openapi-docs.json
@make generate-language-examples
@make generate
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor stack --lift-enum-descriptions --merge-multipath-endpoints --multipath-redirects --include-language-examples --output output/openapi/elasticsearch-openapi-docs.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/output/openapi/elasticsearch-serverless-openapi.json
Expand Down
5 changes: 5 additions & 0 deletions compiler-rs/clients_schema_to_openapi/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub struct Cli {
/// output a redirection map when merging multipath endpoints
#[argh(switch)]
pub multipath_redirects: bool,

/// include the x-codeSamples extension with language examples for all endpoints
#[argh(switch)]
pub include_language_examples: bool,
}

impl Cli {
Expand Down Expand Up @@ -74,6 +78,7 @@ impl From<Cli> for Configuration {
lift_enum_descriptions: cli.lift_enum_descriptions,
merge_multipath_endpoints: cli.merge_multipath_endpoints,
multipath_redirects: cli.multipath_redirects,
include_language_examples: cli.include_language_examples,
namespaces: if cli.namespace.is_empty() {
None
} else {
Expand Down
3 changes: 3 additions & 0 deletions compiler-rs/clients_schema_to_openapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub struct Configuration {

/// Should we output a redirect map when merging multipath endpoints?
pub multipath_redirects: bool,

/// include the x-codeSamples extension with language examples for all endpoints
pub include_language_examples: bool,
}

pub struct OpenApiConversion {
Expand Down
41 changes: 22 additions & 19 deletions compiler-rs/clients_schema_to_openapi/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,31 +347,34 @@ pub fn add_endpoint(
// add the x-state extension for availability
let mut extensions = crate::availability_as_extensions(&endpoint.availability, &tac.config.flavor);

// add the x-codeSamples extension
let mut code_samples = vec![];
if let Some(examples) = request.examples.clone() {
if let Some((_, example)) = examples.first() {
let request_line = example.method_request.clone().unwrap_or(String::from(""));
let request_body = example.value.clone().unwrap_or(String::from(""));
if !request_line.is_empty() {
code_samples.push(serde_json::json!({
"lang": "Console",
"source": request_line + "\n" + request_body.as_str(),
}));
}
if let Some(alternatives) = example.alternatives.clone() {
for alternative in alternatives.iter() {
if tac.config.include_language_examples {
// add the x-codeSamples extension
let mut code_samples = vec![];
if let Some(examples) = request.examples.clone() {
if let Some((_, example)) = examples.first() {
let request_line = example.method_request.clone().unwrap_or(String::from(""));
let request_body = example.value.clone().unwrap_or(String::from(""));
if !request_line.is_empty() {
code_samples.push(serde_json::json!({
"lang": alternative.language,
"source": alternative.code.as_str(),
"lang": "Console",
"source": request_line + "\n" + request_body.as_str(),
}));
}
if let Some(alternatives) = example.alternatives.clone() {
for alternative in alternatives.iter() {
code_samples.push(serde_json::json!({
"lang": alternative.language,
"source": alternative.code.as_str(),
}));
}
}
}
}
if !code_samples.is_empty() {
extensions.insert("x-codeSamples".to_string(), serde_json::json!(code_samples));
}
}
if !code_samples.is_empty() {
extensions.insert("x-codeSamples".to_string(), serde_json::json!(code_samples));
}

extensions.append(&mut crate::product_meta_as_extensions(namespace, product_meta));

// Create the operation, it will be repeated if we have several methods
Expand Down
Binary file modified compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm
Binary file not shown.
5 changes: 3 additions & 2 deletions docs/examples/generate-language-examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ async function generateLanguages(example) {
request += '\n' + JSON.stringify(data.value);
}
}
data.alternatives = [];
const alternatives = [];
for (const lang of LANGUAGES) {
data.alternatives.push({
alternatives.push({
language: lang,
code: (await convertRequests(request, lang, {})).trim(),
});
}
data.alternatives = alternatives.concat(data.alternatives.filter(pair => !LANGUAGES.includes(pair.language)));
doc.delete('alternatives');
doc.add(doc.createPair('alternatives', data.alternatives));
await fs.promises.writeFile(example, doc.toString({lineWidth: 132}));
Expand Down
Loading