Remove aide
This commit is contained in:
parent
0908a5b527
commit
4ca55768c5
15 changed files with 85 additions and 562 deletions
286
backend/Cargo.lock
generated
286
backend/Cargo.lock
generated
|
|
@ -17,20 +17,6 @@ version = "2.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom 0.2.15",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"version_check",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
|
|
@ -40,41 +26,6 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aide"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5678d2978845ddb4bd736a026f467dd652d831e9e6254b0e41b07f7ee7523309"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"http",
|
||||
"indexmap 2.7.0",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_qs",
|
||||
"thiserror 1.0.69",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aide-axum-typed-multipart"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b8f5c830a08754addfa31fa09e6c183bac8d2ae7bd007131f9eb84fcb87a40e"
|
||||
dependencies = [
|
||||
"aide",
|
||||
"axum",
|
||||
"axum_typed_multipart",
|
||||
"indexmap 2.7.0",
|
||||
"schemars",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
|
|
@ -265,26 +216,6 @@ dependencies = [
|
|||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-jsonschema"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcffe29ca1b60172349fea781ec34441d598809bd227ccbb5bf5dc2879cd9c78"
|
||||
dependencies = [
|
||||
"aide",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"http",
|
||||
"http-body",
|
||||
"itertools",
|
||||
"jsonschema",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-macros"
|
||||
version = "0.4.2"
|
||||
|
|
@ -368,21 +299,6 @@ version = "0.6.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
|
|
@ -407,12 +323,6 @@ version = "3.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "bytecount"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
|
@ -700,12 +610,6 @@ version = "0.15.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
|
|
@ -768,16 +672,6 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fancy-regex"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.2.0"
|
||||
|
|
@ -816,16 +710,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fraction"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3027ae1df8d41b4bed2241c8fdad4acc1e7af60c8e17743534b545e77182d678"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.31"
|
||||
|
|
@ -943,10 +827,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1346,24 +1228,6 @@ version = "1.70.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "iso8601"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.14"
|
||||
|
|
@ -1380,34 +1244,6 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonschema"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"base64 0.21.7",
|
||||
"bytecount",
|
||||
"fancy-regex",
|
||||
"fraction",
|
||||
"getrandom 0.2.15",
|
||||
"iso8601",
|
||||
"itoa",
|
||||
"memchr",
|
||||
"num-cmp",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
|
@ -1521,12 +1357,6 @@ dependencies = [
|
|||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.0"
|
||||
|
|
@ -1564,16 +1394,6 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
|
|
@ -1584,30 +1404,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.4"
|
||||
|
|
@ -1625,21 +1421,6 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-cmp"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa"
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1666,17 +1447,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
|
@ -2077,34 +1847,6 @@ dependencies = [
|
|||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"chrono",
|
||||
"dyn-clone",
|
||||
"indexmap 2.7.0",
|
||||
"schemars_derive",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
|
|
@ -2137,17 +1879,6 @@ dependencies = [
|
|||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.140"
|
||||
|
|
@ -2170,19 +1901,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_qs"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"futures",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
|
|
@ -2610,12 +2328,9 @@ dependencies = [
|
|||
name = "sync_server"
|
||||
version = "0.3.15"
|
||||
dependencies = [
|
||||
"aide",
|
||||
"aide-axum-typed-multipart",
|
||||
"anyhow",
|
||||
"axum",
|
||||
"axum-extra",
|
||||
"axum-jsonschema",
|
||||
"axum_typed_multipart",
|
||||
"bimap",
|
||||
"chrono",
|
||||
|
|
@ -2626,7 +2341,6 @@ dependencies = [
|
|||
"rand 0.9.0",
|
||||
"regex",
|
||||
"sanitize-filename",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
|
|
|
|||
|
|
@ -18,22 +18,18 @@ log = { version = "0.4.27" }
|
|||
anyhow = { version = "1.0.98", features = ["backtrace"] }
|
||||
axum = { version = "0.7.4", features = ["ws", "macros", "tracing", "multipart"]}
|
||||
axum-extra = { version = "0.9.6", features = ["typed-header"] }
|
||||
aide-axum-typed-multipart = "0.13.0"
|
||||
axum_typed_multipart = "0.11.0"
|
||||
tower-http = { version = "0.6.1", features = ["cors", "trace", "limit", "timeout"] }
|
||||
tracing = "0.1.41"
|
||||
tracing-subscriber = { version = "0.3.19", features = ["fmt", "env-filter"]}
|
||||
serde_yaml = "0.9.34"
|
||||
sqlx = { version = "0.8.6", features = ["sqlite", "runtime-tokio", "uuid", "chrono"] }
|
||||
chrono = { version = "0.4.41", features = ["serde"] }
|
||||
aide = { version = "0.13.5", features = ["axum", "axum-ws", "scalar", "axum-headers"] }
|
||||
schemars = { version = "0.8.22", features = ["chrono", "uuid1", "bytes"] }
|
||||
tracing = "0.1.41"
|
||||
rand = "0.9.0"
|
||||
sanitize-filename = "0.6.0"
|
||||
axum-jsonschema = { version = "0.8.0", features = ["aide"] }
|
||||
regex = "1.11.1"
|
||||
clap = { version = "4.5.38", features = ["derive"] }
|
||||
futures = "0.3.31"
|
||||
serde_yaml = "0.9.34"
|
||||
serde_json = "1.0.140"
|
||||
clap-verbosity-flag = "3.0.3"
|
||||
bimap = "0.6.3"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use sync_lib::bytes_to_base64;
|
||||
use ts_rs::TS;
|
||||
|
|
@ -27,7 +26,7 @@ impl PartialEq<Self> for StoredDocumentVersion {
|
|||
fn eq(&self, other: &Self) -> bool { self.vault_update_id == other.vault_update_id }
|
||||
}
|
||||
|
||||
#[derive(TS, Debug, Clone, Serialize, JsonSchema)]
|
||||
#[derive(TS, Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DocumentVersionWithoutContent {
|
||||
#[ts(as = "i32")]
|
||||
|
|
@ -59,7 +58,7 @@ impl From<StoredDocumentVersion> for DocumentVersionWithoutContent {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, JsonSchema)]
|
||||
#[derive(TS, Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DocumentVersion {
|
||||
pub vault_update_id: VaultUpdateId,
|
||||
|
|
|
|||
|
|
@ -12,29 +12,20 @@ mod responses;
|
|||
mod update_document;
|
||||
mod websocket;
|
||||
|
||||
use std::{ffi::OsString, sync::Arc, time::Duration};
|
||||
use std::{ffi::OsString, time::Duration};
|
||||
|
||||
use aide::{
|
||||
axum::{
|
||||
ApiRouter,
|
||||
routing::{delete, get, post, put},
|
||||
},
|
||||
openapi::{Info, OpenApi},
|
||||
scalar::Scalar,
|
||||
transform::TransformOpenApi,
|
||||
};
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use auth::auth_middleware;
|
||||
use axum::{
|
||||
Extension, Json,
|
||||
Router,
|
||||
extract::{DefaultBodyLimit, Request},
|
||||
http::{self, HeaderValue, Method},
|
||||
middleware,
|
||||
response::IntoResponse,
|
||||
routing::IntoMakeService,
|
||||
routing::{IntoMakeService, delete, get, post, put},
|
||||
};
|
||||
use device_id_header::DEVICE_ID_HEADER_NAME;
|
||||
use log::{error, info};
|
||||
use log::info;
|
||||
use tokio::signal;
|
||||
use tower_http::{
|
||||
LatencyUnit,
|
||||
|
|
@ -51,26 +42,20 @@ use tracing::{Level, info_span};
|
|||
use crate::{
|
||||
app_state::AppState,
|
||||
config::server_config::ServerConfig,
|
||||
errors::{SerializedError, client_error, not_found_error},
|
||||
errors::{client_error, not_found_error},
|
||||
};
|
||||
|
||||
pub async fn create_server(config_path: Option<OsString>) -> Result<()> {
|
||||
aide::r#gen::on_error(|err| error!("{err}"));
|
||||
aide::r#gen::extract_schemas(true);
|
||||
|
||||
let app_state = AppState::try_new(config_path)
|
||||
.await
|
||||
.context("Failed to initialise app state")?;
|
||||
|
||||
let server_config = app_state.config.server.clone();
|
||||
|
||||
let mut api = create_open_api();
|
||||
let app = ApiRouter::new()
|
||||
let app = Router::new()
|
||||
.nest("/", get_authed_routes(app_state.clone()))
|
||||
.api_route("/vaults/:vault_id/ping", get(ping::ping))
|
||||
.route("/vaults/:vault_id/ping", get(ping::ping))
|
||||
.route("/vaults/:vault_id/ws", get(websocket::websocket_handler))
|
||||
.route("/", Scalar::new("/api.json").axum_route())
|
||||
.route("/api.json", axum::routing::get(serve_api))
|
||||
.layer(DefaultBodyLimit::disable())
|
||||
.layer(RequestBodyLimitLayer::new(
|
||||
app_state.config.server.max_body_size_mb * 1024 * 1024,
|
||||
|
|
@ -108,8 +93,6 @@ pub async fn create_server(config_path: Option<OsString>) -> Result<()> {
|
|||
.on_failure(DefaultOnFailure::new().level(Level::ERROR)),
|
||||
)
|
||||
.with_state(app_state)
|
||||
.finish_api_with(&mut api, add_api_docs_error_example)
|
||||
.layer(Extension(Arc::new(api))) // https://github.com/tamasfe/aide/blob/507f4a8822bc0c13cbda0f589da1e0f4cbcdb812/examples/example-axum/src/main.rs#L39
|
||||
.fallback(handle_404)
|
||||
.fallback(handle_405)
|
||||
.into_make_service();
|
||||
|
|
@ -117,67 +100,33 @@ pub async fn create_server(config_path: Option<OsString>) -> Result<()> {
|
|||
start_server(app, &server_config).await
|
||||
}
|
||||
|
||||
async fn serve_api(Extension(api): Extension<Arc<OpenApi>>) -> impl IntoResponse { Json(api) }
|
||||
|
||||
fn create_open_api() -> OpenApi {
|
||||
OpenApi {
|
||||
info: Info {
|
||||
title: "VaultLink sync server".to_owned(),
|
||||
summary: Some(
|
||||
"Simple API for syncing documents between concurrent clients.".to_owned(),
|
||||
),
|
||||
description: Some(include_str!("../README.md").to_owned()),
|
||||
version: env!("CARGO_PKG_VERSION").to_owned(),
|
||||
..Info::default()
|
||||
},
|
||||
..OpenApi::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn add_api_docs_error_example(api: TransformOpenApi<'_>) -> TransformOpenApi<'_> {
|
||||
api.default_response_with::<Json<SerializedError>, _>(|res| {
|
||||
res.example(SerializedError {
|
||||
message: "An error has occurred".to_owned(),
|
||||
causes: vec![],
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn get_authed_routes(app_state: AppState) -> ApiRouter<AppState> {
|
||||
ApiRouter::new()
|
||||
.api_route(
|
||||
fn get_authed_routes(app_state: AppState) -> Router<AppState> {
|
||||
Router::new()
|
||||
.route(
|
||||
"/vaults/:vault_id/documents",
|
||||
get(fetch_latest_documents::fetch_latest_documents),
|
||||
)
|
||||
.api_route(
|
||||
.route(
|
||||
"/vaults/:vault_id/documents",
|
||||
post(create_document::create_document_multipart),
|
||||
post(create_document::create_document),
|
||||
)
|
||||
.api_route(
|
||||
"/vaults/:vault_id/documents/json",
|
||||
post(create_document::create_document_json),
|
||||
)
|
||||
.api_route(
|
||||
.route(
|
||||
"/vaults/:vault_id/documents/:document_id",
|
||||
get(fetch_latest_document_version::fetch_latest_document_version),
|
||||
)
|
||||
.api_route(
|
||||
.route(
|
||||
"/vaults/:vault_id/documents/:document_id",
|
||||
put(update_document::update_document_multipart),
|
||||
put(update_document::update_document),
|
||||
)
|
||||
.api_route(
|
||||
"/vaults/:vault_id/documents/:document_id/json",
|
||||
put(update_document::update_document_json),
|
||||
)
|
||||
.api_route(
|
||||
.route(
|
||||
"/vaults/:vault_id/documents/:document_id/versions/:version_id",
|
||||
put(fetch_document_version::fetch_document_version),
|
||||
)
|
||||
.api_route(
|
||||
.route(
|
||||
"/vaults/:vault_id/documents/:document_id/versions/:version_id/content",
|
||||
put(fetch_document_version_content::fetch_document_version_content),
|
||||
)
|
||||
.api_route(
|
||||
.route(
|
||||
"/vaults/:vault_id/documents/:document_id",
|
||||
delete(delete_document::delete_document),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,33 +1,24 @@
|
|||
use aide_axum_typed_multipart::TypedMultipart;
|
||||
use anyhow::Context as _;
|
||||
use axum::{
|
||||
Extension,
|
||||
Extension, Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use axum_extra::TypedHeader;
|
||||
use axum_jsonschema::Json;
|
||||
use schemars::JsonSchema;
|
||||
use axum_typed_multipart::TypedMultipart;
|
||||
use serde::Deserialize;
|
||||
use sync_lib::base64_to_bytes;
|
||||
|
||||
use super::{
|
||||
device_id_header::DeviceIdHeader,
|
||||
requests::{CreateDocumentVersion, CreateDocumentVersionMultipart},
|
||||
};
|
||||
use super::{device_id_header::DeviceIdHeader, requests::CreateDocumentVersion};
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::models::{
|
||||
DocumentId, DocumentVersionWithoutContent, StoredDocumentVersion, VaultId,
|
||||
},
|
||||
database::models::{DocumentVersionWithoutContent, StoredDocumentVersion, VaultId},
|
||||
},
|
||||
config::user_config::User,
|
||||
errors::{SyncServerError, client_error, server_error},
|
||||
utils::{normalize::normalize, sanitize_path::sanitize_path},
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct CreateDocumentPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
@ -37,63 +28,12 @@ pub struct CreateDocumentPathParams {
|
|||
/// already. If a document with the same path exists, a new version is created
|
||||
/// with their content merged.
|
||||
#[axum::debug_handler]
|
||||
pub async fn create_document_multipart(
|
||||
pub async fn create_document(
|
||||
Path(CreateDocumentPathParams { vault_id }): Path<CreateDocumentPathParams>,
|
||||
Extension(user): Extension<User>,
|
||||
TypedHeader(device_id): TypedHeader<DeviceIdHeader>,
|
||||
State(state): State<AppState>,
|
||||
TypedMultipart(axum_typed_multipart::TypedMultipart(request)): TypedMultipart<
|
||||
CreateDocumentVersionMultipart,
|
||||
>,
|
||||
) -> Result<Json<DocumentVersionWithoutContent>, SyncServerError> {
|
||||
internal_create_document(
|
||||
user,
|
||||
device_id,
|
||||
state,
|
||||
vault_id,
|
||||
request.document_id,
|
||||
request.relative_path,
|
||||
request.content.contents.to_vec(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Create a new document in case a document with the same doesn't exist
|
||||
/// already. If a document with the same path exists, a new version is created
|
||||
/// with their content merged.
|
||||
#[axum::debug_handler]
|
||||
pub async fn create_document_json(
|
||||
Path(CreateDocumentPathParams { vault_id }): Path<CreateDocumentPathParams>,
|
||||
Extension(user): Extension<User>,
|
||||
TypedHeader(device_id): TypedHeader<DeviceIdHeader>,
|
||||
State(state): State<AppState>,
|
||||
Json(request): Json<CreateDocumentVersion>,
|
||||
) -> Result<Json<DocumentVersionWithoutContent>, SyncServerError> {
|
||||
let content_bytes = base64_to_bytes(&request.content_base64)
|
||||
.context("Failed to decode base64 content in request")
|
||||
.map_err(client_error)?;
|
||||
|
||||
internal_create_document(
|
||||
user,
|
||||
device_id,
|
||||
state,
|
||||
vault_id,
|
||||
request.document_id,
|
||||
request.relative_path,
|
||||
content_bytes,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn internal_create_document(
|
||||
user: User,
|
||||
device_id: DeviceIdHeader,
|
||||
state: AppState,
|
||||
vault_id: VaultId,
|
||||
document_id: Option<DocumentId>,
|
||||
relative_path: String,
|
||||
content: Vec<u8>,
|
||||
TypedMultipart(request): TypedMultipart<CreateDocumentVersion>,
|
||||
) -> Result<Json<DocumentVersionWithoutContent>, SyncServerError> {
|
||||
let mut transaction = state
|
||||
.database
|
||||
|
|
@ -101,7 +41,7 @@ async fn internal_create_document(
|
|||
.await
|
||||
.map_err(server_error)?;
|
||||
|
||||
let document_id = match document_id {
|
||||
let document_id = match request.document_id {
|
||||
Some(document_id) => {
|
||||
let existing_version = state
|
||||
.database
|
||||
|
|
@ -126,13 +66,13 @@ async fn internal_create_document(
|
|||
.await
|
||||
.map_err(server_error)?;
|
||||
|
||||
let sanitized_relative_path = sanitize_path(&relative_path);
|
||||
let sanitized_relative_path = sanitize_path(&request.relative_path);
|
||||
|
||||
let new_version = StoredDocumentVersion {
|
||||
vault_update_id: last_update_id + 1,
|
||||
document_id,
|
||||
relative_path: sanitized_relative_path,
|
||||
content,
|
||||
content: request.content.contents.to_vec(),
|
||||
updated_date: chrono::Utc::now(),
|
||||
is_deleted: false,
|
||||
user_id: user.name,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
use anyhow::Context as _;
|
||||
use axum::{
|
||||
Extension,
|
||||
Extension, Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use axum_extra::TypedHeader;
|
||||
use axum_jsonschema::Json;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{device_id_header::DeviceIdHeader, requests::DeleteDocumentVersion};
|
||||
|
|
@ -21,8 +19,7 @@ use crate::{
|
|||
utils::{normalize::normalize, sanitize_path::sanitize_path},
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct DeleteDocumentPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use anyhow::anyhow;
|
||||
use axum::extract::{Path, State};
|
||||
use axum_jsonschema::Json;
|
||||
use schemars::JsonSchema;
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -13,8 +14,7 @@ use crate::{
|
|||
utils::normalize::normalize,
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct FetchDocumentVersionPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use axum::{
|
|||
body::Bytes,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -15,8 +14,7 @@ use crate::{
|
|||
utils::normalize::normalize,
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct FetchDocumentVersionContentPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use anyhow::anyhow;
|
||||
use axum::extract::{Path, State};
|
||||
use axum_jsonschema::Json;
|
||||
use schemars::JsonSchema;
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -13,8 +14,7 @@ use crate::{
|
|||
utils::normalize::normalize,
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct FetchLatestDocumentVersionPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use axum::extract::{Path, Query, State};
|
||||
use axum_jsonschema::Json;
|
||||
use schemars::JsonSchema;
|
||||
use axum::{
|
||||
Json,
|
||||
extract::{Path, Query, State},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::responses::FetchLatestDocumentsResponse;
|
||||
|
|
@ -13,15 +14,13 @@ use crate::{
|
|||
utils::normalize::normalize,
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct FetchLatestDocumentsPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct QueryParams {
|
||||
since_update_id: Option<VaultUpdateId>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use axum_extra::{
|
|||
TypedHeader,
|
||||
headers::{Authorization, authorization::Bearer},
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{auth::auth, responses::PingResponse};
|
||||
|
|
@ -16,8 +15,7 @@ use crate::{
|
|||
utils::normalize::normalize,
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct PingPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
use aide_axum_typed_multipart::FieldData;
|
||||
use axum::body::Bytes;
|
||||
use axum_typed_multipart::TryFromMultipart;
|
||||
use schemars::JsonSchema;
|
||||
use axum_typed_multipart::{FieldData, TryFromMultipart};
|
||||
use serde::{self, Deserialize};
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::app_state::database::models::{DocumentId, VaultUpdateId};
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[derive(TS, Debug, TryFromMultipart)]
|
||||
#[ts(export)]
|
||||
pub struct CreateDocumentVersion {
|
||||
/// The client can decide the document id (if it wishes to) in order
|
||||
/// to help with syncing. If the client does not provide a document id,
|
||||
|
|
@ -15,36 +14,26 @@ pub struct CreateDocumentVersion {
|
|||
/// it must not already exist in the database.
|
||||
pub document_id: Option<DocumentId>,
|
||||
pub relative_path: String,
|
||||
pub content_base64: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, TryFromMultipart, JsonSchema)]
|
||||
pub struct CreateDocumentVersionMultipart {
|
||||
pub document_id: Option<DocumentId>,
|
||||
pub relative_path: String,
|
||||
#[ts(as = "Vec<u8>")]
|
||||
#[form_data(limit = "unlimited")]
|
||||
pub content: FieldData<Bytes>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[derive(TS, Debug, TryFromMultipart)]
|
||||
#[ts(export)]
|
||||
pub struct UpdateDocumentVersion {
|
||||
pub parent_version_id: VaultUpdateId,
|
||||
pub relative_path: String,
|
||||
pub content_base64: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, TryFromMultipart, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateDocumentVersionMultipart {
|
||||
pub parent_version_id: VaultUpdateId,
|
||||
pub relative_path: String,
|
||||
#[ts(as = "Vec<u8>")]
|
||||
#[form_data(limit = "unlimited")]
|
||||
pub content: FieldData<Bytes>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
#[derive(TS, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct DeleteDocumentVersion {
|
||||
pub relative_path: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
use schemars::JsonSchema;
|
||||
use serde::{self, Serialize};
|
||||
use ts_rs::TS;
|
||||
|
||||
use crate::app_state::database::models::{
|
||||
DocumentVersion, DocumentVersionWithoutContent, VaultUpdateId,
|
||||
};
|
||||
|
||||
/// Response to a ping request.
|
||||
#[derive(Debug, Clone, Serialize, JsonSchema)]
|
||||
#[derive(TS, Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct PingResponse {
|
||||
/// Semantic version of the server.
|
||||
pub server_version: String,
|
||||
|
|
@ -18,8 +19,9 @@ pub struct PingResponse {
|
|||
}
|
||||
|
||||
/// Response to a fetch latest documents request.
|
||||
#[derive(Debug, Clone, Serialize, JsonSchema)]
|
||||
#[derive(TS, Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export)]
|
||||
pub struct FetchLatestDocumentsResponse {
|
||||
pub latest_documents: Vec<DocumentVersionWithoutContent>,
|
||||
|
||||
|
|
@ -28,8 +30,9 @@ pub struct FetchLatestDocumentsResponse {
|
|||
}
|
||||
|
||||
/// Response to an update document request.
|
||||
#[derive(Debug, Clone, Serialize, JsonSchema)]
|
||||
#[derive(TS, Debug, Clone, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
#[ts(export)]
|
||||
pub enum DocumentUpdateResponse {
|
||||
/// Returned when the created/updated document's content is the same as was
|
||||
/// sent in the create/update request and thus the response doesn't contain
|
||||
|
|
|
|||
|
|
@ -1,33 +1,29 @@
|
|||
use aide_axum_typed_multipart::TypedMultipart;
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use axum::{
|
||||
Extension,
|
||||
Extension, Json,
|
||||
extract::{Path, State},
|
||||
};
|
||||
use axum_extra::TypedHeader;
|
||||
use axum_jsonschema::Json;
|
||||
use axum_typed_multipart::TypedMultipart;
|
||||
use log::info;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use sync_lib::{base64_to_bytes, is_file_type_mergable, merge};
|
||||
use sync_lib::{is_file_type_mergable, merge};
|
||||
|
||||
use super::{
|
||||
device_id_header::DeviceIdHeader,
|
||||
requests::{UpdateDocumentVersion, UpdateDocumentVersionMultipart},
|
||||
device_id_header::DeviceIdHeader, requests::UpdateDocumentVersion,
|
||||
responses::DocumentUpdateResponse,
|
||||
};
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::models::{DocumentId, StoredDocumentVersion, VaultId, VaultUpdateId},
|
||||
database::models::{DocumentId, StoredDocumentVersion, VaultId},
|
||||
},
|
||||
config::user_config::User,
|
||||
errors::{SyncServerError, client_error, not_found_error, server_error},
|
||||
errors::{SyncServerError, not_found_error, server_error},
|
||||
utils::{dedup_paths::dedup_paths, normalize::normalize, sanitize_path::sanitize_path},
|
||||
};
|
||||
|
||||
// This is required for aide to infer the path parameter types and names
|
||||
#[derive(Deserialize, JsonSchema)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct UpdateDocumentPathParams {
|
||||
#[serde(deserialize_with = "normalize")]
|
||||
vault_id: VaultId,
|
||||
|
|
@ -36,7 +32,8 @@ pub struct UpdateDocumentPathParams {
|
|||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn update_document_multipart(
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub async fn update_document(
|
||||
Path(UpdateDocumentPathParams {
|
||||
vault_id,
|
||||
document_id,
|
||||
|
|
@ -44,79 +41,25 @@ pub async fn update_document_multipart(
|
|||
Extension(user): Extension<User>,
|
||||
TypedHeader(device_id): TypedHeader<DeviceIdHeader>,
|
||||
State(state): State<AppState>,
|
||||
TypedMultipart(axum_typed_multipart::TypedMultipart(request)): TypedMultipart<
|
||||
UpdateDocumentVersionMultipart,
|
||||
>,
|
||||
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
|
||||
internal_update_document(
|
||||
user,
|
||||
device_id,
|
||||
state,
|
||||
vault_id,
|
||||
document_id,
|
||||
request.parent_version_id,
|
||||
request.relative_path,
|
||||
request.content.contents.to_vec(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn update_document_json(
|
||||
Path(UpdateDocumentPathParams {
|
||||
vault_id,
|
||||
document_id,
|
||||
}): Path<UpdateDocumentPathParams>,
|
||||
Extension(user): Extension<User>,
|
||||
TypedHeader(device_id): TypedHeader<DeviceIdHeader>,
|
||||
State(state): State<AppState>,
|
||||
Json(request): Json<UpdateDocumentVersion>,
|
||||
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
|
||||
let content_bytes = base64_to_bytes(&request.content_base64)
|
||||
.context("Failed to decode base64 content in request")
|
||||
.map_err(client_error)?;
|
||||
|
||||
internal_update_document(
|
||||
user,
|
||||
device_id,
|
||||
state,
|
||||
vault_id,
|
||||
document_id,
|
||||
request.parent_version_id,
|
||||
request.relative_path,
|
||||
content_bytes,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments, clippy::too_many_lines)]
|
||||
async fn internal_update_document(
|
||||
user: User,
|
||||
device_id: DeviceIdHeader,
|
||||
state: AppState,
|
||||
vault_id: VaultId,
|
||||
document_id: DocumentId,
|
||||
parent_version_id: VaultUpdateId,
|
||||
relative_path: String,
|
||||
content: Vec<u8>,
|
||||
TypedMultipart(request): TypedMultipart<UpdateDocumentVersion>,
|
||||
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
|
||||
// No need for a transaction as document versions are immutable
|
||||
let parent_document = state
|
||||
.database
|
||||
.get_document_version(&vault_id, parent_version_id, None)
|
||||
.get_document_version(&vault_id, request.parent_version_id, None)
|
||||
.await
|
||||
.map_err(server_error)?
|
||||
.map_or_else(
|
||||
|| {
|
||||
Err(not_found_error(anyhow!(
|
||||
"Parent version with id `{}` not found",
|
||||
parent_version_id
|
||||
request.parent_version_id
|
||||
)))
|
||||
},
|
||||
Ok,
|
||||
)?;
|
||||
|
||||
let sanitized_relative_path = sanitize_path(&relative_path);
|
||||
let sanitized_relative_path = sanitize_path(&request.relative_path);
|
||||
|
||||
let mut transaction = state
|
||||
.database
|
||||
|
|
@ -156,6 +99,8 @@ async fn internal_update_document(
|
|||
)));
|
||||
}
|
||||
|
||||
let content = request.content.contents.to_vec();
|
||||
|
||||
// Return the latest version if the content and path are the same as the latest
|
||||
// version
|
||||
if content == latest_version.content && sanitized_relative_path == latest_version.relative_path
|
||||
|
|
|
|||
|
|
@ -3,13 +3,9 @@
|
|||
set -e
|
||||
|
||||
rm -rf backend/sync_server/bindings
|
||||
|
||||
cd backend
|
||||
cargo test export_bindings
|
||||
cd -
|
||||
|
||||
cp -r backend/sync_server/bindings/* frontend/sync-client/src/services/types/
|
||||
|
||||
./scripts/utils/wait-for-server.sh
|
||||
|
||||
npm install -g openapi-typescript
|
||||
openapi-typescript http://localhost:3000/api.json --output frontend/sync-client/src/services/types/http-api.ts
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue