diff --git a/compiler-rs/clients_schema_to_openapi/src/lib.rs b/compiler-rs/clients_schema_to_openapi/src/lib.rs index aae96f3da6..89f333ec7f 100644 --- a/compiler-rs/clients_schema_to_openapi/src/lib.rs +++ b/compiler-rs/clients_schema_to_openapi/src/lib.rs @@ -22,8 +22,8 @@ mod utils; pub mod cli; use indexmap::IndexMap; - -use clients_schema::{Availabilities, Availability, Flavor, IndexedModel, Stability, Visibility}; +use itertools::Itertools; +use clients_schema::{Availabilities, Availability, Flavor, IndexedModel, Privileges, Stability, UrlTemplate, Visibility}; use openapiv3::{Components, OpenAPI}; use serde_json::{Map,Value}; use clients_schema::transform::ExpandConfig; @@ -201,6 +201,52 @@ pub fn product_meta_as_extensions(namespace: &str, product_meta: &IndexMap) -> IndexMap { + let mut result = IndexMap::new(); + let mut auths_list: Vec = Vec::new(); + + if let Some(privs) = privileges { + if !privs.index.is_empty() { + let mut index_priv = "Index privileges: ".to_string(); + index_priv += &privs.index.iter() + .map(|a| format!("`{a}`")) + .join(","); + index_priv += "\n"; + auths_list.push(Value::String(index_priv)); + } + if !privs.cluster.is_empty() { + let mut cluster_priv = "Cluster privileges: ".to_string(); + cluster_priv += &privs.cluster.iter() + .map(|a| format!("`{a}`")) + .join(","); + cluster_priv += "\n"; + auths_list.push(Value::String(cluster_priv)); + } + result.insert("x-req-auth".to_string(),Value::Array(auths_list)); + } + result +} + +pub fn paths_as_extentions(urls: Vec) -> IndexMap { + let mut result = IndexMap::new(); + if !urls.is_empty() { + let mut paths_list: Vec = Vec::new(); + for url in urls { + for method in url.methods { + let lower_method = method.to_lowercase(); + let path = &url.path; + paths_list.push(Value::String(format!(r#"
+ {method} + {path} +
+ "#))); + } + } + result.insert("x-variations".to_string(), Value::Array(paths_list)); + } + result +} + pub fn availability_as_extensions(availabilities: &Option, flavor: &Option) -> IndexMap { let mut result = IndexMap::new(); convert_availabilities(availabilities, flavor, &mut result); diff --git a/compiler-rs/clients_schema_to_openapi/src/paths.rs b/compiler-rs/clients_schema_to_openapi/src/paths.rs index 6e1fac4459..7d52352579 100644 --- a/compiler-rs/clients_schema_to_openapi/src/paths.rs +++ b/compiler-rs/clients_schema_to_openapi/src/paths.rs @@ -19,11 +19,10 @@ use std::collections::HashMap; use std::fmt::Write; use anyhow::{anyhow, bail}; -use clients_schema::{Privileges, Property}; +use clients_schema::{Property}; use indexmap::IndexMap; use indexmap::indexmap; use icu_segmenter::SentenceSegmenter; -use itertools::Itertools; use openapiv3::{ MediaType, Parameter, ParameterData, ParameterSchemaOrContent, PathItem, PathStyle, Paths, QueryStyle, ReferenceOr, RequestBody, Response, Responses, StatusCode, Example @@ -31,7 +30,7 @@ use openapiv3::{ use serde_json::Value; use clients_schema::SchemaExample; use crate::components::TypesAndComponents; -use crate::convert_availabilities; +use crate::{auths_as_extentions, convert_availabilities, paths_as_extentions}; /// Add an endpoint to the OpenAPI schema. This will result in the addition of a number of elements to the /// openapi schema's `paths` and `components` sections. @@ -248,6 +247,8 @@ pub fn add_endpoint( let mut new_endpoint: clients_schema::Endpoint; + let mut longest_urls = Vec::new(); + let endpoint = if is_multipath && tac.config.merge_multipath_endpoints { // Add redirects for operations that would have been generated otherwise @@ -274,6 +275,8 @@ pub fn add_endpoint( let mut urls = vec![longest_path]; std::mem::swap(&mut endpoint.urls, &mut urls); + longest_urls = urls; + let split_desc = split_summary_desc(&endpoint.description); // Make sure the description is stays at the top @@ -282,24 +285,6 @@ pub fn add_endpoint( None => String::new(), }; - // Convert removed paths to descriptions - write!(description, "**All methods and paths for this operation:**\n\n")?; - - for url in urls { - for method in url.methods { - let lower_method = method.to_lowercase(); - let path = &url.path; - write!( - description, - r#"
- {method} - {path} -
- "# - )?; - } - } - if let Some(desc) = &split_desc.description { write!(description, "\n\n{}", desc)?; } @@ -335,18 +320,15 @@ pub fn add_endpoint( parameters.append(&mut query_params.clone()); - let sum_desc = split_summary_desc(&endpoint.description); - - let privilege_desc = add_privileges(&endpoint.privileges); - - let full_desc = match (sum_desc.description, privilege_desc) { - (Some(a), Some(b)) => Some(a+ &b), - (opt_a, opt_b) => opt_a.or(opt_b) - }; - // add the x-state extension for availability let mut extensions = crate::availability_as_extensions(&endpoint.availability, &tac.config.flavor); + // add the x-variations extension for paths + extensions.append(&mut paths_as_extentions(longest_urls.clone())); + + // add the x-req-auth extension for auth privileges + extensions.append(&mut auths_as_extentions(&endpoint.privileges)); + if tac.config.include_language_examples { // add the x-codeSamples extension let mut code_samples = vec![]; @@ -375,8 +357,12 @@ pub fn add_endpoint( } } + // add the x-metaTags extension for product name extensions.append(&mut crate::product_meta_as_extensions(namespace, product_meta)); + // split summary from description + let sum_desc = split_summary_desc(&endpoint.description); + // Create the operation, it will be repeated if we have several methods let operation = openapiv3::Operation { tags: if let Some(doc_tag) = &endpoint.doc_tag { @@ -385,7 +371,7 @@ pub fn add_endpoint( vec![namespace.to_string()] }, summary: sum_desc.summary, - description: full_desc, + description: sum_desc.description, external_docs: tac.convert_external_docs(endpoint), // external_docs: None, // Need values that differ from client purposes operation_id: None, // set in clone_operation below with operation_counter @@ -522,28 +508,6 @@ fn split_summary_desc(desc: &str) -> SplitDesc{ } } -fn add_privileges(privileges: &Option) -> Option{ - if let Some(privs) = privileges { - let mut result = "\n\n## Required authorization\n\n".to_string(); - if !privs.index.is_empty() { - result += "* Index privileges: "; - result += &privs.index.iter() - .map(|a| format!("`{a}`")) - .join(","); - result += "\n"; - } - if !privs.cluster.is_empty() { - result += "* Cluster privileges: "; - result += &privs.cluster.iter() - .map(|a| format!("`{a}`")) - .join(","); - result += "\n"; - } - return Some(result) - } - None -} - #[derive(PartialEq,Debug)] struct SplitDesc { summary: Option, diff --git a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm index 7dc834a35a..e1a48ddd77 100644 Binary files a/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm and b/compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm differ