first commit
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# `per-plugin.ts` — `createPerPluginSwaggerUiHandler`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
This module exposes the per-plugin variant of the Swagger UI handler. The host's `/docs/{plugin}` route serves a UI scoped to a single plugin's routes, and that view points at a plugin-filtered OpenAPI document (typically `?plugin=<id>` or `/openapi/<id>.json`). The factory takes a derivation callback (`openapiUrlForPlugin`) so the host owns the URL-shape convention.
|
||||
|
||||
The factory is a thin composition over `createSwaggerUiHandler`: it derives the document URL by calling `openapiUrlForPlugin(plugin)`, then forwards every other option unchanged. All validation, asset resolution, and HTML rendering happen inside the underlying handler factory — this module never duplicates those concerns.
|
||||
|
||||
## Features
|
||||
|
||||
- `createPerPluginSwaggerUiHandler({ openapiUrlForPlugin, plugin, ...options })` — returns a `SwaggerUiHandler` pointing at the filtered URL.
|
||||
- Forwards every `SwaggerUiOptionsInput` field to the underlying handler.
|
||||
- Same eager validation contract — bad options throw at construction.
|
||||
- Same asset-resolution contract — bundled mode without basePath throws ASSETS_MISSING.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { createPerPluginSwaggerUiHandler } from "@suaveplan/api-openapi-ui-swagger/per-plugin";
|
||||
|
||||
const handler = createPerPluginSwaggerUiHandler({
|
||||
openapiUrlForPlugin: (p) => `/openapi.json?plugin=${encodeURIComponent(p)}`,
|
||||
plugin: "billing",
|
||||
});
|
||||
const res = handler();
|
||||
// res.body references /openapi.json?plugin=billing
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { createPerPluginSwaggerUiHandler } from "@suaveplan/api-openapi-ui-swagger/per-plugin";
|
||||
|
||||
const handlers = new Map(
|
||||
["billing", "auth", "contacts"].map((plugin) => [
|
||||
plugin,
|
||||
createPerPluginSwaggerUiHandler({
|
||||
openapiUrlForPlugin: (p) => `/openapi/${p}.json`,
|
||||
plugin,
|
||||
title: `${plugin} — API`,
|
||||
theme: "dark",
|
||||
tryItOutEnabled: false,
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
// host.router mounts handlers.get(plugin) at /docs/<plugin>
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `interface CreatePerPluginSwaggerUiHandlerInput extends SwaggerUiOptionsInput { openapiUrlForPlugin: (plugin: string) => string; plugin: string; assetBasePath?: string }`.
|
||||
- `createPerPluginSwaggerUiHandler(input): SwaggerUiHandler`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`openapiUrlForPlugin` is a function (not a template string) because hosts wire their OpenAPI emitter to a wide range of URL shapes — query-parameter filtering, path-based filtering, host-based multi-tenancy. A callback keeps the package out of that decision.
|
||||
|
||||
The handler returned here is identical in shape to `createSwaggerUiHandler`'s output, so the host's route adapter does not need a per-handler branch. Operators wanting a single UI mount at `/docs/ui/swagger/{plugin}` create one handler per plugin and dispatch by path segment.
|
||||
Reference in New Issue
Block a user