Skip to content

Commit d28b2f3

Browse files
Merge remote-tracking branch 'origin/main' into feature/mistral-chat-completion-integration
# Conflicts: # output/openapi/elasticsearch-openapi.json # output/openapi/elasticsearch-serverless-openapi.json
2 parents ae8fc07 + 8d7d457 commit d28b2f3

File tree

566 files changed

+3095
-508
lines changed

Some content is hidden

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

566 files changed

+3095
-508
lines changed

.backportrc.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"repoOwner": "elastic",
3+
"repoName": "elasticsearch-specification",
4+
"targetBranchChoices": ["9.0", "8.19", "8.18", "8.17"],
5+
"fork": false
6+
}

compiler-rs/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler-rs/clients_schema/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub struct Availability {
264264
pub visibility: Option<Visibility>,
265265
}
266266

267-
/// The availability of an
267+
/// The availability of an endpoint, field or parameter
268268
pub type Availabilities = IndexMap<Flavor, Availability>;
269269

270270
pub trait AvailabilityFilter: Fn(&Option<Availabilities>) -> bool {}
@@ -494,6 +494,7 @@ impl TypeDefinition {
494494
#[derive(Debug, Clone, Serialize, Deserialize)]
495495
pub struct SchemaExample {
496496
pub summary: Option<String>,
497+
pub method_request: Option<String>,
497498
pub description: Option<String>,
498499
pub value: Option<String>,
499500
pub external_value: Option<String>,

compiler-rs/clients_schema_to_openapi/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ clients_schema = {path="../clients_schema"}
1010
argh = { workspace = true }
1111
derive_more = { version = "2", features = ["from_str"] }
1212
serde_json = { workspace = true }
13-
serde_ignored = { workspace = true }
13+
itertools = { workspace = true }
1414
icu_segmenter = { workspace = true }
1515
openapiv3 = { workspace = true }
1616
anyhow = { workspace = true }

compiler-rs/clients_schema_to_openapi/src/lib.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ pub mod cli;
2323

2424
use indexmap::IndexMap;
2525

26-
use clients_schema::{Availabilities, Flavor, IndexedModel, Stability, Visibility};
26+
use clients_schema::{Availabilities, Availability, Flavor, IndexedModel, Stability, Visibility};
2727
use openapiv3::{Components, OpenAPI};
28+
use serde_json::Value;
2829
use clients_schema::transform::ExpandConfig;
2930
use crate::components::TypesAndComponents;
3031

@@ -149,30 +150,37 @@ fn info(model: &IndexedModel) -> openapiv3::Info {
149150
}
150151
}
151152

152-
pub fn availability_as_extensions(availabilities: &Option<Availabilities>) -> IndexMap<String, serde_json::Value> {
153+
pub fn availability_as_extensions(availabilities: &Option<Availabilities>, flavor: &Option<Flavor>) -> IndexMap<String, serde_json::Value> {
153154
let mut result = IndexMap::new();
155+
convert_availabilities(availabilities, flavor, &mut result);
156+
result
157+
}
154158

159+
pub fn convert_availabilities(availabilities: &Option<Availabilities>, flavor: &Option<Flavor>, result: &mut IndexMap<String, Value>) {
155160
if let Some(avails) = availabilities {
156-
// We may have several availabilities, but since generally exists only on stateful (stack)
157-
for (_, availability) in avails {
158-
if let Some(stability) = &availability.stability {
159-
match stability {
161+
if let Some(flav) = flavor {
162+
if let Some(availability) = avails.get(flav) {
163+
let Availability {since,stability,..} = &availability;
164+
let stab = stability.clone().unwrap_or(Stability::Stable);
165+
let mut since_str = "".to_string();
166+
if let Some(since) = since {
167+
since_str = format!("; Added in {since}");
168+
}
169+
match stab {
160170
Stability::Beta => {
161-
result.insert("x-beta".to_string(), serde_json::Value::Bool(true));
171+
let beta_since = format!("Beta{since_str}");
172+
result.insert("x-state".to_string(), Value::String(beta_since));
162173
}
163174
Stability::Experimental => {
164-
result.insert("x-state".to_string(), serde_json::Value::String("Technical preview".to_string()));
175+
let exp_since = format!("Technical preview{since_str}");
176+
result.insert("x-state".to_string(), Value::String(exp_since));
165177
}
166-
Stability::Stable => {
167-
if let Some(since) = &availability.since {
168-
let stable_since = "Added in ".to_string() + since;
169-
result.insert("x-state".to_string(), serde_json::Value::String(stable_since));
170-
}
178+
Stability::Stable => {
179+
let stable_since = format!("Generally available{since_str}");
180+
result.insert("x-state".to_string(), Value::String(stable_since));
171181
}
172182
}
173183
}
174184
}
175185
}
176-
177-
result
178186
}

compiler-rs/clients_schema_to_openapi/src/paths.rs

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,26 @@ use std::collections::HashMap;
1919
use std::fmt::Write;
2020

2121
use anyhow::{anyhow, bail};
22-
use clients_schema::Property;
22+
use clients_schema::{Privileges, Property};
2323
use indexmap::IndexMap;
2424
use indexmap::indexmap;
2525
use icu_segmenter::SentenceSegmenter;
26+
use itertools::Itertools;
2627
use openapiv3::{
2728
MediaType, Parameter, ParameterData, ParameterSchemaOrContent, PathItem, PathStyle, Paths, QueryStyle, ReferenceOr,
2829
RequestBody, Response, Responses, StatusCode, Example
2930
};
31+
use serde_json::Value;
3032
use clients_schema::SchemaExample;
31-
3233
use crate::components::TypesAndComponents;
34+
use crate::convert_availabilities;
3335

3436
/// Add an endpoint to the OpenAPI schema. This will result in the addition of a number of elements to the
3537
/// openapi schema's `paths` and `components` sections.
3638
pub fn add_endpoint(
3739
endpoint: &clients_schema::Endpoint,
3840
tac: &mut TypesAndComponents,
39-
out: &mut Paths,
41+
out: &mut Paths
4042
) -> anyhow::Result<()> {
4143
if endpoint.request.is_none() {
4244
// tracing::warn!("Endpoint {} is missing a request -- ignored", &endpoint.name);
@@ -60,6 +62,8 @@ pub fn add_endpoint(
6062
let request = tac.model.get_request(endpoint.request.as_ref().unwrap())?;
6163

6264
fn parameter_data(prop: &Property, in_path: bool, tac: &mut TypesAndComponents) -> anyhow::Result<ParameterData> {
65+
let mut extensions: IndexMap<String,Value> = Default::default();
66+
convert_availabilities(&prop.availability, &tac.config.flavor, &mut extensions);
6367
Ok(ParameterData {
6468
name: prop.name.clone(),
6569
description: tac.property_description(prop)?,
@@ -198,7 +202,7 @@ pub fn add_endpoint(
198202
// If this endpoint response has examples in schema.json, convert them to the
199203
// OpenAPI format and add them to the endpoint response in the OpenAPI document.
200204
let response_examples = if let Some(examples) = &response_def.examples {
201-
get_openapi_examples(examples)
205+
get_openapi_examples(examples)
202206
} else {
203207
IndexMap::new()
204208
};
@@ -250,6 +254,51 @@ pub fn add_endpoint(
250254
parameters.append(&mut query_params.clone());
251255

252256
let sum_desc = split_summary_desc(&endpoint.description);
257+
258+
let privilege_desc = add_privileges(&endpoint.privileges);
259+
260+
let full_desc = match (sum_desc.description, privilege_desc) {
261+
(Some(a), Some(b)) => Some(a+ &b),
262+
(opt_a, opt_b) => opt_a.or(opt_b)
263+
};
264+
265+
// add the x-state extension for availability
266+
let mut extensions = crate::availability_as_extensions(&endpoint.availability, &tac.config.flavor);
267+
268+
// add the x-codeSamples extension
269+
let mut code_samples = vec![];
270+
if let Some(examples) = request.examples.clone() {
271+
if let Some((_, example)) = examples.first() {
272+
let request_line = example.method_request.clone().unwrap_or(String::from(""));
273+
let request_body = example.value.clone().unwrap_or(String::from(""));
274+
if !request_line.is_empty() {
275+
code_samples.push(serde_json::json!({
276+
"lang": "Console",
277+
"source": request_line + "\n" + request_body.as_str(),
278+
}));
279+
}
280+
}
281+
}
282+
if code_samples.is_empty() {
283+
// if there are no example requests we look for example responses
284+
// this can only happen for examples that do not have a request body
285+
if let Some(examples) = response_def.examples.clone() {
286+
if let Some((_, example)) = examples.first() {
287+
let request_line = example.method_request.clone().unwrap_or(String::from(""));
288+
if !request_line.is_empty() {
289+
code_samples.push(serde_json::json!({
290+
"lang": "Console",
291+
"source": request_line + "\n",
292+
}));
293+
}
294+
}
295+
}
296+
}
297+
if !code_samples.is_empty() {
298+
extensions.insert("x-codeSamples".to_string(), serde_json::json!(code_samples));
299+
}
300+
let mut ext_availability = crate::availability_as_extensions(&endpoint.availability, &tac.config.flavor);
301+
extensions.append(&mut ext_availability);
253302

254303
// Create the operation, it will be repeated if we have several methods
255304
let operation = openapiv3::Operation {
@@ -259,7 +308,7 @@ pub fn add_endpoint(
259308
vec![namespace.to_string()]
260309
},
261310
summary: sum_desc.summary,
262-
description: sum_desc.description,
311+
description: full_desc,
263312
external_docs: tac.convert_external_docs(endpoint),
264313
// external_docs: None, // Need values that differ from client purposes
265314
operation_id: None, // set in clone_operation below with operation_counter
@@ -274,7 +323,7 @@ pub fn add_endpoint(
274323
deprecated: endpoint.deprecation.is_some(),
275324
security: None,
276325
servers: vec![],
277-
extensions: crate::availability_as_extensions(&endpoint.availability),
326+
extensions
278327
};
279328

280329

@@ -403,6 +452,26 @@ fn split_summary_desc(desc: &str) -> SplitDesc{
403452
}
404453
}
405454

455+
fn add_privileges(privileges: &Option<Privileges>) -> Option<String>{
456+
if let Some(privs) = privileges {
457+
let mut result = "\n ##Required authorization\n".to_string();
458+
if !privs.index.is_empty() {
459+
result += "* Index privileges: ";
460+
result += &privs.index.iter()
461+
.map(|a| format!("`{a}`"))
462+
.join(",");
463+
}
464+
if !privs.cluster.is_empty() {
465+
result += "* Cluster privileges: ";
466+
result += &privs.cluster.iter()
467+
.map(|a| format!("`{a}`"))
468+
.join(",");
469+
}
470+
return Some(result)
471+
}
472+
None
473+
}
474+
406475
#[derive(PartialEq,Debug)]
407476
struct SplitDesc {
408477
summary: Option<String>,

compiler-rs/clients_schema_to_openapi/src/schemas.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ impl<'a> TypesAndComponents<'a> {
469469
data.external_docs = self.convert_external_docs(prop);
470470
data.deprecated = prop.deprecation.is_some();
471471
data.description = self.property_description(prop)?;
472-
data.extensions = crate::availability_as_extensions(&prop.availability);
472+
data.extensions = crate::availability_as_extensions(&prop.availability, &self.config.flavor);
473473
// TODO: prop.aliases as extensions
474474
// TODO: prop.server_default as extension
475475
// TODO: prop.doc_id as extension (new representation of since and stability)
18.5 KB
Binary file not shown.

compiler/src/model/metamodel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ export class Example {
271271
summary?: string
272272
/** Long description. */
273273
description?: string
274+
/** request method and URL */
275+
method_request?: string
274276
/** Embedded literal example. Mutually exclusive with `external_value` */
275277
value?: string
276278
/** A URI that points to the literal example */

0 commit comments

Comments
 (0)