limit to only mapping when asked to and fix non-uniq mappings

This commit is contained in:
Mohamed Zenadi 2019-01-08 12:21:05 +01:00 committed by zeapo
parent e82e98ebbb
commit 05ea976c26
2 changed files with 44 additions and 20 deletions

View File

@ -1,12 +1,8 @@
import { action, observable } from 'mobx';
import { OpenAPIExternalDocumentation, OpenAPISchema, Referenced } from '../../types';
import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import { FieldModel } from './Field';
import { MergedOpenAPISchema } from '../';
import { OpenAPIExternalDocumentation, OpenAPISchema, Referenced } from '../../types';
import {
detectType,
extractExtensions,
@ -21,6 +17,10 @@ import {
import { l } from '../Labels';
import { OpenAPIParser } from '../OpenAPIParser';
import { RedocNormalizedOptions } from '../RedocNormalizedOptions';
import { FieldModel } from './Field';
// TODO: refactor this model, maybe use getters instead of copying all the values
export class SchemaModel {
pointer: string;
@ -216,29 +216,52 @@ export class SchemaModel {
) {
const discriminator = getDiscriminator(schema)!;
this.discriminatorProp = discriminator.propertyName;
const derived = parser.findDerived([...(schema.parentRefs || []), this.pointer]);
let derived: Dict<string> = {};
const mapping = discriminator.mapping || {};
// Defines if the mapping is exhaustive. This avoids having references
// that overlap with the mapping entries
let isLimitedToMapping = discriminator['x-limitToMapping'] || false;
// if there are no mappings, assume non-exhaustive
if (Object.keys(mapping).length === 0) {
isLimitedToMapping = false;
}
// when non-exhaustive, search for implicit references
if (!isLimitedToMapping) {
derived = 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;
derived[variant.$ref] = JsonPointer.baseName(variant.$ref);
}
}
}
const mapping = discriminator.mapping || {};
for (const name in mapping) {
derived[mapping[name]] = name;
// concatenate the implict refs with the mapping ones
const mappingOneOf = Object.keys(mapping).map(name => {
const ref = mapping[name];
// do not include implicit refs in the list when we have a mapped one
if (ref in derived) {
delete derived[ref];
}
const refs = Object.keys(derived);
this.oneOf = refs.map(ref => {
const innerSchema = new SchemaModel(parser, parser.byRef(ref)!, ref, this.options, true);
innerSchema.title = name;
return innerSchema;
});
this.oneOf = mappingOneOf.concat(
Object.keys(derived).map(ref => {
const innerSchema = new SchemaModel(parser, parser.byRef(ref)!, ref, this.options, true);
innerSchema.title = derived[ref];
return innerSchema;
});
}),
);
}
}

View File

@ -144,6 +144,7 @@ export interface OpenAPISchema {
export interface OpenAPIDiscriminator {
propertyName: string;
mapping?: { [name: string]: string };
'x-limitToMapping'?: boolean;
}
export interface OpenAPIMediaType {