chore: update everything to work with utoipa

This commit is contained in:
Zomatree
2025-11-13 23:06:41 +00:00
parent 27ea7345ea
commit ac60b2c795
148 changed files with 1200 additions and 1117 deletions

View File

@@ -47,20 +47,23 @@ revolt-files = { version = "0.8.9", path = "../../core/files" }
revolt-config = { version = "0.8.9", path = "../../core/config" }
revolt-database = { version = "0.8.9", path = "../../core/database", features = [
"axum-impl",
"utoipa",
] }
revolt-result = { version = "0.8.9", path = "../../core/result", features = [
"utoipa",
"axum",
] }
revolt-ratelimits = { version = "0.8.9", path = "../../core/ratelimits", features = ["axum"] }
revolt-ratelimits = { version = "0.8.9", path = "../../core/ratelimits", features = [
"axum",
] }
# Axum / web server
tempfile = "3.12.0"
axum-macros = "0.4.1"
axum_typed_multipart = "0.12.1"
axum = { version = "0.7.5", features = ["multipart"] }
axum-macros = "0.5.0"
axum_typed_multipart = "0.16.4"
axum = { version = "0.8.6", features = ["multipart"] }
tower-http = { version = "0.5.2", features = ["cors"] }
# OpenAPI & documentation generation
utoipa-scalar = { version = "0.1.0", features = ["axum"] }
utoipa = { version = "4.2.3", features = ["axum_extras", "ulid"] }
utoipa-scalar = { version = "0.3.0", features = ["axum"] }
utoipa = { version = "5.4.0", features = ["ulid"] }

View File

@@ -23,9 +23,14 @@ use sha2::Digest;
use tempfile::NamedTempFile;
use tokio::time::Instant;
use tower_http::cors::{AllowHeaders, Any, CorsLayer};
use utoipa::ToSchema;
use utoipa::{
openapi::{schema::ObjectBuilder, SchemaFormat},
PartialSchema, ToSchema,
};
use crate::{exif::strip_metadata, metadata::generate_metadata, mime_type::determine_mime_type, AppState};
use crate::{
exif::strip_metadata, metadata::generate_metadata, mime_type::determine_mime_type, AppState,
};
/// Build the API router
pub async fn router() -> Router<AppState> {
@@ -122,14 +127,32 @@ pub enum Tag {
}
/// Request body for upload
#[derive(ToSchema, TryFromMultipart)]
#[derive(TryFromMultipart)]
pub struct UploadPayload {
#[schema(format = Binary)]
#[allow(dead_code)]
#[form_data(limit = "unlimited")] // handled by axum
file: FieldData<NamedTempFile>,
}
impl ToSchema for UploadPayload {
fn name() -> std::borrow::Cow<'static, str> {
std::borrow::Cow::Borrowed("UploadPayload")
}
}
impl PartialSchema for UploadPayload {
fn schema() -> utoipa::openapi::RefOr<utoipa::openapi::schema::Schema> {
ObjectBuilder::new()
.property(
"file",
ObjectBuilder::new().format(Some(SchemaFormat::KnownFormat(
utoipa::openapi::KnownFormat::Binary,
))),
)
.into()
}
}
/// Successful upload response
#[derive(Serialize, Debug, ToSchema)]
pub struct UploadResponse {
@@ -160,8 +183,8 @@ pub struct UploadResponse {
),
request_body(content_type = "multipart/form-data", content = UploadPayload),
security(
("session_token" = []),
("bot_token" = [])
("Session-Token" = []),
("Bot-Token" = [])
)
)]
async fn upload_file(

View File

@@ -3,13 +3,10 @@ use std::net::{Ipv4Addr, SocketAddr};
use axum::{middleware::from_fn_with_state, Router};
use axum_macros::FromRef;
use revolt_database::{Database, DatabaseInfo};
use revolt_database::{Database, DatabaseInfo, User, util::utoipa::TokenSecurity};
use revolt_ratelimits::axum as ratelimiter;
use tokio::net::TcpListener;
use utoipa::{
openapi::security::{ApiKey, ApiKeyValue, SecurityScheme},
Modify, OpenApi,
};
use utoipa::OpenApi;
use utoipa_scalar::{Scalar, Servable as ScalarServable};
mod api;
@@ -36,7 +33,7 @@ async fn main() -> Result<(), std::io::Error> {
// Configure API schema
#[derive(OpenApi)]
#[openapi(
modifiers(&SecurityAddon),
modifiers(&TokenSecurity),
paths(
api::root,
api::upload_file,
@@ -59,23 +56,6 @@ async fn main() -> Result<(), std::io::Error> {
)]
struct ApiDoc;
struct SecurityAddon;
impl Modify for SecurityAddon {
fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
if let Some(components) = openapi.components.as_mut() {
components.add_security_scheme(
"bot_token",
SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("X-Bot-Token"))),
);
components.add_security_scheme(
"session_token",
SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::new("X-Session-Token"))),
);
}
}
}
// Connect to the database
let db = DatabaseInfo::Auto.connect().await.unwrap();
let ratelimits = ratelimiter::RatelimitStorage::new(ratelimits::AutumnRatelimits);