From 3f336d66f3bf57a40df00fa53d01a9ce3890ca3e Mon Sep 17 00:00:00 2001 From: David Plugge Date: Fri, 15 Sep 2023 19:06:55 +0200 Subject: [PATCH 1/2] support array response schemas --- src/utils.ts | 105 +++++++++------------------------------------------ 1 file changed, 18 insertions(+), 87 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 8707fa3..91516fb 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import type { HTTPMethod, LocalHook } from 'elysia' -import { Kind, type TSchema } from '@sinclair/typebox' +import { Kind, type TSchema, type TAnySchema } from '@sinclair/typebox' import type { OpenAPIV3 } from 'openapi-types' import deepClone from 'lodash.clonedeep' @@ -36,13 +36,7 @@ export const mapProperties = ( const mapTypesResponse = ( types: string[], - schema: - | string - | { - type: string - properties: Object - required: string[] - } + schema: TAnySchema ) => { const responses: Record = {} @@ -111,89 +105,26 @@ export const registerSchemaPath = ({ const paramsSchema = hook?.params const headerSchema = hook?.headers const querySchema = hook?.query - let responseSchema = hook?.response as unknown as OpenAPIV3.ResponsesObject + const responseSchema: OpenAPIV3.ResponsesObject = {} - if (typeof responseSchema === 'object') { - if (Kind in responseSchema) { - const { type, properties, required, ...rest } = - responseSchema as typeof responseSchema & { - type: string - properties: Object - required: string[] - } - - responseSchema = { - '200': { - ...rest, - description: rest.description as any, - content: mapTypesResponse( - contentTypes, - type === 'object' || type === 'array' - ? ({ - type, - properties, - required - } as any) - : responseSchema - ) - } - } - } else { - Object.entries(responseSchema as Record).forEach( - ([key, value]) => { - if (typeof value === 'string') { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { type, properties, required, ...rest } = models[ - value - ] as TSchema & { - type: string - properties: Object - required: string[] - } - - responseSchema[key] = { - ...rest, - description: rest.description as any, - content: mapTypesResponse(contentTypes, value) - } - } else { - const { type, properties, required, ...rest } = - value as typeof value & { - type: string - properties: Object - required: string[] - } - - responseSchema[key] = { - ...rest, - description: rest.description as any, - content: mapTypesResponse(contentTypes, { - type, - properties, - required - }) - } - } - } - ) - } - } else if (typeof responseSchema === 'string') { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { type, properties, required, ...rest } = models[ - responseSchema - ] as TSchema & { - type: string - properties: Object - required: string[] + const addToResponseSchema = (code: string, { description, ...schema }: TAnySchema) => { + responseSchema[code] = { + description: description as string, + content: mapTypesResponse(contentTypes, schema) } + } - responseSchema = { - // @ts-ignore - '200': { - ...rest, - content: mapTypesResponse(contentTypes, responseSchema) - } + const userProvidedResponseSchema = hook?.response; + if (typeof userProvidedResponseSchema === 'object') { + if (Kind in userProvidedResponseSchema) { + addToResponseSchema('200', userProvidedResponseSchema); + } else { + Object.entries(userProvidedResponseSchema as Record).forEach(([key, value]) => { + addToResponseSchema(key, typeof value === 'string' ? models[value] : value) + }) } + } else if (typeof userProvidedResponseSchema === 'string') { + addToResponseSchema('200', models[userProvidedResponseSchema]) } const parameters = [ From d01ea5c47eb32fc8700ed32a637a649b40950e82 Mon Sep 17 00:00:00 2001 From: David Plugge Date: Sat, 25 Nov 2023 19:06:19 +0100 Subject: [PATCH 2/2] handle no-content types --- src/utils.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index e22d351..45eaf47 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -112,13 +112,18 @@ export const registerSchemaPath = ({ code: string, { description, ...schema }: TAnySchema, ) => { + const ignore = ['Undefined', 'Null', 'Void'].includes(schema[Kind]); + responseSchema[code] = { description: description as string, - content: mapTypesResponse(contentTypes, schema), + content: ignore + ? undefined + : mapTypesResponse(contentTypes, schema), }; }; const userProvidedResponseSchema = hook?.response; + if (typeof userProvidedResponseSchema === 'object') { if (Kind in userProvidedResponseSchema) { addToResponseSchema('200', userProvidedResponseSchema);