@zudojs/openapi
Turns your routes and schemas into an OpenAPI 3.0 or 3.1 document, checks that the document is valid, and serves it — together with a ready-made documentation page.
OVERVIEW
An OpenAPI document is a machine-readable description of an HTTP API. It lists every path, every method, what you send, and what comes back. It is normally written as one JSON or YAML file.
Because it is machine-readable, tools can read it and do work for you: render browsable documentation, generate a client library in another language, produce request collections, or check in CI that your API has not changed by accident.
Writing that file by hand goes stale the moment code changes. @zudojs/openapi builds it from the route metadata and schemas you already have, so the description and the code move together.
- You expose an HTTP API and want documentation that cannot drift from the code.
- Someone needs a generated client or SDK for your API.
- You want a contract check in CI that fails when the spec becomes invalid.
- You want a Swagger UI or ReDoc page without wiring one up yourself.
- Your service is internal-only and nobody reads a spec for it.
- You only need runtime input validation — that is @zudojs/schema.
- Your API is GraphQL or RPC — OpenAPI describes HTTP endpoints.
openapi.json file for you, tells you when that file is wrong, and hands you a web page that displays it.
INSTALLATION
The runtime dependencies are @zudojs/errors (v1.3.0) and @zudojs/constants (v1.1.2), which supplies the schema ceilings the converter emits. Install @zudojs/schema too if you want to register schemas rather than hand-written OpenAPI objects:
Schemas are read structurally, not imported, so any object with the same runtime shape works.
QUICK START
OpenAPIManager is the one class most applications use. You give it document metadata, add routes, then ask for the document.
Three things happened without you asking:
- →
/orders/:idbecame the OpenAPI path template/orders/{id}. - → The
idparameter was markedrequired: true, because OpenAPI requires that of every path parameter. - → The document got a
info["x-logo"]entry so viewers show a logo. See Branding.
generate() is safe to call as many times as you like. Every change to the manager throws away the cached document, so the next call sees your new routes.
DESCRIBING ROUTES
A route here is a method, a path, and some metadata. The metadata lives under metadata.openapi and holds the fields OpenAPI calls an operation: what this endpoint is called, what it takes, and what it returns.
Every field is optional. The main ones:
| Field | What it does |
|---|---|
operationId | Unique name for the endpoint. Code generators turn it into a method name. |
summary / description | Short and long human text. |
tags | Groups endpoints together in the rendered page. |
parameters | Path, query, header or cookie inputs. Each has name, in, and optionally schema, required, example. |
params / query / headers / cookies | Shorthand: one object schema each, and every property becomes a parameter. |
requestBody | The body the endpoint accepts, keyed by media type. |
body | Shorthand: a schema sent as application/json, or { schema, contentType?, required? }. |
responses | Keyed by status code, a 4XX-style range, or default. Each is a Response Object with a description, or the shorthand { schema }, whose description defaults to the reason phrase. Leave it out and the operation gets default: "Undocumented response" plus a warning (see below). |
security / servers / externalDocs | Per-operation overrides of the document-level values. security: [] marks the operation public. |
deprecated | Marks the endpoint as going away. |
hidden | Leaves the route out of the generated document entirely. |
This adds a second route with a body and a tag, then prints the methods that ended up on the path:
Use addRoute for a route you are adding once; it throws if the same route is already registered. Use setRoute when replacing is what you want, and removeRoute(method, path) to drop one.
Since v1.4.0 “the same route” means the same method and the same OpenAPI path template, not the same source string. GET /users/:id and GET /users/{id} both become the path item /users/{id}, so the second one is now rejected with an OpenAPIRouteError. Before v1.4.0 both registered and generation silently kept only the last one: an operation disappeared from the published document and validate() reported nothing wrong. hasRoute, setRoute and removeRoute accept either spelling for the same route.
/files/* and /users/:id? both throw an OpenAPIRouteError instead of quietly producing a path template no tool understands. Generating from an @zudojs/http router avoids this: the router resolves those patterns first (an optional segment becomes two paths, a wildcard a {rest} slot).
Routes with no documented responses
OpenAPI requires every operation to list at least one response. If a route declares none (no responses field, or responses: {}), the generator does not make one up. It emits a default response described as "Undocumented response", which keeps the document valid while saying honestly that nothing is known, and it reports a warning so you can fix the route:
Before v1.5.0 such a route got an invented "200": { description: "OK" }. That was a guess, and often a wrong one: a DELETE that answers 204 No Content was published as returning 200, so a client generated from the document expected a body that never came. The guess also hid the problem, because the validator's “every operation declares a response” check could never fire.
The warning reaches three places: the onRouteWarning(message) option (accepted by new OpenAPIManager, createOpenAPIDocumentFromRoutes and createOpenAPIManagerFromRoutes), onSchemaWarning under the name "routes", and manager.routeWarnings(). @zudojs/http's generateOpenAPIDocument passes its own onRouteWarning through, so these arrive next to its duplicate-route warnings.
200 now shows default instead, and each one logs a warning. The fix is to declare the responses the endpoint really returns; the warning then goes away.
GENERATING FROM A ROUTE TABLE
Most of the time you do not want to call addRoute once per endpoint. Your routes already exist somewhere — in a router, or in a list of operations — and the document should come from that list, so it can never describe an endpoint that is not there.
createOpenAPIDocumentFromRoutes(routes, { info }) does that. routes is a plain array of route descriptors: one object per endpoint, holding its method, its path, and the same documentation fields as metadata.openapi, all flattened into one object. Schemas can be @zudojs/schema schemas, which are converted for you.
What happened: /users/:id became /users/{id} with a required id parameter, the body schema became a required application/json request body, the 404 kept its description, and the 200 and 201 got theirs from the reason phrase. validate: true throws an OpenAPIValidationError if the result is invalid.
security: [] on a route means "this one is public". It overrides the document-wide security, so /health needs no token while every other route does. Leaving security out means "use the document's setting".
The route descriptor
An OpenAPIRouteDescriptor is RouteOpenAPIMetadata plus method and path. Only those two are required.
| Field | What it does |
|---|---|
method | Any case. It must be one an OpenAPI path item can hold: get put post delete options head patch trace. |
path | /users/:id or /users/{id}. Optional, regex-constrained and wildcard segments have no OpenAPI spelling; the route source resolves them before handing the path over. |
summary, description, operationId, tags, deprecated, servers, externalDocs | Copied to the operation. |
security | Operation security. [] marks it public and overrides the document's security. |
params, query, headers, cookies | One object schema each; every property becomes a parameter. required comes from the schema, and path parameters are always required. |
body | A schema (sent as application/json, required), or { schema, contentType?, required?, description?, example? }. A raw requestBody wins over it. |
responses | Keyed by status, NXX range or default: a Response Object, or { schema, description?, contentType?, headers?, example? }. The description defaults to the reason phrase, e.g. "Not Found". |
parameters | Explicit parameters. Highest precedence. |
inferredParameters | Parameters the source worked out itself, such as a regex constraint. Lowest precedence. |
hidden | true leaves the operation out. |
Every path template slot is documented as a required string parameter even when nothing declares it. A declared path parameter the template does not contain is dropped with a warning, rather than producing an invalid document. Warnings reach onRouteWarning, onSchemaWarning under the name "routes", and manager.routeWarnings(). A route with no responses warns too (see Routes with no documented responses).
Where descriptors come from
- → @zudojs/http builds them from a router's registered routes:
generateOpenAPIDocument(router, { info })andmountOpenAPI(router, { info })call this function for you. - → @zudojs/api builds them from operations:
toOpenAPIRouteDescriptors(registry, { basePath }). - → Or write the array yourself, as above.
Keeping a manager instead
createOpenAPIManagerFromRoutes(routes, options) takes the same arguments but returns the OpenAPIManager, so you can serve it with toResponse() and toUIResponse(). When your routes change, manager.setRoutes(routes.map(routeDescriptorToRouteInfo)) replaces the whole route set at once, rejecting duplicates before anything changes. routeDescriptorToRouteInfo converts one descriptor into the { method, path, metadata } shape addRoute takes.
SCHEMAS
A schema describes the shape of a value: which fields exist, their types, and what counts as valid. OpenAPI has its own schema dialect, and addSchema translates a @zudojs/schema schema into it.
Registering a schema puts it in components.schemas under the name you give, so operations can point at it with a $ref instead of repeating it.
optional, default, any and unknown fields are left out of required, matching what the runtime accepts; constraints on coerced schemas and factory defaults are carried into the document. A string or array with no explicit maximum gets the limit the runtime enforces (maxLength: 255 / maxItems: 1000), read from @zudojs/constants SCHEMA_DEFAULT_MAX_STRING_LENGTH / SCHEMA_DEFAULT_MAX_ARRAY_LENGTH.
Point an operation at it with createComponentReference, which builds the $ref string and escapes names containing / or ~:
Unknown keys
An object schema decides what happens to a key it does not declare: .strip() (the default) discards it and accepts the payload, .passthrough() keeps it, and .strict() rejects the payload. Only .strict() emits additionalProperties: false, because that keyword is OpenAPI for “reject the payload”.
Before v1.4.0 a stripping object emitted additionalProperties: false too. A client generated from that document refused requests the service would have accepted — it declared the extra key fatal while the parser was quietly dropping it. It also made objectSchema({…}) and objectSchema({…}).strip() document differently despite validating identically. Both now produce the same schema.
.strict() loses its additionalProperties: false, so the first regeneration produces a diff that is expected rather than a regression. A spec file that is never regenerated keeps publishing the old, stricter contract.
When a constraint cannot be expressed
Some things your schema can say have no OpenAPI equivalent. Rather than emit an empty {} and let you find out in production, the converter records a warning and still emits everything it can.
OpenAPI's pattern keyword carries the regular expression source and nothing else — there is no place to put i or m. A case-insensitive pattern would therefore become case-sensitive in the published document, which is stricter than the code that actually validates requests. The converter no longer lets that pass unremarked: the flags show up in a warning naming the pattern.
Warnings from a schema you registered are collected per component:
Already have an OpenAPI schema object, hand-written or from somewhere else? Register it as-is with addRawSchema(name, schema), which skips conversion.
3.0 VS 3.1
OpenAPI 3.0 and 3.1 spell several schema keywords differently. Emitting the 3.1 spelling into a 3.0 document does not fail loudly — a strict tool rejects the whole file and a lenient one drops the keyword, so the constraint is simply gone.
The converter takes the target version from the manager and emits the spelling that version defines. You choose the version once, in the constructor.
| Your constraint | 3.1.x | 3.0.x |
|---|---|---|
gt(5) | exclusiveMinimum: 5 | minimum: 5, exclusiveMinimum: true |
lt(10) | exclusiveMaximum: 10 | maximum: 10, exclusiveMaximum: true |
| nullable value | type: ["string", "null"] | nullable: true |
| literal | const: "yes" | enum: ["yes"] |
| tuple | prefixItems | minItems / maxItems |
In 3.1, exclusiveMinimum holds the number. In 3.0 it is a boolean that modifies minimum. Both spellings now come out right:
"3.1.0" unless a tool you depend on only reads 3.0. Either way the constraints you wrote survive the translation.
VALIDATION
A document can be well-formed JSON and still be a broken OpenAPI file. The validator reads a finished document and reports what is wrong before a tool downstream trips over it.
validate() reports; it never throws:
Two operations share the operationId "orders.get", so a code generator would produce two methods with the same name. Rename the second one (say, "orders.list") and it passes.
What it checks
- → Required document fields are present and
openapinames a supported version. - → Every operation declares at least one response, keyed by a status code, a
4XX-style range ordefault, each with a description. Generated documents always pass this one (an undocumented route getsdefaultand a warning), so it matters most for documents built by hand. - → Path templates and
in: "path"parameters agree in both directions, path parameters are required, no parameter is declared twice in one list (an operation-level parameter may override a path-level one), and no two paths are identical apart from their template parameter names. - →
operationIdvalues are unique and withinMAX_OPERATION_ID_LENGTH. - → Every
securityrequirement names a scheme declared incomponents.securitySchemes, and every declared scheme is used somewhere. - → Every local
$refresolves inside the document, and every non-local one uses an allowed scheme. - → No path still uses
:idinstead of{id}.
Where a $ref may point
A $ref is an instruction to whatever reads the document: go fetch this and paste it here. Most refs are local — #/components/schemas/Order — and the validator checks they resolve.
A ref that is not local is checked for its URI scheme. Only http and https are allowed. Anything else is an error.
# was accepted. A document carrying file:///etc/passwd or http://169.254.169.254/latest/meta-data/ validated cleanly, and the resolver that later followed it turned your spec into a file read or a request to a cloud metadata endpoint. Non-fetchable schemes are now rejected outright.
An https or relative ref is legal OpenAPI, so it is a warning, not an error: the document stays valid, but you are told something outside it will be fetched. Bundle the target into components if the source is not fully trusted.
Failing loudly
Pass true to generate, toJSON or toYAML and an invalid document throws instead. The error carries the issues:
manager.generate(true) in a CI test. The build fails the moment a route stops matching its documented contract.
SERVING THE DOCS
Two endpoints are all you need. One serves the specification, the other serves a page that reads it.
- →
toResponse()— the document itself, as JSON or YAML. - →
toUIResponse({ specUrl })— a complete HTML documentation page that fetches the spec fromspecUrl.
Both return the same plain shape — { status, headers, body } — so any HTTP adapter can turn them into its own response type.
Wired into an HTTP framework, that is two handlers:
On @zudojs/http you do not write these two handlers: mountOpenAPI(router, { info }) registers both, generated from the router's own routes.
Open /docs and you get a browsable page: every endpoint listed by tag, expandable request and response shapes, and a "try it out" button that sends a real request.
Swagger UI or ReDoc
Swagger UI is the default: interactive, good for poking at an API by hand. ReDoc renders a three-column reference document — better for reading, no try-it-out. Choose with renderer.
You can also render the page on its own, without a manager, with renderOpenAPIUI. It returns the HTML string; serve it with content-type: text/html.
| Option | What it does | Default |
|---|---|---|
specUrl | Where the page fetches the document from. Required. | — |
title | Page title and header text. | "API reference" |
renderer | "swagger" or "redoc". | "swagger" |
logo | Header logo, or false for none. | Zudo wordmark |
favicon | Favicon URL or data URI, or false. | Zudo favicon |
customCss | CSS appended after the built-in theme. | — |
assetsBaseUrl | Where the viewer's own JS and CSS load from. | pinned jsDelivr (swagger-ui-dist@5.33.0, redoc@2.5.4) with SRI |
assetIntegrity | SRI hashes for the viewer assets, or false to omit integrity. | the pinned hashes when assetsBaseUrl is unset; none when it is set |
contentSecurityPolicy | content-security-policy header sent by toUIResponse, or false for none. Ignored by renderOpenAPIUI. | restrictive policy from buildOpenAPIUIContentSecurityPolicy |
connectSources | Extra origins "Try it out" may call, added to connect-src. The document's absolute servers are added automatically. | [] |
swaggerOptions | Extra options passed to SwaggerUIBundle. Ignored by ReDoc. | — |
Air-gapped deployments
By default the page loads exact, pinned versions of Swagger UI or ReDoc from cdn.jsdelivr.net with Subresource Integrity, and toUIResponse sends a restrictive content-security-policy header (pass contentSecurityPolicy: false to omit it). A machine with no internet access renders a blank page. Host the viewer's files yourself and point assetsBaseUrl at them:
For ReDoc the file needed under that base is redoc.standalone.js.
renderOpenAPIUI refuses input that would break out of the page. A javascript: or vbscript: URL throws a TypeError (the scheme is read after stripping control characters, so java\nscript: is caught), a data: URL that is not an image throws, an empty specUrl throws, and customCss containing </style> throws rather than being mangled — that sequence would end the style block and let the rest be parsed as HTML.
BRANDING
ReDoc, Scalar and several other viewers look for a logo in a non-standard info["x-logo"] field. Generated documents carry one by default, so a spec opened in any of those tools shows a logo instead of nothing.
The branding option controls it. There are three ways to use it:
| Value | Result |
|---|---|
omitted or true | The Zudo mark, in x-logo and in the UI page header. |
false | No x-logo at all, and no logo on the page. |
{ url, href, altText } | Your own logo, used in both places. |
A logo you put on info yourself is never overwritten — set info["x-logo"] directly and that is what the document carries, whatever branding says.
The brand assets are exported too, as inline SVG strings and as data URIs, so a page can use them with no extra network request:
The full set: ZUDO_MARK_SVG, ZUDO_MARK_DARK_SVG, ZUDO_WORDMARK_SVG, ZUDO_WORDMARK_DARK_SVG, ZUDO_FAVICON_SVG, and a _DATA_URI counterpart for each.
BUILDING BY HAND
If you are not generating from routes — describing an API you did not write, or assembling a document in a script — use OpenAPIDocumentBuilder. Every method returns the builder, so calls chain, and build() returns the finished document.
The builder and the manager assemble documents through the same registry, so both produce the same shape and obey the same rules.
Serialize any document with toOpenAPIJSON or toOpenAPIYAML. The YAML is real YAML: strings that YAML would otherwise reinterpret — true, null, 1.0, anything starting with a reserved character — come out quoted.
API REFERENCE
Classes
| Name | What it does | Notes |
|---|---|---|
OpenAPIManager | Collects routes and schemas, generates, validates, serializes and serves. | The class most apps use. createOpenAPIManager(options) is the factory. |
OpenAPIDocumentBuilder | Chainable builder for a document written by hand. | createOpenAPIDocumentBuilder(options) is the factory. |
OpenAPIRegistryImpl | The low-level store of paths, components and metadata. | Used by both of the above. Reach for it only if you need direct control. |
OpenAPIRouteScannerImpl | Holds routes and converts them to operations. | addRoute, setRoute, removeRoute, scan, clear. |
OpenAPIValidatorImpl | Validates a finished document. | createOpenAPIValidator() is the factory. |
SchemaRegistryImpl | Converts and stores named component schemas. | Collects conversion warnings per name. |
OpenAPIManager methods
| Name | What it does | Notes |
|---|---|---|
addRoute(route) | Registers a route. | Throws on a duplicate method + OpenAPI path template. |
setRoute(route) | Registers a route, replacing any existing one. | — |
removeRoute(method, path) | Removes a route. | Returns whether one was removed. |
setRoutes(routes) | Replaces the whole route set. | Rejects duplicates before anything changes. Chainable. |
routeWarnings() | Warnings from the last route conversion. | For example a declared path parameter the path lacks, or a route with no documented responses. |
addSchema(name, schema) | Converts a @zudojs/schema schema and registers it. | Conversion warnings land in schemaWarnings(). |
addRawSchema(name, schema) | Registers an already-converted OpenAPI schema. | No conversion. |
setInfo, addServer, addTag | Set document metadata. | Chainable. |
addSecurityScheme(name, scheme) | Declares an authentication scheme. | Pair with addSecurityRequirement. |
addSecurityRequirement(req) | Requires a scheme document-wide. | Validated against declared schemes. |
generate(validate?) | Builds the document. | Idempotent. true throws on an invalid result. |
getDocument(validate?) | Returns the document, using the cache when fresh. | Rebuilds when stale or absent. |
validate() | Validates without throwing. | Returns { valid, errors, warnings }. |
toJSON(validate?) / toYAML(validate?) | Serializes the document. | — |
toResponse(options?) | HTTP response carrying the document. | format, validate, cacheControl. |
toUIResponse(options) | HTTP response carrying a documentation page. | Takes the renderOpenAPIUI options. |
schemaWarnings() | Conversion warnings, keyed by component name. | Read-only map. |
invalidateCache() | Drops the cached document. | Every mutation calls it for you. |
reset() | Drops every route, component and the cache. | Use instead of the deprecated invalidate(). |
version | The version this manager emits. | Getter. |
Functions
| Name | What it does | Notes |
|---|---|---|
createOpenAPIDocumentFromRoutes(routes, options) | Generates a document from route descriptors. | See Generating from a route table. |
createOpenAPIManagerFromRoutes(routes, options) | The same, returning the manager. | For toResponse / toUIResponse. |
routeDescriptorToRouteInfo(descriptor) | Descriptor to { method, path, metadata }. | Throws OpenAPIRouteError on an unsupported method. |
renderOpenAPIUI(options) | Returns a complete HTML documentation page. | Swagger UI or ReDoc. |
zudoLogo(overrides?) | The default logo object. | Frozen; pass overrides for a variant. |
svgToDataUri(svg) | Encodes an SVG string as a compact data URI. | No network request needed to show it. |
convertSchema(schema, options?) | Converts one schema without a registry. | Returns { schema, warnings }. |
createSchemaConverter(options?) | A reusable converter bound to options. | — |
isVersion31(version) | Whether a version string is 3.1.x. | — |
createComponentReference(section, name) | Builds a $ref object. | Escapes names per RFC 6901. |
escapeJsonPointerSegment / unescapeJsonPointerSegment | Escape and unescape one pointer segment. | ~ and /. |
toOpenAPIPath(path) | /users/:id → /users/{id}. | Throws on wildcard or optional segments. |
extractPathParameters(path) | Parameter names in a path template. | — |
convertRouteToOpenAPI(method, path, metadata?) | Turns one route into an operation. | — |
buildResponses(metadata?) | The responses object for an operation. | When none are declared, returns { default: { description: "Undocumented response" } }; it never invents a 200. |
isOpenAPIMethod(method) | Whether a string is an OpenAPI method. | Type guard. |
toOpenAPIJSON(document) / toOpenAPIYAML(document) | Serialize a document. | YAML quotes ambiguous strings. |
createOpenAPIError / isOpenAPIError / formatIssuePath | Error helpers. | formatIssuePath renders an issue path as paths./orders.get. |
Types
| Name | What it does | Notes |
|---|---|---|
OpenAPIManagerOptions | Constructor options. | version, info, servers, tags, security, cacheTtlMs, onSchemaWarning, onRouteWarning, branding, now. |
OpenAPIUIOptions | Options for the documentation page. | See the table in Serving. |
OpenAPIUIRenderer | "swagger" | "redoc". | — |
OpenAPIUIResponse | { status, headers, body } for the page. | Returned by toUIResponse. |
OpenAPIDocumentResponse | { status, headers, body } for the spec. | Returned by toResponse. |
OpenAPILogo | { url, href?, altText?, backgroundColor? }. | The shape of info["x-logo"]. |
RouteInfo / RouteMetadata / RouteOpenAPIMetadata / RouteParameterMetadata | What addRoute accepts. | — |
OpenAPIRouteDescriptor / OpenAPIDocumentFromRoutesOptions | Input to createOpenAPIDocumentFromRoutes. | Options: info (required), validate, securitySchemes, schemas, plus the manager options. |
OpenAPIValidationResult / OpenAPIValidationIssue | Validator output. | An issue is { path, message, severity }. |
SchemaConversionResult / SchemaConversionOptions | Converter input and output. | — |
OpenAPIDocument, OpenAPIOperation, OpenAPISchema, … | The specification object types. | Mirror the OpenAPI standard; all exported from the package root. |
Errors
All extend OpenAPIError, the @zudojs/errors class re-exported here (a BaseError). They default to status 500 and are not exposed to clients — these are failures while your service builds its own specification, not answers to a request.
| Name | Thrown when | Notes |
|---|---|---|
OpenAPIValidationError | A document fails validation. | Carries issues and a format() summary. |
OpenAPIRouteError | A path or method cannot become an operation. | Wildcards, optional parameters, unsupported methods. |
OpenAPISchemaError | A schema cannot be converted. | Includes unresolvable recursion. |
OpenAPIComponentConflictError | A component name is registered twice with different content. | Extends OpenAPIComponentError. |
OpenAPIVersionError | An unsupported version is requested. | See SUPPORTED_OPENAPI_VERSIONS. |
OpenAPIDocumentError, OpenAPIComponentError, OpenAPIReferenceError, OpenAPISerializationError, OpenAPIOperationError | The remaining failure kinds. | Each accepts statusCode and expose overrides. |
Constants
| Name | Value | Notes |
|---|---|---|
DEFAULT_OPENAPI_VERSION | "3.1.0" | Used when you pass no version. |
SUPPORTED_OPENAPI_VERSIONS | 3.0.0–3.0.3, 3.1.0, 3.1.1 | Anything else is rejected. |
MAX_OPERATION_ID_LENGTH | 128 | Longer ids fail validation. |
COMPONENT_REF_PREFIX | "#/components" | Prefix of every local $ref. |
DEFAULT_MEDIA_TYPE | "application/json" | Content type of toResponse(). |
UNDOCUMENTED_RESPONSE_DESCRIPTION | "Undocumented response" | Description of the default response a route with none gets. |
DEFAULT_SERVER_URL | "http://localhost" | Fallback server URL. |
DOCUMENT_CACHE_TTL_MS | 300000 | Five minutes. Override with cacheTtlMs. |
STATUS_CODE_CATEGORIES | 1XX…5XX | The range keys OpenAPI allows. |
RESPONSE_KEY_PATTERN | RegExp | What a valid response key looks like. |
PATH_TEMPLATE_PARAMETER | RegExp | Matches {name} in a path. |
ZUDO_SITE_URL and the ZUDO_* assets | SVG strings and data URIs | See Branding. |
COMMON MISTAKES
-
Leaving out the responses.
A route with noresponsesis published with adefault“Undocumented response”, and every generated client has to guess what comes back. Declare the real ones, such as"204"for a delete, and listen toonRouteWarningso a new undocumented route shows up in your logs. -
Serving the spec but not a page, or a page but not the spec.
AtoUIResponsepage fetchesspecUrlat load time and shows an error if nothing answers. Register both handlers, and makespecUrlmatch the route the spec is actually on. -
Assuming a 3.1 document still means the same thing as 3.0.
Copying a document between versions silently drops exclusive bounds and nullability. Setversionon the manager and let the converter emit the right spelling. -
Ignoring schema warnings.
A dropped constraint — an unknown string format, a regex flag OpenAPI cannot express — is not an error, so nothing stops the build. PassonSchemaWarningor readschemaWarnings()and log them. -
Pasting a
$reffrom an untrusted document.
A non-http(s)ref is now an error, but anhttpsone is only a warning — legal OpenAPI, and still a fetch your resolver will perform. Bundle the target intocomponentswhen the source is not yours. -
Calling the deprecated
invalidate()expecting a cache drop.
It clears every registered route as well. UseinvalidateCache()for the cache,reset()when you really mean to empty the manager.
COMPLETE EXPORT INDEX
Every name @zudojs/openapi exports from its package root at v1.5.0 — 138 in total, generated from the package’s own entry point rather than written by hand. The sections above explain the ones you reach for most; this is the exhaustive list, so nothing shipped is undocumented. Names not covered above are typically internal helpers and supporting types.
Show all 138 exports
OpenAPIComponentConflictError OpenAPIComponentError OpenAPIDocumentBuilder OpenAPIDocumentError OpenAPIError OpenAPIManager OpenAPIOperationError OpenAPIReferenceError OpenAPIRegistryImpl OpenAPIRouteError OpenAPIRouteScannerImpl OpenAPISchemaError OpenAPISerializationError OpenAPIValidationError OpenAPIValidatorImpl OpenAPIVersionError SchemaRegistryImplbuildOpenAPIUIContentSecurityPolicy buildOperationParameters buildOperationRequestBody buildOperationResponses buildResponses convertRouteToOpenAPI convertSchema createComponentReference createOpenAPIDocumentBuilder createOpenAPIDocumentFromRoutes createOpenAPIError createOpenAPIManager createOpenAPIManagerFromRoutes createOpenAPIValidator createSchemaConverter describeResponseKey escapeJsonPointerSegment extractPathParameters formatIssuePath isOpenAPIError isOpenAPIMethod isSchemaDefinition isVersion31 renderOpenAPIUI resolveSchemaInput routeDescriptorToRouteInfo svgToDataUri toOpenAPIJSON toOpenAPIPath toOpenAPIYAML unescapeJsonPointerSegment zudoLogoOpenAPIComponentRegistration OpenAPIComponents OpenAPIContact OpenAPIDiscriminator OpenAPIDocument OpenAPIDocumentFromRoutesOptions OpenAPIDocumentOptions OpenAPIDocumentResponse OpenAPIEncoding OpenAPIErrorOptions OpenAPIExample OpenAPIExternalDocumentation OpenAPIHeader OpenAPIInfo OpenAPILicense OpenAPILink OpenAPILogo OpenAPIManagerOptions OpenAPIMediaType OpenAPIOAuthFlow OpenAPIOAuthFlows OpenAPIOperation OpenAPIParameter OpenAPIPathItem OpenAPIReference OpenAPIRegistry OpenAPIRequestBody OpenAPIResponse OpenAPIRoute OpenAPIRouteBody OpenAPIRouteDescriptor OpenAPIRouteResponse OpenAPISchema OpenAPISecurityRequirement OpenAPISecurityScheme OpenAPIServer OpenAPIServerVariable OpenAPITag OpenAPIUIAssetIntegrity OpenAPIUIOptions OpenAPIUIResponse OpenAPIValidationIssue OpenAPIValidationResult OpenAPIValidator OpenAPIXml RouteInfo RouteMetadata RouteOpenAPIMetadata RouteParameterMetadata SchemaConversionOptions SchemaConversionResult SchemaConverter SchemaInputOptions SchemaRegistry SchemaRegistryOptionsComponentSection OpenAPIHttpMethod OpenAPIParameterLocation OpenAPIPaths OpenAPIResponses OpenAPISchemaInput OpenAPIUIRenderer OpenAPIVersion RouteConversionOptionsCOMPONENT_REF_PREFIX DEFAULT_MEDIA_TYPE DEFAULT_OPENAPI_VERSION DEFAULT_SERVER_URL DOCUMENT_CACHE_TTL_MS MAX_OPERATION_ID_LENGTH PATH_TEMPLATE_PARAMETER REDOC_VERSION RESPONSE_KEY_PATTERN STATUS_CODE_CATEGORIES SUPPORTED_OPENAPI_VERSIONS SWAGGER_UI_VERSION UNDOCUMENTED_RESPONSE_DESCRIPTION ZUDO_FAVICON_DATA_URI ZUDO_FAVICON_SVG ZUDO_MARK_DARK_DATA_URI ZUDO_MARK_DARK_SVG ZUDO_MARK_DATA_URI ZUDO_MARK_SVG ZUDO_SITE_URL ZUDO_WORDMARK_DARK_DATA_URI ZUDO_WORDMARK_DARK_SVG ZUDO_WORDMARK_DATA_URI ZUDO_WORDMARK_SVG ZUDOLIB_TO_OPENAPI_METHODS