Skip to content

Commit

Permalink
Add response header mapping for OpenApiV2Parser (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
wilmveel authored May 24, 2024
1 parent 23931a2 commit e6c952b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import community.flock.kotlinx.openapi.bindings.v2.SchemaObject
import community.flock.kotlinx.openapi.bindings.v2.SchemaOrReferenceObject
import community.flock.kotlinx.openapi.bindings.v2.StatusCode
import community.flock.kotlinx.openapi.bindings.v2.SwaggerObject
import community.flock.kotlinx.openapi.bindings.v2.HeaderObject
import community.flock.wirespec.compiler.core.parse.AST
import community.flock.wirespec.compiler.core.parse.Endpoint
import community.flock.wirespec.compiler.core.parse.Enum
Expand Down Expand Up @@ -103,6 +104,12 @@ class OpenApiV2Emitter {
.associate {
StatusCode(it.status) to ResponseObject(
description = "$identifier ${it.status} response",
headers = it.headers.associate {
it.identifier.value to HeaderObject(
type = it.reference.value,
items = if(it.reference.isIterable) it.reference.emit() else null
)
},
schema = it.content
?.takeIf { content -> content.reference !is Field.Reference.Unit }
?.let { content ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package community.flock.wirespec.openapi.v2

import community.flock.kotlinx.openapi.bindings.v2.Type as OpenapiType
import arrow.core.filterIsInstance
import community.flock.kotlinx.openapi.bindings.v2.BooleanObject
import community.flock.kotlinx.openapi.bindings.v2.HeaderObject
import community.flock.kotlinx.openapi.bindings.v2.HeaderOrReferenceObject
import community.flock.kotlinx.openapi.bindings.v2.OpenAPI
import community.flock.kotlinx.openapi.bindings.v2.OperationObject
import community.flock.kotlinx.openapi.bindings.v2.ParameterLocation
Expand All @@ -28,7 +31,6 @@ import community.flock.wirespec.compiler.core.parse.Node
import community.flock.wirespec.compiler.core.parse.Type
import community.flock.wirespec.openapi.Common.className
import kotlinx.serialization.json.Json
import community.flock.kotlinx.openapi.bindings.v2.Type as OpenapiType

class OpenApiV2Parser(private val openApi: SwaggerObject) {

Expand Down Expand Up @@ -81,14 +83,17 @@ class OpenApiV2Parser(private val openApi: SwaggerObject) {
}
.ifEmpty { listOf(Endpoint.Request(null)) }
val responses = operation.responses.orEmpty()
.mapValues { it.value.resolve() }
.flatMap { (status, res) ->
(openApi.produces.orEmpty() + operation.produces.orEmpty())
.distinct()
.ifEmpty { listOf("application/json") }.map { type ->
Endpoint.Response(
status = status.value,
headers = emptyList(),
content = res.resolve().schema?.let { schema ->
headers = res.headers
?.map { (identifier, header) -> header.resolve().toField(identifier) }
.orEmpty(),
content = res.schema?.let { schema ->
Endpoint.Content(
type = type,
reference = when (schema) {
Expand Down Expand Up @@ -122,6 +127,14 @@ class OpenApiV2Parser(private val openApi: SwaggerObject) {
}
}

private fun String.mapType() = when (this.lowercase()) {
"string" -> Reference.Primitive.Type.String
"number" -> Reference.Primitive.Type.Number
"integer" -> Reference.Primitive.Type.Integer
"boolean" -> Reference.Primitive.Type.Boolean
else -> error("Cannot map type: $this")
}

private fun parseParameters() = openApi.flatMapRequests { req ->
val parameters = req.pathItem.resolveParameters() + req.operation.resolveParameters()
val name = req.operation.toName() ?: (req.path.toName() + req.method.name)
Expand Down Expand Up @@ -245,6 +258,12 @@ class OpenApiV2Parser(private val openApi: SwaggerObject) {
is ReferenceObject -> this.resolveResponseObject()
}

private fun HeaderOrReferenceObject.resolve(): HeaderObject =
when (this) {
is HeaderObject -> this
is ReferenceObject -> error("Headers cannot be referenced in open api v2")
}

private fun ParameterOrReferenceObject.resolve(): ParameterObject =
when (this) {
is ParameterObject -> this
Expand Down Expand Up @@ -412,6 +431,18 @@ class OpenApiV2Parser(private val openApi: SwaggerObject) {
else -> error("Type is not a primitive")
}

private fun HeaderObject.toField(identifier: String) =
Field(
identifier = Identifier(identifier),
reference = when (type) {
"array" -> items?.resolve()?.toReference(identifier)
?: error("Item cannot be null")

else -> Reference.Primitive(type.mapType(), false, false)
},
isNullable = true
)

private fun SchemaObject.toField(name: String) = properties.orEmpty().map { (key, value) ->
when (value) {
is SchemaObject -> {
Expand Down

0 comments on commit e6c952b

Please sign in to comment.