# Capability Spec Delta: api-openapi-ui-swagger (api-openapi-ui-swagger) **Package**: `@suaveplan/api-openapi-ui-swagger` **Status**: PROPOSED > Every requirement below carries a `**Verified by:**` line at authoring time. ## ADDED Requirements ### Requirement: Swagger UI handler renders the host's OpenAPI document The package SHALL expose `createSwaggerUiHandler({ openapiUrl, title, tryItOutEnabled })` returning an HTTP handler responding with the Swagger UI HTML shell pointing at `openapiUrl`. #### Scenario: handler returns HTML referencing openapiUrl - WHEN the handler is invoked with `openapiUrl = "/openapi.json"` - THEN the response is `text/html` AND the body references `/openapi.json` #### Scenario: tryItOutEnabled toggles Swagger config - WHEN `tryItOutEnabled: false` - THEN the embedded Swagger config disables try-it-out **Verified by:** `src/handler/handler.test.ts::"handler returns HTML referencing openapiUrl"` AND `src/handler/handler.test.ts::"tryItOutEnabled toggles Swagger config"` --- ### Requirement: Per-plugin handler points at filtered URL The package SHALL expose `createPerPluginSwaggerUiHandler({ openapiUrlForPlugin, plugin })` whose shell references the plugin-filtered URL. #### Scenario: per-plugin URL embedded - WHEN the per-plugin handler is invoked with a filtered URL - THEN the response body references that filtered URL **Verified by:** `src/per-plugin/per-plugin.test.ts::"per-plugin handler embeds filtered URL"` --- ### Requirement: Options validated by Zod The package SHALL validate `SwaggerUiOptions` via a Zod schema. Invalid options raise `OPENAPI_UI_SWAGGER_INVALID_OPTIONS` at boot. #### Scenario: invalid option rejected at boot - WHEN `theme` is set to a non-allowed value - THEN handler construction throws `OPENAPI_UI_SWAGGER_INVALID_OPTIONS` **Verified by:** `src/options/options.test.ts::"invalid theme rejected by schema"` --- ### Requirement: Asset strategy supports cdn and bundled The package SHALL resolve the Swagger UI runtime asset from `host.openapi.uiAssets`. `"cdn"` returns the upstream CDN URL; `"bundled"` returns the path to the embedded asset. A missing bundled asset raises `OPENAPI_UI_SWAGGER_ASSETS_MISSING`. #### Scenario: cdn mode returns CDN URL - WHEN `uiAssets = "cdn"` - THEN the resolved asset URL points at the documented Swagger CDN #### Scenario: bundled mode without asset raises - WHEN `uiAssets = "bundled"` AND the bundled asset is missing - THEN handler construction throws `OPENAPI_UI_SWAGGER_ASSETS_MISSING` **Verified by:** `src/assets/assets.test.ts::"cdn mode returns CDN URL"` AND `src/assets/assets.test.ts::"bundled mode without asset raises ASSETS_MISSING"`