From 709aba3030d092c97a56004ef3cf55135943c11e Mon Sep 17 00:00:00 2001 From: Oskar Lebuda Date: Thu, 5 Dec 2024 08:31:16 +0100 Subject: [PATCH] openapi - add components --- src/runtime/internal/routes/openapi.ts | 21 +++++++++++++++++---- src/types/handler.ts | 6 ++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/runtime/internal/routes/openapi.ts b/src/runtime/internal/routes/openapi.ts index 8aa4b7f4ae..39417a09c8 100644 --- a/src/runtime/internal/routes/openapi.ts +++ b/src/runtime/internal/routes/openapi.ts @@ -1,5 +1,6 @@ import { type HTTPMethod, eventHandler, getRequestURL } from "h3"; import type { + ComponentsObject, OpenAPI3, OperationObject, ParameterObject, @@ -9,6 +10,7 @@ import type { import { joinURL } from "ufo"; import { handlersMeta } from "#nitro-internal-virtual/server-handlers-meta"; import { useRuntimeConfig } from "../config"; +import type { DeepPartial } from "../../../types/_utils"; // Served as /_openapi.json export default eventHandler((event) => { @@ -22,6 +24,8 @@ export default eventHandler((event) => { ...runtimeConfig.nitro?.openAPI?.meta, }; + const { paths, components } = getOpenApiMeta(); + return { openapi: "3.1.0", info: { @@ -36,17 +40,22 @@ export default eventHandler((event) => { variables: {}, }, ], - paths: getPaths(), + paths, + components, }; }); -function getPaths(): PathsObject { +function getOpenApiMeta(): DeepPartial { const paths: PathsObject = {}; + const componentsSchema: ComponentsObject = { + schemas: {}, + }; for (const h of handlersMeta) { const { route, parameters } = normalizeRoute(h.route || ""); const tags = defaultTags(h.route || ""); const method = (h.method || "get").toLowerCase() as Lowercase; + const { components, ...openAPI } = h.meta?.openAPI || {}; const item: PathItemObject = { [method]: { @@ -55,10 +64,14 @@ function getPaths(): PathsObject { responses: { 200: { description: "OK" }, }, - ...h.meta?.openAPI, + ...openAPI, }, }; + if (components) { + Object.assign(componentsSchema.schemas!, components); + } + if (paths[route] === undefined) { paths[route] = item; } else { @@ -66,7 +79,7 @@ function getPaths(): PathsObject { } } - return paths; + return { paths, components: componentsSchema }; } function normalizeRoute(_route: string) { diff --git a/src/types/handler.ts b/src/types/handler.ts index db2493ee7a..f807a3c045 100644 --- a/src/types/handler.ts +++ b/src/types/handler.ts @@ -1,12 +1,14 @@ import type { EventHandler, H3Error, H3Event, RouterMethod } from "h3"; import type { PresetName } from "nitropack/presets"; -import type { OperationObject } from "openapi-typescript"; +import type { OperationObject, SchemaObject } from "openapi-typescript"; type MaybeArray = T | T[]; /** @exprerimental */ export interface NitroRouteMeta { - openAPI?: OperationObject; + openAPI?: OperationObject & { + components?: Record; + }; } export interface NitroEventHandler {