# `per-plugin.ts` — `createPerPluginSwaggerUiHandler` _(no submodules)_ ## 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=` or `/openapi/.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/ ``` ## 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.