Skip to content

Commit

Permalink
Fix Map representation in generated OpenAPI specs (#3049)
Browse files Browse the repository at this point in the history
  • Loading branch information
guizmaii authored Aug 23, 2024
1 parent da8d8be commit 719fb15
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1007,11 +1007,9 @@ final case class EndpointGen(config: Config) {
case JsonSchema.ArrayType(None, _, _) => None
case JsonSchema.ArrayType(Some(schema), _, _) =>
schemaToCode(schema, openAPI, name, annotations)
case JsonSchema.Object(properties, additionalProperties, _)
if properties.nonEmpty && additionalProperties.isRight =>
// Can't be an object and a map at the same time
case obj: JsonSchema.Object if obj.isInvalid =>
throw new Exception("Object with properties and additionalProperties is not supported")
case obj @ JsonSchema.Object(properties, additionalProperties, _) if additionalProperties.isLeft =>
case obj @ JsonSchema.Object(properties, _, _) if obj.isClosedDictionary =>
val unvalidatedFields = fieldsOfObject(openAPI, annotations)(obj)
val fields = validateFields(unvalidatedFields)
val nested =
Expand Down Expand Up @@ -1044,10 +1042,10 @@ final case class EndpointGen(config: Config) {
enums = Nil,
),
)
case JsonSchema.Object(_, _, _) =>
// properties.isEmpty && additionalProperties.isRight
case JsonSchema.Object(_, _, _) =>
// if obt.isOpenDictionary
throw new IllegalArgumentException("Top-level maps are not supported")
case JsonSchema.Enum(enums) =>
case JsonSchema.Enum(enums) =>
Some(
Code.File(
List("component", name.capitalize + ".scala"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2812,6 +2812,13 @@ object OpenAPIGenSpec extends ZIOSpecDefault {
| "nestedOption" : {
| "$ref" : "#/components/schemas/Recursive"
| },
| "nestedMap" : {
| "type" : "object",
| "properties" : {},
| "additionalProperties" : {
| "$ref" : "#/components/schemas/Recursive"
| }
| },
| "nestedList" : {
| "type" :
| "array",
Expand All @@ -2823,10 +2830,6 @@ object OpenAPIGenSpec extends ZIOSpecDefault {
| "$ref" : "#/components/schemas/NestedRecursive"
| }
| },
| "additionalProperties" :
| {
| "$ref" : "#/components/schemas/Recursive"
| },
| "required" : [
| "nestedOption",
| "nestedList",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1212,10 +1212,30 @@ object JsonSchema {
additionalProperties: Either[Boolean, JsonSchema],
required: Chunk[java.lang.String],
) extends JsonSchema {

/**
* This Object represents an "open dictionary", aka a Map
*
* See: https://github.com/zio/zio-http/issues/3048#issuecomment-2306291192
*/
def isOpenDictionary: Boolean = properties.isEmpty && additionalProperties.isRight

/**
* This Object represents a "closed dictionary", aka a case class
*
* See: https://github.com/zio/zio-http/issues/3048#issuecomment-2306291192
*/
def isClosedDictionary: Boolean = additionalProperties.isLeft

/**
* Can't represent a case class and a Map at the same time
*/
def isInvalid: Boolean = properties.nonEmpty && additionalProperties.isRight

def addAll(value: Chunk[(java.lang.String, JsonSchema)]): Object =
value.foldLeft(this) { case (obj, (name, schema)) =>
schema match {
case Object(properties, additionalProperties, required) =>
case thatObj @ Object(properties, additionalProperties, required) if thatObj.isClosedDictionary =>
obj.copy(
properties = obj.properties ++ properties,
additionalProperties = combineAdditionalProperties(obj.additionalProperties, additionalProperties),
Expand Down

0 comments on commit 719fb15

Please sign in to comment.