Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f457d9ce7b | ||
|
|
9efe6f64b6 | ||
|
|
3ef166738c | ||
|
|
1bc9c18504 | ||
|
|
de1659d10e | ||
|
|
5471b49f2a | ||
|
|
062a84378d | ||
|
|
de15410394 |
14 changed files with 403 additions and 124 deletions
114
Cargo.lock
generated
114
Cargo.lock
generated
|
|
@ -135,15 +135,6 @@ dependencies = [
|
|||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "archery"
|
||||
version = "1.2.2"
|
||||
|
|
@ -990,17 +981,6 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "1.0.0"
|
||||
|
|
@ -1276,7 +1256,6 @@ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
|||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
"zlib-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1681,7 +1660,6 @@ dependencies = [
|
|||
"url",
|
||||
"utoipa",
|
||||
"utoipa-axum",
|
||||
"utoipa-swagger-ui",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3924,41 +3902,6 @@ dependencies = [
|
|||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e7760e252aaba7b09f4be00e36476cf585bdb68a53552ac954cdf504ab4bc9"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bcfc4d6f53af43755f7a723e4b6b8794fcce052a178dd8c6c1dadc5f5343097"
|
||||
dependencies = [
|
||||
"mime_guess",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn 2.0.119",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0"
|
||||
dependencies = [
|
||||
"sha2 0.11.0",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.3"
|
||||
|
|
@ -5078,31 +5021,6 @@ dependencies = [
|
|||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-swagger-ui"
|
||||
version = "9.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"base64",
|
||||
"mime_guess",
|
||||
"regex",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
"utoipa",
|
||||
"utoipa-swagger-ui-vendored",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-swagger-ui-vendored"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2eebbbfe4093922c2b6734d7c679ebfebd704a0d7e56dfcb0d05818ce28977d"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.24.0"
|
||||
|
|
@ -5745,40 +5663,8 @@ dependencies = [
|
|||
"syn 2.0.119",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"zopfli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zlib-rs"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b142a20ec14a91d5bc708c1dc21b080c550113d8aa77afa29635673a65dd02c5"
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"crc32fast",
|
||||
"log",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -116,8 +116,3 @@ hmac = "0.13"
|
|||
sha2 = "0.11"
|
||||
utoipa = { version = "5", features = ["axum_extras"] }
|
||||
utoipa-axum = "0.2"
|
||||
# "vendored" bundles a pinned Swagger UI dist via utoipa-swagger-ui-vendored
|
||||
# instead of the crate's default curl-download build script — required in
|
||||
# the nix sandbox, which has no network at build time outside the
|
||||
# Cargo.lock-pinned dependency fetch.
|
||||
utoipa-swagger-ui = { version = "9", features = ["axum", "vendored"] }
|
||||
|
|
|
|||
|
|
@ -142,6 +142,9 @@
|
|||
agentBaseToplevel = lib.mkDefault self.packages.x86_64-linux.agent-base-toplevel;
|
||||
managerToplevel = lib.mkDefault self.packages.x86_64-linux.ruth-toplevel;
|
||||
};
|
||||
services.hyperhive.gateway.swaggerUiTheme =
|
||||
lib.mkDefault
|
||||
self.packages.${pkgs.stdenv.hostPlatform.system}.swagger-ui-theme;
|
||||
};
|
||||
hive-ci = ./nix/host-modules/hive-ci.nix;
|
||||
hive-forge = ./nix/host-modules/hive-forge;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ tracing-subscriber.workspace = true
|
|||
problem_details = { version = "0.9.0", features = ["axum"] }
|
||||
utoipa.workspace = true
|
||||
utoipa-axum.workspace = true
|
||||
utoipa-swagger-ui.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
tempfile = "3"
|
||||
|
|
|
|||
|
|
@ -7,18 +7,23 @@ use std::sync::Arc;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use axum::{
|
||||
Json,
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
routing::get,
|
||||
};
|
||||
use utoipa::OpenApi;
|
||||
use utoipa_axum::{router::OpenApiRouter, routes};
|
||||
use utoipa_swagger_ui::SwaggerUi;
|
||||
|
||||
use crate::coordinator::Coordinator;
|
||||
use crate::lifecycle;
|
||||
|
||||
/// Root of the auto-generated `OpenAPI` spec (`/api/openapi.json`, browsable
|
||||
/// at `/api/docs`) — see [`utoipa`]. Only routes carrying a
|
||||
/// Root of the auto-generated `OpenAPI` spec, served raw at
|
||||
/// `/api/openapi.json` — see [`utoipa`]. Swagger UI itself (browsable at
|
||||
/// `/api/docs`) is nginx-hosted straight from the nix store now (see
|
||||
/// `nix/host-modules/hive-gateway/vhosts.nix`'s `swaggerUiLocations`);
|
||||
/// c0re only needs to serve the JSON this route generates, not the whole
|
||||
/// vendored UI. Only routes carrying a
|
||||
/// `#[utoipa::path(...)]` annotation show up; the rest of the (much
|
||||
/// larger) route table below is undocumented for now. Deliberately
|
||||
/// incremental: an unannotated route just doesn't appear in the spec,
|
||||
|
|
@ -206,8 +211,15 @@ pub async fn serve(
|
|||
.routes(routes!(state_snapshot::dashboard_stream))
|
||||
.routes(routes!(state_snapshot::dashboard_history))
|
||||
.split_for_parts();
|
||||
// Just the JSON, not the UI — Swagger UI itself is nginx-hosted from
|
||||
// the nix store (see the module doc comment above `ApiDoc`). `api`
|
||||
// is `Clone`; each request gets its own owned copy for `Json` to
|
||||
// serialize.
|
||||
let app = router
|
||||
.merge(SwaggerUi::new("/api/docs").url("/api/openapi.json", api))
|
||||
.route(
|
||||
"/api/openapi.json",
|
||||
get(move || async move { Json(api.clone()) }),
|
||||
)
|
||||
.with_state(AppState {
|
||||
coord,
|
||||
webhook_secret,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,13 @@ let
|
|||
# container's).
|
||||
dashboardDist = "${config.services.hyperhive.c0re.servedFrontend}/dashboard";
|
||||
|
||||
# Full hyperhive-themed Swagger UI dist — nginx serves this whole
|
||||
# tree straight from the store at /api/docs/, no hive-c0re fallback
|
||||
# (see vhosts.nix's `swaggerUiLocations` and
|
||||
# nix/packages/swagger-ui-{dist,theme}.nix). Own option under this
|
||||
# module (not c0re's) — hive-c0re has no relationship to it.
|
||||
swaggerUiTheme = cfg.swaggerUiTheme;
|
||||
|
||||
# Self-signed TLS is the implicit floor: when neither an operator cert
|
||||
# (`tls.certDir`) nor ACME (`tls.acme.enable`) is configured, the gateway
|
||||
# generates + serves a hive-CA-signed leaf (see hive-tls.nix). There is no
|
||||
|
|
@ -261,6 +268,7 @@ in
|
|||
matrixCfg
|
||||
hyperhiveDomain
|
||||
dashboardDist
|
||||
swaggerUiTheme
|
||||
tlsCert
|
||||
tlsKey
|
||||
;
|
||||
|
|
|
|||
|
|
@ -254,6 +254,21 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
swaggerUiTheme = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
defaultText = lib.literalExpression "hyperhive.packages.\${system}.swagger-ui-theme";
|
||||
description = ''
|
||||
Full Swagger UI static dist, hyperhive-themed (see
|
||||
`nix/packages/swagger-ui-theme.nix`, built on
|
||||
`nix/packages/swagger-ui-dist.nix`). The gateway serves this
|
||||
whole tree directly at `/api/docs/` — hive-c0re hosts none of
|
||||
it, only the dynamic `/api/openapi.json` route (proxied
|
||||
through, unaffected by this option). Override to ship a
|
||||
custom theme (or the plain vendored dist) without a gateway
|
||||
rebuild.
|
||||
'';
|
||||
};
|
||||
|
||||
hsts = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
matrixCfg,
|
||||
hyperhiveDomain,
|
||||
dashboardDist,
|
||||
swaggerUiTheme, # nix/packages/swagger-ui-theme.nix: has index.html + hyperhive-theme.css
|
||||
errorPages, # ./error-pages.nix: { notFound, unreachable, unauthorized }
|
||||
tlsCert,
|
||||
tlsKey,
|
||||
|
|
@ -304,6 +305,40 @@ let
|
|||
proxyPass = "http://${cfg.upstreamHost}:${toString cfg.upstreamPort}";
|
||||
};
|
||||
};
|
||||
|
||||
# Swagger UI: nginx hosts the FULL themed dist (`swaggerUiTheme` —
|
||||
# vendored Swagger UI + our overlay, see nix/packages/swagger-ui-
|
||||
# dist.nix + swagger-ui-theme.nix) straight from the store, with NO
|
||||
# fallback to hive-c0re at all — per the operator's shape: "core
|
||||
# should not need the swagger ui at all if it is hosted in gateway"
|
||||
# / "core only hosts the json". Only `/api/openapi.json`
|
||||
# (the live-generated spec `index.html` fetches; not under this
|
||||
# prefix) still proxies to c0re via "/api/" below — that's the one
|
||||
# thing that has to stay dynamic.
|
||||
#
|
||||
# Prefix location, not exact-match: wins over "/api/" on plain
|
||||
# prefix length (no ordering/`=` needed), and now needs to cover
|
||||
# every file in the tree (bundle.js, maps, favicons, …), not just
|
||||
# our 2 override files — hive-c0re no longer serves any of this as
|
||||
# a fallback once its own `utoipa-swagger-ui` mount is removed.
|
||||
# `= /api/docs` (no trailing slash) issues the same redirect
|
||||
# `utoipa-swagger-ui`'s router used to: that mount is going away
|
||||
# too, so nginx has to own it now, or the H0M3 hub's own `/api/docs`
|
||||
# link (no trailing slash) would 404 once hive-c0re drops the route.
|
||||
swaggerUiLocations = {
|
||||
"= /api/docs" = {
|
||||
extraConfig = ''
|
||||
return 301 /api/docs/;
|
||||
'';
|
||||
};
|
||||
"/api/docs/" = {
|
||||
alias = "${swaggerUiTheme}/";
|
||||
extraConfig = ''
|
||||
index index.html;
|
||||
${dashboardAuth}
|
||||
'';
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
# Accept-header SPA map for the matrix GUI only (see docs/gateway.md
|
||||
|
|
@ -325,6 +360,7 @@ in
|
|||
// wellKnownLocations
|
||||
// agentLocations
|
||||
// dashboardProxyLocation
|
||||
// swaggerUiLocations
|
||||
// lib.optionalAttrs cfg.auth.enable {
|
||||
# Internal-only target for the 401 error_page above.
|
||||
# `internal` prevents direct client access; `alias` serves
|
||||
|
|
|
|||
|
|
@ -18,6 +18,13 @@ let
|
|||
inherit (nixpkgs.lib) nixosSystem;
|
||||
};
|
||||
|
||||
# Plain vendored Swagger UI dist (./swagger-ui-dist.nix) + the
|
||||
# hyperhive-themed overlay on top (./swagger-ui-theme.nix) — bound
|
||||
# here (not just inline in the attrset below) so the theme
|
||||
# derivation can take the dist derivation as an explicit input.
|
||||
swagger-ui-dist = pkgs.callPackage ./swagger-ui-dist.nix { };
|
||||
swagger-ui-theme = pkgs.callPackage ./swagger-ui-theme.nix { inherit swagger-ui-dist; };
|
||||
|
||||
# Every per-binary package: name → description. The single source of
|
||||
# truth for the bin list — it drives the per-bin extractor packages
|
||||
# and the `default` bundle, so adding a binary is one entry here.
|
||||
|
|
@ -158,6 +165,13 @@ in
|
|||
xdg-icons = pkgs.callPackage ./hive-xdg-icons.nix {
|
||||
hyperhiveSvg = ../../branding/hyperhive.svg;
|
||||
};
|
||||
# Swagger UI: plain vendored dist + the hyperhive-themed overlay —
|
||||
# see ./swagger-ui-dist.nix / ./swagger-ui-theme.nix (both computed
|
||||
# above, in `let`). The gateway serves `swagger-ui-theme`'s full
|
||||
# tree straight from the store at /api/docs/; a theme tweak is a
|
||||
# gateway config change, not a hive-c0re rebuild. `swagger-ui-dist`
|
||||
# is exposed too since it's independently useful/inspectable.
|
||||
inherit swagger-ui-dist swagger-ui-theme;
|
||||
|
||||
# Pre-built per-container system closures. Exposed as packages
|
||||
# so operators can `nix build .#agent-base-toplevel` (or wire
|
||||
|
|
|
|||
47
nix/packages/swagger-ui-dist.nix
Normal file
47
nix/packages/swagger-ui-dist.nix
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
stdenv,
|
||||
fetchurl,
|
||||
}:
|
||||
|
||||
# Pure vendored Swagger UI 5.17.14 static dist — no hyperhive theming
|
||||
# (see ./swagger-ui-theme.nix for that layer). Deliberately NOT sourced
|
||||
# via the Rust `utoipa-swagger-ui-vendored` crate / Cargo.lock (per the
|
||||
# operator's ask: a nix package that just contains the plain static
|
||||
# dist, not fetched via cargo) — hive-c0re no longer needs to know this
|
||||
# exists at all once the gateway hosts it directly.
|
||||
#
|
||||
# Sourced straight from the `swagger-ui-dist` npm package, which ships
|
||||
# exactly the built `dist/` files (no source, no build step needed) at
|
||||
# the same release as the Rust ecosystem's vendored copy — verified by
|
||||
# comparing this tarball's recorded `gitHead` (in its `package.json`,
|
||||
# `74ed0adebfc9c8dd0de2bf8e81495b022a66c083`) against the commit the
|
||||
# `utoipa-swagger-ui-vendored` crate's own pinned zip was built from
|
||||
# (same hash, printed by `unzip -l` on that zip's first entry).
|
||||
stdenv.mkDerivation {
|
||||
pname = "swagger-ui-dist";
|
||||
version = "5.17.14";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz";
|
||||
hash = "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==";
|
||||
};
|
||||
|
||||
sourceRoot = "package";
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out
|
||||
# The npm package also carries a few node-consumption conveniences
|
||||
# (package.json, index.js, absolute-path.js, README/LICENSE/NOTICE)
|
||||
# alongside the actual browser dist — only copy what a web server
|
||||
# should ever expose.
|
||||
cp *.html *.css *.css.map *.js *.js.map *.png $out/
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Vendored Swagger UI 5.17.14 static dist (unthemed), from the swagger-ui-dist npm package";
|
||||
homepage = "https://forge.darkest.space/hyperhive/hyperhive";
|
||||
};
|
||||
}
|
||||
52
nix/packages/swagger-ui-theme.nix
Normal file
52
nix/packages/swagger-ui-theme.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
stdenv,
|
||||
swagger-ui-dist,
|
||||
}:
|
||||
|
||||
# hyperhive's Catppuccin Mocha re-theme of Swagger UI: overlays our 3
|
||||
# hand-authored override files (`swagger-ui-theme/`, top-level — not
|
||||
# under `hive-c0re/`, which has no relationship to these files) onto
|
||||
# the plain vendored dist (./swagger-ui-dist.nix). This is the FULL
|
||||
# tree hive-gateway's nginx serves at `/api/docs/` — hive-c0re hosts
|
||||
# none of it, only the dynamic `/api/openapi.json` (see
|
||||
# nix/host-modules/hive-gateway/vhosts.nix).
|
||||
#
|
||||
# Output layout: every file from `swagger-ui-dist`, with 3 replaced:
|
||||
# index.html adds colors.css (live stylix theme) +
|
||||
# hyperhive-theme.css <link>s
|
||||
# hyperhive-theme.css new; the re-theme, consumes --baseNN vars
|
||||
# swagger-initializer.js hardcodes `url: "/api/openapi.json"` —
|
||||
# `utoipa-swagger-ui`'s `serve()` normally
|
||||
# rewrites this per-request from a
|
||||
# `{{config}}` placeholder its OWN build.rs
|
||||
# injects (`replace_default_url_with_config`
|
||||
# + `format_config`); hive-c0re doesn't serve
|
||||
# this file at all anymore, so that rewrite
|
||||
# is baked in statically here instead —
|
||||
# hand-verified byte-for-byte against what
|
||||
# `format_config` would produce, by applying
|
||||
# the same transform to the real vendored
|
||||
# file rather than typing it from scratch.
|
||||
stdenv.mkDerivation {
|
||||
pname = "hyperhive-swagger-ui-theme";
|
||||
version = "0.1.0";
|
||||
|
||||
dontUnpack = true;
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out
|
||||
cp -r ${swagger-ui-dist}/. $out/
|
||||
chmod -R u+w $out
|
||||
install -m644 ${../../swagger-ui-theme/index.html} $out/index.html
|
||||
install -m644 ${../../swagger-ui-theme/hyperhive-theme.css} $out/hyperhive-theme.css
|
||||
install -m644 ${../../swagger-ui-theme/swagger-initializer.js} $out/swagger-initializer.js
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "hyperhive Swagger UI Catppuccin Mocha re-theme — full static dist, nginx-served at /api/docs/";
|
||||
homepage = "https://forge.darkest.space/hyperhive/hyperhive";
|
||||
};
|
||||
}
|
||||
161
swagger-ui-theme/hyperhive-theme.css
Normal file
161
swagger-ui-theme/hyperhive-theme.css
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/* Partial hyperhive reskin for the vendored Swagger UI at /api/docs.
|
||||
Recolors chrome (background, topbar, borders, links, inputs) to
|
||||
match the dashboard. Swagger's own semantic HTTP-method badge colours
|
||||
and execute/cancel button colours are left alone — those carry
|
||||
meaning independent of hyperhive branding.
|
||||
|
||||
Loaded after swagger-ui.css (see index.html) so these rules win the
|
||||
cascade without `!important`, except where noted below.
|
||||
|
||||
`--baseNN` values come from `/static/colors.css` (linked in
|
||||
index.html, same origin as the dashboard) — this follows the
|
||||
operator's live stylix theme, not a hardcoded copy. See
|
||||
frontend/packages/shared/src/colors.css for the base16 contract. */
|
||||
|
||||
/* Page chrome */
|
||||
html,
|
||||
body {
|
||||
background: var(--base00);
|
||||
}
|
||||
.swagger-ui {
|
||||
color: var(--base05);
|
||||
font-family: "JetBrains Mono", "Fira Code", "Cascadia Code",
|
||||
"Source Code Pro", monospace;
|
||||
}
|
||||
|
||||
/* Topbar */
|
||||
.swagger-ui .topbar {
|
||||
background: var(--base01);
|
||||
border-bottom: 1px solid var(--base02);
|
||||
}
|
||||
.swagger-ui .topbar .download-url-wrapper input[type="text"] {
|
||||
border-color: var(--base02);
|
||||
background: var(--base00);
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui .topbar .download-url-wrapper .download-url-button {
|
||||
background: var(--base0E);
|
||||
color: var(--base01);
|
||||
}
|
||||
|
||||
/* Info block + links */
|
||||
.swagger-ui .info .title,
|
||||
.swagger-ui .info li,
|
||||
.swagger-ui .info p,
|
||||
.swagger-ui .info table {
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui a.nostyle,
|
||||
.swagger-ui a.nostyle:visited,
|
||||
.swagger-ui .info a {
|
||||
color: var(--base0D);
|
||||
}
|
||||
.swagger-ui .opblock-tag {
|
||||
color: var(--base05);
|
||||
border-bottom-color: var(--base02);
|
||||
}
|
||||
.swagger-ui .opblock-tag:hover {
|
||||
background: color-mix(in srgb, var(--base0E) 8%, transparent);
|
||||
}
|
||||
|
||||
/* Scheme/server selector bar. */
|
||||
.swagger-ui .scheme-container {
|
||||
background: var(--base01);
|
||||
box-shadow: none;
|
||||
border-bottom: 1px solid var(--base02);
|
||||
}
|
||||
|
||||
/* Endpoint rows — method-colour left border stays; only the card body
|
||||
is recoloured. */
|
||||
.swagger-ui .opblock {
|
||||
background: var(--base01);
|
||||
border-color: var(--base02);
|
||||
}
|
||||
.swagger-ui .opblock .opblock-summary-description,
|
||||
.swagger-ui .opblock .opblock-summary-path,
|
||||
.swagger-ui .opblock .opblock-summary-path__deprecated {
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui .opblock .opblock-section-header {
|
||||
background: var(--base00);
|
||||
}
|
||||
.swagger-ui .opblock-description-wrapper p,
|
||||
.swagger-ui .opblock-external-docs-wrapper p,
|
||||
.swagger-ui .opblock-title_normal p,
|
||||
.swagger-ui .parameter__name,
|
||||
.swagger-ui .parameter__type,
|
||||
.swagger-ui .parameter__deprecated,
|
||||
.swagger-ui .parameter__in,
|
||||
.swagger-ui table.model tr.property-row td {
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui .tab li,
|
||||
.swagger-ui .opblock .opblock-section-header h4,
|
||||
.swagger-ui .opblock .opblock-section-header label {
|
||||
color: var(--base05);
|
||||
}
|
||||
|
||||
/* Response / model tables. */
|
||||
.swagger-ui table thead tr td,
|
||||
.swagger-ui table thead tr th {
|
||||
color: var(--base05);
|
||||
border-bottom-color: var(--base02);
|
||||
}
|
||||
.swagger-ui .responses-inner h4,
|
||||
.swagger-ui .responses-inner h5 {
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui .response-col_status {
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui .model-box,
|
||||
.swagger-ui section.models {
|
||||
background: var(--base01);
|
||||
}
|
||||
.swagger-ui section.models {
|
||||
border-color: var(--base02);
|
||||
}
|
||||
.swagger-ui section.models h4 {
|
||||
color: var(--base05);
|
||||
}
|
||||
.swagger-ui .model {
|
||||
color: var(--base05);
|
||||
}
|
||||
|
||||
/* Form controls */
|
||||
.swagger-ui select,
|
||||
.swagger-ui input[type="text"],
|
||||
.swagger-ui input[type="password"],
|
||||
.swagger-ui input[type="search"],
|
||||
.swagger-ui input[type="email"],
|
||||
.swagger-ui input[type="file"],
|
||||
.swagger-ui textarea {
|
||||
background: var(--base00);
|
||||
color: var(--base05);
|
||||
border-color: var(--base02);
|
||||
}
|
||||
|
||||
/* Generic buttons (Try it out / Reset / Authorize etc) — execute/cancel
|
||||
keep Swagger's own colours. */
|
||||
.swagger-ui .btn {
|
||||
color: var(--base05);
|
||||
border-color: var(--base02);
|
||||
background: var(--base00);
|
||||
}
|
||||
.swagger-ui .btn.authorize {
|
||||
color: var(--base0E);
|
||||
border-color: var(--base0E);
|
||||
}
|
||||
.swagger-ui .btn.authorize svg {
|
||||
fill: var(--base0E);
|
||||
}
|
||||
|
||||
/* `!important`: highlight.js re-asserts this per-token inline, so a
|
||||
plain override loses. Scoped to the code-sample block background
|
||||
only — token colours stay as highlight.js's theme provides. */
|
||||
.swagger-ui .highlight-code {
|
||||
background: var(--base00) !important;
|
||||
}
|
||||
.swagger-ui .microlight {
|
||||
color: var(--base05);
|
||||
}
|
||||
30
swagger-ui-theme/index.html
Normal file
30
swagger-ui-theme/index.html
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<!-- Served by the gateway's nginx — one of 3 files (see also
|
||||
hyperhive-theme.css, swagger-initializer.js) that
|
||||
nix/packages/swagger-ui-theme.nix overlays onto the plain vendored
|
||||
dist (swagger-ui-dist.nix), and the whole result is what
|
||||
vhosts.nix's `swaggerUiLocations` serves at /api/docs/, wholesale,
|
||||
with NO hive-c0re fallback for any file in the tree. Byte-identical
|
||||
to the vendored Swagger UI's dist/index.html except two added
|
||||
<link>s: `colors.css` (same origin as the dashboard — so this
|
||||
resolves the operator's live stylix theme, not a frozen copy) and
|
||||
hyperhive-theme.css, which consumes its `--baseNN` vars. -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Swagger UI</title>
|
||||
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
|
||||
<link rel="stylesheet" type="text/css" href="index.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/colors.css" />
|
||||
<link rel="stylesheet" type="text/css" href="hyperhive-theme.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" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="swagger-ui"></div>
|
||||
<script src="./swagger-ui-bundle.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-ui-standalone-preset.js" charset="UTF-8"> </script>
|
||||
<script src="./swagger-initializer.js" charset="UTF-8"> </script>
|
||||
</body>
|
||||
</html>
|
||||
21
swagger-ui-theme/swagger-initializer.js
Normal file
21
swagger-ui-theme/swagger-initializer.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
window.onload = function() {
|
||||
//<editor-fold desc="Changeable Configuration Block">
|
||||
|
||||
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
|
||||
window.ui = SwaggerUIBundle({
|
||||
"dom_id": "#swagger-ui",
|
||||
"url": "/api/openapi.json",
|
||||
"deepLinking": true,
|
||||
"layout": "StandaloneLayout",
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
|
||||
});
|
||||
|
||||
//</editor-fold>
|
||||
};
|
||||
Loading…
Reference in a new issue