Skip to content

Commit

Permalink
Merge pull request #782 from BitGo/DX-441-allow-refs-to-have-descript…
Browse files Browse the repository at this point in the history
…ions

feat: allow `refs` to have `descriptions/examples/patterns`
  • Loading branch information
bitgopatmcl authored Jun 4, 2024
2 parents 99eb5f7 + 41c80be commit 7b853d9
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 1 deletion.
9 changes: 8 additions & 1 deletion packages/openapi-generator/src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ function schemaToOpenAPI(
// Or should we just conflate explicit null and undefined properties?
return { nullable: true, enum: [] };
case 'ref':
return { $ref: `#/components/schemas/${schema.name}` };
// if defaultOpenAPIObject is empty, no need to wrap the $ref in an allOf array
if (Object.keys(defaultOpenAPIObject).length === 0) {
return { $ref: `#/components/schemas/${schema.name}` };
}
return {
allOf: [{ $ref: `#/components/schemas/${schema.name}` }],
...defaultOpenAPIObject,
};
case 'array':
const innerSchema = schemaToOpenAPI(schema.items);
if (innerSchema === undefined) {
Expand Down
5 changes: 5 additions & 0 deletions packages/openapi-generator/src/optimize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ export function optimize(schema: Schema): Schema {
} else if (schema.type === 'tuple') {
const schemas = schema.schemas.map(optimize);
return { type: 'tuple', schemas };
} else if (schema.type === 'ref') {
if (schema.comment) {
return { ...schema, comment: schema.comment };
}
return schema;
} else {
return schema;
}
Expand Down
146 changes: 146 additions & 0 deletions packages/openapi-generator/test/openapi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2180,3 +2180,149 @@ testCase('route with descriptions, patterns, and examples', ROUTE_WITH_DESCRIPTI
schemas: {}
}
});

const ROUTE_WITH_DESCRIPTIONS_FOR_REFERENCES = `
import * as t from 'io-ts';
import * as h from '@api-ts/io-ts-http';
const Foo = t.type({ foo: t.string });
const Bar = t.type({ bar: t.number });
/**
* 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: {
bar: t.array(t.string),
},
body: {
/**
* This is a foo description.
* @example "BitGo Inc"
*/
foo: Foo,
bar: Bar,
},
}),
response: {
200: {
test: t.string
}
},
});
`;

testCase('route with descriptions for references', ROUTE_WITH_DESCRIPTIONS_FOR_REFERENCES, {
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: [
{
name: 'bar',
in: 'query',
required: true,
schema: {
type: 'array',
items: {
type: 'string'
}
}
}
],
requestBody: {
content: {
'application/json': {
schema: {
type: 'object',
properties: {
// needs to be wrapped in an allOf to preserve the description
foo: {
allOf: [
{
$ref: '#/components/schemas/Foo'
}
],
description: 'This is a foo description.',
example: 'BitGo Inc'
},
// should not need to be wrapped in an allOf
bar: {
$ref: '#/components/schemas/Bar'
}
},
required: [
'foo',
'bar'
]
}
}
}
},
responses: {
'200': {
description: 'OK',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
test: {
type: 'string'
}
},
required: [
'test'
]
}
}
}
}
}
}
}
},
components: {
schemas: {
Foo: {
title: 'Foo',
type: 'object',
properties: {
foo: {
type: 'string'
}
},
required: [
'foo'
]
},
Bar: {
title: 'Bar',
type: 'object',
properties: {
bar: {
type: 'number'
}
},
required: [
'bar'
]
}
}
}
});

0 comments on commit 7b853d9

Please sign in to comment.