Skip to content

Commit

Permalink
Improve support for generating aggregated inlined objects (#264)
Browse files Browse the repository at this point in the history
Fabrikt now supports inlined definitions of aggregated objects > 1. For example:
```
    Dog:
      type: object
      properties:
        walker:
          allOf:
            - $ref: "#/components/schemas/Person"
            - $ref: "#/components/schemas/Company"

```
Support is preserved for the special case where the aggregation is over a single schema.
Highlighted by the API supplied in Issue #262
  • Loading branch information
cjbooms authored Jan 29, 2024
1 parent e6300c9 commit d1a5e4f
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 29 deletions.
14 changes: 10 additions & 4 deletions src/main/kotlin/com/cjbooms/fabrikt/util/KaizenParserExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@ object KaizenParserExtensions {
getDiscriminatorForInLinedObjectUnderAllOf()?.propertyName != null

fun Schema.isInlinedObjectDefinition() =
isObjectType() && !isSchemaLess() && (
(isObjectType() || isAggregatedObject()) && !isSchemaLess() && (
Overlay.of(this).pathFromRoot.contains("properties") ||
Overlay.of(this).pathFromRoot.contains("items")
)

private fun Schema.isAggregatedObject(): Boolean =
combinedAnyOfAndAllOfSchemas().size > 1

fun Schema.isInlinedTypedAdditionalProperties() =
isObjectType() && !isSchemaLess() && Overlay.of(this).pathFromRoot.contains("additionalProperties")

Expand Down Expand Up @@ -188,7 +191,7 @@ object KaizenParserExtensions {
fun Schema.safeName(): String =
when {
isOneOfPolymorphicTypes() -> this.oneOfSchemas.first().allOfSchemas.first().safeName()
isPropertyWithAllOfSingleType() -> this.allOfSchemas.first().safeName()
isInlinedAggregationOfExactlyOne() -> combinedAnyOfAndAllOfSchemas().first().safeName()
name != null -> name
else -> Overlay.of(this).pathFromRoot
.splitToSequence("/")
Expand Down Expand Up @@ -222,8 +225,11 @@ object KaizenParserExtensions {
fun Schema.isOneOfSuperInterface() =
discriminator != null && discriminator.propertyName != null && oneOfSchemas.isNotEmpty()

private fun Schema.isPropertyWithAllOfSingleType() =
allOfSchemas?.size == 1 && isInlinedPropertySchema()
private fun Schema.isInlinedAggregationOfExactlyOne() =
combinedAnyOfAndAllOfSchemas().size == 1 && isInlinedPropertySchema()

private fun Schema.combinedAnyOfAndAllOfSchemas(): List<Schema> =
(allOfSchemas ?: emptyList()) + (anyOfSchemas ?: emptyList())

/**
* The `pathFromRoot` of a property schema ends with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ModelGeneratorTest {
"validationAnnotations",
"wildCardTypes",
"singleAllOf",
"singleAllOfProperty",
"inlinedAggregatedObjects",
"responsesSchema",
"webhook",
"instantDateTime",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ components:
description: "The person walking the dog."
allOf:
- $ref: "#/components/schemas/Person"
- $ref: "#/components/schemas/Company"

Person:
type: object
Expand All @@ -27,3 +28,11 @@ components:
properties:
name:
type: string

Company:
type: object
required:
- companyName
properties:
companyName:
type: string
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package examples.inlinedAggregatedObjects.models

import com.fasterxml.jackson.`annotation`.JsonProperty
import javax.validation.Valid
import javax.validation.constraints.NotNull
import kotlin.String

public data class Company(
@param:JsonProperty("companyName")
@get:JsonProperty("companyName")
@get:NotNull
public val companyName: String,
)

public data class Dog(
@param:JsonProperty("owner")
@get:JsonProperty("owner")
@get:Valid
public val owner: Person? = null,
@param:JsonProperty("walker")
@get:JsonProperty("walker")
@get:Valid
public val walker: DogWalker? = null,
)

public data class DogWalker(
@param:JsonProperty("name")
@get:JsonProperty("name")
@get:NotNull
public val name: String,
@param:JsonProperty("companyName")
@get:JsonProperty("companyName")
@get:NotNull
public val companyName: String,
)

public data class Person(
@param:JsonProperty("name")
@get:JsonProperty("name")
@get:NotNull
public val name: String,
)
24 changes: 0 additions & 24 deletions src/test/resources/examples/singleAllOfProperty/models/Models.kt

This file was deleted.

0 comments on commit d1a5e4f

Please sign in to comment.