-
Notifications
You must be signed in to change notification settings - Fork 0
OpenAPI and Scalar
Source of truth:
docs/openapi.md· ADR:ADR-0025
Generation-first OpenAPI 3.1 plus an optional Scalar reference UI — with zero new npm dependencies (Scalar loads from its public CDN in a generated HTML shell). The JSON document is canonical; Scalar is a replaceable presentation layer.
import { defineApp, json, route } from "lugas";
defineApp({
openapi: {
document: {
title: "Store API",
version: "1.0.0",
description: "Product catalog and orders",
},
path: "/openapi.json", // default
ui: { path: "/docs" }, // or ui: true → "/docs"; omit for no UI
},
routes: {
"/products/:id": {
GET: route({
openapi: {
summary: "Get product details",
operationId: "getProduct",
tags: ["Products"],
},
handler: (ctx) => json(200, { id: ctx.params.id }),
}),
},
},
});-
Prepared graph facts — paths, HTTP methods, module names (as tags). Bun path syntax converts:
/items/:id→/items/{id}. -
Standard Schema declarations (
params,query,headers,body), with feature-detected Standard JSON Schema: a validator exposing~standard.jsonSchema()has its schema used verbatim; validators without a representation document presence only (requiredness from declared position, body astype: object) — never a guessed shape. -
route({ openapi })metadata —summary,description,operationId,tags,deprecated, explicitresponses, and schema overrides forparams/query/headers/body. -
RFC 9457 Problem Details registered as
#/components/schemas/ProblemDetailsand documented as every operation's default error response — the framework's real error envelope.
The document is generated once at defineApp() time (the routing graph is snapshotted by contract), so what the document says cannot drift from what serves.
The document and UI handlers pass through the traffic gate, error policy, Structured Logging, and CORS wrappers like any route, and appear in lugas-manifest-v1 as ordinary facts.
-
openapi.pathorui.pathcolliding with an existing route orassets.filesmapping →LUGAS_OPENAPI_002at startup. - Self-collision between document and UI paths, or malformed config →
LUGAS_OPENAPI_001. - Absent
openapiconfig means no endpoints, no files, nothing.
ui is opt-in by design. The shell loads Scalar's script from the public CDN — a third-party runtime fetch — so production deployments may prefer to gate the route, keep it development-only, or replace the shell entirely (the JSON is the contract).
Pinned by tests/openapi/; evidence in docs/reports/issues/M8-004.md.
LugasJS Wiki
Server facilities
- CORS
- Server-Sent Events
- Structured Logging
- OpenAPI and Scalar
- Drizzle
- Service Lifecycle
- Assets and Body Limits
Reference
Repository