diff --git a/demo/examples/tests/discriminator.yaml b/demo/examples/tests/discriminator.yaml index 1a5f70c1a..b95e56b30 100644 --- a/demo/examples/tests/discriminator.yaml +++ b/demo/examples/tests/discriminator.yaml @@ -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: @@ -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: @@ -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" diff --git a/packages/docusaurus-theme-openapi-docs/src/theme/Schema/index.tsx b/packages/docusaurus-theme-openapi-docs/src/theme/Schema/index.tsx index 9db3b103c..0538aecce 100644 --- a/packages/docusaurus-theme-openapi-docs/src/theme/Schema/index.tsx +++ b/packages/docusaurus-theme-openapi-docs/src/theme/Schema/index.tsx @@ -317,7 +317,10 @@ const DiscriminatorNode: React.FC = ({ 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; @@ -350,21 +353,28 @@ const DiscriminatorNode: React.FC = ({ 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 (