diff --git a/hive-c0re/swagger-ui-theme/index.html b/hive-c0re/swagger-ui-theme/index.html index 5fd30668..a357a703 100644 --- a/hive-c0re/swagger-ui-theme/index.html +++ b/hive-c0re/swagger-ui-theme/index.html @@ -1,16 +1,13 @@ - + 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"; }; }