Skip to content

Commit

Permalink
Fix openapi v2 alias definition
Browse files Browse the repository at this point in the history
  • Loading branch information
wilmveel committed Nov 1, 2023
1 parent 7810a8c commit 6d484e5
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/openapi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ kotlin {
dependencies {
implementation(project(":src:compiler:core"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
implementation("community.flock.kotlinx.openapi.bindings:kotlin-openapi-bindings:0.0.15")
implementation("community.flock.kotlinx.openapi.bindings:kotlin-openapi-bindings:0.0.17")
}
}
commonTest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package community.flock.wirespec.openapi.v2

import arrow.core.filterIsInstance
import community.flock.kotlinx.openapi.bindings.v2.BooleanObject
import community.flock.kotlinx.openapi.bindings.v2.OpenAPI
import community.flock.kotlinx.openapi.bindings.v2.OperationObject
Expand Down Expand Up @@ -165,6 +166,7 @@ class OpenApiParser(private val openApi: SwaggerObject) {
}

private fun parseDefinitions() = openApi.definitions.orEmpty()
.filterIsInstance<String, SchemaObject>()
.filter { it.value.additionalProperties == null }
.flatMap { it.value.flatten(className(it.key)) }

Expand Down Expand Up @@ -197,19 +199,18 @@ class OpenApiParser(private val openApi: SwaggerObject) {
private fun ReferenceObject.resolveSchemaObject() =
openApi.definitions
?.get(getReference())
?.let { this to it }
?: error("Cannot resolve ref: $ref")

private fun SchemaOrReferenceObject.resolve(): SchemaObject =
when (this) {
is SchemaObject -> this
is ReferenceObject -> this.resolveSchemaObject().second
is ReferenceObject -> this.resolveSchemaObject().resolve()
}

private fun SchemaOrReferenceOrBooleanObject.resolve(): SchemaObject =
when (this) {
is SchemaObject -> this
is ReferenceObject -> this.resolveSchemaObject().second
is ReferenceObject -> this.resolveSchemaObject().resolve()
is BooleanObject -> TODO()
}

Expand Down Expand Up @@ -298,24 +299,28 @@ class OpenApiParser(private val openApi: SwaggerObject) {
}

private fun ReferenceObject.toReference(): Reference =
resolveSchemaObject().let { (referencingObject, schema) ->
resolveSchemaObject().let { refOrSchema ->
val schema = refOrSchema.resolve()
when {
schema.additionalProperties != null -> when (val additionalProperties = schema.additionalProperties!!) {
is BooleanObject -> Reference.Any(false, true)
is ReferenceObject -> additionalProperties.toReference().toMap()
is SchemaObject -> additionalProperties.toReference(getReference()).toMap()
}

schema.enum != null -> Reference.Custom(className(referencingObject.getReference()), false, false)
schema.enum != null -> Reference.Custom(className(this.getReference()), false, false)
schema.type.isPrimitive() -> Reference.Primitive(schema.type!!.toPrimitive(), false, false)
else -> when (schema.type) {
OpenapiType.ARRAY -> when (val items = schema.items) {
is ReferenceObject -> Reference.Custom(className(items.getReference()), true)
is SchemaObject -> Reference.Custom(className(referencingObject.getReference(), "Array"), true)
is SchemaObject -> Reference.Custom(className(this.getReference(), "Array"), true)
null -> error("items cannot be null when type is array: ${this.ref}")
}

else -> Reference.Custom(className(referencingObject.getReference()), false)
else -> when(refOrSchema){
is SchemaObject -> Reference.Custom(className(this.getReference()), false)
is ReferenceObject -> Reference.Custom(className(refOrSchema.getReference()), false)
}

}
}
Expand Down Expand Up @@ -376,7 +381,7 @@ class OpenApiParser(private val openApi: SwaggerObject) {
is SchemaObject -> {
Field(
identifier = Field.Identifier(key),
reference = when(value.type){
reference = when (value.type) {
OpenapiType.ARRAY -> value.toReference(className(name, key, "Array"))
else -> value.toReference(className(name, key))
},
Expand Down
41 changes: 41 additions & 0 deletions src/openapi/src/commonTest/resources/v2/alias.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"swagger": "2.0",
"info": {
"title": "Alias",
"version": "1.0.0"
},
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/alisa": {
"get": {
"responses": {
"200": {
"description": "Ok",
"schema": {
"$ref": "#/definitions/Bar"
}
}
}
}
}
},
"definitions": {
"Foo": {
"type": "object",
"properties": {
"a": {
"type": "string"
}
}
},
"Bar": {
"$ref": "#/definitions/Foo"
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,53 @@ class OpenApiParserTest {
assertEquals(expectedEndpoint, endpoints)
}

@Test
fun alias() {
val json = IO.readOpenApi("v2/alias.json")

val openApi = OpenAPI.decodeFromString(json)
val ast = OpenApiParser.parse(openApi)

val expected = listOf(
Endpoint(
name = "AlisaGET",
method = Endpoint.Method.GET,
path = listOf(Endpoint.Segment.Literal(value = "alisa")),
query = emptyList(),
headers = emptyList(),
cookies = emptyList(),
requests = listOf(Endpoint.Request(content = null)),
responses = listOf(
Endpoint.Response(
status = "200",
content = Endpoint.Content(
type = "application/json",
reference = Custom(value = "Foo", isIterable = false, isMap = false),
isNullable = false
)
)
)
),
Type(
name = "Foo",
shape = Shape(
value = listOf(
Field(
identifier = Identifier(value = "a"),
reference = Primitive(
type = Primitive.Type.String,
isIterable = false,
isMap = false
),
isNullable = true
)
)
)
)
)
assertEquals(expected, ast)
}

@Test
fun objectInRequest() {
val json = IO.readOpenApi("v2/object-in-request.json")
Expand All @@ -227,7 +274,6 @@ class OpenApiParserTest {
val ast = OpenApiParser.parse(openApi)

assertEquals(Expected.objectInRequest, ast)
assertEquals(Expected.objectInRequest, ast)
}

@Test
Expand Down

0 comments on commit 6d484e5

Please sign in to comment.