Files
skills/plugins/library-navigator/skills/api-stack/api-openapi/sp-api-openapi/SKILL.md
2026-06-09 21:06:27 +01:00

5.4 KiB

name, description
name description
sp-api-openapi Fetch-native OpenAPI 3.1 document generation and self-contained doc UIs (Swagger UI, Redoc, Scalar) for the Suaveplan API platform. Maps framework-neutral RouteDescriptor[] into a deterministic OpenAPI 3.1.0 document, serves it at /openapi.json, and exposes three pinned doc-UI shells as ./ui/* subpaths. Meta-package re-exporting doc-UI renderers from sibling packages; owns document builder and openapi-route directly.

@suaveplan/api-openapi

Purpose

Fetch-native OpenAPI 3.1 document generation and self-contained doc UIs for the Suaveplan API platform. Turns a plugin's framework-neutral RouteDescriptor[] into a deterministic OpenAPI 3.1.0 document, serves it as a RouteDescriptor at /openapi.json, and exposes three pinned doc-UI shells (Swagger UI, Redoc, Scalar) as ./ui/* subpaths.

Depends on no schema runtime (zod/valibot) and no host framework — the same runtime that serves the API serves its documentation.

This is a meta-package: the doc-UI shared contract + helpers and the API_OPENAPI.* error codes live in @suaveplan/api-openapi-core, and the three doc-UI renderers live in @suaveplan/api-openapi-ui-{redoc,scalar,swagger}; this package re-exports their public surface unchanged so existing imports keep working, and continues to own the document builder and the openapi-route descriptor factory directly.

Architecture

Component Source Role
buildOpenApiDocument src/document/document.ts Routes → OpenAPI 3.1.0 document
openApiRoute src/openapi-route/openapi-route.ts GET RouteDescriptor serving document as JSON
swaggerUiRoute re-exported from @suaveplan/api-openapi-ui-swagger Swagger UI shell
redocUiRoute re-exported from @suaveplan/api-openapi-ui-redoc Redoc shell
scalarUiRoute re-exported from @suaveplan/api-openapi-ui-scalar Scalar API Reference shell
API_OPENAPI_CODES re-exported from @suaveplan/api-openapi-core Error-code registry

File Structure

src/
  index.ts              # Barrel: re-exports from core + UI packages, owns document + openapi-route
  document/
    document.ts         # buildOpenApiDocument implementation
    document.types.ts   # OpenApiDocument, Operation, PathItem, etc.
    document.md
  openapi-route/
    openapi-route.ts    # openApiRoute factory
    openapi-route.md

Entry Points

Import Exports
@suaveplan/api-openapi buildOpenApiDocument, openApiRoute, swaggerUiRoute, redocUiRoute, scalarUiRoute, API_OPENAPI_CODES, ApiOpenApiError, doc UI types
@suaveplan/api-openapi/document buildOpenApiDocument + OpenAPI types
@suaveplan/api-openapi/openapi-route openApiRoute, OpenApiRouteOptions
@suaveplan/api-openapi/error-codes API_OPENAPI_CODES, ApiOpenApiError
@suaveplan/api-openapi/ui/swagger swaggerUiRoute, swaggerUiHtml, SWAGGER_UI_VERSION
@suaveplan/api-openapi/ui/redoc redocUiRoute, redocUiHtml, REDOC_VERSION
@suaveplan/api-openapi/ui/scalar scalarUiRoute, scalarUiHtml, SCALAR_VERSION
@suaveplan/api-openapi/ui/shared Shared spec-URL validation, escaping, route wrapper

Patterns

Serve OpenAPI document + Swagger UI

import { createApi, type Plugin, type RouteRegistrar } from "@suaveplan/api";
import { buildOpenApiDocument } from "@suaveplan/api-openapi/document";
import { openApiRoute } from "@suaveplan/api-openapi/openapi-route";
import { swaggerUiRoute } from "@suaveplan/api-openapi/ui/swagger";

const doc = buildOpenApiDocument(myRoutes, { title: "API", version: "1.0.0" });

const docsPlugin: Plugin = {
    manifest: { name: "api-docs", version: "1.0.0", apiHost: "^0.1.0", isolation: "trusted", trustLevel: "first-party", requiredCapabilities: [] },
    register(reg: RouteRegistrar) {
        reg.addRoute(openApiRoute(doc));              // GET /openapi.json
        reg.addRoute(swaggerUiRoute({ specUrl: "/openapi.json" })); // GET /docs
    },
};

const runtime = createApi({ plugins: [docsPlugin], capabilities: [] });
await runtime.start("api-docs");

Document builder only

import { buildOpenApiDocument } from "@suaveplan/api-openapi/document";

const doc = buildOpenApiDocument(routes, {
    title: "My API",
    version: "1.0.0",
});

Constraints

  • Meta-package — doc-UI renderers and error codes live in sibling packages; this package re-exports them unchanged.
  • No schema runtime dependency — works with structural JSON-Schema embedding; generic fallback when none exposed.
  • Deterministic output — same routes always produce the same document.
  • :param → {param} — Express-style path params converted to OpenAPI templating.
  • Auth → bearer security — platform auth schemes mapped to OpenAPI security definitions.
  • Public route — openApiRoute marks meta.auth: null so auth middleware skips it.
  • Dependencies: @suaveplan/api-core, @suaveplan/api-openapi-core, @suaveplan/api-openapi-ui-redoc, @suaveplan/api-openapi-ui-scalar, @suaveplan/api-openapi-ui-swagger, @suaveplan/api-types, tslib.

Checklist

  • Read src/document/document.ts before modifying OpenAPI generation
  • Read src/openapi-route/openapi-route.ts before changing route semantics
  • Preserve meta-package boundary — do not inline sibling package code
  • Ensure deterministic output — same input must produce identical documents