vika_cli/commands/
update.rs1use crate::config::loader::load_config;
2use crate::config::validator::validate_config;
3use crate::error::Result;
4use crate::generator::api_client::generate_api_client;
5use crate::generator::swagger_parser::{fetch_and_parse_spec, filter_common_schemas};
6use crate::generator::ts_typings::generate_typings_with_registry;
7use crate::generator::writer::{write_api_client, write_schemas};
8use crate::generator::zod_schema::generate_zod_schemas_with_registry;
9use colored::*;
10use std::path::PathBuf;
11
12pub async fn run() -> Result<()> {
13 println!("{}", "🔄 Updating generated code...".bright_cyan());
14 println!();
15
16 let config = load_config()?;
18 validate_config(&config)?;
19
20 use crate::error::GenerationError;
21
22 let spec_path = config.spec_path.ok_or(GenerationError::SpecPathRequired)?;
24
25 let selected_modules = if config.modules.selected.is_empty() {
27 return Err(GenerationError::NoModulesSelected.into());
28 } else {
29 config.modules.selected.clone()
30 };
31
32 println!(
33 "{}",
34 format!("📥 Fetching spec from: {}", spec_path).bright_blue()
35 );
36 let parsed = fetch_and_parse_spec(&spec_path).await?;
37 println!(
38 "{}",
39 format!("✅ Parsed spec with {} modules", parsed.modules.len()).green()
40 );
41 println!();
42 println!(
43 "{}",
44 format!(
45 "📦 Updating {} module(s): {}",
46 selected_modules.len(),
47 selected_modules.join(", ")
48 )
49 .bright_green()
50 );
51 println!();
52
53 let (filtered_module_schemas, common_schemas) =
55 filter_common_schemas(&parsed.module_schemas, &selected_modules);
56
57 let schemas_dir = PathBuf::from(&config.schemas.output);
59 let apis_dir = PathBuf::from(&config.apis.output);
60
61 let mut total_files = 0;
62 let mut module_summary: Vec<(String, usize)> = Vec::new();
63
64 if !common_schemas.is_empty() {
66 println!("{}", "🔨 Regenerating common schemas...".bright_cyan());
67
68 let mut shared_enum_registry = std::collections::HashMap::new();
70
71 let common_types = generate_typings_with_registry(
73 &parsed.openapi,
74 &parsed.schemas,
75 &common_schemas,
76 &mut shared_enum_registry,
77 )?;
78
79 let common_zod_schemas = generate_zod_schemas_with_registry(
81 &parsed.openapi,
82 &parsed.schemas,
83 &common_schemas,
84 &mut shared_enum_registry,
85 )?;
86
87 let common_files =
89 write_schemas(&schemas_dir, "common", &common_types, &common_zod_schemas)?;
90 total_files += common_files.len();
91 module_summary.push(("common".to_string(), common_files.len()));
92 }
93
94 for module in &selected_modules {
95 println!(
96 "{}",
97 format!("🔨 Regenerating code for module: {}", module).bright_cyan()
98 );
99
100 let operations = parsed
102 .operations_by_tag
103 .get(module)
104 .cloned()
105 .unwrap_or_default();
106
107 if operations.is_empty() {
108 println!(
109 "{}",
110 format!("⚠️ No operations found for module: {}", module).yellow()
111 );
112 continue;
113 }
114
115 let module_schema_names = filtered_module_schemas
117 .get(module)
118 .cloned()
119 .unwrap_or_default();
120
121 let mut shared_enum_registry = std::collections::HashMap::new();
123
124 let types = if !module_schema_names.is_empty() {
126 generate_typings_with_registry(
127 &parsed.openapi,
128 &parsed.schemas,
129 &module_schema_names,
130 &mut shared_enum_registry,
131 )?
132 } else {
133 Vec::new()
134 };
135
136 let zod_schemas = if !module_schema_names.is_empty() {
138 generate_zod_schemas_with_registry(
139 &parsed.openapi,
140 &parsed.schemas,
141 &module_schema_names,
142 &mut shared_enum_registry,
143 )?
144 } else {
145 Vec::new()
146 };
147
148 let api_functions =
150 generate_api_client(&parsed.openapi, &operations, module, &common_schemas)?;
151
152 let schema_files = write_schemas(&schemas_dir, module, &types, &zod_schemas)?;
154 total_files += schema_files.len();
155
156 let api_files = write_api_client(&apis_dir, module, &api_functions)?;
158 total_files += api_files.len();
159
160 let module_file_count = schema_files.len() + api_files.len();
161 module_summary.push((module.clone(), module_file_count));
162 println!(
163 "{}",
164 format!(
165 "✅ Regenerated {} files for module: {}",
166 module_file_count, module
167 )
168 .green()
169 );
170 }
171
172 println!();
173 println!(
174 "{}",
175 format!("✨ Successfully updated {} files!", total_files).bright_green()
176 );
177 println!();
178 println!("{}", "Updated files:".bright_cyan());
179 println!(" 📁 Schemas: {}", config.schemas.output);
180 println!(" 📁 APIs: {}", config.apis.output);
181 println!();
182 if !module_summary.is_empty() {
183 println!("{}", "Module breakdown:".bright_cyan());
184 for (module, count) in &module_summary {
185 println!(" • {}: {} files", module, count);
186 }
187 }
188
189 Ok(())
190}