Skip to main content

schemaui_cli/web/
mod.rs

1use std::fs;
2
3use color_eyre::eyre::{Report, Result};
4use schemaui::SchemaUI;
5use schemaui::precompile::web::{
6    build_session_snapshot, write_session_snapshot_json, write_session_snapshot_ts_module,
7};
8use schemaui::web::session::ServeOptions as WebServeOptions;
9
10use crate::cli::{WebCommand, WebSnapshotCommand};
11use crate::session::diagnostics::DiagnosticCollector;
12use crate::session::format::resolve_format_hint;
13use crate::session::schema_source::{load_optional_document, resolve_session_inputs};
14use crate::session::{SessionBundle, prepare_session};
15
16pub fn run_cli(cmd: WebCommand) -> Result<()> {
17    let session = prepare_session(&cmd.common)?;
18    execute_web_session(session, cmd)
19}
20
21fn execute_web_session(session: SessionBundle, cmd: WebCommand) -> Result<()> {
22    let SessionBundle {
23        schema,
24        defaults,
25        title,
26        output,
27    } = session;
28
29    let mut ui = SchemaUI::new(schema);
30    if let Some(title) = title {
31        ui = ui.with_title(title);
32    }
33    if let Some(ref defaults) = defaults {
34        ui = ui.with_default_data(defaults);
35    }
36    if let Some(options) = output {
37        ui = ui.with_output(options);
38    }
39
40    let serve = WebServeOptions {
41        host: cmd.host,
42        port: cmd.port,
43    };
44
45    ui.run_web(serve).map_err(Report::msg).map(|_| ())
46}
47
48pub fn run_snapshot_cli(cmd: WebSnapshotCommand) -> Result<()> {
49    let schema_spec = cmd.common.schema.as_deref();
50    let config_spec = cmd.common.config.as_deref();
51    let mut diagnostics = DiagnosticCollector::default();
52    let schema_stdin = schema_spec == Some("-");
53    let config_stdin = config_spec == Some("-");
54    if schema_stdin && config_stdin {
55        diagnostics.push_input(
56            "schema/config",
57            "cannot read schema and config from stdin simultaneously; provide inline content, files, or a remote schema",
58        );
59    }
60    let schema_hint = resolve_format_hint(schema_spec, "schema", &mut diagnostics);
61    let config_hint = resolve_format_hint(config_spec, "config", &mut diagnostics);
62    let schema_document = load_optional_document(
63        schema_spec,
64        schema_hint.hint.format,
65        "schema",
66        schema_hint.blocked || (schema_stdin && config_stdin),
67        &mut diagnostics,
68    );
69    let config_document = load_optional_document(
70        config_spec,
71        config_hint.hint.format,
72        "config",
73        config_hint.blocked || (schema_stdin && config_stdin),
74        &mut diagnostics,
75    );
76    diagnostics.into_result()?;
77    let resolved = resolve_session_inputs(schema_document, config_document).map_err(Report::msg)?;
78    let snapshot = build_session_snapshot(&resolved.schema, resolved.defaults.as_ref())
79        .map_err(Report::msg)?;
80
81    fs::create_dir_all(&cmd.out_dir)?;
82    let json_out = cmd.out_dir.join("session_snapshot.json");
83    let ts_out = cmd.out_dir.join("session_snapshot.ts");
84
85    write_session_snapshot_json(&snapshot, &json_out).map_err(Report::msg)?;
86    write_session_snapshot_ts_module(&snapshot, &ts_out, &cmd.ts_export).map_err(Report::msg)?;
87
88    eprintln!("Generated Web precompile snapshots:");
89    eprintln!("  JSON:      {:?}", json_out);
90    eprintln!("  TypeScript: {:?}", ts_out);
91
92    Ok(())
93}