Skip to main content

aperture_cli/cache/
models.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
5pub struct CachedSpec {
6    /// Cache format version to detect incompatible changes
7    pub cache_format_version: u32,
8    pub name: String,
9    pub version: String,
10    pub commands: Vec<CachedCommand>,
11    /// Base URL extracted from the first server in the `OpenAPI` spec
12    pub base_url: Option<String>,
13    /// All server URLs from the `OpenAPI` spec for future multi-environment support
14    pub servers: Vec<String>,
15    /// Security schemes defined in the `OpenAPI` spec with `x-aperture-secret` mappings
16    pub security_schemes: HashMap<String, CachedSecurityScheme>,
17    /// Endpoints skipped during validation due to unsupported features (added in v0.1.2)
18    #[serde(default)]
19    pub skipped_endpoints: Vec<SkippedEndpoint>,
20    /// Server variables defined in the `OpenAPI` spec for URL template resolution (added in v0.1.3)
21    #[serde(default)]
22    pub server_variables: HashMap<String, ServerVariable>,
23}
24
25impl CachedSpec {
26    /// Creates a new `CachedSpec` with default values for testing
27    #[cfg(test)]
28    #[must_use]
29    pub fn new_for_test(name: &str) -> Self {
30        Self {
31            cache_format_version: CACHE_FORMAT_VERSION,
32            name: name.to_string(),
33            version: "1.0.0".to_string(),
34            commands: vec![],
35            base_url: None,
36            servers: vec![],
37            security_schemes: HashMap::new(),
38            skipped_endpoints: vec![],
39            server_variables: HashMap::new(),
40        }
41    }
42}
43
44/// Example usage for a command
45#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
46pub struct CommandExample {
47    /// Brief description of what this example demonstrates
48    pub description: String,
49    /// The complete command line example
50    pub command_line: String,
51    /// Optional explanation of the parameters used
52    pub explanation: Option<String>,
53}
54
55/// Information about an endpoint that was skipped during spec validation
56#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
57pub struct SkippedEndpoint {
58    pub path: String,
59    pub method: String,
60    pub content_type: String,
61    pub reason: String,
62}
63
64/// Current cache format version - increment when making breaking changes to `CachedSpec`
65///
66/// Version 2: Added `skipped_endpoints` field to track endpoints skipped during validation
67/// Version 3: Added `server_variables` field to support `OpenAPI` server URL template variables
68/// Version 4: Added `example` field to `CachedResponse` for response schema examples
69/// Version 5: Added `display_group`, `display_name`, `aliases`, `hidden` fields for command mapping
70pub const CACHE_FORMAT_VERSION: u32 = 5;
71
72/// Global cache metadata for all cached specifications
73#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
74pub struct GlobalCacheMetadata {
75    /// Cache format version for all specs
76    pub cache_format_version: u32,
77    /// Individual spec metadata
78    pub specs: std::collections::HashMap<String, SpecMetadata>,
79}
80
81/// Metadata for a single cached specification
82#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
83pub struct SpecMetadata {
84    /// When this spec cache was created/updated
85    pub updated_at: String, // Using String for simplicity in serialization
86    /// Size of the cached spec file in bytes
87    pub file_size: u64,
88    /// SHA-256 hash of the original spec file content for cache invalidation
89    #[serde(default)]
90    pub content_hash: Option<String>,
91    /// File modification time (seconds since epoch) for fast staleness checks
92    #[serde(default)]
93    pub mtime_secs: Option<u64>,
94    /// Size of the original spec file in bytes (distinct from cached binary size)
95    #[serde(default)]
96    pub spec_file_size: Option<u64>,
97}
98
99impl Default for GlobalCacheMetadata {
100    fn default() -> Self {
101        Self {
102            cache_format_version: CACHE_FORMAT_VERSION,
103            specs: std::collections::HashMap::new(),
104        }
105    }
106}
107
108#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
109pub struct CachedCommand {
110    pub name: String,
111    pub description: Option<String>,
112    pub summary: Option<String>,
113    pub operation_id: String,
114    pub method: String,
115    pub path: String,
116    pub parameters: Vec<CachedParameter>,
117    pub request_body: Option<CachedRequestBody>,
118    pub responses: Vec<CachedResponse>,
119    /// Security requirements for this operation (references to security scheme names)
120    pub security_requirements: Vec<String>,
121    /// All tags associated with this operation
122    pub tags: Vec<String>,
123    /// Whether this operation is deprecated
124    pub deprecated: bool,
125    /// External documentation URL if available
126    pub external_docs_url: Option<String>,
127    /// Usage examples for this command (added in v0.1.6)
128    #[serde(default)]
129    pub examples: Vec<CommandExample>,
130    /// Display name override for the command group (tag), from command mapping (added in v5)
131    #[serde(default)]
132    pub display_group: Option<String>,
133    /// Display name override for the subcommand (operation), from command mapping (added in v5)
134    #[serde(default)]
135    pub display_name: Option<String>,
136    /// Additional subcommand aliases from command mapping (added in v5)
137    #[serde(default)]
138    pub aliases: Vec<String>,
139    /// Whether this command is hidden from help output, from command mapping (added in v5)
140    #[serde(default)]
141    pub hidden: bool,
142}
143
144#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
145pub struct CachedParameter {
146    pub name: String,
147    pub location: String,
148    pub required: bool,
149    pub description: Option<String>,
150    pub schema: Option<String>,
151    pub schema_type: Option<String>,
152    pub format: Option<String>,
153    pub default_value: Option<String>,
154    pub enum_values: Vec<String>,
155    pub example: Option<String>,
156}
157
158#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
159pub struct CachedRequestBody {
160    pub content_type: String,
161    pub schema: String,
162    pub required: bool,
163    pub description: Option<String>,
164    pub example: Option<String>,
165}
166
167#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
168pub struct CachedResponse {
169    pub status_code: String,
170    pub description: Option<String>,
171    pub content_type: Option<String>,
172    pub schema: Option<String>,
173    /// Example response value (JSON-serialized)
174    #[serde(default)]
175    pub example: Option<String>,
176}
177
178/// Cached representation of a security scheme with x-aperture-secret mapping
179#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
180pub struct CachedSecurityScheme {
181    /// Security scheme name from the `OpenAPI` spec
182    pub name: String,
183    /// Type of security scheme (apiKey, http, oauth2, etc.)
184    pub scheme_type: String,
185    /// Subtype for http schemes (bearer, basic, etc.)
186    pub scheme: Option<String>,
187    /// Location for apiKey schemes (header, query, cookie)
188    pub location: Option<String>,
189    /// Parameter name for apiKey schemes (e.g., "Authorization", "X-API-Key")
190    pub parameter_name: Option<String>,
191    /// Description of the security scheme from `OpenAPI` spec
192    pub description: Option<String>,
193    /// Bearer format for HTTP bearer schemes (e.g., "JWT")
194    pub bearer_format: Option<String>,
195    /// x-aperture-secret mapping for environment variable resolution
196    pub aperture_secret: Option<CachedApertureSecret>,
197}
198
199/// Cached representation of x-aperture-secret extension
200#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
201pub struct CachedApertureSecret {
202    /// Source of the secret (currently only "env" supported)
203    pub source: String,
204    /// Environment variable name to read the secret from
205    pub name: String,
206}
207
208/// Cached representation of an `OpenAPI` server variable for URL template resolution
209#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
210pub struct ServerVariable {
211    /// Default value for the variable if not provided via CLI
212    pub default: Option<String>,
213    /// Allowed values for the variable (enum constraint)
214    pub enum_values: Vec<String>,
215    /// Description of the server variable from `OpenAPI` spec
216    pub description: Option<String>,
217}