Files
2026-05-27 23:29:53 +01:00

2.4 KiB

@suaveplan/api-openapi-ui-scalar — Scalar UI adapter for the /docs endpoint

Package: @suaveplan/api-openapi-ui-scalar Status: PROPOSED Type: new-package Stage: 8 — see umbrella openspec/changes/api-plugin-foundation/

Why

Per design doc §7 the default /docs UI is Scalar — modern, fast, low-bundle, supports OpenAPI 3.1 natively. Wrapping it in its own package keeps the surface clean: operators that prefer Swagger or ReDoc swap the package, not the host config logic.

What changes

  • ADDED: createScalarUiHandler({ openapiUrl, theme, title }) — returns an HTTP handler that serves the Scalar HTML shell pointing at the host's /openapi.json URL. Configurable theme / title / default-open-section / search.
  • ADDED: Per-plugin variant createPerPluginScalarUiHandler({ openapiUrlForPlugin, plugin }) — used by the host to mount /docs/{plugin}.
  • ADDED: ScalarUiOptions Zod schema — validates host config when this UI is selected as host.openapi.ui = "scalar".
  • ADDED: A static-asset strategy — Scalar's runtime bundle is shipped CDN-or-bundled per host.openapi.uiAssets ("cdn" | "bundled"); bundled mode embeds the asset under dist/assets/ for air-gapped hosts.
  • ADDED: Error codes (OPENAPI_UI_SCALAR_*): ASSETS_MISSING, INVALID_OPTIONS.

Out of scope

  • Modifying Scalar itself — this is a thin shell.
  • Authoring OpenAPI documents — that's api-openapi.
  • Swagger or ReDoc — sibling packages.

Source mapping

Genesis-original. Source of design intent: docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md.

Requirement Design doc section
Default /docs UI is Scalar §7
Pluggable UI (api-openapi-ui-{scalar,swagger,redoc}) §7

Verification approach

  • src/handler/handler.test.ts — handler returns HTML with the right Scalar bootstrap config; openapiUrl is embedded; CSP-friendly nonce supported.
  • src/per-plugin/per-plugin.test.ts — per-plugin variant points at /openapi.json?plugin=<name> (or the host-configured filter URL).
  • src/assets/assets.test.ts — "cdn" vs "bundled" modes resolve the right asset URL; missing bundled asset raises OPENAPI_UI_SCALAR_ASSETS_MISSING.
  • tests/dep-graph.test.ts — runtime deps include api-types, error, zod, the Scalar runtime.

Migration impact

None — additive only. api-host selects this when host.openapi.ui = "scalar".