Working utoipa setup
This commit is contained in:
parent
1b142b1855
commit
2e2ddf017b
32 changed files with 55 additions and 1550 deletions
|
@ -43,6 +43,7 @@
|
|||
### API
|
||||
|
||||
- API version is now 8.0.
|
||||
- Documentation is now served under `/docs` instead of `/swagger` (eg. `http://localhost:5050/docs`)
|
||||
- Clients are now expected to send their preferred API major version in a `Accept-Version` header. Omitting this currently defaults to `7`, but will become an error in future Polaris releases. Support for API version 7 will be removed entirely in a future release.
|
||||
- Most API responses now support gzip compression.
|
||||
- The response format of the `/browse`, `/flatten`, `/get_playlist`, `/search/<query>` endpoints has been modified to accomodate large lists.
|
||||
|
|
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -1851,7 +1851,11 @@ dependencies = [
|
|||
"ureq",
|
||||
"utoipa",
|
||||
"utoipa-axum",
|
||||
<<<<<<< HEAD
|
||||
"utoipa-swagger-ui",
|
||||
=======
|
||||
"utoipa-scalar",
|
||||
>>>>>>> 7653e4b (Working utoipa setup)
|
||||
"winres",
|
||||
]
|
||||
|
||||
|
@ -2711,6 +2715,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
<<<<<<< HEAD
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2722,6 +2727,8 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.96",
|
||||
=======
|
||||
>>>>>>> 7653e4b (Working utoipa setup)
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3106,6 +3113,7 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
<<<<<<< HEAD
|
||||
name = "utoipa-swagger-ui"
|
||||
version = "8.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
@ -3131,6 +3139,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e2eebbbfe4093922c2b6734d7c679ebfebd704a0d7e56dfcb0d05818ce28977d"
|
||||
|
||||
[[package]]
|
||||
=======
|
||||
name = "utoipa-scalar"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088e93bf19f6bd06e0aacb02ca432b3c5a449c4aec2e4aa9fc333a667f2b2c55"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"utoipa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
>>>>>>> 7653e4b (Working utoipa setup)
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
@ -3527,37 +3549,6 @@ dependencies = [
|
|||
"syn 2.0.96",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae9c1ea7b3a5e1f4b922ff856a129881167511563dc219869afe3787fc0c1a45"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"displaydoc",
|
||||
"flate2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"thiserror 2.0.11",
|
||||
"zopfli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"crc32fast",
|
||||
"lockfree-object-pool",
|
||||
"log",
|
||||
"once_cell",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.4.12"
|
||||
|
|
|
@ -66,8 +66,8 @@ trie-rs = { version = "0.4.2", features = ["serde"] }
|
|||
unicase = "2.7.0"
|
||||
ureq = { version = "2.10.0", default-features = false, features = ["tls"] }
|
||||
utoipa = { version = "5.3", features = ["axum_extras"] }
|
||||
utoipa-swagger-ui = { version = "8.1", features = ["axum", "vendored"] }
|
||||
utoipa-axum = { version = "0.1" }
|
||||
utoipa-scalar = { version = "0.2", features = ["axum"] }
|
||||
|
||||
[dependencies.axum]
|
||||
version = "0.8.1"
|
||||
|
|
|
@ -40,7 +40,7 @@ Password: `demo_password`
|
|||
|
||||
### API Documentation
|
||||
|
||||
The Polaris server API is documented via [Swagger](https://demo.polaris.stream/swagger/). Every installation of Polaris distributes this documentation, with the ability to use the `Try it out` buttons. To access it, simply open http://localhost:5050/swagger/ in your browser on the machine running Polaris.
|
||||
The Polaris server API is documented via [OpenAPI](https://demo.polaris.stream/docs/). Every installation of Polaris distributes this interactive documentation. To access it, simply open http://localhost:5050/docs/ in your browser on the machine running Polaris.
|
||||
|
||||
## Credits & License Information
|
||||
|
||||
|
|
|
@ -13,10 +13,9 @@ Polaris supports a few command line arguments which are useful during developmen
|
|||
- `-c some/config.toml` sets the location of the configuration file. This is useful to preconfigure users and music directories.
|
||||
- `--data some/path` sets the folder Polaris will use to store runtime data such as playlists, collection index and auth secrets.
|
||||
- `-w some/path/to/web/dir` lets you point to the directory to be served as the web interface. You can find a suitable directory in your Polaris install (under `/web`), or from the [latest polaris-web release](https://github.com/agersant/polaris-web/releases/latest/download/web.zip).
|
||||
- `-s some/path/to/swagger/dir` lets you point to the directory to be served as the swagger API documentation. You'll probably want to point this to the `/docs/swagger` directory of the polaris repository.
|
||||
- `-f` (on Linux) makes Polaris not fork into a separate process.
|
||||
|
||||
Putting it all together, a typical command to compile and run the program would be: `cargo run -- -w web -s docs/swagger -c test-config.toml`
|
||||
Putting it all together, a typical command to compile and run the program would be: `cargo run -- -w web -c test-config.toml`
|
||||
|
||||
While Polaris is running, access the web UI at [http://localhost:5050](http://localhost:5050).
|
||||
|
||||
|
|
Binary file not shown.
Before ![]() (image error) Size: 665 B |
Binary file not shown.
Before ![]() (image error) Size: 628 B |
|
@ -1,60 +0,0 @@
|
|||
<!-- HTML for static distribution bundle build -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Polaris Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="swagger-ui.css">
|
||||
<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />
|
||||
<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />
|
||||
<style>
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
overflow: -moz-scrollbars-vertical;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="swagger-ui-bundle.js"> </script>
|
||||
<script src="swagger-ui-standalone-preset.js"> </script>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
// Begin Swagger UI call region
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "polaris-api.json",
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
// End Swagger UI call region
|
||||
|
||||
window.ui = ui
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,67 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en-US">
|
||||
<body onload="run()">
|
||||
</body>
|
||||
</html>
|
||||
<script>
|
||||
'use strict';
|
||||
function run () {
|
||||
var oauth2 = window.opener.swaggerUIRedirectOauth2;
|
||||
var sentState = oauth2.state;
|
||||
var redirectUrl = oauth2.redirectUrl;
|
||||
var isValid, qp, arr;
|
||||
|
||||
if (/code|token|error/.test(window.location.hash)) {
|
||||
qp = window.location.hash.substring(1);
|
||||
} else {
|
||||
qp = location.search.substring(1);
|
||||
}
|
||||
|
||||
arr = qp.split("&")
|
||||
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
|
||||
qp = qp ? JSON.parse('{' + arr.join() + '}',
|
||||
function (key, value) {
|
||||
return key === "" ? value : decodeURIComponent(value)
|
||||
}
|
||||
) : {}
|
||||
|
||||
isValid = qp.state === sentState
|
||||
|
||||
if ((
|
||||
oauth2.auth.schema.get("flow") === "accessCode"||
|
||||
oauth2.auth.schema.get("flow") === "authorizationCode"
|
||||
) && !oauth2.auth.code) {
|
||||
if (!isValid) {
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "warning",
|
||||
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
|
||||
});
|
||||
}
|
||||
|
||||
if (qp.code) {
|
||||
delete oauth2.state;
|
||||
oauth2.auth.code = qp.code;
|
||||
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
|
||||
} else {
|
||||
let oauthErrorMsg
|
||||
if (qp.error) {
|
||||
oauthErrorMsg = "["+qp.error+"]: " +
|
||||
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
|
||||
(qp.error_uri ? "More info: "+qp.error_uri : "");
|
||||
}
|
||||
|
||||
oauth2.errCb({
|
||||
authId: oauth2.auth.name,
|
||||
source: "auth",
|
||||
level: "error",
|
||||
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
|
||||
}
|
||||
window.close();
|
||||
}
|
||||
</script>
|
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,7 @@ echo "Creating output directory"
|
|||
mkdir -p release/tmp/polaris
|
||||
|
||||
echo "Copying package files"
|
||||
cp -r web docs/swagger src migrations test-data build.rs Cargo.toml Cargo.lock rust-toolchain res/unix/Makefile release/tmp/polaris
|
||||
cp -r web src migrations test-data build.rs Cargo.toml Cargo.lock rust-toolchain res/unix/Makefile release/tmp/polaris
|
||||
|
||||
echo "Creating tarball"
|
||||
tar -zc -C release/tmp -f release/polaris.tar.gz polaris
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
<ComponentRef Id="ProgramMenuDir" />
|
||||
<ComponentRef Id="CleanupExtraData" />
|
||||
<ComponentGroupRef Id="WebUI" />
|
||||
<ComponentGroupRef Id="SwaggerUI" />
|
||||
</Feature>
|
||||
<Icon Id="polaris.exe" SourceFile="polaris.exe" />
|
||||
<Property Id="ARPPRODUCTICON" Value="polaris.exe" />
|
||||
|
|
|
@ -8,7 +8,6 @@ if (!(Test-Path env:POLARIS_VERSION)) {
|
|||
# And remove the code setting these as defaults in `service/mod.rs`
|
||||
# $script:INSTALL_DIR = "%LOCALAPPDATA%\Permafrost\Polaris"
|
||||
# $env:POLARIS_WEB_DIR = "$INSTALL_DIR\web"
|
||||
# $env:POLARIS_SWAGGER_DIR = "$INSTALL_DIR\swagger"
|
||||
# $env:POLARIS_DB_DIR = "$INSTALL_DIR"
|
||||
# $env:POLARIS_LOG_DIR = "$INSTALL_DIR"
|
||||
# $env:POLARIS_CACHE_DIR = "$INSTALL_DIR"
|
||||
|
@ -29,7 +28,6 @@ Copy-Item .\res\windows\installer\dialog.bmp .\release\tmp\
|
|||
Copy-Item .\target\release\polaris.exe .\release\tmp\
|
||||
Copy-Item .\target\release\polaris-cli.exe .\release\tmp\
|
||||
Copy-Item .\web .\release\tmp\web -recurse
|
||||
Copy-Item .\docs\swagger .\release\tmp\swagger -recurse
|
||||
|
||||
""
|
||||
"Inserting version number in installer config"
|
||||
|
@ -41,15 +39,13 @@ $wxs.Save('.\res\windows\installer\installer.wxs')
|
|||
"Creating installer"
|
||||
$heat_exe = Join-Path $env:WIX bin\heat.exe
|
||||
& $heat_exe dir .\release\tmp\web\ -ag -g1 -dr AppDataPolaris -cg WebUI -sfrag -var wix.WebUIDir -out .\release\tmp\web_ui_fragment.wxs
|
||||
& $heat_exe dir .\release\tmp\swagger\ -ag -g1 -dr AppDataPolaris -cg SwaggerUI -sfrag -var wix.SwaggerUIDir -out .\release\tmp\swagger_ui_fragment.wxs
|
||||
|
||||
$candle_exe = Join-Path $env:WIX bin\candle.exe
|
||||
& $candle_exe -wx -ext WixUtilExtension -arch x64 -out .\release\tmp\web_ui_fragment.wixobj .\release\tmp\web_ui_fragment.wxs
|
||||
& $candle_exe -wx -ext WixUtilExtension -arch x64 -out .\release\tmp\swagger_ui_fragment.wixobj .\release\tmp\swagger_ui_fragment.wxs
|
||||
& $candle_exe -wx -ext WixUtilExtension -arch x64 -out .\release\tmp\installer.wixobj .\res\windows\installer\installer.wxs
|
||||
|
||||
$light_exe = Join-Path $env:WIX bin\light.exe
|
||||
& $light_exe -dWebUIDir=".\release\tmp\web" -dSwaggerUIDir=".\release\tmp\swagger" -wx -ext WixUtilExtension -ext WixUIExtension -spdb -sw1076 -sice:ICE38 -sice:ICE64 -out .\release\polaris.msi .\release\tmp\installer.wixobj .\release\tmp\web_ui_fragment.wixobj .\release\tmp\swagger_ui_fragment.wixobj
|
||||
& $light_exe -dWebUIDir=".\release\tmp\web" -wx -ext WixUtilExtension -ext WixUIExtension -spdb -sw1076 -sice:ICE38 -sice:ICE64 -out .\release\polaris.msi .\release\tmp\installer.wixobj .\release\tmp\web_ui_fragment.wixobj
|
||||
|
||||
"Cleaning up"
|
||||
Remove-Item -Recurse .\release\tmp
|
||||
|
|
|
@ -154,7 +154,6 @@ pub enum Error {
|
|||
pub struct App {
|
||||
pub port: u16,
|
||||
pub web_dir_path: PathBuf,
|
||||
pub swagger_dir_path: PathBuf,
|
||||
pub ddns_manager: ddns::Manager,
|
||||
pub scanner: scanner::Scanner,
|
||||
pub index_manager: index::Manager,
|
||||
|
@ -172,9 +171,6 @@ impl App {
|
|||
fs::create_dir_all(&paths.web_dir_path)
|
||||
.map_err(|e| Error::Io(paths.web_dir_path.clone(), e))?;
|
||||
|
||||
fs::create_dir_all(&paths.swagger_dir_path)
|
||||
.map_err(|e| Error::Io(paths.swagger_dir_path.clone(), e))?;
|
||||
|
||||
let peaks_dir_path = paths.cache_dir_path.join("peaks");
|
||||
fs::create_dir_all(&peaks_dir_path).map_err(|e| Error::Io(peaks_dir_path.clone(), e))?;
|
||||
|
||||
|
@ -198,7 +194,6 @@ impl App {
|
|||
let app = Self {
|
||||
port,
|
||||
web_dir_path: paths.web_dir_path,
|
||||
swagger_dir_path: paths.swagger_dir_path,
|
||||
ddns_manager,
|
||||
scanner,
|
||||
index_manager,
|
||||
|
|
|
@ -135,7 +135,6 @@ fn main() -> Result<(), Error> {
|
|||
if !cli_options.foreground {
|
||||
info!("Pid file location is {:#?}", paths.pid_file_path);
|
||||
}
|
||||
info!("Swagger files location is {:#?}", paths.swagger_dir_path);
|
||||
info!("Web client files location is {:#?}", paths.web_dir_path);
|
||||
|
||||
async_main(cli_options, paths)
|
||||
|
|
|
@ -12,7 +12,6 @@ pub struct CLIOptions {
|
|||
pub cache_dir_path: Option<PathBuf>,
|
||||
pub data_dir_path: Option<PathBuf>,
|
||||
pub web_dir_path: Option<PathBuf>,
|
||||
pub swagger_dir_path: Option<PathBuf>,
|
||||
pub port: Option<u16>,
|
||||
pub log_level: Option<LevelFilter>,
|
||||
}
|
||||
|
@ -45,7 +44,6 @@ impl Manager {
|
|||
cache_dir_path: matches.opt_str("cache").map(PathBuf::from),
|
||||
data_dir_path: matches.opt_str("data").map(PathBuf::from),
|
||||
web_dir_path: matches.opt_str("w").map(PathBuf::from),
|
||||
swagger_dir_path: matches.opt_str("s").map(PathBuf::from),
|
||||
port: matches.opt_str("p").and_then(|p| p.parse().ok()),
|
||||
log_level: matches.opt_str("log-level").and_then(|l| l.parse().ok()),
|
||||
})
|
||||
|
@ -62,7 +60,6 @@ fn get_options() -> getopts::Options {
|
|||
options.optopt("p", "port", "set polaris to run on a custom port", "PORT");
|
||||
options.optopt("d", "database", "set the path to index database", "FILE");
|
||||
options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
|
||||
options.optopt("s", "swagger", "set the path to swagger files", "DIRECTORY");
|
||||
options.optopt(
|
||||
"",
|
||||
"cache",
|
||||
|
|
|
@ -10,7 +10,6 @@ pub struct Paths {
|
|||
pub log_file_path: Option<PathBuf>,
|
||||
#[cfg(unix)]
|
||||
pub pid_file_path: PathBuf,
|
||||
pub swagger_dir_path: PathBuf,
|
||||
pub web_dir_path: PathBuf,
|
||||
}
|
||||
|
||||
|
@ -26,7 +25,6 @@ impl Default for Paths {
|
|||
db_file_path: [".", "db.sqlite"].iter().collect(),
|
||||
log_file_path: Some([".", "polaris.log"].iter().collect()),
|
||||
pid_file_path: [".", "polaris.pid"].iter().collect(),
|
||||
swagger_dir_path: [".", "docs", "swagger"].iter().collect(),
|
||||
web_dir_path: [".", "web"].iter().collect(),
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +42,6 @@ impl Default for Paths {
|
|||
data_dir_path: install_directory.clone(),
|
||||
db_file_path: install_directory.join("db.sqlite"),
|
||||
log_file_path: Some(install_directory.join("polaris.log")),
|
||||
swagger_dir_path: install_directory.join("swagger"),
|
||||
web_dir_path: install_directory.join("web"),
|
||||
}
|
||||
}
|
||||
|
@ -76,9 +73,6 @@ impl Paths {
|
|||
.map(PathBuf::from)
|
||||
.map(|p| p.join("polaris.pid"))
|
||||
.unwrap_or(defaults.pid_file_path),
|
||||
swagger_dir_path: option_env!("POLARIS_SWAGGER_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or(defaults.swagger_dir_path),
|
||||
web_dir_path: option_env!("POLARIS_WEB_DIR")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or(defaults.web_dir_path),
|
||||
|
@ -103,9 +97,6 @@ impl Paths {
|
|||
if let Some(path) = &cli_options.pid_file_path {
|
||||
path.clone_into(&mut paths.pid_file_path);
|
||||
}
|
||||
if let Some(path) = &cli_options.swagger_dir_path {
|
||||
path.clone_into(&mut paths.swagger_dir_path);
|
||||
}
|
||||
if let Some(path) = &cli_options.web_dir_path {
|
||||
path.clone_into(&mut paths.web_dir_path);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use tower_http::{
|
|||
};
|
||||
use utoipa::OpenApi;
|
||||
use utoipa_axum::router::OpenApiRouter;
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
use utoipa_scalar::{Scalar, Servable};
|
||||
|
||||
mod api;
|
||||
mod auth;
|
||||
|
@ -21,20 +21,18 @@ mod version;
|
|||
pub mod test;
|
||||
|
||||
pub fn make_router(app: App) -> NormalizePath<Router> {
|
||||
let swagger = ServeDir::new(&app.swagger_dir_path);
|
||||
|
||||
let static_files = Router::new()
|
||||
.fallback_service(ServeDir::new(&app.web_dir_path))
|
||||
.layer(CompressionLayer::new());
|
||||
|
||||
let (open_api_router, open_api) =
|
||||
OpenApiRouter::with_openapi(doc::ApiDoc::openapi()).split_for_parts();
|
||||
let (open_api_router, open_api) = OpenApiRouter::with_openapi(doc::ApiDoc::openapi())
|
||||
.nest("/api", api::router())
|
||||
.split_for_parts();
|
||||
|
||||
let router = open_api_router
|
||||
.merge(SwaggerUi::new("/swagger-ui"))
|
||||
.nest("/api", api::router())
|
||||
.with_state(app.clone())
|
||||
.nest("/", static_files)
|
||||
.merge(Scalar::with_url("/docs", open_api))
|
||||
.fallback_service(static_files)
|
||||
.layer(logger::LogLayer::new());
|
||||
|
||||
NormalizePathLayer::trim_trailing_slash().layer(router)
|
||||
|
|
|
@ -4,13 +4,14 @@ use axum::{
|
|||
extract::{DefaultBodyLimit, Path, Query, State},
|
||||
response::{IntoResponse, Response},
|
||||
routing::{delete, get, post, put},
|
||||
Json, Router,
|
||||
Json,
|
||||
};
|
||||
use axum_extra::headers::Range;
|
||||
use axum_extra::TypedHeader;
|
||||
use axum_range::{KnownSize, Ranged};
|
||||
use regex::Regex;
|
||||
use tower_http::{compression::CompressionLayer, CompressionLevel};
|
||||
use utoipa_axum::{router::OpenApiRouter, routes};
|
||||
|
||||
use crate::{
|
||||
app::{auth, config, ddns, index, peaks, playlist, scanner, thumbnail, App},
|
||||
|
@ -22,11 +23,11 @@ use crate::{
|
|||
|
||||
use super::auth::{AdminRights, Auth};
|
||||
|
||||
pub fn router() -> Router<App> {
|
||||
Router::new()
|
||||
pub fn router() -> OpenApiRouter<App> {
|
||||
OpenApiRouter::new()
|
||||
// Basic
|
||||
.route("/version", get(get_version))
|
||||
.route("/initial_setup", get(get_initial_setup))
|
||||
.routes(routes!(get_version))
|
||||
.routes(routes!(get_initial_setup))
|
||||
.route("/auth", post(post_auth))
|
||||
// Configuration
|
||||
.route("/settings", get(get_settings))
|
||||
|
@ -77,6 +78,13 @@ pub fn router() -> Router<App> {
|
|||
.route("/audio/{*path}", get(get_audio))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/version",
|
||||
responses(
|
||||
(status = 200, body = dto::Version),
|
||||
),
|
||||
)]
|
||||
async fn get_version() -> Json<dto::Version> {
|
||||
let current_version = dto::Version {
|
||||
major: API_MAJOR_VERSION,
|
||||
|
|
|
@ -29,7 +29,6 @@ impl TestService for AxumTestService {
|
|||
#[cfg(unix)]
|
||||
pid_file_path: output_dir.join("polaris.pid"),
|
||||
log_file_path: None,
|
||||
swagger_dir_path: ["docs", "swagger"].iter().collect(),
|
||||
web_dir_path: ["test-data", "web"].iter().collect(),
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use utoipa::ToSchema;
|
|||
use crate::app::{config, index, peaks, playlist, scanner, thumbnail};
|
||||
use std::{collections::HashMap, convert::From, path::PathBuf, time::UNIX_EPOCH};
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize)]
|
||||
#[derive(PartialEq, Eq, Debug, Serialize, Deserialize, ToSchema)]
|
||||
pub struct Version {
|
||||
pub major: i32,
|
||||
pub minor: i32,
|
||||
|
|
|
@ -14,11 +14,11 @@ mod admin;
|
|||
mod auth;
|
||||
mod browser;
|
||||
mod collection;
|
||||
mod docs;
|
||||
mod media;
|
||||
mod playlist;
|
||||
mod search;
|
||||
mod settings;
|
||||
mod swagger;
|
||||
mod user;
|
||||
mod web;
|
||||
|
||||
|
|
|
@ -4,17 +4,17 @@ use crate::server::test::{add_trailing_slash, protocol, ServiceType, TestService
|
|||
use crate::test_name;
|
||||
|
||||
#[tokio::test]
|
||||
async fn can_get_swagger_index() {
|
||||
async fn can_get_docs_index() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::swagger_index();
|
||||
let request = protocol::docs_index();
|
||||
let response = service.fetch(&request).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn can_get_swagger_index_with_trailing_slash() {
|
||||
async fn can_get_docs_index_with_trailing_slash() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let mut request = protocol::swagger_index();
|
||||
let mut request = protocol::docs_index();
|
||||
add_trailing_slash(&mut request);
|
||||
let response = service.fetch(&request).await;
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
|
@ -32,10 +32,10 @@ pub fn web_index() -> Request<()> {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn swagger_index() -> Request<()> {
|
||||
pub fn docs_index() -> Request<()> {
|
||||
Request::builder()
|
||||
.method(Method::GET)
|
||||
.uri("/swagger")
|
||||
.uri("/docs")
|
||||
.body(())
|
||||
.unwrap()
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue