1use oag_core::ir::IrSpec;
2use oag_core::{CodeGenerator, GeneratedFile};
3use oag_typescript::emitters::scaffold::ScaffoldOptions;
4use oag_typescript::{TypeScriptConfig, TypeScriptGenerator};
5use thiserror::Error;
6
7use crate::emitters;
8
9#[derive(Debug, Error)]
10pub enum ReactError {
11 #[error("typescript generation failed: {0}")]
12 TypeScript(#[from] oag_typescript::generator::TypeScriptError),
13
14 #[error("template render failed: {0}")]
15 Render(String),
16}
17
18#[derive(Debug, Clone, Default)]
20pub struct ReactConfig {
21 pub base_url: Option<String>,
22 pub no_jsdoc: bool,
23 pub scaffold: Option<ScaffoldOptions>,
25}
26
27pub struct ReactGenerator;
29
30impl CodeGenerator for ReactGenerator {
31 type Config = ReactConfig;
32 type Error = ReactError;
33
34 fn generate(
35 &self,
36 ir: &IrSpec,
37 config: &Self::Config,
38 ) -> Result<Vec<GeneratedFile>, Self::Error> {
39 let ts_config = TypeScriptConfig {
41 base_url: config.base_url.clone(),
42 no_jsdoc: config.no_jsdoc,
43 scaffold: config.scaffold.clone(),
44 };
45 let mut files = TypeScriptGenerator.generate(ir, &ts_config)?;
46
47 files.push(GeneratedFile {
49 path: "hooks.ts".to_string(),
50 content: emitters::hooks::emit_hooks(ir),
51 });
52
53 files.push(GeneratedFile {
54 path: "provider.ts".to_string(),
55 content: emitters::provider::emit_provider(),
56 });
57
58 if let Some(idx) = files.iter().position(|f| f.path == "index.ts") {
60 files[idx] = GeneratedFile {
61 path: "index.ts".to_string(),
62 content: emitters::index::emit_index(),
63 };
64 }
65
66 Ok(files)
67 }
68}