fix: merge allOf in correct order (#2020)

This commit is contained in:
Alex Varchuk 2022-05-26 14:54:03 +03:00 committed by GitHub
parent 82712c5b40
commit 1e4ea03d4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 120 additions and 4 deletions

View File

@ -274,6 +274,9 @@ export class OpenAPIParser {
properties, properties,
items, items,
required, required,
oneOf,
anyOf,
title,
...otherConstraints ...otherConstraints
} = subSchema; } = subSchema;
@ -324,9 +327,17 @@ export class OpenAPIParser {
receiver.required = (receiver.required || []).concat(required); receiver.required = (receiver.required || []).concat(required);
} }
if (oneOf !== undefined) {
receiver.oneOf = oneOf;
}
if (anyOf !== undefined) {
receiver.anyOf = anyOf;
}
// merge rest of constraints // merge rest of constraints
// TODO: do more intelligent merge // TODO: do more intelligent merge
receiver = { ...receiver, ...otherConstraints }; receiver = { ...receiver, title: receiver.title || title, ...otherConstraints };
if (subSchemaRef) { if (subSchemaRef) {
receiver.parentRefs!.push(subSchemaRef); receiver.parentRefs!.push(subSchemaRef);

View File

@ -9,14 +9,50 @@ describe('Models', () => {
let parser; let parser;
test('should hoist oneOfs when mergin allOf', () => { test('should hoist oneOfs when mergin allOf', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const spec = require('./fixtures/oneOfHoist.json'); const spec = require('./fixtures/oneOfHoist.json');
parser = new OpenAPIParser(spec, undefined, opts); parser = new OpenAPIParser(spec, undefined, opts);
expect(parser.mergeAllOf(spec.components.schemas.test)).toMatchSnapshot(); expect(parser.mergeAllOf(spec.components.schemas.test)).toMatchSnapshot();
}); });
test('should get schema name from named schema', () => {
const spec = require('./fixtures/mergeAllOf.json');
parser = new OpenAPIParser(spec, undefined, opts);
const schema = parser.mergeAllOf(spec.components.schemas.Case1, '#/components/schemas/Case1');
expect(schema.title).toEqual('Case1');
});
test('should get schema name from first allOf', () => {
const spec = require('./fixtures/mergeAllOf.json');
parser = new OpenAPIParser(spec, undefined, opts);
const schema = parser.mergeAllOf(
spec.components.schemas.Case2.properties.a,
'#components/schemas/Case2/properties/a',
);
expect(schema.title).toEqual('Bar');
});
test('should get schema name from named schema', () => {
const spec = require('./fixtures/mergeAllOf.json');
parser = new OpenAPIParser(spec, undefined, opts);
const schema = parser.mergeAllOf(
spec.components.schemas.Case3.schemas.Foo,
'#components/schemas/Case3/schemas/Foo',
);
expect(schema.title).toEqual('Foo');
});
test('should merge oneOff to inside allOff', () => {
// TODO: should hoist
const spec = require('./fixtures/mergeAllOf.json');
parser = new OpenAPIParser(spec, undefined, opts);
const schema = parser.mergeAllOf(spec.components.schemas.Case4);
expect(schema.title).toEqual('Foo');
expect(schema.parentRefs).toHaveLength(1);
expect(schema.parentRefs[0]).toEqual('#/components/schemas/Ref');
expect(schema.oneOf).toEqual([{ title: 'Bar' }, { title: 'Baz' }]);
});
test('should override description from $ref of the referenced component, when sibling description exists ', () => { test('should override description from $ref of the referenced component, when sibling description exists ', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const spec = require('./fixtures/siblingRefDescription.json'); const spec = require('./fixtures/siblingRefDescription.json');
parser = new OpenAPIParser(spec, undefined, opts); parser = new OpenAPIParser(spec, undefined, opts);
const schemaOrRef: Referenced<OpenAPIParameter> = { const schemaOrRef: Referenced<OpenAPIParameter> = {
@ -28,7 +64,6 @@ describe('Models', () => {
}); });
test('should correct resolve double $ref if no need sibling', () => { test('should correct resolve double $ref if no need sibling', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const spec = require('./fixtures/3.1/schemaDefinition.json'); const spec = require('./fixtures/3.1/schemaDefinition.json');
parser = new OpenAPIParser(spec, undefined, opts); parser = new OpenAPIParser(spec, undefined, opts);
const schemaOrRef: Referenced<OpenAPIParameter> = { const schemaOrRef: Referenced<OpenAPIParameter> = {

View File

@ -0,0 +1,70 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.0",
"title": "Foo"
},
"components": {
"schemas": {
"Case1": {
"allOf": [
{
"title": "Bar"
},
{
"title": "Baz"
}
]
},
"Case2": {
"properties": {
"a": {
"allOf": [
{
"title": "Bar"
},
{
"title": "Baz"
}
]
}
}
},
"Case3": {
"schemas": {
"Foo": {
"title": "Foo",
"allOf": [
{
"title": "Bar"
},
{
"title": "Baz"
}
]
}
}
},
"Case4": {
"allOf": [
{
"title": "Foo"
},
{
"$ref": "#/components/schemas/Ref"
}
]
},
"Ref": {
"oneOf": [
{
"title": "Bar"
},
{
"title": "Baz"
}
]
}
}
}
}