lenso_contract_codegen/
browser.rs1use std::{fmt::Write as _, path::Path};
2
3use super::{
4 CodegenError, contract_ir, load_descriptor, pascal_case, quote_string, snake_case,
5 typescript_property_name,
6};
7
8const BROWSER_RUNTIME_IMPORT: &str = r#"import {
9 validatePortableJson,
10 validateResult,
11 validateSchema,
12} from "@lenso/contract-runtime/browser";
13"#;
14
15pub fn generate_browser_request_client(path: &Path) -> Result<String, CodegenError> {
18 let descriptor = load_descriptor(path)?;
19 let contract = contract_ir(&descriptor);
20 let client_name = contract
21 .capability_id
22 .split('@')
23 .next()
24 .and_then(|id| id.rsplit('.').next())
25 .map_or_else(|| "Capability".to_owned(), pascal_case);
26 let mut methods = String::new();
27 for operation in contract
28 .operations
29 .iter()
30 .filter(|operation| operation.interaction == "request")
31 {
32 let descriptor_operation = descriptor
33 .operations
34 .iter()
35 .find(|candidate| candidate.name == operation.name)
36 .expect("Contract IR operations come from the Descriptor");
37 let method = typescript_property_name(&snake_case(&operation.name));
38 let route = format!(
39 "/api/capabilities/{}/{}",
40 contract.capability_id, operation.name
41 );
42 writeln!(
43 methods,
44 " async {method}(request, token) {{\n validateSchema(request, {request_schema}, \"request\");\n const response = await fetchTransport({}, {{\n method: \"POST\",\n headers: {{ \"authorization\": `Bearer ${{token}}`, \"content-type\": \"application/json\" }},\n body: JSON.stringify(request),\n }});\n const result = await response.json();\n validatePortableJson(result);\n validateResult(result, {response_schema}, {error_schema});\n return result;\n }},",
45 quote_string(&route),
46 request_schema = descriptor_operation.request_schema,
47 response_schema = descriptor_operation.response_schema,
48 error_schema = descriptor_operation.domain_error_schema,
49 )
50 .expect("writing to a String cannot fail");
51 }
52 let mut output = format!(
53 "// @generated by lenso-contract-codegen from {}; do not edit.\n{BROWSER_RUNTIME_IMPORT}\n",
54 contract.capability_id
55 );
56 write!(
57 output,
58 "export function create{client_name}Client(fetchTransport = fetch) {{\n return {{\n{methods} }};\n}}\n"
59 )
60 .expect("writing to a String cannot fail");
61 Ok(output)
62}