Skip to main content

oag_react_swr_client/
generator.rs

1use oag_core::config::{GeneratorConfig, GeneratorId};
2use oag_core::ir::IrSpec;
3use oag_core::{CodeGenerator, GeneratedFile, GeneratorError, normalize_generated};
4use oag_node_client::NodeClientGenerator;
5use oag_node_client::emitters::source_path;
6
7use crate::emitters;
8
9/// React/SWR code generator. Produces the TypeScript client files plus React hooks.
10pub struct ReactSwrClientGenerator;
11
12impl CodeGenerator for ReactSwrClientGenerator {
13    fn id(&self) -> GeneratorId {
14        GeneratorId::ReactSwrClient
15    }
16
17    fn generate(
18        &self,
19        ir: &IrSpec,
20        config: &GeneratorConfig,
21    ) -> Result<Vec<GeneratedFile>, GeneratorError> {
22        let scaffold_options = NodeClientGenerator::build_scaffold_options(ir, config, true);
23
24        // Generate base TypeScript client files via the node-client generator
25        // We manually produce the files to inject react scaffold options
26        let no_jsdoc = config.no_jsdoc.unwrap_or(false);
27        let sd = &config.source_dir;
28        let mut files = vec![
29            GeneratedFile {
30                path: source_path(sd, "types.ts"),
31                content: oag_node_client::emitters::types::emit_types(ir),
32            },
33            GeneratedFile {
34                path: source_path(sd, "sse.ts"),
35                content: oag_node_client::emitters::sse::emit_sse(),
36            },
37            GeneratedFile {
38                path: source_path(sd, "client.ts"),
39                content: oag_node_client::emitters::client::emit_client(ir, no_jsdoc),
40            },
41        ];
42
43        if let Some(ref scaffold) = scaffold_options {
44            files.extend(oag_node_client::emitters::scaffold::emit_scaffold(scaffold));
45
46            if scaffold.test_runner.is_some() {
47                files.push(GeneratedFile {
48                    path: source_path(sd, "client.test.ts"),
49                    content: oag_node_client::emitters::tests::emit_client_tests(ir),
50                });
51                files.push(GeneratedFile {
52                    path: source_path(sd, "hooks.test.tsx"),
53                    content: emitters::tests::emit_hooks_tests(ir),
54                });
55            }
56        }
57
58        // Add React-specific files
59        files.push(GeneratedFile {
60            path: source_path(sd, "hooks.tsx"),
61            content: emitters::hooks::emit_hooks(ir),
62        });
63
64        files.push(GeneratedFile {
65            path: source_path(sd, "provider.tsx"),
66            content: emitters::provider::emit_provider(),
67        });
68
69        // Add React index.tsx (includes hooks + provider exports)
70        files.push(GeneratedFile {
71            path: source_path(sd, "index.tsx"),
72            content: emitters::index::emit_index(),
73        });
74
75        for file in &mut files {
76            file.content = normalize_generated(&file.content);
77        }
78        Ok(files)
79    }
80}