diff --git a/.github/workflows/base.yml b/.github/workflows/base.yml index b85ef441d..131d44d0e 100644 --- a/.github/workflows/base.yml +++ b/.github/workflows/base.yml @@ -21,7 +21,7 @@ on: - 'scripts/**' - 'third-party/**' - 'toolchains/**' - - 'workflows/web-test*' + - '.github/workflows/web-test*' name: Base GitHub Action for Check, Test and Lints diff --git a/Cargo.toml b/Cargo.toml index 9018ef159..2d5ade78d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,6 +96,9 @@ aws-config = "1.6.0" aws-sdk-s3 = "1.79.0" quinn = "0.11" utoipa = "5.3" +utoipa-axum = "0.2.0" +utoipa-swagger-ui = "9.0" + rdkafka = "0.37" threadpool = "1.8.1" lru-mem = "0.3.0" diff --git a/ceres/src/model/git.rs b/ceres/src/model/git.rs index af90facc9..9ec007ff8 100644 --- a/ceres/src/model/git.rs +++ b/ceres/src/model/git.rs @@ -6,7 +6,7 @@ use mercury::internal::object::{ tree::{TreeItem, TreeItemMode}, }; -#[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize)] +#[derive(PartialEq, Eq, Debug, Clone, Default, Serialize, Deserialize, ToSchema)] pub struct CreateFileInfo { /// can be a file or directory pub is_directory: bool, @@ -32,13 +32,13 @@ pub struct TreeQuery { pub path: String, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, IntoParams)] pub struct BlobContentQuery { #[serde(default = "default_path")] pub path: String, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct LatestCommitInfo { pub oid: String, pub date: String, @@ -48,7 +48,7 @@ pub struct LatestCommitInfo { pub status: String, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct UserInfo { pub display_name: String, pub avatar_url: String, @@ -63,7 +63,7 @@ impl Default for UserInfo { } } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, ToSchema)] pub struct TreeCommitItem { pub oid: String, pub name: String, diff --git a/docker/mono-pg-dockerfile b/docker/mono-pg-dockerfile index 874c18a81..44f9d3271 100644 --- a/docker/mono-pg-dockerfile +++ b/docker/mono-pg-dockerfile @@ -15,8 +15,4 @@ ENV POSTGRES_PASSWORD=mono EXPOSE 5432 -# Add the database initialization script to the container -# When the container starts, PostgreSQL will automatically execute all .sql files in the docker-entrypoint-initdb.d/ directory -COPY ./sql/postgres/pg_20241204__init.sql /docker-entrypoint-initdb.d/ - CMD ["postgres"] diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 779305f38..95b326180 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -33,3 +33,6 @@ reqwest = { workspace = true, features = ["json"] } lazy_static = { workspace = true } chrono = { workspace = true } quinn = { workspace = true } +utoipa = { workspace = true, features = ["axum_extras"] } +utoipa-axum = { workspace = true } +utoipa-swagger-ui = { workspace = true, features = ["axum"] } \ No newline at end of file diff --git a/gateway/src/api/github_router.rs b/gateway/src/api/github_router.rs index f07a16564..bd2a60329 100644 --- a/gateway/src/api/github_router.rs +++ b/gateway/src/api/github_router.rs @@ -2,10 +2,11 @@ use crate::api::MegaApiServiceState; use axum::http::{HeaderMap, StatusCode}; use axum::response::IntoResponse; use axum::routing::post; -use axum::{Json, Router}; +use axum::Json; use lazy_static::lazy_static; use reqwest::Client; use serde_json::Value; +use utoipa_axum::router::OpenApiRouter; lazy_static! { static ref CLIENT: Client = Client::builder() @@ -14,8 +15,8 @@ lazy_static! { .unwrap(); } -pub fn routers() -> Router { - Router::new().route("/github/webhook", post(webhook)) +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new().route("/github/webhook", post(webhook)) } /// Handle the GitHub webhook event.
diff --git a/gateway/src/https_server.rs b/gateway/src/https_server.rs index f1f74a59b..a32f74e91 100644 --- a/gateway/src/https_server.rs +++ b/gateway/src/https_server.rs @@ -13,6 +13,8 @@ use jupiter::context::Context; use mono::api::lfs::lfs_router; use mono::api::MonoApiServiceState; use mono::server::https_server::{get_method_router, post_method_router, AppState}; +use utoipa::OpenApi; +use utoipa_axum::router::OpenApiRouter; use crate::api::{github_router, MegaApiServiceState}; @@ -66,17 +68,17 @@ pub async fn app(context: Context, host: String, port: u16, p2p: P2pOptions) -> p2p, }; - pub fn mega_routers() -> Router { - Router::new().merge(github_router::routers()) + pub fn mega_routers() -> OpenApiRouter { + OpenApiRouter::new().merge(github_router::routers()) } // add RequestDecompressionLayer for handle gzip encode // add TraceLayer for log record // add CorsLayer to add cors header - Router::new() + let (router, _) = OpenApiRouter::with_openapi(ApiDoc::openapi()) .merge(lfs_router::routers().with_state(mono_api_state.clone())) .merge( - Router::new() + OpenApiRouter::new() .nest( "/api/v1/mono", mono::api::api_router::routers().with_state(mono_api_state.clone()), @@ -97,6 +99,8 @@ pub async fn app(context: Context, host: String, port: u16, p2p: P2pOptions) -> .layer(TraceLayer::new_for_http()) .layer(RequestDecompressionLayer::new()) .with_state(state) + .split_for_parts(); + router } pub fn check_run_with_p2p(context: Context, p2p: P2pOptions) { @@ -116,5 +120,8 @@ pub fn check_run_with_p2p(context: Context, p2p: P2pOptions) { }; } +#[derive(OpenApi)] +struct ApiDoc; + #[cfg(test)] mod tests {} diff --git a/mono/Cargo.toml b/mono/Cargo.toml index 75857f9b7..7e8896ace 100644 --- a/mono/Cargo.toml +++ b/mono/Cargo.toml @@ -54,6 +54,8 @@ async-session = { workspace = true } http = { workspace = true } cedar-policy = { workspace = true } utoipa = { workspace = true, features = ["axum_extras"] } +utoipa-axum = { workspace = true } +utoipa-swagger-ui = { workspace = true, features = ["axum"] } [target.'cfg(not(windows))'.dependencies] jemallocator = { workspace = true } diff --git a/mono/src/api/api_router.rs b/mono/src/api/api_router.rs index b45dbffc2..bdbe4a17f 100644 --- a/mono/src/api/api_router.rs +++ b/mono/src/api/api_router.rs @@ -4,8 +4,8 @@ use axum::{ body::Body, extract::{Path, Query, State}, response::{IntoResponse, Response}, - routing::{get, post}, - Json, Router, + routing::get, + Json, }; use http::StatusCode; @@ -17,31 +17,42 @@ use ceres::{ }, }; use common::model::CommonResult; +use utoipa_axum::{router::OpenApiRouter, routes}; -use crate::api::error::ApiError; use crate::api::issue::issue_router; use crate::api::mr::mr_router; use crate::api::user::user_router; use crate::api::MonoApiServiceState; - -pub fn routers() -> Router { - let router = Router::new() - .route("/status", get(life_cycle_check)) - .route("/create-file", post(create_file)) - .route("/latest-commit", get(get_latest_commit)) - .route("/tree/commit-info", get(get_tree_commit_info)) - .route("/tree/path-can-clone", get(path_can_be_cloned)) - .route("/tree", get(get_tree_info)) - .route("/blob", get(get_blob_string)) +use crate::{api::error::ApiError, server::https_server::GIT_TAG}; + +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new() + .routes(routes!(life_cycle_check)) + .routes(routes!(create_file)) + .routes(routes!(get_latest_commit)) + .routes(routes!(get_tree_commit_info)) + .routes(routes!(path_can_be_cloned)) + .routes(routes!(get_tree_info)) + .routes(routes!(get_blob_string)) .route("/file/blob/{object_id}", get(get_blob_file)) - .route("/file/tree", get(get_tree_file)); - Router::new() - .merge(router) + .route("/file/tree", get(get_tree_file)) .merge(mr_router::routers()) .merge(user_router::routers()) .merge(issue_router::routers()) } +/// Get blob file as string +#[utoipa::path( + get, + params( + BlobContentQuery + ), + path = "/blob", + responses( + (status = 200, body = CommonResult, content_type = "application/json") + ), + tag = GIT_TAG +)] async fn get_blob_string( Query(query): Query, state: State, @@ -54,10 +65,29 @@ async fn get_blob_string( Ok(Json(CommonResult::success(data))) } +/// Health Check +#[utoipa::path( + get, + path = "/status", + responses( + (status = 200, body = str, content_type = "text/plain") + ), + tag = GIT_TAG +)] async fn life_cycle_check() -> Result { Ok(Json("http ready")) } +/// Create file in web UI +#[utoipa::path( + get, + path = "/create-file", + request_body = CreateFileInfo, + responses( + (status = 200, body = CommonResult, content_type = "application/json") + ), + tag = GIT_TAG +)] async fn create_file( state: State, Json(json): Json, @@ -70,6 +100,18 @@ async fn create_file( Ok(Json(CommonResult::success(None))) } +/// Get latest commit by path +#[utoipa::path( + get, + path = "/latest-commit", + params( + CodePreviewQuery + ), + responses( + (status = 200, body = LatestCommitInfo, content_type = "application/json") + ), + tag = GIT_TAG +)] async fn get_latest_commit( Query(query): Query, state: State, @@ -82,6 +124,18 @@ async fn get_latest_commit( Ok(Json(res)) } +/// Get tree brief info +#[utoipa::path( + get, + path = "/tree", + params( + CodePreviewQuery + ), + responses( + (status = 200, body = CommonResult>, content_type = "application/json") + ), + tag = GIT_TAG +)] async fn get_tree_info( Query(query): Query, state: State, @@ -94,17 +148,17 @@ async fn get_tree_info( Ok(Json(CommonResult::success(Some(data)))) } +/// List matching trees with commit msg by query #[utoipa::path( get, - path = "api/v1/tree/commit-info", + path = "/tree/commit-info", params( CodePreviewQuery ), responses( - (status = 200, description = "List matching trees by query", - body = CommonResult>, - content_type = "application/json") - ) + (status = 200, body = CommonResult>, content_type = "application/json") + ), + tag = GIT_TAG )] async fn get_tree_commit_info( Query(query): Query, @@ -159,6 +213,18 @@ pub async fn get_tree_file( .unwrap()) } +/// Check if a path can be cloned +#[utoipa::path( + get, + path = "/tree/path-can-clone", + params( + BlobContentQuery + ), + responses( + (status = 200, body = CommonResult, content_type = "application/json") + ), + tag = GIT_TAG +)] async fn path_can_be_cloned( Query(query): Query, state: State, @@ -180,16 +246,3 @@ async fn path_can_be_cloned( }; Ok(Json(CommonResult::success(Some(res)))) } - -#[cfg(test)] -mod test { - use utoipa::OpenApi; - - #[test] - fn generate_swagger_json() { - #[derive(OpenApi)] - #[openapi(paths(crate::api::api_router::get_tree_commit_info))] - struct ApiDoc; - println!("{}", ApiDoc::openapi().to_pretty_json().unwrap()); - } -} diff --git a/mono/src/api/issue/issue_router.rs b/mono/src/api/issue/issue_router.rs index e69c01843..d294b511e 100644 --- a/mono/src/api/issue/issue_router.rs +++ b/mono/src/api/issue/issue_router.rs @@ -1,10 +1,11 @@ use axum::{ extract::{Path, State}, routing::{get, post}, - Json, Router, + Json, }; use bytes::Bytes; use serde::Deserialize; +use utoipa_axum::router::OpenApiRouter; use common::model::{CommonPage, CommonResult, PageParams}; @@ -13,10 +14,10 @@ use crate::api::issue::{IssueDetail, IssueItem, NewIssue}; use crate::api::oauth::model::LoginUser; use crate::api::MonoApiServiceState; -pub fn routers() -> Router { - Router::new().nest( +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new().nest( "/issue", - Router::new() + OpenApiRouter::new() .route("/list", post(fetch_issue_list)) .route("/new", post(new_issue)) .route("/{link}/close", post(close_issue)) diff --git a/mono/src/api/lfs/lfs_router.rs b/mono/src/api/lfs/lfs_router.rs index 0314dfdfd..a6c1fba18 100644 --- a/mono/src/api/lfs/lfs_router.rs +++ b/mono/src/api/lfs/lfs_router.rs @@ -49,9 +49,10 @@ use axum::{ http::{Request, StatusCode}, response::Response, routing::{get, post, put}, - Json, Router, + Json, }; use futures::TryStreamExt; +use utoipa_axum::router::OpenApiRouter; use ceres::lfs::{ handler, @@ -68,8 +69,8 @@ const LFS_CONTENT_TYPE: &str = "application/vnd.git-lfs+json"; /// The [LFS Server Discovery](https://github.com/git-lfs/git-lfs/blob/main/docs/api/server-discovery.md) /// document describes the server LFS discovery protocol. -pub fn routers() -> Router { - Router::new() +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new() .route("/objects/{object_id}", get(lfs_download_object)) .route("/objects/{object_id}/{chunk_id}", get(lfs_download_chunk)) .route("/objects/{object_id}", put(lfs_upload_object)) diff --git a/mono/src/api/mr/mr_router.rs b/mono/src/api/mr/mr_router.rs index 55173a911..620a28e6d 100644 --- a/mono/src/api/mr/mr_router.rs +++ b/mono/src/api/mr/mr_router.rs @@ -3,10 +3,10 @@ use std::collections::HashMap; use axum::{ extract::{Path, State}, routing::{get, post}, - Json, Router, + Json, }; - use bytes::Bytes; +use utoipa_axum::router::OpenApiRouter; use callisto::sea_orm_active_enums::{ConvTypeEnum, MergeStatusEnum}; use ceres::protocol::mr::MergeRequest; @@ -19,10 +19,10 @@ use crate::api::oauth::model::LoginUser; use crate::api::util; use crate::api::MonoApiServiceState; -pub fn routers() -> Router { - Router::new().nest( +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new().nest( "/mr", - Router::new() + OpenApiRouter::new() .route("/list", post(fetch_mr_list)) .route("/{link}/detail", get(mr_detail)) .route("/{link}/merge", post(merge)) diff --git a/mono/src/api/oauth/mod.rs b/mono/src/api/oauth/mod.rs index 9cce2a17d..4e7c5ecad 100644 --- a/mono/src/api/oauth/mod.rs +++ b/mono/src/api/oauth/mod.rs @@ -5,7 +5,7 @@ use axum::{ http::{header::SET_COOKIE, HeaderMap}, response::{IntoResponse, Redirect, Response}, routing::get, - RequestPartsExt, Router, + RequestPartsExt, }; use axum_extra::{headers, typed_header::TypedHeaderRejectionReason, TypedHeader}; use callisto::user; @@ -19,6 +19,7 @@ use oauth2::{ use common::config::OauthConfig; use jupiter::storage::user_storage::UserStorage; use model::{GitHubUserJson, LoginUser, OauthCallbackParams}; +use utoipa_axum::router::OpenApiRouter; use crate::api::error::ApiError; use crate::api::MonoApiServiceState; @@ -29,8 +30,8 @@ pub mod model; static COOKIE_NAME: &str = "SESSION"; -pub fn routers() -> Router { - Router::new() +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new() .route("/github", get(github_auth)) .route("/authorized", get(login_authorized)) .route("/logout", get(logout)) diff --git a/mono/src/api/user/user_router.rs b/mono/src/api/user/user_router.rs index 957c5a61e..16540fd3f 100644 --- a/mono/src/api/user/user_router.rs +++ b/mono/src/api/user/user_router.rs @@ -3,9 +3,10 @@ use std::collections::HashMap; use axum::{ extract::{Path, Query, State}, routing::{get, post}, - Json, Router, + Json, }; use russh::keys::{parse_public_key_base64, HashAlg}; +use utoipa_axum::router::OpenApiRouter; use common::model::CommonResult; @@ -15,10 +16,10 @@ use crate::api::user::model::ListToken; use crate::api::MonoApiServiceState; use crate::api::{error::ApiError, oauth::model::LoginUser, util}; -pub fn routers() -> Router { - Router::new().nest( +pub fn routers() -> OpenApiRouter { + OpenApiRouter::new().nest( "/user", - Router::new() + OpenApiRouter::new() .route("/", get(user)) .route("/ssh", get(list_key)) .route("/ssh", post(add_key)) diff --git a/mono/src/server/https_server.rs b/mono/src/server/https_server.rs index 094507153..9d600b96e 100644 --- a/mono/src/server/https_server.rs +++ b/mono/src/server/https_server.rs @@ -21,6 +21,9 @@ use ceres::protocol::{ServiceType, SmartProtocol, TransportProtocol}; use common::errors::ProtocolError; use common::model::{CommonHttpOptions, InfoRefsParams}; use jupiter::context::Context; +use utoipa::OpenApi; +use utoipa_axum::router::OpenApiRouter; +use utoipa_swagger_ui::SwaggerUi; use crate::api::api_router::{self}; use crate::api::lfs::lfs_router; @@ -98,13 +101,13 @@ pub async fn app(context: Context, host: String, port: u16) -> Router { // add RequestDecompressionLayer for handle gzip encode // add TraceLayer for log record // add CorsLayer to add cors header - Router::new() + let (router, api) = OpenApiRouter::with_openapi(ApiDoc::openapi()) .merge(lfs_router::routers().with_state(api_state.clone())) - .merge(Router::new().nest( + .nest( "/api/v1", api_router::routers().with_state(api_state.clone()), - )) - .merge(Router::new().nest("/auth", oauth::routers().with_state(api_state.clone()))) + ) + .nest("/auth", oauth::routers().with_state(api_state.clone())) // Using Regular Expressions for Path Matching in Protocol .route("/{*path}", get(get_method_router).post(post_method_router)) .layer( @@ -116,6 +119,8 @@ pub async fn app(context: Context, host: String, port: u16) -> Router { .layer(TraceLayer::new_for_http()) .layer(RequestDecompressionLayer::new()) .with_state(state) + .split_for_parts(); + router.merge(SwaggerUi::new("/swagger-ui").url("/api/openapi.json", api)) } lazy_static! { @@ -172,5 +177,29 @@ pub async fn post_method_router( } } +pub const GIT_TAG: &str = "git"; +pub const MR_TAG: &str = "merge_request"; +#[derive(OpenApi)] +#[openapi( + tags( + (name = GIT_TAG, description = "Git API endpoints"), + (name = MR_TAG, description = "Merge Request API endpoints") + ) +)] +struct ApiDoc; + #[cfg(test)] -mod tests {} +mod test { + use std::{fs, io::Write}; + use utoipa::OpenApi; + + use crate::server::https_server::ApiDoc; + + #[test] + fn generate_swagger_json() { + let mut file = fs::File::create("gitmono.json").unwrap(); + let json = ApiDoc::openapi().to_pretty_json().unwrap(); + file.write_all(json.as_bytes()).unwrap(); + println!("{}", json); + } +} diff --git a/moon/packages/types/generated.ts b/moon/packages/types/generated.ts index 34fdc169a..13fb080e3 100644 --- a/moon/packages/types/generated.ts +++ b/moon/packages/types/generated.ts @@ -3033,6 +3033,12 @@ export type FigmaKeyPair = { write_key: string } +export type CommonResultString = { + data?: string + err_message: string + req_result: boolean +} + export type CommonResultVecTreeBriefItem = { data?: { content_type: string @@ -3043,12 +3049,61 @@ export type CommonResultVecTreeBriefItem = { req_result: boolean } +export type CommonResultVecTreeCommitItem = { + data?: { + content_type: string + date: string + message: string + name: string + oid: string + }[] + err_message: string + req_result: boolean +} + +export type CommonResultBool = { + data?: boolean + err_message: string + req_result: boolean +} + +export type CreateFileInfo = { + content?: string | null + /** can be a file or directory */ + is_directory: boolean + name: string + /** leave empty if it's under root */ + path: string +} + +export type LatestCommitInfo = { + author: UserInfo + committer: UserInfo + date: string + oid: string + short_message: string + status: string +} + export type TreeBriefItem = { content_type: string name: string path: string } +export type TreeCommitItem = { + content_type: string + date: string + message: string + name: string + oid: string +} + +export type UserInfo = { + avatar_url: string + display_name: string +} + export type PostActivityViewsData = UserNotificationCounts export type GetAttachmentsCommentersData = OrganizationMember[] @@ -4182,6 +4237,23 @@ export type PostThreadsV2Data = V2MessageThread export type PostSignInFigmaData = FigmaKeyPair +export type GetApiBlobParams = { + path?: string +} + +export type GetApiBlobData = CommonResultString + +export type GetApiCreateFileData = CommonResultString + +export type GetApiLatestCommitParams = { + refs?: string + path?: string +} + +export type GetApiLatestCommitData = LatestCommitInfo + +export type GetApiStatusData = string + export type GetApiTreeParams = { refs?: string path?: string @@ -4189,6 +4261,19 @@ export type GetApiTreeParams = { export type GetApiTreeData = CommonResultVecTreeBriefItem +export type GetApiTreeCommitInfoParams = { + refs?: string + path?: string +} + +export type GetApiTreeCommitInfoData = CommonResultVecTreeCommitItem + +export type GetApiTreePathCanCloneParams = { + path?: string +} + +export type GetApiTreePathCanCloneData = CommonResultBool + export type QueryParamsType = Record export type ResponseFormat = keyof Omit @@ -12471,19 +12556,166 @@ export class Api extends HttpClient { + const base = 'GET:/api/v1/blob' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (params: GetApiBlobParams) => dataTaggedQueryKey([base, params]), + request: (query: GetApiBlobParams, params: RequestParams = {}) => + this.request({ + path: `/api/v1/blob`, + method: 'GET', + query: query, + ...params + }) + } + }, + + /** + * No description + * + * @tags git + * @name GetApiCreateFile + * @summary Create file in web UI + * @request GET:/api/v1/create-file + */ + getApiCreateFile: () => { + const base = 'GET:/api/v1/create-file' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: () => dataTaggedQueryKey([base]), + request: (data: CreateFileInfo, params: RequestParams = {}) => + this.request({ + path: `/api/v1/create-file`, + method: 'GET', + body: data, + type: ContentType.Json, + ...params + }) + } + }, + + /** + * No description + * + * @tags git + * @name GetApiLatestCommit + * @summary Get latest commit by path + * @request GET:/api/v1/latest-commit + */ + getApiLatestCommit: () => { + const base = 'GET:/api/v1/latest-commit' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (params: GetApiLatestCommitParams) => dataTaggedQueryKey([base, params]), + request: (query: GetApiLatestCommitParams, params: RequestParams = {}) => + this.request({ + path: `/api/v1/latest-commit`, + method: 'GET', + query: query, + ...params + }) + } + }, + + /** + * No description + * + * @tags git + * @name GetApiStatus + * @summary Health Check + * @request GET:/api/v1/status + */ + getApiStatus: () => { + const base = 'GET:/api/v1/status' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: () => dataTaggedQueryKey([base]), + request: (params: RequestParams = {}) => + this.request({ + path: `/api/v1/status`, + method: 'GET', + ...params + }) + } + }, + + /** + * No description + * + * @tags git * @name GetApiTree - * @request GET:api/v1/tree/ + * @summary Get tree brief info + * @request GET:/api/v1/tree */ getApiTree: () => { - const base = 'GET:api/v1/tree/' as const + const base = 'GET:/api/v1/tree' as const return { baseKey: dataTaggedQueryKey([base]), requestKey: (params: GetApiTreeParams) => dataTaggedQueryKey([base, params]), request: (query: GetApiTreeParams, params: RequestParams = {}) => this.request({ - path: `api/v1/tree/`, + path: `/api/v1/tree`, + method: 'GET', + query: query, + ...params + }) + } + }, + + /** + * No description + * + * @tags git + * @name GetApiTreeCommitInfo + * @summary List matching trees with commit msg by query + * @request GET:/api/v1/tree/commit-info + */ + getApiTreeCommitInfo: () => { + const base = 'GET:/api/v1/tree/commit-info' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (params: GetApiTreeCommitInfoParams) => + dataTaggedQueryKey([base, params]), + request: (query: GetApiTreeCommitInfoParams, params: RequestParams = {}) => + this.request({ + path: `/api/v1/tree/commit-info`, + method: 'GET', + query: query, + ...params + }) + } + }, + + /** + * No description + * + * @tags git + * @name GetApiTreePathCanClone + * @summary Check if a path can be cloned + * @request GET:/api/v1/tree/path-can-clone + */ + getApiTreePathCanClone: () => { + const base = 'GET:/api/v1/tree/path-can-clone' as const + + return { + baseKey: dataTaggedQueryKey([base]), + requestKey: (params: GetApiTreePathCanCloneParams) => + dataTaggedQueryKey([base, params]), + request: (query: GetApiTreePathCanCloneParams, params: RequestParams = {}) => + this.request({ + path: `/api/v1/tree/path-can-clone`, method: 'GET', query: query, ...params