mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 18:43:43 +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;
|
activeDescendant.active = true;
|
||||||
|
|
||||||
this.pointer = activeDescendant.$ref;
|
this.schema = this.specMgr.getDescendant(activeDescendant, this.componentSchema);
|
||||||
this.schema = this.specMgr.byPointer(this.pointer);
|
this.pointer = this.schema._pointer || activeDescendant.$ref;
|
||||||
this.normalizer.reset();
|
this.normalizer.reset();
|
||||||
this.schema = this.normalizer.normalize(this.schema, this.normPointer,
|
this.schema = this.normalizer.normalize(this.schema, this.normPointer,
|
||||||
{resolved: true});
|
{resolved: true});
|
||||||
|
@ -54,19 +54,22 @@ export class JsonSchema extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
initDescendants() {
|
initDescendants() {
|
||||||
this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer);
|
this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer, this.schema);
|
||||||
if (!this.descendants.length) return;
|
if (!this.descendants.length) return;
|
||||||
this.hasDescendants = true;
|
this.hasDescendants = true;
|
||||||
let discriminator = this.schema.discriminator || this.schema['x-extendedDiscriminator'];
|
let discriminator = this.schema.discriminator || this.schema['x-extendedDiscriminator'];
|
||||||
let discrProperty = this.schema._properties &&
|
let discrProperty = this.schema.properties &&
|
||||||
this.schema._properties.filter((prop) => prop.name === discriminator)[0];
|
this.schema.properties[discriminator];
|
||||||
if (discrProperty && discrProperty.enum) {
|
if (discrProperty && discrProperty.enum) {
|
||||||
let enumOrder = {};
|
let enumOrder = {};
|
||||||
discrProperty.enum.forEach((enumItem, idx) => {
|
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;
|
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'];
|
let discriminator = this.componentSchema.discriminator || this.componentSchema['x-discriminatorBasePointer'];
|
||||||
if (discriminator) {
|
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) {
|
if (descendants.length) {
|
||||||
// TODO: sync up with dropdown
|
// TODO: sync up with dropdown
|
||||||
selectedDescendant = descendants[0];
|
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,
|
this.componentSchema = this._normalizer.normalize(Object.assign({}, descSchema), selectedDescendant.$ref,
|
||||||
{omitParent: false});
|
{omitParent: false});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,10 @@ import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
|
||||||
import { MdRenderer } from './md-renderer';
|
import { MdRenderer } from './md-renderer';
|
||||||
|
|
||||||
|
function getDiscriminator(obj) {
|
||||||
|
return obj.discriminator || obj['x-extendedDiscriminator'];
|
||||||
|
}
|
||||||
|
|
||||||
export class SpecManager {
|
export class SpecManager {
|
||||||
public _schema: any = {};
|
public _schema: any = {};
|
||||||
public apiUrl: string;
|
public apiUrl: string;
|
||||||
|
@ -158,8 +162,8 @@ export class SpecManager {
|
||||||
return tagsMap;
|
return tagsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
findDerivedDefinitions(defPointer) {
|
findDerivedDefinitions(defPointer, schema) {
|
||||||
let definition = this.byPointer(defPointer);
|
let definition = schema || this.byPointer(defPointer);
|
||||||
if (!definition) throw new Error(`Can't load schema at ${defPointer}`);
|
if (!definition) throw new Error(`Can't load schema at ${defPointer}`);
|
||||||
if (!definition.discriminator && !definition['x-extendedDiscriminator']) return [];
|
if (!definition.discriminator && !definition['x-extendedDiscriminator']) return [];
|
||||||
|
|
||||||
|
@ -172,7 +176,20 @@ export class SpecManager {
|
||||||
!def['x-derived-from']) continue;
|
!def['x-derived-from']) continue;
|
||||||
let subTypes = def['x-derived-from'] ||
|
let subTypes = def['x-derived-from'] ||
|
||||||
def.allOf.map(subType => subType._pointer || subType.$ref);
|
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;
|
if (idx < 0) continue;
|
||||||
|
|
||||||
let derivedName = defName;
|
let derivedName = defName;
|
||||||
|
@ -188,4 +205,19 @@ export class SpecManager {
|
||||||
return res;
|
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