From 30d053c62ca5a01ba2bbd757dc635a06531cd504 Mon Sep 17 00:00:00 2001 From: hochgi Date: Wed, 13 Nov 2024 09:45:18 +0200 Subject: [PATCH] better condition logic now properly handles correctly these cases: extra_attributes: type: object additionalProperties: true extra_attributes: type: object additionalProperties: {} extra_attributes: additionalProperties: true but fails for this case, which might not be an issue (or an issue with zio-schema): extra_attributes: additionalProperties: {} --- .../http/endpoint/openapi/JsonSchema.scala | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/zio-http/shared/src/main/scala/zio/http/endpoint/openapi/JsonSchema.scala b/zio-http/shared/src/main/scala/zio/http/endpoint/openapi/JsonSchema.scala index 6c6ef1ca5..13388be78 100644 --- a/zio-http/shared/src/main/scala/zio/http/endpoint/openapi/JsonSchema.scala +++ b/zio-http/shared/src/main/scala/zio/http/endpoint/openapi/JsonSchema.scala @@ -255,14 +255,29 @@ object JsonSchema { private[openapi] def fromSerializableSchema(schema: SerializableJsonSchema): JsonSchema = { + val definedAttributesCount = schema.productIterator.count(_.asInstanceOf[Option[_]].isDefined) + // if type: object with additionalProperties defined, // but nothing else, we should assume a free form object - def anyObject: Boolean = schema.additionalProperties.collect { case BoolOrSchema.BooleanWrapper(true) => - schema.schemaType.contains(TypeOrTypes.Type("object")) && - schema.productIterator.count(_.asInstanceOf[Option[_]].isDefined) == 2 - }.exists(identity) + // if type is not defined, but additionalProperties is, + // and nothing else, object is assumed again. + // if both type: object and additionalProperties are defined, + // and nothing else, object is assumed. + def anyObject: Boolean = { + val isObject = schema.schemaType.contains(TypeOrTypes.Type("object")) + val hasAttrs = schema.additionalProperties.collect { case BoolOrSchema.BooleanWrapper(b) => + b + }.exists(identity) + + // if definedAttributesCount == 0, this also yields true, + // but we check for it before calling this function, + // thus no need to check it here. + val isAnyObj = List(isObject, hasAttrs).count(identity) == definedAttributesCount + + isAnyObj + } - if (schema.productIterator.forall(_.asInstanceOf[Option[_]].isEmpty)) JsonSchema.AnyJson + if (definedAttributesCount == 0) JsonSchema.AnyJson else if (anyObject) JsonSchema.Object(Map.empty, Right(JsonSchema.AnyJson), Chunk.empty) else { val additionalProperties = schema.additionalProperties match {