From 1160af8869221f2fced00778fb31b79da1a6b6bc Mon Sep 17 00:00:00 2001 From: Alexander Galabov Date: Fri, 6 Dec 2024 13:36:21 +0200 Subject: [PATCH] handle ref objects for responses --- spec/custom-components.spec.ts | 46 ++++++++++++++++++++++++++++++++++ src/openapi-generator.ts | 20 +++++++++++---- src/openapi-registry.ts | 2 +- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/spec/custom-components.spec.ts b/spec/custom-components.spec.ts index cd258cf..23a8355 100644 --- a/spec/custom-components.spec.ts +++ b/spec/custom-components.spec.ts @@ -93,4 +93,50 @@ describe('Custom components', () => { }, }); }); + + it('can generate responses', () => { + const registry = new OpenAPIRegistry(); + + const response = registry.registerComponent('responses', 'BadRequest', { + description: 'BadRequest', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { name: { type: 'string' } }, + }, + }, + }, + }); + + registry.registerPath({ + summary: 'Get user of an organization', + method: 'get', + path: '/test', + responses: { + '400': response.ref, + }, + }); + + const builder = new OpenApiGeneratorV3(registry.definitions); + const document = builder.generateDocument(testDocConfig); + + expect(document.paths['/test']?.get?.responses['400']).toEqual({ + $ref: '#/components/responses/BadRequest', + }); + + expect(document.components!.responses).toEqual({ + BadRequest: { + description: 'BadRequest', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { name: { type: 'string' } }, + }, + }, + }, + }, + }); + }); }); diff --git a/src/openapi-generator.ts b/src/openapi-generator.ts index 66d29d9..596f0c6 100644 --- a/src/openapi-generator.ts +++ b/src/openapi-generator.ts @@ -597,11 +597,15 @@ export class OpenAPIGenerator { return routeDoc; } - private getResponse({ - content, - headers, - ...rest - }: ResponseConfig): ResponseObject | ReferenceObject { + private getResponse( + response: ResponseConfig | ReferenceObject + ): ResponseObject | ReferenceObject { + if (this.isReferenceObject(response)) { + return response; + } + + const { content, headers, ...rest } = response; + const responseContent = content ? { content: this.getBodyContent(content) } : {}; @@ -626,6 +630,12 @@ export class OpenAPIGenerator { }; } + private isReferenceObject( + schema: T | ReferenceObject + ): schema is ReferenceObject { + return '$ref' in schema; + } + private getResponseHeaders(headers: AnyZodObject): HeadersObject { const schemaShape = headers._def.shape(); diff --git a/src/openapi-registry.ts b/src/openapi-registry.ts index f92dcb4..5b4df1a 100644 --- a/src/openapi-registry.ts +++ b/src/openapi-registry.ts @@ -119,7 +119,7 @@ export type RouteConfig = Omit & { headers?: RouteParameter | ZodType[]; }; responses: { - [statusCode: string]: ResponseConfig; + [statusCode: string]: ResponseConfig | ReferenceObject; }; };