Skip to content

Commit

Permalink
Merge pull request #800 from BitGo/DX-480-nullable-optional-union
Browse files Browse the repository at this point in the history
feat: add support for unions that are nullable and optional
  • Loading branch information
bitgopatmcl authored Jun 13, 2024
2 parents ddfc6e7 + ac2c974 commit d765208
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 2 deletions.
10 changes: 8 additions & 2 deletions packages/openapi-generator/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,17 @@ function schemaToOpenAPI(
// If there are two schemas and one of the schemas is undefined, that means the union is a case of `optional` type
const undefinedSchema = schema.schemas.find((s) => s.type === 'undefined');
const nonUndefinedSchema = schema.schemas.find((s) => s.type !== 'undefined');
// If nullSchema exists, that means that the union is also nullable
const nullSchema = schema.schemas.find((s) => s.type === 'null');
// and we can just return the other schema (while attaching the comment to that schema)
const isOptional =
schema.schemas.length == 2 && undefinedSchema && nonUndefinedSchema;
schema.schemas.length >= 2 && undefinedSchema && nonUndefinedSchema;
if (isOptional) {
return schemaToOpenAPI({ ...nonUndefinedSchema, comment: schema.comment });
return schemaToOpenAPI({
...nonUndefinedSchema,
comment: schema.comment,
...(nullSchema ? { nullable: true } : {}),
});
}

for (const s of schema.schemas) {
Expand Down
90 changes: 90 additions & 0 deletions packages/openapi-generator/test/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2736,3 +2736,93 @@ testCase('route with optional array query parameter and documentation', ROUTE_WI
schemas: {}
}
});


const ROUTE_WITH_ARRAY_UNION_NULL_UNDEFINED_QUERY_PARAM = `
import * as t from 'io-ts';
import * as h from '@api-ts/io-ts-http';
/**
* A simple route with type descriptions for references
*
* @operationId api.v1.test
* @tag Test Routes
*/
export const route = h.httpRoute({
path: '/foo',
method: 'GET',
request: h.httpRequest({
query: {
/**
* This is a foo description.
* @example abc
* @pattern ^[a-z]+$
*/
ipRestrict: t.union([t.array(t.string), t.null, t.undefined]),
},
}),
response: {
200: {
test: t.string
}
},
});
`;

testCase('route with array union of null and undefined', ROUTE_WITH_ARRAY_UNION_NULL_UNDEFINED_QUERY_PARAM, {
openapi: '3.0.3',
info: {
title: 'Test',
version: '1.0.0'
},
paths: {
'/foo': {
get: {
summary: 'A simple route with type descriptions for references',
operationId: 'api.v1.test',
tags: [
'Test Routes'
],
parameters: [
{
description: 'This is a foo description.',
in: 'query',
name: 'ipRestrict',
schema: {
items: {
description: 'This is a foo description.',
example: 'abc',
type: 'string',
pattern: '^[a-z]+$'
},
type: 'array'
}
}
],
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
test: {
type: 'string'
}
},
required: [
'test'
]
}
}
}
}
}
}
}
},
components: {
schemas: {}
}
});

0 comments on commit d765208

Please sign in to comment.