Skip to content

Commit

Permalink
fix: support discriminator mapping 1-n
Browse files Browse the repository at this point in the history
fixes #1111
  • Loading branch information
RomanHotsiy committed Dec 12, 2019
1 parent 81a44a2 commit 6e390f9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
6 changes: 3 additions & 3 deletions src/services/OpenAPIParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,16 @@ 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]);
if (
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;
Expand Down
32 changes: 25 additions & 7 deletions src/services/models/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,27 +216,45 @@ 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) {
if (variant.$ref === undefined) {
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: 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 });
}
}

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];
this.oneOf = refs.map(({ $ref, name }) => {
const innerSchema = new SchemaModel(parser, parser.byRef($ref)!, $ref, this.options, true);
innerSchema.title = name;
return innerSchema;
});
}
Expand Down

0 comments on commit 6e390f9

Please sign in to comment.