Skip to content
Open
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
50 changes: 48 additions & 2 deletions compiler-rs/clients_schema_to_openapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -201,6 +201,52 @@ pub fn product_meta_as_extensions(namespace: &str, product_meta: &IndexMap<Strin
result
}

pub fn auths_as_extentions(privileges: &Option<Privileges>) -> IndexMap<String, Value> {
let mut result = IndexMap::new();
let mut auths_list: Vec<Value> = 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<UrlTemplate>) -> IndexMap<String, Value> {
let mut result = IndexMap::new();
if !urls.is_empty() {
let mut paths_list: Vec<Value> = 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#"<div>
<span class="operation-verb {lower_method}">{method}</span>
<span class="operation-path">{path}</span>
</div>
"#)));
}
}
result.insert("x-variations".to_string(), Value::Array(paths_list));
}
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);
Expand Down
70 changes: 17 additions & 53 deletions compiler-rs/clients_schema_to_openapi/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,18 @@ 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
};
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.
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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#"<div>
<span class="operation-verb {lower_method}">{method}</span>
<span class="operation-path">{path}</span>
</div>
"#
)?;
}
}

if let Some(desc) = &split_desc.description {
write!(description, "\n\n{}", desc)?;
}
Expand Down Expand Up @@ -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![];
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -522,28 +508,6 @@ fn split_summary_desc(desc: &str) -> SplitDesc{
}
}

fn add_privileges(privileges: &Option<Privileges>) -> Option<String>{
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<String>,
Expand Down
Binary file modified compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm
Binary file not shown.
Loading