diff --git a/Cargo.lock b/Cargo.lock index 8ac44a4c..399f5765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", -] diff --git a/Cargo.toml b/Cargo.toml index eb79b132..56a33612 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] } diff --git a/flake.nix b/flake.nix index 63818b00..87d4f7e4 100644 --- a/flake.nix +++ b/flake.nix @@ -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; diff --git a/hive-c0re/Cargo.toml b/hive-c0re/Cargo.toml index 98a6e459..a4dae331 100644 --- a/hive-c0re/Cargo.toml +++ b/hive-c0re/Cargo.toml @@ -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" diff --git a/hive-c0re/src/dashboard/mod.rs b/hive-c0re/src/dashboard/mod.rs index 9e2a12e6..463ce242 100644 --- a/hive-c0re/src/dashboard/mod.rs +++ b/hive-c0re/src/dashboard/mod.rs @@ -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, diff --git a/nix/host-modules/hive-gateway/default.nix b/nix/host-modules/hive-gateway/default.nix index d23de50d..a9df82c5 100644 --- a/nix/host-modules/hive-gateway/default.nix +++ b/nix/host-modules/hive-gateway/default.nix @@ -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 ; diff --git a/nix/host-modules/hive-gateway/options.nix b/nix/host-modules/hive-gateway/options.nix index 211a8c3a..9f3ed563 100644 --- a/nix/host-modules/hive-gateway/options.nix +++ b/nix/host-modules/hive-gateway/options.nix @@ -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; diff --git a/nix/host-modules/hive-gateway/vhosts.nix b/nix/host-modules/hive-gateway/vhosts.nix index e9fc2370..f94395b5 100644 --- a/nix/host-modules/hive-gateway/vhosts.nix +++ b/nix/host-modules/hive-gateway/vhosts.nix @@ -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 diff --git a/nix/packages/default.nix b/nix/packages/default.nix index 29c14b4d..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,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 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 new file mode 100644 index 00000000..f93c5e40 --- /dev/null +++ b/nix/packages/swagger-ui-theme.nix @@ -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 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"; + }; +} diff --git a/swagger-ui-theme/hyperhive-theme.css b/swagger-ui-theme/hyperhive-theme.css new file mode 100644 index 00000000..627d7a95 --- /dev/null +++ b/swagger-ui-theme/hyperhive-theme.css @@ -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); +} diff --git a/swagger-ui-theme/index.html b/swagger-ui-theme/index.html new file mode 100644 index 00000000..a357a703 --- /dev/null +++ b/swagger-ui-theme/index.html @@ -0,0 +1,30 @@ + + + + + + Swagger UI + + + + + + + + + +
+ + + + + diff --git a/swagger-ui-theme/swagger-initializer.js b/swagger-ui-theme/swagger-initializer.js new file mode 100644 index 00000000..1e2c4abc --- /dev/null +++ b/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 + ], + + }); + + // +};