Skip to main content

schemaui_cli/web/
mod.rs

1use std::fs;
2
3use anyhow::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        description,
27        output,
28    } = session;
29
30    let mut ui = if let Some(defaults) = defaults {
31        SchemaUI::new(defaults).with_schema(schema)
32    } else {
33        SchemaUI::from_schema(schema)
34    };
35    if let Some(title) = title {
36        ui = ui.with_title(title);
37    }
38    if let Some(description) = description {
39        ui = ui.with_description(description);
40    }
41
42    let serve = WebServeOptions {
43        host: cmd.host,
44        port: cmd.port,
45    };
46
47    let value = ui.run_web(serve)?;
48    if let Some(options) = output {
49        options.write(&value)?;
50    }
51    Ok(())
52}
53
54pub fn run_snapshot_cli(cmd: WebSnapshotCommand) -> Result<()> {
55    let schema_spec = cmd.common.schema.as_deref();
56    let config_spec = cmd.common.config.as_deref();
57    let mut diagnostics = DiagnosticCollector::default();
58    let schema_stdin = schema_spec == Some("-");
59    let config_stdin = config_spec == Some("-");
60    if schema_stdin && config_stdin {
61        diagnostics.push_input(
62            "schema/config",
63            "cannot read schema and config from stdin simultaneously; provide inline content, files, or a remote schema",
64        );
65    }
66    let schema_hint = resolve_format_hint(schema_spec, "schema", &mut diagnostics);
67    let config_hint = resolve_format_hint(config_spec, "config", &mut diagnostics);
68    let schema_document = load_optional_document(
69        schema_spec,
70        schema_hint.hint.format,
71        "schema",
72        schema_hint.blocked || (schema_stdin && config_stdin),
73        &mut diagnostics,
74    );
75    let config_document = load_optional_document(
76        config_spec,
77        config_hint.hint.format,
78        "config",
79        config_hint.blocked || (schema_stdin && config_stdin),
80        &mut diagnostics,
81    );
82    diagnostics.into_result()?;
83    let resolved = resolve_session_inputs(schema_document, config_document)?;
84    let mut snapshot = build_session_snapshot(&resolved.schema, resolved.defaults.as_ref())?;
85    if let Some(title) = cmd.common.title {
86        snapshot.title = Some(title);
87    }
88    if let Some(description) = cmd.common.description {
89        snapshot.description = Some(description);
90    }
91
92    fs::create_dir_all(&cmd.out_dir)?;
93    let json_out = cmd.out_dir.join("session_snapshot.json");
94    let ts_out = cmd.out_dir.join("session_snapshot.ts");
95
96    write_session_snapshot_json(&snapshot, &json_out)?;
97    write_session_snapshot_ts_module(&snapshot, &ts_out, &cmd.ts_export)?;
98
99    eprintln!("Generated Web precompile snapshots:");
100    eprintln!("  JSON:      {:?}", json_out);
101    eprintln!("  TypeScript: {:?}", ts_out);
102
103    Ok(())
104}