Skip to main content

schemaui_cli/web/
mod.rs

1use std::fs;
2use std::path::PathBuf;
3
4use color_eyre::eyre::{Report, Result};
5use schemaui::precompile::web::{
6    build_session_snapshot_from_files, write_session_snapshot_json,
7    write_session_snapshot_ts_module,
8};
9use schemaui::web::session::ServeOptions as WebServeOptions;
10use schemaui::{DocumentFormat, SchemaUI};
11
12use crate::cli::{WebCommand, WebSnapshotCommand};
13use crate::session::{SessionBundle, prepare_session};
14
15pub fn run_cli(cmd: WebCommand) -> Result<()> {
16    let session = prepare_session(&cmd.common)?;
17    execute_web_session(session, cmd)
18}
19
20fn execute_web_session(session: SessionBundle, cmd: WebCommand) -> Result<()> {
21    let SessionBundle {
22        schema,
23        defaults,
24        title,
25        output,
26    } = session;
27
28    let mut ui = SchemaUI::new(schema);
29    if let Some(title) = title {
30        ui = ui.with_title(title);
31    }
32    if let Some(ref defaults) = defaults {
33        ui = ui.with_default_data(defaults);
34    }
35    if let Some(options) = output {
36        ui = ui.with_output(options);
37    }
38
39    let serve = WebServeOptions {
40        host: cmd.host,
41        port: cmd.port,
42    };
43
44    ui.run_web(serve).map_err(Report::msg).map(|_| ())
45}
46
47pub fn run_snapshot_cli(cmd: WebSnapshotCommand) -> Result<()> {
48    // For snapshots we intentionally use a simpler pipeline that only supports
49    // file-based schema/config. This keeps behaviour predictable and mirrors
50    // the `web_snapshot_codegen` example.
51
52    let schema_spec = cmd
53        .common
54        .schema
55        .as_deref()
56        .ok_or_else(|| Report::msg("web-snapshot requires --schema <PATH>"))?;
57    if schema_spec == "-" {
58        return Err(Report::msg(
59            "web-snapshot does not support --schema - (stdin); please pass a file path",
60        ));
61    }
62
63    let config_spec = cmd.common.config.as_deref();
64    if config_spec == Some("-") {
65        return Err(Report::msg(
66            "web-snapshot does not support --config - (stdin); please pass a file path",
67        ));
68    }
69
70    let schema_path = PathBuf::from(schema_spec);
71    if !schema_path.exists() {
72        return Err(Report::msg(format!(
73            "schema path {:?} does not exist",
74            schema_path
75        )));
76    }
77
78    let defaults_path = config_spec.map(PathBuf::from);
79    if let Some(ref p) = defaults_path
80        && !p.exists()
81    {
82        return Err(Report::msg(format!("config path {:?} does not exist", p)));
83    }
84
85    let format = DocumentFormat::from_extension(&schema_path).unwrap_or(DocumentFormat::Json);
86
87    let snapshot =
88        build_session_snapshot_from_files(&schema_path, format, defaults_path.as_deref())
89            .map_err(Report::msg)?;
90
91    fs::create_dir_all(&cmd.out_dir)?;
92    let json_out = cmd.out_dir.join("session_snapshot.json");
93    let ts_out = cmd.out_dir.join("session_snapshot.ts");
94
95    write_session_snapshot_json(&snapshot, &json_out).map_err(Report::msg)?;
96    write_session_snapshot_ts_module(&snapshot, &ts_out, &cmd.ts_export).map_err(Report::msg)?;
97
98    eprintln!("Generated Web precompile snapshots:");
99    eprintln!("  JSON:      {:?}", json_out);
100    eprintln!("  TypeScript: {:?}", ts_out);
101
102    Ok(())
103}