From 6e390f9c7909da0b5d1d6fc571ab4ad92e715d6e Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Thu, 12 Dec 2019 15:21:41 +0200 Subject: [PATCH] fix: support discriminator mapping 1-n fixes #1111 --- src/services/OpenAPIParser.ts | 6 +++--- src/services/models/Schema.ts | 32 +++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/services/OpenAPIParser.ts b/src/services/OpenAPIParser.ts index 449b555e..c8a4d5c5 100644 --- a/src/services/OpenAPIParser.ts +++ b/src/services/OpenAPIParser.ts @@ -296,8 +296,8 @@ export class OpenAPIParser { * returns map of definition pointer to definition name * @param $refs array of references to find derived from */ - findDerived($refs: string[]): Dict { - const res: Dict = {}; + findDerived($refs: string[]): Dict { + const res: Dict = {}; const schemas = (this.spec.components && this.spec.components.schemas) || {}; for (const defName in schemas) { const def = this.deref(schemas[defName]); @@ -305,7 +305,7 @@ export class OpenAPIParser { def.allOf !== undefined && def.allOf.find(obj => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1) ) { - res['#/components/schemas/' + defName] = def['x-discriminator-value'] || defName; + res['#/components/schemas/' + defName] = [def['x-discriminator-value'] || defName]; } } return res; diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts index 6b228711..fb541103 100644 --- a/src/services/models/Schema.ts +++ b/src/services/models/Schema.ts @@ -216,7 +216,7 @@ export class SchemaModel { ) { const discriminator = getDiscriminator(schema)!; this.discriminatorProp = discriminator.propertyName; - const derived = parser.findDerived([...(schema.parentRefs || []), this.pointer]); + const inversedMapping = parser.findDerived([...(schema.parentRefs || []), this.pointer]); if (schema.oneOf) { for (const variant of schema.oneOf) { @@ -224,19 +224,37 @@ export class SchemaModel { continue; } const name = JsonPointer.baseName(variant.$ref); - derived[variant.$ref] = name; + inversedMapping[variant.$ref] = [name]; } } const mapping = discriminator.mapping || {}; for (const name in mapping) { - derived[mapping[name]] = name; + const $ref = mapping[name]; + + if (Array.isArray(inversedMapping[$ref])) { + inversedMapping[$ref].push(name); + } else { + inversedMapping[$ref] = [name]; + } } - const refs = Object.keys(derived); - this.oneOf = refs.map(ref => { - const innerSchema = new SchemaModel(parser, parser.byRef(ref)!, ref, this.options, true); - innerSchema.title = derived[ref]; + const refs: Array<{ $ref; name }> = []; + + for (const $ref of Object.keys(inversedMapping)) { + const names = inversedMapping[$ref]; + if (Array.isArray(names)) { + for (const name of names) { + refs.push({ $ref, name }); + } + } else { + refs.push({ $ref, name: names }); + } + } + + this.oneOf = refs.map(({ $ref, name }) => { + const innerSchema = new SchemaModel(parser, parser.byRef($ref)!, $ref, this.options, true); + innerSchema.title = name; return innerSchema; }); }