66 lines
2.7 KiB
Markdown
66 lines
2.7 KiB
Markdown
<!-- markdownlint-disable MD024 -->
|
|
|
|
# Capability Spec: api-openapi-ui-scalar
|
|
|
|
**Package**: `@suaveplan/api-openapi-ui-scalar`
|
|
**Status**: ACTIVE
|
|
|
|
> Every requirement below carries a `**Verified by:**` line at authoring time.
|
|
|
|
## ADDED Requirements
|
|
|
|
### Requirement: Scalar UI handler renders the host's OpenAPI document
|
|
|
|
The package SHALL expose `createScalarUiHandler({ openapiUrl, theme, title })` returning an HTTP handler that responds with the Scalar HTML shell. The shell MUST reference `openapiUrl` as its document source.
|
|
|
|
#### Scenario: handler returns HTML pointing at openapiUrl
|
|
|
|
- WHEN the handler is invoked with `openapiUrl = "/openapi.json"`
|
|
- THEN the response Content-Type is `text/html` AND the body references `/openapi.json` exactly once in the Scalar configuration block
|
|
|
|
**Verified by:** `src/handler/handler.test.ts::"handler returns HTML referencing openapiUrl"`
|
|
|
|
---
|
|
|
|
### Requirement: Per-plugin handler points at filtered URL
|
|
|
|
The package SHALL expose `createPerPluginScalarUiHandler({ openapiUrlForPlugin, plugin })` whose shell references the plugin-filtered URL.
|
|
|
|
#### Scenario: per-plugin handler uses filtered URL
|
|
|
|
- WHEN `createPerPluginScalarUiHandler({ openapiUrlForPlugin: "/openapi.json?plugin=billing", plugin: "billing" })` is invoked
|
|
- THEN the response body references that filtered URL
|
|
|
|
**Verified by:** `src/per-plugin/per-plugin.test.ts::"per-plugin handler embeds filtered URL"`
|
|
|
|
---
|
|
|
|
### Requirement: Host config options validated by Zod
|
|
|
|
The package SHALL validate `ScalarUiOptions` via a Zod schema. Invalid configuration raises `OPENAPI_UI_SCALAR_INVALID_OPTIONS` at host boot before the handler is registered.
|
|
|
|
#### Scenario: invalid options rejected at boot
|
|
|
|
- WHEN host config sets `theme` to a non-allowed value
|
|
- THEN handler construction throws `OPENAPI_UI_SCALAR_INVALID_OPTIONS`
|
|
|
|
**Verified by:** `src/options/options.test.ts::"invalid theme is rejected by schema"`
|
|
|
|
---
|
|
|
|
### Requirement: Asset strategy supports cdn and bundled modes
|
|
|
|
The package SHALL resolve the Scalar runtime asset URL from `host.openapi.uiAssets`. `"cdn"` returns the upstream CDN URL; `"bundled"` returns the path to the embedded asset under `dist/assets/`. A missing bundled asset raises `OPENAPI_UI_SCALAR_ASSETS_MISSING`.
|
|
|
|
#### Scenario: cdn mode returns CDN URL
|
|
|
|
- WHEN `uiAssets = "cdn"`
|
|
- THEN the resolved asset URL points at the documented Scalar CDN
|
|
|
|
#### Scenario: bundled mode requires file present
|
|
|
|
- WHEN `uiAssets = "bundled"` AND the bundled asset is missing from `dist/assets/`
|
|
- THEN handler construction throws `OPENAPI_UI_SCALAR_ASSETS_MISSING`
|
|
|
|
**Verified by:** `src/assets/assets.test.ts::"cdn mode returns documented CDN URL"` AND `src/assets/assets.test.ts::"bundled mode without asset raises ASSETS_MISSING"`
|