alibi_core/openapi/
annotations.rs1use super::{OpenApiEndpoint, OpenApiField, OpenApiModel, PluginOpenApiMetadata};
3use crate::AuthRoute;
4use alibi_schema_registry::{EntityRole, FieldDef, core_fields};
5use serde_json::json;
6
7fn wire_name(name: &str) -> String {
8 let mut words = name.split('_');
9 let mut output = words.next().unwrap_or_default().to_owned();
10 for word in words {
11 let mut letters = word.chars();
12 if let Some(first) = letters.next() {
13 output.extend(first.to_uppercase());
14 output.extend(letters);
15 }
16 }
17 output
18}
19fn field(field: &FieldDef, core: bool) -> Option<OpenApiField> {
20 if field.is_primary_key {
21 return None;
22 }
23 let ty = field.ty.trim_start_matches("Option<").trim_end_matches('>');
24 let schema = match ty {
25 "DateTimeUtc" => json!({"type":"string","format":"date-time"}),
26 "bool" => json!({"type":"boolean"}),
27 "i64" | "f64" => json!({"type":"number"}),
28 "Json" => json!({"type":"json"}),
29 _ => json!({"type":"string"}),
30 };
31 let mut field = OpenApiField::new(
32 wire_name(field.name),
33 schema,
34 !field.ty.starts_with("Option<"),
35 );
36 if core && matches!(field.name.as_str(), "name" | "email") {
37 field.required = true;
38 }
39 if core && field.name == "emailVerified" {
40 field.input = false;
41 if let Some(object) = field.schema.as_object_mut() {
42 _ = object.insert("default".into(), json!(false));
43 }
44 }
45 Some(field)
46}
47#[must_use]
49pub fn core_models() -> Vec<OpenApiModel> {
50 [
51 ("User", EntityRole::User),
52 ("Session", EntityRole::Session),
53 ("Account", EntityRole::Account),
54 ("Verification", EntityRole::Verification),
55 ]
56 .into_iter()
57 .map(|(name, role)| {
58 OpenApiModel::new(
59 name,
60 core_fields(role)
61 .iter()
62 .filter_map(|definition| field(definition, true))
63 .collect(),
64 )
65 })
66 .collect()
67}
68#[must_use]
70pub fn route_metadata(routes: &[AuthRoute]) -> PluginOpenApiMetadata {
71 PluginOpenApiMetadata {
72 endpoints: routes
73 .iter()
74 .map(|route| {
75 (
76 route.method.clone(),
77 route.path.clone(),
78 OpenApiEndpoint {
79 operation_id: Some(route.operation_id.clone()),
80 ..Default::default()
81 },
82 )
83 })
84 .collect(),
85 ..Default::default()
86 }
87}