use crate::postman::{Item, Request, Response};
use pulldown_cmark::html;
struct Route {
method: String,
path: String,
}
impl Route {
fn new(method: String, path: String) -> Route {
Route { method, path }
}
}
fn remove_braces(text: &String) -> String {
if text.contains("{") {
let mut fixed_text: String;
fixed_text = text.replace("{", "");
fixed_text = fixed_text.replace("}", "");
fixed_text
} else {
text.to_string()
}
}
fn folder_endpoints(i: u16, item: &Item, routes: Vec<Route>, description: String) -> String {
let mut routes_html = format!("<p>{} Endpoints</p>\n", item.name);
let name = wrap_literal(&item.name);
if routes.len() > 0 {
for route in routes {
let method = route.method;
let path = wrap_literal(&route.path);
routes_html.push_str(&format!(
"<p><span class='{method}'>{method}</span>{path}</p>\n",
))
}
return format!(
r#"
<h{i} id={name}>{name}</h{i}>
<div class="grid grid-cols-1 md:grid-cols-2">
<div class="p-2">
{description}
</div>
<div class="p-6 pl-0 mx-10 rounded-xl bg-primary-800 border-primary-100 border">
{routes_html}
</div>
</div>
"#
);
} else {
return format!(
r#"
<h{i} id={name}>{name}</h{i}>
<div>
<div class="p-2">
{description}
</div>
</div>
"#
);
}
}
fn wrap_literal(text: &String) -> String {
let mut fixed_text = r#"{`"#.to_string();
fixed_text.push_str(&text);
fixed_text.push_str(r#"`}"#);
fixed_text
}
pub fn folder(folder: &Item, i: u16) -> (String, String) {
let mut description_html = "".to_string();
if let Some(description) = &folder.description {
let parser = pulldown_cmark::Parser::new(description);
html::push_html(&mut description_html, parser);
}
let mut routes: Vec<Route> = Vec::new();
if let Some(sub_folder) = &folder.item {
for item in sub_folder {
if let Some(request) = &item.request {
if let Some((_, path_no_base)) = request.url.raw.split_once('/') {
let mut path_fixed = "/".to_string();
path_fixed.push_str(path_no_base);
if let Some((path_no_params, _)) = path_fixed.split_once('?') {
let route = Route::new(request.method.clone(), path_no_params.to_string());
routes.push(route);
} else {
let route = Route::new(request.method.clone(), path_fixed);
routes.push(route);
}
}
}
}
}
let folder_markup = folder_endpoints(i, folder, routes, description_html);
let name = remove_braces(&folder.name);
let link = format!("<a href='#{name}' class='a{i}'>{name}</a>");
return (folder_markup, link);
}
pub fn request(item: &Item, request: &Request, i: u16) -> (String, String) {
let mut description_parsed = String::new();
if let Some(description) = &request.description {
let mut html_output = String::new();
let parser = pulldown_cmark::Parser::new(description);
html::push_html(&mut html_output, parser);
description_parsed.push_str(&html_output);
}
let url = &request.url.raw;
let method = &request.method;
let mut request_data = format!("\n'{i}': {{\npath: `{url}`,\nmethod: '{method}',\n");
if let Some(body) = &request.body {
request_data.push_str("body: `");
request_data.push_str(&body.raw);
request_data.push_str("`,");
}
request_data.push_str("},");
let re = regex::Regex::new(r"\{\{(\w+)\}\}").expect("Unable to parse regex");
let request_data_fixed = re
.replace_all(&request_data, |caps: ®ex::Captures| {
format!("${{$envs[$vars.environment].{}}}", &caps[1])
})
.to_string();
let name = &item.name;
let mut result = format!("\n<Request key={{'{i}'}} title='{name}' >\n",);
result.push_str(&description_parsed);
result.push_str("\n</Request>\n");
(result, request_data_fixed)
}
pub fn response(responses: &Vec<Response>) -> String {
let mut responses_markup = String::new();
for response in responses {
let body = wrap_literal(&response.body);
let name = &response.name;
let response_markup = format!("<h6>{name}</h6>IndexMap<pre><code>{body}</code></pre>");
responses_markup.push_str(&response_markup);
}
responses_markup
}
pub fn requests(requests_json: &String) -> String {
let mut data = r#"
import type { RequestsType } from "./globals";
import type { Readable } from "svelte/store";
import { derived } from "svelte/store";
import { vars } from "./store";
import { envs } from "./envs";
export const requests: Readable<RequestsType> = derived(
[vars, envs],
([$vars, $envs]) => {
return {
"#
.to_string();
data.push_str(&requests_json);
data.push_str(
r#"
}
}
);"#,
);
data
}