first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
# `assets.ts` — Swagger UI asset resolution
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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)` — produces `https://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_MISSING` raised whenever a bundled name is unknown or `basePath` is omitted in bundled mode.
## Usage: Basic
```ts
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
```ts
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` — throws `OpenapiUiSwaggerError` if `name` is not registered.
- `listBundledAssetNames(): readonly string[]`.
- `resolveAssets({mode, version, basePath?}): ResolvedAssets` — `mode = "bundled"` without `basePath` throws 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).