mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 10:33:44 +03:00
Support inherited discriminator (only one at the moment)
This commit is contained in:
parent
d3af2e6867
commit
86c0dcbfe1
|
@ -45,8 +45,8 @@ export class JsonSchema extends BaseComponent implements OnInit {
|
|||
});
|
||||
activeDescendant.active = true;
|
||||
|
||||
this.pointer = activeDescendant.$ref;
|
||||
this.schema = this.specMgr.byPointer(this.pointer);
|
||||
this.schema = this.specMgr.getDescendant(activeDescendant, this.componentSchema);
|
||||
this.pointer = this.schema._pointer || activeDescendant.$ref;
|
||||
this.normalizer.reset();
|
||||
this.schema = this.normalizer.normalize(this.schema, this.normPointer,
|
||||
{resolved: true});
|
||||
|
@ -54,19 +54,22 @@ export class JsonSchema extends BaseComponent implements OnInit {
|
|||
}
|
||||
|
||||
initDescendants() {
|
||||
this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer);
|
||||
this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer, this.schema);
|
||||
if (!this.descendants.length) return;
|
||||
this.hasDescendants = true;
|
||||
let discriminator = this.schema.discriminator || this.schema['x-extendedDiscriminator'];
|
||||
let discrProperty = this.schema._properties &&
|
||||
this.schema._properties.filter((prop) => prop.name === discriminator)[0];
|
||||
let discrProperty = this.schema.properties &&
|
||||
this.schema.properties[discriminator];
|
||||
if (discrProperty && discrProperty.enum) {
|
||||
let enumOrder = {};
|
||||
discrProperty.enum.forEach((enumItem, idx) => {
|
||||
enumOrder[enumItem.val] = idx;
|
||||
enumOrder[enumItem] = idx;
|
||||
});
|
||||
|
||||
this.schema._descendants.sort((a, b) => {
|
||||
this.descendants = this.descendants
|
||||
.filter(a => {
|
||||
return enumOrder[a.name] != undefined;
|
||||
}).sort((a, b) => {
|
||||
return enumOrder[a.name] > enumOrder[b.name] ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
|||
|
||||
let discriminator = this.componentSchema.discriminator || this.componentSchema['x-discriminatorBasePointer'];
|
||||
if (discriminator) {
|
||||
let descendants = this.specMgr.findDerivedDefinitions(this.componentSchema._pointer || this.pointer);
|
||||
let descendants = this.specMgr.findDerivedDefinitions(this.componentSchema._pointer || this.pointer, this.componentSchema);
|
||||
if (descendants.length) {
|
||||
// TODO: sync up with dropdown
|
||||
selectedDescendant = descendants[0];
|
||||
let descSchema = this.specMgr.byPointer(selectedDescendant.$ref);
|
||||
let descSchema = this.specMgr.getDescendant(selectedDescendant, this.componentSchema);
|
||||
this.componentSchema = this._normalizer.normalize(Object.assign({}, descSchema), selectedDescendant.$ref,
|
||||
{omitParent: false});
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
|||
|
||||
import { MdRenderer } from './md-renderer';
|
||||
|
||||
function getDiscriminator(obj) {
|
||||
return obj.discriminator || obj['x-extendedDiscriminator'];
|
||||
}
|
||||
|
||||
export class SpecManager {
|
||||
public _schema: any = {};
|
||||
public apiUrl: string;
|
||||
|
@ -158,8 +162,8 @@ export class SpecManager {
|
|||
return tagsMap;
|
||||
}
|
||||
|
||||
findDerivedDefinitions(defPointer) {
|
||||
let definition = this.byPointer(defPointer);
|
||||
findDerivedDefinitions(defPointer, schema) {
|
||||
let definition = schema || this.byPointer(defPointer);
|
||||
if (!definition) throw new Error(`Can't load schema at ${defPointer}`);
|
||||
if (!definition.discriminator && !definition['x-extendedDiscriminator']) return [];
|
||||
|
||||
|
@ -172,7 +176,20 @@ export class SpecManager {
|
|||
!def['x-derived-from']) continue;
|
||||
let subTypes = def['x-derived-from'] ||
|
||||
def.allOf.map(subType => subType._pointer || subType.$ref);
|
||||
let idx = subTypes.findIndex(ref => ref === defPointer);
|
||||
|
||||
let pointers;
|
||||
if (definition['x-derived-from']) {
|
||||
pointers = [defPointer, ...definition['x-derived-from']];
|
||||
} else {
|
||||
pointers = [defPointer];
|
||||
}
|
||||
let idx = -1;
|
||||
|
||||
for (let ptr of pointers) {
|
||||
idx = subTypes.findIndex(ref => ptr && ref === ptr);
|
||||
if (idx >= 0) break;
|
||||
}
|
||||
|
||||
if (idx < 0) continue;
|
||||
|
||||
let derivedName = defName;
|
||||
|
@ -188,4 +205,19 @@ export class SpecManager {
|
|||
return res;
|
||||
}
|
||||
|
||||
getDescendant(descendant, componentSchema) {
|
||||
let res;
|
||||
if (!getDiscriminator(componentSchema) && componentSchema.allOf) {
|
||||
// discriminator inherited from parents
|
||||
// only one discriminator and only one level of inheritence is supported at the moment
|
||||
res = Object.assign({}, componentSchema);
|
||||
let idx = res.allOf.findIndex(subSpec => !!getDiscriminator(subSpec));
|
||||
res.allOf[idx] = this.byPointer(descendant.$ref);
|
||||
} else {
|
||||
// this.pointer = activeDescendant.$ref;
|
||||
res = this.byPointer(descendant.$ref);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user