Merge pull request #1766 from Redocly/fix/missing-description-when-ref-used-1727

fix: OpenAPI 3.1: Missing description when $ref used #1727
This commit is contained in:
Roman 2021-10-11 12:18:19 +03:00 committed by GitHub
commit ba25e24087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 11 deletions

View File

@ -174,6 +174,18 @@ export class OpenAPIParser {
return obj; return obj;
} }
shallowDeref<T extends unknown>(obj: OpenAPIRef | T): T {
if (this.isRef(obj)) {
const schemaName = getDefinitionName(obj.$ref);
if (schemaName && this.options.ignoreNamedSchemas.has(schemaName)) {
return { type: 'object', title: schemaName } as T;
}
const resolved = this.byRef<T>(obj.$ref);
return this.allowMergeRefs ? this.mergeRefs(obj, resolved, false) : (resolved as T);
}
return obj;
}
mergeRefs(ref, resolved, mergeAsAllOf: boolean) { mergeRefs(ref, resolved, mergeAsAllOf: boolean) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { $ref, ...rest } = ref; const { $ref, ...rest } = ref;
@ -194,13 +206,6 @@ export class OpenAPIParser {
} }
} }
shalowDeref<T extends object>(obj: OpenAPIRef | T): T {
if (this.isRef(obj)) {
return this.byRef<T>(obj.$ref)!;
}
return obj;
}
/** /**
* Merge allOf constraints. * Merge allOf constraints.
* @param schema schema with allOF * @param schema schema with allOF

View File

@ -1,5 +1,6 @@
import { OpenAPIParser } from '../OpenAPIParser'; import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions'; import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import { OpenAPIParameter, Referenced } from '../../types';
const opts = new RedocNormalizedOptions({}); const opts = new RedocNormalizedOptions({});
@ -13,5 +14,18 @@ describe('Models', () => {
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 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');
parser = new OpenAPIParser(spec, undefined, opts);
const schemaOrRef: Referenced<OpenAPIParameter> = {
$ref: '#/components/schemas/Test',
description: 'Overriden description',
};
expect(parser.shallowDeref(schemaOrRef)).toMatchSnapshot();
});
}); });
}); });

View File

@ -86,3 +86,10 @@ Object {
], ],
} }
`; `;
exports[`Models Schema should override description from $ref of the referenced component, when sibling description exists 1`] = `
Object {
"description": "Overriden description",
"type": "object",
}
`;

View File

@ -0,0 +1,39 @@
{
"openapi": "3.1.0",
"info": {
"title": "AA",
"version": "1.0"
},
"paths": {
"/test": {
"get": {
"operationId": "test",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"testAttr": {
"description": "Overriden description",
"$ref": "#/components/schemas/Test"
}
}
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Test": {
"type": "object",
"description": "Refed description"
}
}
}
}

View File

@ -40,7 +40,7 @@ export class MediaTypeModel {
this.examples = { this.examples = {
default: new ExampleModel( default: new ExampleModel(
parser, parser,
{ value: parser.shalowDeref(info.example) }, { value: parser.shallowDeref(info.example) },
name, name,
info.encoding, info.encoding,
), ),

View File

@ -78,7 +78,7 @@ export class SchemaModel {
makeObservable(this); makeObservable(this);
this.pointer = schemaOrRef.$ref || pointer || ''; this.pointer = schemaOrRef.$ref || pointer || '';
this.rawSchema = parser.deref(schemaOrRef, false, true); this.rawSchema = parser.shallowDeref(schemaOrRef);
this.schema = parser.mergeAllOf(this.rawSchema, this.pointer, isChild); this.schema = parser.mergeAllOf(this.rawSchema, this.pointer, isChild);
this.init(parser, isChild); this.init(parser, isChild);

View File

@ -505,13 +505,13 @@ export function mergeParams(
): Array<Referenced<OpenAPIParameter>> { ): Array<Referenced<OpenAPIParameter>> {
const operationParamNames = {}; const operationParamNames = {};
operationParams.forEach(param => { operationParams.forEach(param => {
param = parser.shalowDeref(param); param = parser.shallowDeref(param);
operationParamNames[param.name + '_' + param.in] = true; operationParamNames[param.name + '_' + param.in] = true;
}); });
// filter out path params overridden by operation ones with the same name // filter out path params overridden by operation ones with the same name
pathParams = pathParams.filter(param => { pathParams = pathParams.filter(param => {
param = parser.shalowDeref(param); param = parser.shallowDeref(param);
return !operationParamNames[param.name + '_' + param.in]; return !operationParamNames[param.name + '_' + param.in];
}); });