3.5 KiB
assets.ts — Swagger UI asset resolution
(no submodules)
Purpose
This module owns the asset-resolution policy for the Swagger UI shell. The shell needs two payloads at boot — the upstream swagger-ui.css stylesheet and the swagger-ui-bundle.js runtime — and operators get to choose how the host serves them: from the documented swagger-ui-dist CDN or from a bundled drop the host ships under its own assets pipeline.
Centralising the dispatch here keeps the rendering side of the package pure: the HTML shell takes a ResolvedAssets triple and never branches on the mode. That separation is what makes the package portable across api-host (which exposes its own asset routes) and standalone-tier deployments that prefer the CDN to keep the wire payload tiny.
Features
resolveCdnAssets(version)— produceshttps://cdn.jsdelivr.net/npm/swagger-ui-dist@<version>/{swagger-ui.css,swagger-ui-bundle.js}.resolveBundledAssets(basePath)— anchors the embedded asset URLs under the host-supplied prefix.readBundledAsset(name)— exposes the literal bytes of a bundled asset; the host serves these from its asset route.listBundledAssetNames()— registry introspection.resolveAssets({mode, version, basePath?})— dispatch helper consumed by the handler.OPENAPI_UI_SWAGGER.ASSETS_MISSINGraised whenever a bundled name is unknown orbasePathis omitted in bundled mode.
Usage: Basic
import { resolveCdnAssets } from "@suaveplan/api-openapi-ui-swagger/assets";
const assets = resolveCdnAssets("5.17.14");
// assets.cssHref === "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.17.14/swagger-ui.css"
Usage: Advanced
import {
listBundledAssetNames,
readBundledAsset,
resolveAssets,
} from "@suaveplan/api-openapi-ui-swagger/assets";
const assetRoute = "/docs/ui/swagger/assets";
const resolved = resolveAssets({
mode: "bundled",
version: "5.17.14",
basePath: assetRoute,
});
// Host mounts an asset route that serves the bundled bytes from this map.
for (const name of listBundledAssetNames()) {
const bytes = readBundledAsset(name);
// host.serve(`${assetRoute}/${name}`, bytes)
void bytes;
}
void resolved;
API Reference
interface ResolvedAssets { cssHref; jsHref; mode: "cdn"|"bundled" }.resolveCdnAssets(version: string): ResolvedAssets.resolveBundledAssets(basePath: string): ResolvedAssets.readBundledAsset(name: string): string— throwsOpenapiUiSwaggerErrorifnameis not registered.listBundledAssetNames(): readonly string[].resolveAssets({mode, version, basePath?}): ResolvedAssets—mode = "bundled"withoutbasePaththrows ASSETS_MISSING.
Implementation Notes
The bundled asset registry is closed by design — adding a new asset is a package release, not a runtime extension point. That guarantees the host never serves an asset the package can't account for in spec deltas.
The "strict-mode" guarantee from the spec is implemented inline: resolveAssets raises ASSETS_MISSING whenever bundled mode is requested without a basePath. The package never falls back silently to the CDN — operators who want CDN behaviour set mode: "cdn" explicitly.
CDN base is hard-coded to https://cdn.jsdelivr.net/npm/swagger-ui-dist matching the upstream @hono/swagger-ui adapter. Changing the CDN base requires a package release; pinning to a different CDN is out of scope (consumers proxying through their own CDN can serve via bundled mode).