aboutsummaryrefslogtreecommitdiffstats
path: root/crates/api-core/src
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2026-04-04 10:51:18 +0200
committerrtkay123 <dev@kanjala.com>2026-04-04 10:51:18 +0200
commit19c25138f88acf19c9a959a58de4f58e54026ebc (patch)
treebd854f20c539770a92fb451503b4c6d132c110a6 /crates/api-core/src
parent41d90f42c37df06dabfd717d19f3dc72b5ba2d11 (diff)
downloadsellershut-19c25138f88acf19c9a959a58de4f58e54026ebc.tar.bz2
sellershut-19c25138f88acf19c9a959a58de4f58e54026ebc.zip
feat: connect to db
Diffstat (limited to 'crates/api-core/src')
-rw-r--r--crates/api-core/src/auth/mod.rs9
-rw-r--r--crates/api-core/src/auth/provider.rs14
-rw-r--r--crates/api-core/src/health/apidoc.rs12
-rw-r--r--crates/api-core/src/health/mod.rs27
-rw-r--r--crates/api-core/src/lib.rs7
-rw-r--r--crates/api-core/src/models/mod.rs2
-rw-r--r--crates/api-core/src/models/user.rs1
-rw-r--r--crates/api-core/src/version.rs96
8 files changed, 168 insertions, 0 deletions
diff --git a/crates/api-core/src/auth/mod.rs b/crates/api-core/src/auth/mod.rs
new file mode 100644
index 0000000..1045122
--- /dev/null
+++ b/crates/api-core/src/auth/mod.rs
@@ -0,0 +1,9 @@
+pub mod provider;
+
+pub struct AuthClientConfig {
+ pub client_id: String,
+ pub client_secret: String,
+ pub redirect_uri: String,
+ pub token_uri: String,
+ pub auth_url: String,
+}
diff --git a/crates/api-core/src/auth/provider.rs b/crates/api-core/src/auth/provider.rs
new file mode 100644
index 0000000..803472f
--- /dev/null
+++ b/crates/api-core/src/auth/provider.rs
@@ -0,0 +1,14 @@
+#[non_exhaustive]
+/// The oauth provider
+#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
+#[cfg_attr(
+ feature = "utoipa",
+ derive(utoipa::ToSchema, serde::Deserialize, serde::Serialize),
+ schema(example = "v0"),
+ serde(rename_all = "camelCase")
+)]
+pub enum OauthProvider {
+ /// Discord
+ #[cfg(feature = "auth-discord")]
+ Discord,
+}
diff --git a/crates/api-core/src/health/apidoc.rs b/crates/api-core/src/health/apidoc.rs
new file mode 100644
index 0000000..45b8754
--- /dev/null
+++ b/crates/api-core/src/health/apidoc.rs
@@ -0,0 +1,12 @@
+use utoipa::OpenApi;
+
+use crate::Version;
+
+#[derive(OpenApi)]
+#[openapi(
+ tags(
+ (name = "sellershut", description = "API health check"),
+ ),
+ components(schemas(Version))
+)]
+pub struct ApiDocBase;
diff --git a/crates/api-core/src/health/mod.rs b/crates/api-core/src/health/mod.rs
new file mode 100644
index 0000000..a84dc85
--- /dev/null
+++ b/crates/api-core/src/health/mod.rs
@@ -0,0 +1,27 @@
+#[cfg(feature = "utoipa")]
+mod apidoc;
+
+#[cfg(feature = "utoipa")]
+pub use apidoc::*;
+
+#[derive(Default)]
+pub struct BaseService;
+
+impl HealthDriver for BaseService {}
+
+pub trait HealthDriver: Send + Sync {
+ fn health(&self, app: &str, version: &str) -> String {
+ format!("{app} v{version} is live")
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::health::{BaseService, HealthDriver};
+
+ #[test]
+ fn health() {
+ let app = BaseService.health(env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
+ assert!(app.contains("is live"));
+ }
+}
diff --git a/crates/api-core/src/lib.rs b/crates/api-core/src/lib.rs
new file mode 100644
index 0000000..8c22b49
--- /dev/null
+++ b/crates/api-core/src/lib.rs
@@ -0,0 +1,7 @@
+pub mod health;
+pub mod models;
+mod version;
+pub use version::*;
+
+#[cfg(feature = "auth")]
+pub mod auth;
diff --git a/crates/api-core/src/models/mod.rs b/crates/api-core/src/models/mod.rs
new file mode 100644
index 0000000..0f2db76
--- /dev/null
+++ b/crates/api-core/src/models/mod.rs
@@ -0,0 +1,2 @@
+#[cfg(feature = "users")]
+pub mod user;
diff --git a/crates/api-core/src/models/user.rs b/crates/api-core/src/models/user.rs
new file mode 100644
index 0000000..e6ad9f0
--- /dev/null
+++ b/crates/api-core/src/models/user.rs
@@ -0,0 +1 @@
+pub struct User {}
diff --git a/crates/api-core/src/version.rs b/crates/api-core/src/version.rs
new file mode 100644
index 0000000..5f84f3e
--- /dev/null
+++ b/crates/api-core/src/version.rs
@@ -0,0 +1,96 @@
+#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
+#[cfg_attr(
+ feature = "utoipa",
+ derive(utoipa::ToSchema, serde::Deserialize, serde::Serialize),
+ schema(example = "v0"),
+ serde(rename_all = "camelCase")
+)]
+pub enum Version {
+ V0,
+}
+
+#[cfg(feature = "axum")]
+mod request {
+ use super::*;
+ use axum::RequestPartsExt;
+ use axum::extract::{FromRequestParts, Path};
+ use axum::http::StatusCode;
+ use axum::http::request::Parts;
+ use axum::response::{IntoResponse, Response};
+ use std::collections::HashMap;
+
+ impl<S> FromRequestParts<S> for Version
+ where
+ S: Send + Sync,
+ {
+ type Rejection = Response;
+
+ async fn from_request_parts(
+ parts: &mut Parts,
+ _state: &S,
+ ) -> Result<Self, Self::Rejection> {
+ let params: Path<HashMap<String, String>> =
+ parts.extract().await.map_err(IntoResponse::into_response)?;
+
+ let version = params
+ .get("apiVersion")
+ .ok_or_else(|| (StatusCode::NOT_FOUND, "version param missing").into_response())?;
+
+ match version.as_str() {
+ "v0" => Ok(Version::V0),
+ _ => Err((StatusCode::NOT_FOUND, "unknown version").into_response()),
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use axum::{
+ Router,
+ body::Body,
+ http::{Request, StatusCode},
+ routing::get,
+ };
+ use tower::ServiceExt;
+
+ async fn handler(version: Version) -> &'static str {
+ match version {
+ Version::V0 => "ok",
+ }
+ }
+
+ async fn check(endpoint: &str, expected: StatusCode) {
+ let app = app();
+ let response = app
+ .oneshot(
+ Request::builder()
+ .uri(endpoint)
+ .body(Body::empty())
+ .unwrap(),
+ )
+ .await
+ .unwrap();
+ assert_eq!(expected, response.status());
+ }
+
+ fn app() -> Router {
+ Router::new().route("/{apiVersion}/test", get(handler))
+ }
+
+ #[tokio::test]
+ async fn valid_version_v0() {
+ check("/v0/test", StatusCode::OK).await
+ }
+
+ #[tokio::test]
+ async fn unknown_version() {
+ check("/v1/test", StatusCode::NOT_FOUND).await
+ }
+
+ #[tokio::test]
+ async fn missing_version_param() {
+ check("/test", StatusCode::NOT_FOUND).await
+ }
+}