diff --git a/lib/components/JsonSchema/json-schema.ts b/lib/components/JsonSchema/json-schema.ts index 6fa7917d..1ad68d8b 100644 --- a/lib/components/JsonSchema/json-schema.ts +++ b/lib/components/JsonSchema/json-schema.ts @@ -57,7 +57,7 @@ export class JsonSchema extends BaseComponent implements OnInit { this.descendants = this.specMgr.findDerivedDefinitions(this.normPointer); if (!this.descendants.length) return; this.hasDescendants = true; - let discriminator = this.schema.discriminator; + let discriminator = this.schema.discriminator || this.schema['x-extendedDiscriminator']; let discrProperty = this.schema._properties && this.schema._properties.filter((prop) => prop.name === discriminator)[0]; if (discrProperty && discrProperty.enum) { diff --git a/lib/components/SchemaSample/schema-sample.ts b/lib/components/SchemaSample/schema-sample.ts index 11de5307..74e77366 100644 --- a/lib/components/SchemaSample/schema-sample.ts +++ b/lib/components/SchemaSample/schema-sample.ts @@ -48,7 +48,7 @@ export class SchemaSample extends BaseComponent implements OnInit { this.componentSchema = this._normalizer.normalize(this.componentSchema, this.pointer); - let discriminator = this.componentSchema.discriminator; + let discriminator = this.componentSchema.discriminator || this.componentSchema['x-extendedDiscriminator']; if (discriminator) { let descendants = this.specMgr.findDerivedDefinitions(this.componentSchema._pointer || this.pointer); if (descendants.length) { diff --git a/lib/services/schema-helper.service.ts b/lib/services/schema-helper.service.ts index 315761fd..fac99333 100644 --- a/lib/services/schema-helper.service.ts +++ b/lib/services/schema-helper.service.ts @@ -57,9 +57,10 @@ const injectors = { } }, discriminator: { - check: (propertySchema) => propertySchema.discriminator, + check: (propertySchema) => propertySchema.discriminator || propertySchema['x-extendedDiscriminator'], inject: (injectTo, propertySchema = injectTo, pointer) => { injectTo.discriminator = propertySchema.discriminator; + injectTo['x-extendedDiscriminator'] = propertySchema['x-extendedDiscriminator']; } }, simpleArray: { @@ -229,7 +230,8 @@ export class SchemaHelper { propertySchema._pointer = null; } propertySchema._required = !!requiredMap[propName]; - propertySchema.isDiscriminator = (schema.discriminator === propName); + propertySchema.isDiscriminator = (schema.discriminator === propName + || schema['x-extendedDiscriminator'] === propName); return propertySchema; }); diff --git a/lib/services/schema-normalizer.service.ts b/lib/services/schema-normalizer.service.ts index f97d6d65..300a4e27 100644 --- a/lib/services/schema-normalizer.service.ts +++ b/lib/services/schema-normalizer.service.ts @@ -118,7 +118,7 @@ class AllOfMerger { private static mergeObject(into, subSchema, allOfNumber) { if (subSchema.properties) { - if (!into.properties) into.properties = {}; + into.properties = Object.assign({}, into.properties || {}); Object.assign(into.properties, subSchema.properties); Object.keys(subSchema.properties).forEach(propName => { let prop = subSchema.properties[propName]; diff --git a/lib/utils/SpecManager.ts b/lib/utils/SpecManager.ts index 64755d6a..1c4032d5 100644 --- a/lib/utils/SpecManager.ts +++ b/lib/utils/SpecManager.ts @@ -152,19 +152,29 @@ export class SpecManager { findDerivedDefinitions(defPointer) { let definition = this.byPointer(defPointer); if (!definition) throw new Error(`Can't load schema at ${defPointer}`); - if (!definition.discriminator) return []; + if (!definition.discriminator && !definition['x-extendedDiscriminator']) return []; let globalDefs = this._schema.definitions || {}; let res = []; + let extendedDiscriminatorProp = definition['x-extendedDiscriminator']; for (let defName of Object.keys(globalDefs)) { - if (!globalDefs[defName].allOf && - !globalDefs[defName]['x-derived-from']) continue; - let subTypes = globalDefs[defName]['x-derived-from'] || - globalDefs[defName].allOf.map(subType => subType._pointer || subType.$ref); + let def = globalDefs[defName]; + if (!def.allOf && + !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); if (idx < 0) continue; - res.push({name: defName, $ref: `#/definitions/${defName}`}); + let derivedName = defName; + if (extendedDiscriminatorProp) { + let prop = def.properties && def.properties[extendedDiscriminatorProp]; + if (prop && prop.enum && prop.enum.length === 1) { + derivedName = prop.enum[0]; + } + } + + res.push({name: derivedName, $ref: `#/definitions/${defName}`}); } return res; }