Skip to content

Commit

Permalink
Sanitize scala doc string for open api gen (#3047)
Browse files Browse the repository at this point in the history
  • Loading branch information
987Nabil committed Aug 30, 2024
1 parent b4dde6a commit bf29d05
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
2 changes: 1 addition & 1 deletion zio-http/shared/src/main/scala/zio/http/Status.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ sealed trait Status extends Product with Serializable { self =>
lazy val text: String = code.toString

/**
* Returns an Routes[Any, Nothing] that responses with this http status code.
* Returns a Routes[Any, Nothing] that responses with this http status code.
*/
def toRoutes(implicit trace: Trace): Routes[Any, Nothing] =
Handler.status(self).toRoutes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,7 @@ object JsonSchema {
.map(_.name),
)
.deprecated(deprecated(record))
.description(record.annotations.collectFirst { case description(value) => value })
.description(descriptionFromAnnotations(record.annotations))
case collection: Schema.Collection[_, _] =>
collection match {
case Schema.Sequence(elementSchema, _, _, _, _) =>
Expand Down Expand Up @@ -731,6 +731,18 @@ object JsonSchema {

}

private def descriptionFromAnnotations(annotations: Chunk[Any]) = {
def sanitize(str: java.lang.String): java.lang.String =
str.linesIterator
.map(_.trim.stripPrefix("/**").stripPrefix("/*").stripSuffix("*/").stripPrefix("*").trim)
.filterNot(l => l == "\n" || l == "")
.mkString("\n")
annotations.collectFirst {
case description(value) if value.trim.startsWith("/*") => sanitize(value)
case description(value) => value
}
}

sealed trait SchemaStyle extends Product with Serializable
object SchemaStyle {

Expand Down Expand Up @@ -759,7 +771,7 @@ object JsonSchema {
schema.annotations.exists(_.isInstanceOf[scala.deprecated])

private def fieldDoc(schema: Schema.Field[_, _]): Option[java.lang.String] = {
val description0 = schema.annotations.collectFirst { case description(value) => value }
val description0 = descriptionFromAnnotations(schema.annotations)
val defaultValue = schema.annotations.collectFirst { case fieldDefaultValue(value) => value }.map { _ =>
s"${if (description0.isDefined) "\n" else ""}If not set, this field defaults to the value of the default annotation."
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,28 @@ object Scala3OpenAPIGenSpec extends ZIOSpecDefault {
zio.http.endpoint.openapi.OpenAPIGen.gen(endpoint = testEndpoint)
assertTrue(true)
},
test("scala doc for api doc is sanetized") {
/**
* This is the Input documentation
*/
final case class Input(a: String)

implicit val schema: Schema[Input] = DeriveSchema.gen[Input]

val testEndpoint =
(Endpoint(RoutePattern.POST / "test") ?? Doc.p("This is my 'POST /test' endpoint doc"))
.in[Input]
.out[String](mediaType = MediaType.application.json, doc = Doc.p("this is the output doc"))

val spec: String =
OpenAPIGen.fromEndpoints(
title = "This is my OpenAPI doc title",
version = "0.0.0",
endpoints = List(testEndpoint)
).toJson

assertTrue(spec.contains(""""description":"This is the Input documentation""""))
}
)
)
}

0 comments on commit bf29d05

Please sign in to comment.