Skip to content

Commit 07cd8ef

Browse files
authored
fix: edgecase where allOfs would receive a type when one wasn't present (#374)
1 parent 4fd8b42 commit 07cd8ef

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

__tests__/tooling/operation/get-parameters-as-json-schema.test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,56 @@ describe('request bodies', () => {
701701
});
702702

703703
describe('polymorphism / inheritance', () => {
704+
describe('adding missing `type` properties', () => {
705+
it("should not add a `type` to a shapeless-description that's part of an `allOf`", () => {
706+
const oas = createOas({
707+
requestBody: {
708+
content: {
709+
'application/json': {
710+
schema: {
711+
type: 'object',
712+
properties: {
713+
petIds: {
714+
allOf: [{ type: 'array', items: { type: 'string' } }, { description: 'Parameter description' }],
715+
},
716+
},
717+
},
718+
},
719+
},
720+
},
721+
});
722+
723+
const schema = oas.operation('/', 'get').getParametersAsJsonSchema();
724+
725+
expect(schema[0].schema.properties.petIds.allOf[1].type).toBeUndefined();
726+
});
727+
728+
it.each([['anyOf'], ['oneOf']])("should add a `type` to a shapeless-description that's part of an `%s`", prop => {
729+
const oas = createOas({
730+
requestBody: {
731+
content: {
732+
'application/json': {
733+
schema: {
734+
type: 'object',
735+
properties: {
736+
petIds: {
737+
[prop]: [{ type: 'array', items: { type: 'string' } }, { description: 'Parameter description' }],
738+
},
739+
},
740+
},
741+
},
742+
},
743+
},
744+
});
745+
746+
const schema = oas.operation('/', 'get').getParametersAsJsonSchema();
747+
expect(schema[0].schema.properties.petIds[prop][1]).toStrictEqual({
748+
description: 'Parameter description',
749+
type: 'string',
750+
});
751+
});
752+
});
753+
704754
it.each([['allOf'], ['anyOf'], ['oneOf']])('should support nested %s', prop => {
705755
const oas = createOas({
706756
requestBody: {

tooling/operation/get-parameters-as-json-schema.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,17 @@ function searchForExampleByPointer(pointer, examples = []) {
178178
* @link https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md
179179
* @param {Object} data
180180
* @param {Object[]} prevSchemas
181-
* @param {string} currentLocation
181+
* @param {String} currentLocation
182182
* @param {Object} globalDefaults
183+
* @param {Boolean} isPolymorphicAllOfChild
183184
*/
184-
function constructSchema(data, prevSchemas = [], currentLocation = '', globalDefaults) {
185+
function constructSchema(
186+
data,
187+
prevSchemas = [],
188+
currentLocation = '',
189+
globalDefaults,
190+
isPolymorphicAllOfChild = false
191+
) {
185192
const schema = { ...data };
186193

187194
// If this schema contains a `$ref`, it's circular and we shouldn't try to resolve it. Just return and move along.
@@ -197,6 +204,15 @@ function constructSchema(data, prevSchemas = [], currentLocation = '', globalDef
197204
schema.type = 'object';
198205
} else if ('items' in schema) {
199206
schema.type = 'array';
207+
} else if (isPolymorphicAllOfChild) {
208+
// If this schema is immediate child of a polymorphic schema and is neither an array or an object, we should
209+
// leave it alone. Cases like this are common where somebody might use `allOf` in order to dynamically add a
210+
// `description` onto another schema, like such:
211+
//
212+
// allOf: [
213+
// { type: 'array', items: { type: 'string' },
214+
// { description: 'This is the description for the `array`.' }
215+
// ]
200216
} else {
201217
// If we're processing a schema that has no types, no refs, and is just a lone schema, we should treat it at the
202218
// bare minimum as a simple string so we make an attempt to generate valid JSON Schema.
@@ -330,7 +346,13 @@ function constructSchema(data, prevSchemas = [], currentLocation = '', globalDef
330346
['allOf', 'anyOf', 'oneOf'].forEach(polyType => {
331347
if (polyType in schema && Array.isArray(schema[polyType])) {
332348
schema[polyType].forEach((item, idx) => {
333-
schema[polyType][idx] = constructSchema(item, prevSchemas, `${currentLocation}/${idx}`, globalDefaults);
349+
schema[polyType][idx] = constructSchema(
350+
item,
351+
prevSchemas,
352+
`${currentLocation}/${idx}`,
353+
globalDefaults,
354+
polyType === 'allOf'
355+
);
334356
});
335357
}
336358
});

0 commit comments

Comments
 (0)