diff --git a/hive-c0re/swagger-ui-theme/swagger-initializer.js b/hive-c0re/swagger-ui-theme/swagger-initializer.js
new file mode 100644
index 00000000..1e2c4abc
--- /dev/null
+++ b/hive-c0re/swagger-ui-theme/swagger-initializer.js
@@ -0,0 +1,21 @@
+window.onload = function() {
+ //
+
+ // 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
+ ],
+
+ });
+
+ //
+};
diff --git a/nix/host-modules/hive-c0re/options.nix b/nix/host-modules/hive-c0re/options.nix
index b67c0b6b..c5d7088b 100644
--- a/nix/host-modules/hive-c0re/options.nix
+++ b/nix/host-modules/hive-c0re/options.nix
@@ -69,13 +69,13 @@
type = lib.types.package;
defaultText = lib.literalExpression "hyperhive.packages.\${system}.swagger-ui-theme";
description = ''
- Swagger UI re-theme static override files (see
- `nix/packages/swagger-ui-theme.nix`; output has `index.html` +
- `hyperhive-theme.css`). The hive-gateway module `alias`es these
- two files straight from the store over `/api/docs/`, so a theme
- tweak is a gateway config change — hive-c0re's own vendored
- Swagger UI build is untouched. Override to ship a custom theme
- (or the vendored default) without a hive-c0re rebuild.
+ Full Swagger UI static dist, hyperhive-themed (see
+ `nix/packages/swagger-ui-theme.nix`, built on
+ `nix/packages/swagger-ui-dist.nix`). hive-gateway serves this
+ whole tree directly at `/api/docs/` — hive-c0re hosts none of
+ it, only the dynamic `/api/openapi.json` route. Override to
+ ship a custom theme (or the plain vendored dist) without a
+ hive-c0re rebuild.
'';
};
hyperhiveFlake = lib.mkOption {
diff --git a/nix/host-modules/hive-gateway/default.nix b/nix/host-modules/hive-gateway/default.nix
index a2c53f95..28453f06 100644
--- a/nix/host-modules/hive-gateway/default.nix
+++ b/nix/host-modules/hive-gateway/default.nix
@@ -24,10 +24,10 @@ let
# container's).
dashboardDist = "${config.services.hyperhive.c0re.servedFrontend}/dashboard";
- # Swagger UI re-theme static override files — nginx `alias`es these
- # straight from the store over `/api/docs/`, so a theme tweak ships
- # as a gateway config change (see vhosts.nix's `swaggerThemeLocations`
- # and nix/packages/swagger-ui-theme.nix).
+ # 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).
swaggerUiTheme = config.services.hyperhive.c0re.swaggerUiTheme;
# Self-signed TLS is the implicit floor: when neither an operator cert
diff --git a/nix/host-modules/hive-gateway/vhosts.nix b/nix/host-modules/hive-gateway/vhosts.nix
index 645d58f9..f94395b5 100644
--- a/nix/host-modules/hive-gateway/vhosts.nix
+++ b/nix/host-modules/hive-gateway/vhosts.nix
@@ -306,28 +306,35 @@ let
};
};
- # Swagger UI re-theme: exact-match locations `alias`ed straight to
- # `swaggerUiTheme`'s store path, nginx-served with no involvement
- # from hive-c0re at all. `=` locations win over the `/api/` prefix
- # block above regardless of declaration order (nginx's own location-
- # matching precedence — exact match beats longest-prefix), so this
- # doesn't need to be declared before it. Every OTHER Swagger UI asset
- # (bundle.js, openapi.json, favicons, the *vendored* index.html c0re
- # would otherwise serve) still falls through `/api/` to c0re's own
- # embedded `utoipa-swagger-ui` dist unchanged — only these two exact
- # paths are intercepted. A theme tweak is therefore a change to
- # `hive-c0re/swagger-ui-theme/` + a gateway container activation, not
- # a hive-c0re rebuild+restart. See nix/packages/swagger-ui-theme.nix.
- swaggerThemeLocations = {
- "= /api/docs/" = {
+ # 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 = ''
- alias ${swaggerUiTheme}/index.html;
- ${dashboardAuth}
+ return 301 /api/docs/;
'';
};
- "= /api/docs/hyperhive-theme.css" = {
+ "/api/docs/" = {
+ alias = "${swaggerUiTheme}/";
extraConfig = ''
- alias ${swaggerUiTheme}/hyperhive-theme.css;
+ index index.html;
${dashboardAuth}
'';
};
@@ -353,7 +360,7 @@ in
// wellKnownLocations
// agentLocations
// dashboardProxyLocation
- // swaggerThemeLocations
+ // swaggerUiLocations
// lib.optionalAttrs cfg.auth.enable {
# Internal-only target for the 401 error_page above.
# `internal` prevents direct client access; `alias` serves
diff --git a/nix/packages/default.nix b/nix/packages/default.nix
index ce53804f..70c5baa7 100644
--- a/nix/packages/default.nix
+++ b/nix/packages/default.nix
@@ -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,11 +165,13 @@ in
xdg-icons = pkgs.callPackage ./hive-xdg-icons.nix {
hyperhiveSvg = ../../branding/hyperhive.svg;
};
- # Swagger UI re-theme static override files — see
- # ./swagger-ui-theme.nix. The gateway `alias`es these straight from
- # the store; a theme tweak is a gateway config change, not a
- # hive-c0re rebuild.
- swagger-ui-theme = pkgs.callPackage ./swagger-ui-theme.nix { };
+ # 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
diff --git a/nix/packages/swagger-ui-dist.nix b/nix/packages/swagger-ui-dist.nix
new file mode 100644
index 00000000..cc70e995
--- /dev/null
+++ b/nix/packages/swagger-ui-dist.nix
@@ -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";
+ };
+}
diff --git a/nix/packages/swagger-ui-theme.nix b/nix/packages/swagger-ui-theme.nix
index 7e21faa6..a84cb6e0 100644
--- a/nix/packages/swagger-ui-theme.nix
+++ b/nix/packages/swagger-ui-theme.nix
@@ -1,49 +1,58 @@
{
stdenv,
+ swagger-ui-dist,
}:
-# The hand-authored Swagger UI re-theme files (`hive-c0re/swagger-ui-
-# theme/`), shipped as a standalone derivation so the gateway can
-# `alias` them straight from the nix store instead of hive-c0re's own
-# build serving them — see nix/host-modules/hive-gateway/vhosts.nix's
-# `swaggerThemeLocations`. This is what lets a CSS tweak ship as a
-# gateway config change (activate the gateway container) rather than a
-# hive-c0re rebuild+restart: the two files nginx exact-matches
-# (`/api/docs/` and `/api/docs/hyperhive-theme.css`) come from here;
-# every other Swagger UI asset (bundle.js, openapi.json, favicons, …)
-# still falls through the existing `/api/` prefix proxy to hive-c0re's
-# own vendored (unthemed) `utoipa-swagger-ui` embed, unchanged.
+# hyperhive's Catppuccin Mocha re-theme of Swagger UI: overlays our 3
+# hand-authored override files (`hive-c0re/swagger-ui-theme/`) 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).
#
-# Pure data: copied verbatim, no build step.
-#
-# Output layout:
-# $out/index.html — themed index.html Swagger UI page
-# $out/hyperhive-theme.css — the re-theme, consumes --baseNN vars
-# from the dashboard's own colors.css
-# (loaded via an absolute /static/
-# colors.css , same origin)
-
+# Output layout: every file from `swagger-ui-dist`, with 3 replaced:
+# index.html — adds s for colors.css (live stylix
+# theme, same origin) + hyperhive-theme.css
+# hyperhive-theme.css — new; the re-theme itself, consumes
+# --baseNN vars from colors.css
+# swagger-initializer.js — hardcodes `url: "/api/openapi.json"`. The
+# plain vendored copy points at the
+# swagger.io petstore demo; normally
+# `utoipa-swagger-ui`'s `serve()` rewrites
+# this file per-request from a `{{config}}`
+# placeholder it injects at its OWN build
+# time (see that crate's `build.rs`'s
+# `replace_default_url_with_config` +
+# `format_config`). hive-c0re no longer
+# serves this file at all, so that rewrite
+# has to happen here instead — this copy is
+# hand-verified to byte-match what
+# `format_config` would produce for
+# hive-c0re's actual config (single unnamed
+# url, otherwise all `Config` defaults): the
+# same transform applied to the real
+# vendored file, not hand-typed from
+# scratch.
stdenv.mkDerivation {
pname = "hyperhive-swagger-ui-theme";
version = "0.1.0";
- # Narrow src keeps this derivation's input hash decoupled from the
- # rest of the tree — a theme tweak only re-hashes this.
- src = ../../hive-c0re/swagger-ui-theme;
+ dontUnpack = true;
dontBuild = true;
- dontConfigure = true;
installPhase = ''
runHook preInstall
mkdir -p $out
- cp -r ./* $out/
+ cp -r ${swagger-ui-dist}/. $out/
+ chmod -R u+w $out
+ install -m644 ${../../hive-c0re/swagger-ui-theme/index.html} $out/index.html
+ install -m644 ${../../hive-c0re/swagger-ui-theme/hyperhive-theme.css} $out/hyperhive-theme.css
+ install -m644 ${../../hive-c0re/swagger-ui-theme/swagger-initializer.js} $out/swagger-initializer.js
runHook postInstall
'';
- dontFixup = true;
-
meta = {
- description = "hyperhive Swagger UI Catppuccin Mocha re-theme (static override files)";
+ description = "hyperhive Swagger UI Catppuccin Mocha re-theme — full static dist, nginx-served at /api/docs/";
homepage = "https://forge.darkest.space/hyperhive/hyperhive";
};
}