UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

75 lines (69 loc) 2.27 kB
/** * OpenAPI generation handler * OpenAPI helpers for the Beignet server runtime. */ import type { HttpContractConfig } from "../contracts/index.js"; import type { AppEnvironment } from "./health.js"; import type { HttpRequestLike, HttpResponseLike } from "./types.js"; /** * OpenAPI route handler configuration. */ export interface OpenAPIConfig { /** Enable OpenAPI endpoint (default: false) */ enabled?: boolean; /** * Suggested path for the OpenAPI endpoint (e.g., "/api/openapi.json"). * NOTE: This field is for documentation/metadata only and does not control routing. * You must manually wire the openapiHandler to your desired route. */ suggestedPath?: string; /** API title */ title?: string; /** API version */ version?: string; /** API description */ description?: string; } /** * Create a framework-neutral OpenAPI JSON handler. * * The OpenAPI document is generated lazily on the first request and then cached * for the lifetime of the handler. */ export function createOpenAPIHandler( contracts: readonly HttpContractConfig[], openapiConfig: OpenAPIConfig | undefined, _env: AppEnvironment, ): (req: HttpRequestLike) => Promise<HttpResponseLike> { // Lazily generate OpenAPI spec on first request let cachedSpec: object | null = null; return async (_req: HttpRequestLike): Promise<HttpResponseLike> => { // Generate spec if not cached if (!cachedSpec) { try { // Dynamic import to avoid hard dependency const { contractsToOpenAPI } = await import("../openapi/index.js"); cachedSpec = contractsToOpenAPI(contracts, { title: openapiConfig?.title ?? "Beignet API", version: openapiConfig?.version ?? "1.0.0", description: openapiConfig?.description, }); } catch (error) { // OpenAPI generation failed return { status: 500, body: { error: "OpenAPI generation failed", message: error instanceof Error ? error.message : "Unknown error", }, headers: { "Content-Type": "application/json" }, }; } } return { status: 200, body: cachedSpec, headers: { "Content-Type": "application/json" }, }; }; }