@xenterprises/fastify-xswagger
v1.3.0
Published
Fastify plugin for route-scoped Swagger documentation with access control
Readme
@xenterprises/fastify-xswagger
Fastify 5 plugin that generates separate, route-scoped Swagger/OpenAPI documentation per route prefix — with optional Basic Auth protection for private docs and environment-aware disabling. For teams that want their public API docs open and their admin docs locked down, from one registration.
Install
npm install @xenterprises/fastify-xswagger fastify@5fastify@^5.0.0 is a peer dependency.
Minimal example
import Fastify from "fastify";
import xSwagger from "@xenterprises/fastify-xswagger";
const fastify = Fastify({ logger: true });
fastify.get("/public/users", {
schema: { tags: ["users"], description: "List users" },
}, async () => ({ users: [] }));
await fastify.register(xSwagger, {
docs: [{ prefix: "/public", access: "public", title: "Public API" }],
});
await fastify.listen({ port: 3000 });
// Docs UI: http://localhost:3000/public/documentation
// Spec JSON: http://localhost:3000/public/documentation/jsonWith private (Basic Auth) docs:
await fastify.register(xSwagger, {
docs: [
{ prefix: "/public", access: "public", title: "Public API" },
{ prefix: "/admin", access: "private", title: "Admin API" },
],
// Credentials come from the consumer — the plugin never reads process.env
auth: {
username: process.env.DOCS_USER,
password: process.env.DOCS_PASSWORD,
},
environment: process.env.NODE_ENV,
disableInProduction: "public",
});Options
| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| docs | DocConfig[] | Yes | — | Documentation configurations (non-empty array, unique prefixes) |
| auth | { username: string, password: string } | When any doc is private | — | Basic Auth credentials for private doc UIs |
| disableInProduction | boolean \| 'public' | No | false | Which docs to skip when environment === 'production' (see below) |
| environment | string | No | 'development' | Environment name; only 'production' activates disableInProduction |
| docsPath | string | No | '/documentation' | Path appended to each prefix for the Swagger UI |
| active | boolean | No | true | Set false to skip registration entirely |
DocConfig
| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| prefix | string | Yes | — | Route prefix to document (e.g. '/api', '/admin'); must be unique within docs |
| title | string | Yes | — | Title shown in the Swagger UI header |
| access | 'public' \| 'private' | Yes | — | 'private' requires Basic Auth to view the docs |
| version | string | No | '1.0.0' | API version shown in the spec |
| description | string | No | API documentation for <prefix> routes | Description shown in the spec info |
Environment controls
The plugin never reads process.env. Pass environment explicitly; disableInProduction applies only when it is exactly 'production':
| disableInProduction | Non-production | environment: 'production' |
|-----------------------|----------------|------------------------------|
| false (default) | All docs enabled | All docs enabled |
| true | All docs enabled | All docs disabled |
| 'public' | All docs enabled | Only private docs enabled |
Decorators
fastify.xSwagger — single namespace:
config—{ docsPath, disableInProduction, docCount, hasAuth, environment }. Auth credentials are never exposed.docs— map of doc instances keyed by prefix (/admin→admin,/api/v1→api_v1,/→root). Each instance:prefix,access,title,version— the doc configurationuiPath— Swagger UI path (e.g.'/admin/documentation')specPath— spec JSON path (e.g.'/admin/documentation/json')spec()— returns the OpenAPI spec object
Routes
For each enabled doc config, the plugin serves (via @fastify/swagger-ui inside an encapsulated scope):
| Method | Path | Purpose |
|--------|------|---------|
| GET | <prefix><docsPath> | Swagger UI (Basic Auth when access: 'private') |
| GET | <prefix><docsPath>/json | OpenAPI spec JSON (Basic Auth when access: 'private') |
| GET | <prefix><docsPath>/static/* | Swagger UI assets (Basic Auth when access: 'private') |
Route filtering: each doc's spec only includes routes under its prefix. Routes with schema.hide: true are always excluded.
Named exports
import xSwagger, {
ACCESS_LEVELS, // { PUBLIC: 'public', PRIVATE: 'private' }
DEFAULT_DOCS_PATH, // '/documentation'
DISABLE_MODES, // { ALL: true, PUBLIC_ONLY: 'public', NONE: false }
DEFAULT_VERSION, // '1.0.0'
} from "@xenterprises/fastify-xswagger";Error behavior
Registration fails fast with descriptive errors. Messages name the plugin, the option, and an example:
| Error (prefix) | When |
|----------------|------|
| xswagger: missing required option \docs` (non-empty array), e.g. ...|docsmissing, empty, or not an array |
|xswagger: option `docs[N]` must be an object, e.g. ...| A doc entry is not an object |
|xswagger: option `docs[N].prefix` must be a non-empty string, e.g. ...| Missing/invalid prefix |
|xswagger: option `docs[N].title` must be a non-empty string, e.g. ...| Missing/invalid title |
|xswagger: option `docs[N].access` must be 'public' or 'private', e.g. ...| Invalid access level |
|xswagger: option `docs[N].version` must be a string, e.g. ...| Non-string version |
|xswagger: option `docs[N].description` must be a string, e.g. ...| Non-string description |
|xswagger: option `docs` must not contain duplicate prefixes, e.g. ...| Two docs share a prefix |
|xswagger: option `auth` ... is required when using private docs, e.g. ...| Private docs without validauth.username/auth.password|
|xswagger: option `docsPath` must be a non-empty string, e.g. ...| InvaliddocsPath|
|xswagger: option `disableInProduction` must be true, false, or 'public', e.g. ...| InvaliddisableInProduction|
|xswagger: option `environment` must be a string, e.g. ...| Non-stringenvironment|
|xswagger: option `active` must be a boolean, e.g. ...| Non-booleanactive` |
Private doc routes return 401 with a WWW-Authenticate: Basic realm="API Documentation" header when credentials are missing or wrong. Credentials are compared with crypto.timingSafeEqual.
Requirements
- Node.js >= 20
- Fastify ^5.0.0 (peer dependency)
License
Proprietary — All Rights Reserved X Enterprises. See LICENSE.
