diff --git a/src/services/OpenAPIParser.ts b/src/services/OpenAPIParser.ts index 11a001aa..1683e927 100644 --- a/src/services/OpenAPIParser.ts +++ b/src/services/OpenAPIParser.ts @@ -174,6 +174,18 @@ export class OpenAPIParser { return obj; } + shallowDeref(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(obj.$ref); + return this.allowMergeRefs ? this.mergeRefs(obj, resolved, false) : (resolved as T); + } + return obj; + } + mergeRefs(ref, resolved, mergeAsAllOf: boolean) { // eslint-disable-next-line @typescript-eslint/no-unused-vars const { $ref, ...rest } = ref; diff --git a/src/services/__tests__/OpenAPIParser.test.ts b/src/services/__tests__/OpenAPIParser.test.ts index b79f61b4..b8b211ba 100644 --- a/src/services/__tests__/OpenAPIParser.test.ts +++ b/src/services/__tests__/OpenAPIParser.test.ts @@ -1,5 +1,6 @@ import { OpenAPIParser } from '../OpenAPIParser'; import { RedocNormalizedOptions } from '../RedocNormalizedOptions'; +import { OpenAPIParameter, Referenced } from '../../types'; const opts = new RedocNormalizedOptions({}); @@ -13,5 +14,18 @@ describe('Models', () => { parser = new OpenAPIParser(spec, undefined, opts); 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 = { + $ref: '#/components/schemas/Test', + description: 'Overriden description', + }; + + expect(parser.shallowDeref(schemaOrRef)).toMatchSnapshot(); + }); + }); }); diff --git a/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap b/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap index 74a26ed0..ffbcbff5 100644 --- a/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap +++ b/src/services/__tests__/__snapshots__/OpenAPIParser.test.ts.snap @@ -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", +} +`; diff --git a/src/services/__tests__/fixtures/siblingRefDescription.json b/src/services/__tests__/fixtures/siblingRefDescription.json new file mode 100644 index 00000000..b090a963 --- /dev/null +++ b/src/services/__tests__/fixtures/siblingRefDescription.json @@ -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" + } + } + } +} diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts index d79d738b..1b23cf5f 100644 --- a/src/services/models/Schema.ts +++ b/src/services/models/Schema.ts @@ -78,7 +78,7 @@ export class SchemaModel { makeObservable(this); 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.init(parser, isChild);