this repo has no description
1use crate::state::AppState; 2use axum::{ 3 Json, 4 extract::{Query, State}, 5 http::StatusCode, 6 response::{IntoResponse, Response}, 7}; 8use serde::Deserialize; 9use serde_json::json; 10 11#[derive(Deserialize)] 12pub struct DescribeRepoInput { 13 pub repo: String, 14} 15 16pub async fn describe_repo( 17 State(state): State<AppState>, 18 Query(input): Query<DescribeRepoInput>, 19) -> Response { 20 let hostname = std::env::var("PDS_HOSTNAME").unwrap_or_else(|_| "localhost".to_string()); 21 22 let user_row = if input.repo.starts_with("did:") { 23 sqlx::query!("SELECT id, handle, did FROM users WHERE did = $1", input.repo) 24 .fetch_optional(&state.db) 25 .await 26 .map(|opt| opt.map(|r| (r.id, r.handle, r.did))) 27 } else { 28 let suffix = format!(".{}", hostname); 29 let short_handle = if input.repo.ends_with(&suffix) { 30 input.repo.strip_suffix(&suffix).unwrap_or(&input.repo) 31 } else { 32 &input.repo 33 }; 34 sqlx::query!("SELECT id, handle, did FROM users WHERE handle = $1", short_handle) 35 .fetch_optional(&state.db) 36 .await 37 .map(|opt| opt.map(|r| (r.id, r.handle, r.did))) 38 }; 39 40 let (user_id, handle, did) = match user_row { 41 Ok(Some((id, handle, did))) => (id, handle, did), 42 _ => { 43 return ( 44 StatusCode::NOT_FOUND, 45 Json(json!({"error": "NotFound", "message": "Repo not found"})), 46 ) 47 .into_response(); 48 } 49 }; 50 51 let collections_query = 52 sqlx::query!("SELECT DISTINCT collection FROM records WHERE repo_id = $1", user_id) 53 .fetch_all(&state.db) 54 .await; 55 56 let collections: Vec<String> = match collections_query { 57 Ok(rows) => rows.iter().map(|r| r.collection.clone()).collect(), 58 Err(_) => Vec::new(), 59 }; 60 61 let full_handle = format!("{}.{}", handle, hostname); 62 let did_doc = json!({ 63 "id": did, 64 "alsoKnownAs": [format!("at://{}", full_handle)] 65 }); 66 67 Json(json!({ 68 "handle": full_handle, 69 "did": did, 70 "didDoc": did_doc, 71 "collections": collections, 72 "handleIsCorrect": true 73 })) 74 .into_response() 75}