diff --git a/packages/openapi-generator/src/openapi.ts b/packages/openapi-generator/src/openapi.ts index 27f98ac7..13fd74c8 100644 --- a/packages/openapi-generator/src/openapi.ts +++ b/packages/openapi-generator/src/openapi.ts @@ -44,7 +44,7 @@ function schemaToOpenAPI( }, {} as Record, ), - required: schema.required, + ...(schema.required.length > 0 ? { required: schema.required } : {}), }; case 'intersection': return { diff --git a/packages/openapi-generator/test/openapi.test.ts b/packages/openapi-generator/test/openapi.test.ts index 9389b402..93db5a90 100644 --- a/packages/openapi-generator/test/openapi.test.ts +++ b/packages/openapi-generator/test/openapi.test.ts @@ -468,3 +468,73 @@ testCase('source file with a header comment', HEADER_COMMENT, { schemas: {}, }, }); + +const EMPTY_REQUIRED = ` +import * as t from 'io-ts'; +import * as h from '@api-ts/io-ts-http'; + +export const route = h.httpRoute({ + path: '/foo', + method: 'GET', + request: h.httpRequest({ + body: { + foo: t.string, + }, + }), + response: { + /** foo response */ + 200: t.partial({ foo: t.string }) + }, +}); +`; + +// Test that `required` is not emitted as an empty array +testCase('object with no required properties', EMPTY_REQUIRED, { + openapi: '3.0.0', + info: { + title: 'Test', + version: '1.0.0', + }, + paths: { + '/foo': { + get: { + parameters: [], + requestBody: { + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + required: ['foo'], + }, + }, + }, + }, + responses: { + 200: { + description: 'foo response', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + foo: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + components: { + schemas: {}, + }, +});