Migrate `/v1/delegates` route
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
This commit is contained in:
parent
6f8511c360
commit
77e0a176bd
|
|
@ -99,7 +99,7 @@ async fn root_handler(Extension(ctx): Extension<Context>) -> impl IntoResponse {
|
||||||
"type": "GET"
|
"type": "GET"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"href": "/v1/delegates/:urn/projects",
|
"href": "/v1/delegates/:did/projects",
|
||||||
"rel": "projects",
|
"rel": "projects",
|
||||||
"type": "GET"
|
"type": "GET"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,10 @@ pub enum Error {
|
||||||
/// An error occurred while parsing the siwe message.
|
/// An error occurred while parsing the siwe message.
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
SiweParse(#[from] siwe::ParseError),
|
SiweParse(#[from] siwe::ParseError),
|
||||||
|
|
||||||
|
/// Storage error.
|
||||||
|
#[error(transparent)]
|
||||||
|
StorageError(#[from] radicle::storage::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod delegates;
|
||||||
mod node;
|
mod node;
|
||||||
mod sessions;
|
mod sessions;
|
||||||
|
|
||||||
|
|
@ -8,7 +9,8 @@ use crate::api::Context;
|
||||||
pub fn router(ctx: Context) -> Router {
|
pub fn router(ctx: Context) -> Router {
|
||||||
let routes = Router::new()
|
let routes = Router::new()
|
||||||
.merge(node::router(ctx.clone()))
|
.merge(node::router(ctx.clone()))
|
||||||
.merge(sessions::router(ctx));
|
.merge(sessions::router(ctx.clone()))
|
||||||
|
.merge(delegates::router(ctx));
|
||||||
|
|
||||||
Router::new().nest("/v1", routes)
|
Router::new().nest("/v1", routes)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use axum::routing::get;
|
||||||
|
use axum::{Extension, Json, Router};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use radicle::cob::store::Store;
|
||||||
|
use radicle::git::Oid;
|
||||||
|
use radicle::identity::project::Payload;
|
||||||
|
use radicle::identity::{Did, Doc};
|
||||||
|
use radicle::storage::{ReadRepository, WriteStorage};
|
||||||
|
|
||||||
|
use crate::api::axum_extra::{Path, Query};
|
||||||
|
use crate::api::error::Error;
|
||||||
|
use crate::api::Context;
|
||||||
|
use crate::api::PaginationQuery;
|
||||||
|
|
||||||
|
/// Project info.
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Info {
|
||||||
|
/// Project metadata.
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub payload: Payload,
|
||||||
|
pub head: Oid,
|
||||||
|
pub patches: usize,
|
||||||
|
pub issues: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn router(ctx: Context) -> Router {
|
||||||
|
Router::new()
|
||||||
|
.route(
|
||||||
|
"/delegates/:delegate/projects",
|
||||||
|
get(delegates_projects_handler),
|
||||||
|
)
|
||||||
|
.layer(Extension(ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// List all projects which delegate is a part of.
|
||||||
|
/// `GET /delegates/:delegate/projects`
|
||||||
|
async fn delegates_projects_handler(
|
||||||
|
Extension(ctx): Extension<Context>,
|
||||||
|
Path(delegate): Path<Did>,
|
||||||
|
Query(qs): Query<PaginationQuery>,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
let PaginationQuery { page, per_page } = qs;
|
||||||
|
let page = page.unwrap_or(0);
|
||||||
|
let per_page = per_page.unwrap_or(10);
|
||||||
|
let storage = &ctx.profile.storage;
|
||||||
|
let projects = storage
|
||||||
|
.projects()?
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|id| {
|
||||||
|
let Ok(repo) = storage.repository(id) else { return None };
|
||||||
|
let Ok((_, head)) = repo.head() else { return None };
|
||||||
|
let Ok(Doc { payload, delegates, .. }) = repo.project_of(ctx.profile.id()) else { return None };
|
||||||
|
|
||||||
|
if !delegates.iter().any(|d| d.id == delegate) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let Ok(cobs) = Store::open(ctx.profile.public_key, &repo) else { return None };
|
||||||
|
let Ok(issues) = cobs.issues().count() else { return None };
|
||||||
|
let Ok(patches) = cobs.patches().count() else { return None };
|
||||||
|
|
||||||
|
Some(Info {
|
||||||
|
payload,
|
||||||
|
head,
|
||||||
|
issues,
|
||||||
|
patches,
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.skip(page * per_page)
|
||||||
|
.take(per_page)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Ok::<_, Error>(Json(projects))
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue