vika_cli/generator/hooks/
context.rs

1use crate::generator::utils::sanitize_module_name;
2use crate::templates::context::Parameter;
3use serde::Serialize;
4
5/// Context for hook generation.
6#[derive(Debug, Clone, Serialize)]
7pub struct HookContext {
8    pub hook_name: String,
9    pub key_name: String,
10    pub operation_id: String,
11    pub http_method: String,
12    pub path: String,
13    pub path_params: Vec<Parameter>,
14    pub query_params: Vec<Parameter>,
15    pub body_type: Option<String>,
16    pub response_type: String,
17    pub module_name: String,
18    pub spec_name: Option<String>,
19    pub api_import_path: String,
20    pub query_keys_import_path: String,
21    pub param_list: String, // Full parameter list with types: "id: string, query?: { page?: number }"
22    pub param_names: String, // Just parameter names for function calls: "id, query"
23    pub path_param_names: String, // Just path parameter names: "id"
24    pub schema_imports: String, // Schema import statements
25    pub description: String,
26}
27
28impl HookContext {
29    /// Calculate import path to API functions.
30    /// From: src/hooks/{spec}/{module}/useX.ts
31    /// To: src/apis/{spec}/{module}/index.ts
32    pub fn calculate_api_import_path(module_name: &str, spec_name: Option<&str>) -> String {
33        // Calculate depth: hooks/{spec}/{module}/ -> apis/{spec}/{module}/
34        // For multi-spec: hooks/orders/orders/ -> ../../../apis/orders/orders
35        // For single-spec: hooks/users/ -> ../../apis/users
36        let module_depth = module_name.matches('/').count() + 1; // +1 for module directory
37        let spec_depth = if spec_name.is_some() { 1 } else { 0 };
38        let total_depth = module_depth + spec_depth + 1; // +1 for hooks directory
39
40        let sanitized_module = sanitize_module_name(module_name);
41
42        if let Some(spec) = spec_name {
43            let sanitized_spec = sanitize_module_name(spec);
44            format!(
45                "{}apis/{}/{}",
46                "../".repeat(total_depth),
47                sanitized_spec,
48                sanitized_module
49            )
50        } else {
51            format!("{}apis/{}", "../".repeat(total_depth), sanitized_module)
52        }
53    }
54
55    /// Calculate import path to query keys.
56    /// From: src/hooks/{spec}/{module}/useX.ts
57    /// To: src/query-keys/{spec}/{module}.ts
58    pub fn calculate_query_keys_import_path(module_name: &str, spec_name: Option<&str>) -> String {
59        // Calculate depth: hooks/{spec}/{module}/ -> query-keys/{spec}/{module}.ts
60        // For multi-spec: hooks/orders/orders/ -> ../../../query-keys/orders/orders
61        // For single-spec: hooks/users/ -> ../../query-keys/users
62        let module_depth = module_name.matches('/').count() + 1; // +1 for module directory
63        let spec_depth = if spec_name.is_some() { 1 } else { 0 };
64        let total_depth = module_depth + spec_depth + 1; // +1 for hooks directory
65
66        let sanitized_module = sanitize_module_name(module_name);
67
68        if let Some(spec) = spec_name {
69            let sanitized_spec = sanitize_module_name(spec);
70            format!(
71                "{}query-keys/{}/{}",
72                "../".repeat(total_depth),
73                sanitized_spec,
74                sanitized_module
75            )
76        } else {
77            format!(
78                "{}query-keys/{}",
79                "../".repeat(total_depth),
80                sanitized_module
81            )
82        }
83    }
84}