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
* @param $refs array of references to find derived from
*/
findDerived($refs: string[]): Dict<string> {
const res: Dict<string> = {};
findDerived($refs: string[]): Dict<string[]> {
const res: Dict<string[]> = {};
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;

View File

@ -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;
});
}