Skip to content

Support discriminator with no parent/shared properties #1040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion demo/examples/tests/discriminator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,32 @@ paths:
schema:
$ref: "#/components/schemas/BaseSharedMapping"

/discriminator-mapping-no-properties:
get:
tags:
- discriminator
summary: Discriminator with Mapping and No Shared Properties
description: |
Schema:
```yaml
type: object
discriminator:
propertyName: type
mapping:
typeA: "#/components/schemas/TypeA"
typeB: "#/components/schemas/TypeB"
oneOf:
- $ref: '#/components/schemas/TypeA'
- $ref: '#/components/schemas/TypeB'
```
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/BaseSharedMappingNoProperties"

/discriminator-allof-mapping:
get:
tags:
Expand Down Expand Up @@ -401,6 +427,17 @@ components:
- $ref: "#/components/schemas/TypeA"
- $ref: "#/components/schemas/TypeB"

BaseSharedMappingNoProperties:
type: object
discriminator:
propertyName: type
mapping:
typeA: "#/components/schemas/TypeA"
typeB: "#/components/schemas/TypeB"
oneOf:
- $ref: "#/components/schemas/TypeA"
- $ref: "#/components/schemas/TypeB"

BaseAllOfMapping:
type: object
discriminator:
Expand All @@ -409,7 +446,8 @@ components:
typeA: "#/components/schemas/TypeA"
typeB: "#/components/schemas/TypeB"
properties:
type: string
type:
type: string
allOf:
- oneOf:
- $ref: "#/components/schemas/TypeA"
Expand Down
30 changes: 20 additions & 10 deletions packages/docusaurus-theme-openapi-docs/src/theme/Schema/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,10 @@ const DiscriminatorNode: React.FC<DiscriminatorNodeProps> = ({
let discriminatedSchemas: any = {};
let inferredMapping: any = {};

const discriminatorProperty = schema.properties![discriminator.propertyName];
// default to empty object if no parent-level properties exist
const discriminatorProperty = schema.properties
? schema.properties![discriminator.propertyName]
: {};

if (schema.allOf) {
const mergedSchemas = mergeAllOf(schema) as SchemaObject;
Expand Down Expand Up @@ -350,21 +353,28 @@ const DiscriminatorNode: React.FC<DiscriminatorNodeProps> = ({

const subProperties = subSchema.properties || mergedSubSchema.properties;
if (subProperties[discriminator.propertyName]) {
schema.properties![discriminator.propertyName] = {
...schema.properties![discriminator.propertyName],
...subProperties[discriminator.propertyName],
};
if (subSchema.required && !schema.required) {
schema.required = subSchema.required;
if (schema.properties) {
schema.properties![discriminator.propertyName] = {
...schema.properties![discriminator.propertyName],
...subProperties[discriminator.propertyName],
};
if (subSchema.required && !schema.required) {
schema.required = subSchema.required;
}
// Avoid duplicating property
delete subProperties[discriminator.propertyName];
} else {
schema.properties = {};
schema.properties[discriminator.propertyName] =
subProperties[discriminator.propertyName];
// Avoid duplicating property
delete subProperties[discriminator.propertyName];
}
// Avoid duplicating property
delete subProperties[discriminator.propertyName];
}
});

const name = discriminator.propertyName;
const schemaName = getSchemaName(discriminatorProperty);

// Default case for discriminator without oneOf/anyOf/allOf
return (
<PropertyDiscriminator
Expand Down
Loading