Skip to content

Commit df24db9

Browse files
committed
Merge multiple paths in a single operation
# Conflicts: # compiler-rs/clients_schema_to_openapi/src/lib.rs # compiler-rs/compiler-wasm-lib/pkg/compiler_wasm_lib_bg.wasm
1 parent 1302eb5 commit df24db9

File tree

4 files changed

+11207
-25719
lines changed

4 files changed

+11207
-25719
lines changed

compiler-rs/clients_schema_to_openapi/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ use crate::components::TypesAndComponents;
3131
pub struct Configuration {
3232
pub flavor: Option<Flavor>,
3333
pub namespaces: Option<Vec<String>>,
34+
35+
/// If a property value is an enumeration, the description of possible values will be copied in the
36+
/// property's description (also works for arrays of enums).
3437
pub lift_enum_descriptions: bool,
38+
39+
/// Will output endpoints having multiple paths into a single operation. The operation's path will
40+
/// be the longest one (with values for all optional parameters), and the other paths will be added
41+
/// at the beginning of the operation's description.
42+
pub merge_multipath_endpoints: bool,
3543
}
3644

3745
/// Convert an API model into an OpenAPI v3 schema, optionally filtered for a given flavor

compiler-rs/clients_schema_to_openapi/src/paths.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,67 @@ pub fn add_endpoint(
228228
// TODO: add error responses
229229
};
230230

231+
//---- Merge multipath endpoints if asked for
232+
let mut new_endpoint: clients_schema::Endpoint;
233+
234+
let endpoint = if is_multipath && tac.config.merge_multipath_endpoints {
235+
new_endpoint = endpoint.clone();
236+
let endpoint = &mut new_endpoint;
237+
238+
// Sort paths from smallest to longest
239+
endpoint.urls.sort_by_key(|x| x.path.len());
240+
241+
// Keep the longest and its last method so that the operation's path+method are the same as the last one
242+
// (avoids the perception that it may have been chosen randomly).
243+
let mut longest_path = endpoint.urls.last().unwrap().clone();
244+
while longest_path.methods.len() > 1 {
245+
longest_path.methods.remove(0);
246+
}
247+
248+
// Replace endpoint urls with the longest path
249+
let mut urls = vec![longest_path];
250+
std::mem::swap(&mut endpoint.urls, &mut urls);
251+
252+
let split_desc = split_summary_desc(&endpoint.description);
253+
254+
// Make sure the description is stays at the top
255+
let mut description = match split_desc.summary {
256+
Some(summary) => format!("{summary}\n\n"),
257+
None => String::new(),
258+
};
259+
260+
// Convert removed paths to descriptions
261+
write!(description, "**All methods and paths for this operation:**\n\n")?;
262+
263+
for url in urls {
264+
for method in url.methods {
265+
let lower_method = method.to_lowercase();
266+
let path = &url.path;
267+
write!(
268+
description,
269+
r#"<div><operation-summary>
270+
<span class="operation-verb {lower_method}">{method}</span>
271+
<span class="operation-path">{path}</span>
272+
</operation-summary></div>
273+
"#
274+
)?;
275+
}
276+
}
277+
278+
if let Some(desc) = &split_desc.description {
279+
write!(description, "\n\n{}", desc)?;
280+
}
281+
282+
// Replace description
283+
endpoint.description = description;
284+
285+
// Done
286+
endpoint
287+
} else {
288+
// Not multipath or not asked to merge multipath
289+
endpoint
290+
};
291+
231292
//---- Build a path for each url + method
232293
let mut operation_counter = 0;
233294

0 commit comments

Comments
 (0)