oag_node_client/emitters/
types.rs1use minijinja::{Environment, context};
2use oag_core::ir::{IrObjectSchema, IrReturnType, IrSchema, IrSpec};
3
4use crate::type_mapper::ir_type_to_ts;
5
6pub fn emit_types(ir: &IrSpec) -> String {
8 let mut env = Environment::new();
9 env.add_template("types.ts.j2", include_str!("../../templates/types.ts.j2"))
10 .expect("template should be valid");
11 let tmpl = env.get_template("types.ts.j2").unwrap();
12
13 let schemas: Vec<_> = ir.schemas.iter().map(schema_to_ctx).collect();
14 let sse_event_types = collect_sse_event_types(ir);
15
16 tmpl.render(context! {
17 schemas => schemas,
18 sse_event_types => sse_event_types,
19 })
20 .expect("render should succeed")
21}
22
23fn schema_to_ctx(schema: &IrSchema) -> minijinja::Value {
24 match schema {
25 IrSchema::Object(obj) => object_to_ctx(obj),
26 IrSchema::Enum(e) => {
27 let variants: Vec<String> = e.variants.iter().map(|v| format!("\"{v}\"")).collect();
28 context! {
29 kind => "enum",
30 name => e.name.pascal_case.clone(),
31 description => e.description.clone(),
32 variants => variants,
33 }
34 }
35 IrSchema::Alias(a) => {
36 context! {
37 kind => "alias",
38 name => a.name.pascal_case.clone(),
39 description => a.description.clone(),
40 target => ir_type_to_ts(&a.target),
41 }
42 }
43 IrSchema::Union(u) => {
44 let variants: Vec<String> = u.variants.iter().map(ir_type_to_ts).collect();
45 context! {
46 kind => "union",
47 name => u.name.pascal_case.clone(),
48 description => u.description.clone(),
49 variants => variants,
50 }
51 }
52 }
53}
54
55fn object_to_ctx(obj: &IrObjectSchema) -> minijinja::Value {
56 let fields: Vec<minijinja::Value> = obj
57 .fields
58 .iter()
59 .map(|f| {
60 context! {
61 name => f.name.camel_case.clone(),
62 original_name => f.original_name.clone(),
63 type => ir_type_to_ts(&f.field_type),
64 required => f.required,
65 description => f.description.clone(),
66 }
67 })
68 .collect();
69
70 let additional = obj.additional_properties.as_ref().map(ir_type_to_ts);
71
72 context! {
73 kind => "object",
74 name => obj.name.pascal_case.clone(),
75 description => obj.description.clone(),
76 fields => fields,
77 additional_properties => additional,
78 }
79}
80
81fn collect_sse_event_types(ir: &IrSpec) -> Vec<minijinja::Value> {
82 let mut event_types = Vec::new();
83 for op in &ir.operations {
84 if let IrReturnType::Sse(sse) = &op.return_type
85 && let Some(ref event_name) = sse.event_type_name
86 {
87 let variants: Vec<String> = sse.variants.iter().map(ir_type_to_ts).collect();
88 if !variants.is_empty() {
89 event_types.push(context! {
90 name => event_name.clone(),
91 variants => variants,
92 });
93 }
94 }
95 }
96 event_types
97}