fix: support discriminator mapping 1-n

fixes #1111
This commit is contained in:
Roman Hotsiy 2019-12-12 15:21:41 +02:00
parent 81a44a239a
commit 6e390f9c79
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
2 changed files with 28 additions and 10 deletions

View File

@ -296,8 +296,8 @@ export class OpenAPIParser {
* returns map of definition pointer to definition name * returns map of definition pointer to definition name
* @param $refs array of references to find derived from * @param $refs array of references to find derived from
*/ */
findDerived($refs: string[]): Dict<string> { findDerived($refs: string[]): Dict<string[]> {
const res: Dict<string> = {}; const res: Dict<string[]> = {};
const schemas = (this.spec.components && this.spec.components.schemas) || {}; const schemas = (this.spec.components && this.spec.components.schemas) || {};
for (const defName in schemas) { for (const defName in schemas) {
const def = this.deref(schemas[defName]); const def = this.deref(schemas[defName]);
@ -305,7 +305,7 @@ export class OpenAPIParser {
def.allOf !== undefined && def.allOf !== undefined &&
def.allOf.find(obj => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1) 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; return res;

View File

@ -216,7 +216,7 @@ export class SchemaModel {
) { ) {
const discriminator = getDiscriminator(schema)!; const discriminator = getDiscriminator(schema)!;
this.discriminatorProp = discriminator.propertyName; this.discriminatorProp = discriminator.propertyName;
const derived = parser.findDerived([...(schema.parentRefs || []), this.pointer]); const inversedMapping = parser.findDerived([...(schema.parentRefs || []), this.pointer]);
if (schema.oneOf) { if (schema.oneOf) {
for (const variant of schema.oneOf) { for (const variant of schema.oneOf) {
@ -224,19 +224,37 @@ export class SchemaModel {
continue; continue;
} }
const name = JsonPointer.baseName(variant.$ref); const name = JsonPointer.baseName(variant.$ref);
derived[variant.$ref] = name; inversedMapping[variant.$ref] = [name];
} }
} }
const mapping = discriminator.mapping || {}; const mapping = discriminator.mapping || {};
for (const name in 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); const refs: Array<{ $ref; name }> = [];
this.oneOf = refs.map(ref => {
const innerSchema = new SchemaModel(parser, parser.byRef(ref)!, ref, this.options, true); for (const $ref of Object.keys(inversedMapping)) {
innerSchema.title = derived[ref]; 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; return innerSchema;
}); });
} }