oa_forge_emitter_msw/
lib.rs1use std::fmt::Write;
2
3use oa_forge_ir::*;
4
5pub fn emit(api: &ApiSpec, out: &mut String) -> Result<(), std::fmt::Error> {
7 writeln!(out, "// Generated by oa-forge. Do not edit.")?;
8 writeln!(out)?;
9 writeln!(out, "import {{ http, HttpResponse }} from 'msw';")?;
10 writeln!(out, "import type * as Types from './types.gen';")?;
11 writeln!(out)?;
12
13 for endpoint in &api.endpoints {
15 emit_handler_function(endpoint, out)?;
16 }
17
18 writeln!(out, "export const handlers = [")?;
20 for endpoint in &api.endpoints {
21 writeln!(out, " {}Handler(),", endpoint.operation_id)?;
22 }
23 writeln!(out, "];")?;
24
25 Ok(())
26}
27
28fn emit_handler_function(endpoint: &Endpoint, out: &mut String) -> Result<(), std::fmt::Error> {
31 let id = &endpoint.operation_id;
32 let method = endpoint.method.as_lower();
33 let msw_path = path_to_colon_params(&endpoint.path);
34
35 let has_response = endpoint.response.is_some();
36 let response_type = if has_response {
37 format!("Types.{id}Response")
38 } else {
39 "undefined".to_string()
40 };
41
42 writeln!(
44 out,
45 "export function {id}Handler(override?: {response_type} | (() => {response_type})) {{"
46 )?;
47
48 writeln!(out, " return http.{method}('{msw_path}', () => {{")?;
49
50 match endpoint.response_type {
52 ResponseType::Void => {
53 writeln!(out, " return new HttpResponse(null, {{ status: 204 }});")?;
54 }
55 ResponseType::Text => {
56 writeln!(
57 out,
58 " const data = typeof override === 'function' ? override() : override;"
59 )?;
60 writeln!(out, " return HttpResponse.text(data as string ?? '');")?;
61 }
62 ResponseType::Blob => {
63 writeln!(out, " return new HttpResponse(null, {{ status: 200 }});")?;
64 }
65 ResponseType::Json => {
66 writeln!(
67 out,
68 " const data = typeof override === 'function' ? override() : override;"
69 )?;
70 writeln!(out, " return HttpResponse.json(data ?? {{}});")?;
71 }
72 }
73
74 writeln!(out, " }});")?;
75 writeln!(out, "}}")?;
76 writeln!(out)?;
77
78 Ok(())
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn converts_openapi_path_to_msw() {
87 assert_eq!(path_to_colon_params("/pets"), "/pets");
88 assert_eq!(path_to_colon_params("/pets/{petId}"), "/pets/:petId");
89 assert_eq!(
90 path_to_colon_params("/users/{userId}/posts/{postId}"),
91 "/users/:userId/posts/:postId"
92 );
93 }
94}