Skip to content

Commit 7d60099

Browse files
authored
Merge branch 'main' into docs-commands
2 parents badc31c + eacdb7a commit 7d60099

File tree

616 files changed

+8396
-3024
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

616 files changed

+8396
-3024
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,6 @@ compiler/test/**/output/
6969
output/openapi/elasticsearch-serverless-openapi-docs.tmp*.json
7070
output/openapi/elasticsearch-serverless-openapi-docs-final.json
7171
output/openapi/elasticsearch-openapi-docs.tmp*.json
72-
output/openapi/elasticsearch-openapi-docs-final.json
72+
output/openapi/elasticsearch-openapi-docs-final.json
73+
output/openapi/elasticsearch-serverless-openapi-docs.json
74+
output/openapi/elasticsearch-openapi-docs.json

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ transform-to-openapi: ## Generate the OpenAPI definition from the compiled schem
5656
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor serverless --output output/openapi/elasticsearch-serverless-openapi.json
5757

5858
transform-to-openapi-for-docs: ## Generate the OpenAPI definition tailored for API docs generation
59-
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor stack --lift-enum-descriptions --merge-multipath-endpoints --output output/openapi/elasticsearch-openapi-docs.json
59+
@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
60+
@npm run transform-to-openapi -- --schema output/schema/schema.json --flavor serverless --lift-enum-descriptions --merge-multipath-endpoints --multipath-redirects --output output/openapi/elasticsearch-serverless-openapi-docs.json
6061

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

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ Follow the steps to generate the JSON representation, then:
6060
```
6161
# Generate the OpenAPI representation
6262
$ make transform-to-openapi
63+
```
64+
65+
To generate the JSON representation that is used for documentation purposes, the commands are different:
66+
67+
```
68+
# Generate the OpenAPI files
69+
$ make transform-to-openapi-for-docs
6370
6471
# Apply fixes
6572
$ make overlay-docs

compiler-rs/clients_schema_to_openapi/src/cli.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ pub struct Cli {
3131
/// merge endpoints with multiple paths into a single OpenAPI operation [default = false]
3232
#[argh(switch)]
3333
pub merge_multipath_endpoints: bool,
34+
35+
/// output a redirection map when merging multipath endpoints
36+
#[argh(switch)]
37+
pub multipath_redirects: bool,
38+
}
39+
40+
impl Cli {
41+
pub fn redirect_path(&self, output: &PathBuf) -> Option<String> {
42+
if self.multipath_redirects {
43+
let path = output.to_string_lossy();
44+
let path = path.rsplit_once('.').unwrap().0;
45+
Some(format!("{}.redirects.csv", path))
46+
} else {
47+
None
48+
}
49+
}
3450
}
3551

3652
use derive_more::FromStr;
@@ -57,6 +73,7 @@ impl From<Cli> for Configuration {
5773
flavor,
5874
lift_enum_descriptions: cli.lift_enum_descriptions,
5975
merge_multipath_endpoints: cli.merge_multipath_endpoints,
76+
multipath_redirects: cli.multipath_redirects,
6077
namespaces: if cli.namespace.is_empty() {
6178
None
6279
} else {

compiler-rs/clients_schema_to_openapi/src/components.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
use std::collections::BTreeMap;
1819
use clients_schema::TypeName;
1920
use openapiv3::{Components, Parameter, ReferenceOr, RequestBody, Response, Schema, StatusCode};
2021
use crate::Configuration;
@@ -32,11 +33,19 @@ pub struct TypesAndComponents<'a> {
3233
pub config: &'a Configuration,
3334
pub model: &'a clients_schema::IndexedModel,
3435
pub components: &'a mut Components,
36+
// Redirections (if paths multipaths endpoints are merged)
37+
pub redirects: Option<BTreeMap<String, String>>,
3538
}
3639

3740
impl<'a> TypesAndComponents<'a> {
3841
pub fn new(config: &'a Configuration, model: &'a clients_schema::IndexedModel, components: &'a mut Components) -> TypesAndComponents<'a> {
39-
TypesAndComponents { config, model, components }
42+
let redirects = if config.merge_multipath_endpoints && config.multipath_redirects {
43+
Some(BTreeMap::new())
44+
} else {
45+
None
46+
};
47+
48+
TypesAndComponents { config, model, components, redirects }
4049
}
4150

4251
pub fn add_request_body(&mut self, endpoint: &str, body: RequestBody) -> ReferenceOr<RequestBody> {

compiler-rs/clients_schema_to_openapi/src/lib.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,18 @@ pub struct Configuration {
4141
/// be the longest one (with values for all optional parameters), and the other paths will be added
4242
/// at the beginning of the operation's description.
4343
pub merge_multipath_endpoints: bool,
44+
45+
/// Should we output a redirect map when merging multipath endpoints?
46+
pub multipath_redirects: bool,
47+
}
48+
49+
pub struct OpenApiConversion {
50+
pub openapi: OpenAPI,
51+
pub redirects: Option<String>,
4452
}
4553

4654
/// Convert an API model into an OpenAPI v3 schema, optionally filtered for a given flavor
47-
pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow::Result<OpenAPI> {
55+
pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow::Result<OpenApiConversion> {
4856
// Expand generics
4957
schema = clients_schema::transform::expand_generics(schema, ExpandConfig::default())?;
5058

@@ -74,7 +82,7 @@ pub fn convert_schema(mut schema: IndexedModel, config: Configuration) -> anyhow
7482
/// Note: there are ways to represent [generics in JSON Schema], but its unlikely that tooling will understand it.
7583
///
7684
/// [generics in JSON Schema]: https://json-schema.org/blog/posts/dynamicref-and-generics
77-
pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) -> anyhow::Result<OpenAPI> {
85+
pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) -> anyhow::Result<OpenApiConversion> {
7886
let mut openapi = OpenAPI {
7987
openapi: "3.0.3".into(),
8088
info: info(model),
@@ -130,7 +138,21 @@ pub fn convert_expanded_schema(model: &IndexedModel, config: &Configuration) ->
130138
// comp.security_schemes.sort_keys();
131139
// }
132140

133-
Ok(openapi)
141+
let redirects = if let Some(redirects) = tac.redirects {
142+
use std::fmt::Write;
143+
let mut result = String::new();
144+
for (source, target) in redirects.iter() {
145+
writeln!(&mut result, "{},{}", source, target)?;
146+
}
147+
Some(result)
148+
} else {
149+
None
150+
};
151+
152+
Ok(OpenApiConversion {
153+
openapi,
154+
redirects,
155+
})
134156
}
135157

136158
fn info(model: &IndexedModel) -> openapiv3::Info {
@@ -183,7 +205,7 @@ pub fn convert_availabilities(availabilities: &Option<Availabilities>, flavor: &
183205
let exp_since = format!("Technical preview{since_str}");
184206
result.insert("x-state".to_string(), Value::String(exp_since));
185207
}
186-
Stability::Stable => {
208+
Stability::Stable => {
187209
let stable_since = format!("Generally available{since_str}");
188210
result.insert("x-state".to_string(), Value::String(stable_since));
189211
}

compiler-rs/clients_schema_to_openapi/src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ fn main() -> anyhow::Result<()> {
3434

3535
let schema = IndexedModel::from_reader(File::open(&cli.schema)?)?;
3636
let output = cli.output.clone();
37+
let redirect_path = cli.redirect_path(&cli.output);
3738
let openapi = clients_schema_to_openapi::convert_schema(schema, cli.into())?;
38-
serde_json::to_writer_pretty(File::create(&output)?, &openapi)?;
39+
serde_json::to_writer_pretty(File::create(&output)?, &openapi.openapi)?;
40+
41+
if let Some(redirects) = openapi.redirects {
42+
let path = redirect_path.unwrap();
43+
std::fs::write(path, &redirects)?;
44+
}
45+
3946
Ok(())
4047
}

compiler-rs/clients_schema_to_openapi/src/paths.rs

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,16 @@ pub fn add_endpoint(
148148
// }
149149
};
150150

151-
let openapi_example = Example {
152-
value: example,
153-
description: schema_example.description.clone(),
154-
summary: schema_example.summary.clone(),
155-
external_value: None,
156-
extensions: Default::default(),
157-
};
158-
openapi_examples.insert(name.clone(), ReferenceOr::Item(openapi_example));
151+
if example.is_some() {
152+
let openapi_example = Example {
153+
value: example,
154+
description: schema_example.description.clone(),
155+
summary: schema_example.summary.clone(),
156+
external_value: None,
157+
extensions: Default::default(),
158+
};
159+
openapi_examples.insert(name.clone(), ReferenceOr::Item(openapi_example));
160+
}
159161
}
160162
openapi_examples
161163
}
@@ -233,9 +235,27 @@ pub fn add_endpoint(
233235
};
234236

235237
//---- Merge multipath endpoints if asked for
238+
239+
let operation_id: String = endpoint
240+
.name
241+
.chars()
242+
.map(|x| match x {
243+
'_' | '.' => '-',
244+
_ => x,
245+
})
246+
.collect();
247+
236248
let mut new_endpoint: clients_schema::Endpoint;
237249

238250
let endpoint = if is_multipath && tac.config.merge_multipath_endpoints {
251+
252+
// Add redirects for operations that would have been generated otherwise
253+
if let Some(ref mut map) = &mut tac.redirects {
254+
for i in 1..endpoint.urls.len() {
255+
map.insert(format!("{operation_id}-{i}"), operation_id.clone());
256+
}
257+
}
258+
239259
new_endpoint = endpoint.clone();
240260
let endpoint = &mut new_endpoint;
241261

@@ -315,9 +335,9 @@ pub fn add_endpoint(
315335
parameters.append(&mut query_params.clone());
316336

317337
let sum_desc = split_summary_desc(&endpoint.description);
318-
338+
319339
let privilege_desc = add_privileges(&endpoint.privileges);
320-
340+
321341
let full_desc = match (sum_desc.description, privilege_desc) {
322342
(Some(a), Some(b)) => Some(a+ &b),
323343
(opt_a, opt_b) => opt_a.or(opt_b)
@@ -340,21 +360,6 @@ pub fn add_endpoint(
340360
}
341361
}
342362
}
343-
if code_samples.is_empty() {
344-
// if there are no example requests we look for example responses
345-
// this can only happen for examples that do not have a request body
346-
if let Some(examples) = response_def.examples.clone() {
347-
if let Some((_, example)) = examples.first() {
348-
let request_line = example.method_request.clone().unwrap_or(String::from(""));
349-
if !request_line.is_empty() {
350-
code_samples.push(serde_json::json!({
351-
"lang": "Console",
352-
"source": request_line + "\n",
353-
}));
354-
}
355-
}
356-
}
357-
}
358363
if !code_samples.is_empty() {
359364
extensions.insert("x-codeSamples".to_string(), serde_json::json!(code_samples));
360365
}
@@ -452,14 +457,7 @@ pub fn add_endpoint(
452457
};
453458

454459
let mut operation = operation.clone();
455-
let mut operation_id: String = endpoint
456-
.name
457-
.chars()
458-
.map(|x| match x {
459-
'_' | '.' => '-',
460-
_ => x,
461-
})
462-
.collect();
460+
let mut operation_id = operation_id.clone();
463461
if operation_counter != 0 {
464462
write!(&mut operation_id, "-{}", operation_counter)?;
465463
}
@@ -515,18 +513,20 @@ fn split_summary_desc(desc: &str) -> SplitDesc{
515513

516514
fn add_privileges(privileges: &Option<Privileges>) -> Option<String>{
517515
if let Some(privs) = privileges {
518-
let mut result = "\n ##Required authorization\n".to_string();
516+
let mut result = "\n\n## Required authorization\n\n".to_string();
519517
if !privs.index.is_empty() {
520518
result += "* Index privileges: ";
521519
result += &privs.index.iter()
522520
.map(|a| format!("`{a}`"))
523521
.join(",");
522+
result += "\n";
524523
}
525524
if !privs.cluster.is_empty() {
526525
result += "* Cluster privileges: ";
527526
result += &privs.cluster.iter()
528527
.map(|a| format!("`{a}`"))
529528
.join(",");
529+
result += "\n";
530530
}
531531
return Some(result)
532532
}
6.89 KB
Binary file not shown.

compiler-rs/compiler-wasm-lib/src/lib.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,21 @@ pub fn convert0(cli: Cli, cwd: Option<String>) -> anyhow::Result<()> {
5959
Some(ref cwd) => PathBuf::from(cwd).join(&cli.output),
6060
None => cli.output.clone(),
6161
};
62+
let redirect_path = cli.redirect_path(&output);
6263

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

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

68-
let result = serde_json::to_string_pretty(&openapi)?;
69+
let result = serde_json::to_string_pretty(&openapi.openapi)?;
6970
node_fs::write_file_sync(&output.to_string_lossy(), &result);
71+
72+
if let Some(redirects) = openapi.redirects {
73+
let path = redirect_path.unwrap();
74+
node_fs::write_file_sync(&path, &redirects);
75+
}
76+
7077
Ok(())
7178
}
7279

0 commit comments

Comments
 (0)