diff --git a/docs/redoc-vendor-extensions.md b/docs/redoc-vendor-extensions.md index f02bc9b2..e69affed 100644 --- a/docs/redoc-vendor-extensions.md +++ b/docs/redoc-vendor-extensions.md @@ -306,3 +306,37 @@ Player: x-additionalPropertiesName: attribute-name type: string ``` + +#### x-explicitMappingOnly +**ATTENTION**: This is ReDoc-specific vendor extension. It won't be supported by other tools. + +Extends the `discriminator` property of the schema object. + +| Field Name | Type | Description | +| :------------- | :------: | :---------- | +| x-explicitMappingOnly | boolean | limit the discriminator selectpicker to the explicit mappings only | + +###### Usage in ReDoc +ReDoc uses this extension to filter the `discriminator` mappings shown in the selectpicker. +When set to `true`, the selectpicker will only list the the explicitly defined mappings. When `false`, +the default behavior is kept, i.e. explicit and implicit mappings will be shown. + +###### x-explicitMappingOnly example + + +```yaml +Pet: + type: object + required: + - name + - photoUrls + discriminator: + propertyName: petType + x-explicitMappingOnly: true + mapping: + cat: "#/components/schemas/Cat" + bee: "#/components/schemas/HoneyBee" +``` + +Will show in the selectpicker only the items `cat` and `bee`, even though the `Dog` class inherits from +the `Pet` class. diff --git a/src/services/models/Schema.ts b/src/services/models/Schema.ts index 7fb5a8e9..b6401c9a 100644 --- a/src/services/models/Schema.ts +++ b/src/services/models/Schema.ts @@ -240,6 +240,15 @@ export class SchemaModel { } const mapping = discriminator.mapping || {}; + + // Defines if the mapping is exhaustive. This avoids having references + // that overlap with the mapping entries + let isLimitedToMapping = discriminator['x-explicitMappingOnly'] || false; + // if there are no mappings, assume non-exhaustive + if (Object.keys(mapping).length === 0) { + isLimitedToMapping = false; + } + const explicitInversedMapping = {}; for (const name in mapping) { const $ref = mapping[name]; @@ -252,7 +261,7 @@ export class SchemaModel { } } - const inversedMapping = { ...implicitInversedMapping, ...explicitInversedMapping }; + const inversedMapping = isLimitedToMapping ? { ...explicitInversedMapping } : { ...implicitInversedMapping, ...explicitInversedMapping }; const refs: Array<{ $ref; name }> = []; diff --git a/src/types/open-api.d.ts b/src/types/open-api.d.ts index 4fb04a83..891d7a0f 100644 --- a/src/types/open-api.d.ts +++ b/src/types/open-api.d.ts @@ -144,6 +144,7 @@ export interface OpenAPISchema { export interface OpenAPIDiscriminator { propertyName: string; mapping?: { [name: string]: string }; + 'x-explicitMappingOnly'?: boolean; } export interface OpenAPIMediaType { diff --git a/src/utils/openapi.ts b/src/utils/openapi.ts index 74511e3d..1ee0bd14 100644 --- a/src/utils/openapi.ts +++ b/src/utils/openapi.ts @@ -579,6 +579,7 @@ export function isRedocExtension(key: string): boolean { 'x-tagGroups': true, 'x-traitTag': true, 'x-additionalPropertiesName': true, + 'x-explicitMappingOnly': true, }; return key in redocExtensions;