Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion e2e/polymorphism/src/test/resources/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ info:
version: 0.1.9

servers:
- url: http://api.example.com/v1
- url: http://api.example.com:80/v1
description: Optional server description, e.g. Main (production) server
- url: http://172.0.0.1:8080/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa
private lateinit var securitySchemes: Map<String, SecurityScheme>
private var globalSecurityRequirements: List<String> = emptyList()

private val ignoreUnknownJson = Json {
ignoreUnknownKeys = true
}

override fun generate(schema: OpenApi3): List<FileSpec> {
processSecurity(schema)
val serversEnum = generateServersEnum(schema)
Expand All @@ -60,20 +64,6 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa
val pathTree = buildPathTree(schema.paths)
val clientSpecs = mutableListOf<FileSpec>()
pathTree.generateClients("", clientSpecs)
/*val clients = pathTree.children.map { node ->
val path = node.path.substringAfter('/')
val prefix = if (path.toIntOrNull() != null) {
// probably a version path (e.g. /3/...)
"v$path"
} else path

val allPaths = node.getAllPaths()
generateClientForPackagePrefix(schema, prefix, allPaths)
}*/
/*val clients = schema.paths.entries.groupBy { it.key.drop(1).substringBefore("/") }
.mapValues { (firstSegment, paths) ->
generateClientForPackagePrefix(schema, firstSegment, paths.associate { it.key to it.value})
}*/
return clientSpecs + serversEnum
}

Expand All @@ -88,9 +78,7 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa

private fun processSecurity(schema: OpenApi3) {
if (schema.securitySchemes.isNotEmpty()) {
securitySchemes = Json {
ignoreUnknownKeys = true
}.decodeFromString<Map<String, SecurityScheme>>(Overlay.of(schema.securitySchemes).toJson().toString())
securitySchemes = ignoreUnknownJson.decodeFromString<Map<String, SecurityScheme>>(Overlay.of(schema.securitySchemes).toJson().toString())
.mapValues { (_, scheme) ->
if (scheme is ApiKey && scheme.bearerFormat == "bearer") {
// Some strange syntax for defining bearer.
Expand All @@ -104,8 +92,13 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa

private fun generateServersEnum(schema: OpenApi3): FileSpec {
val enumNames = schema.servers.associateWith {
it.url.substringAfter("//").substringBefore("/")
it.url.substringAfter("//") // after scheme
.substringBefore("/") // before first slash = domain name with port
.substringBefore(":") // domain name without port
.split(".", "-").joinToString("_") { it.uppercase() }
.let { name ->
if (name.first().isDigit()) "IP_$name" else name
}
}
val enum = TypeSpec.enumBuilder(ClassName(packages.client, "Servers"))
.primaryConstructor(FunSpec.constructorBuilder().addParameter("url", String::class).build())
Expand Down Expand Up @@ -225,9 +218,7 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa
val funcSpecs: List<EndpointTools> = paths.flatMap { (pathString, path) ->
path.operations.map { (verb, operation) ->
val pathLevelSecurity = operation.securityRequirements.flatMap { it.requirements.keys }
val security = if (pathLevelSecurity.isEmpty())
globalSecurityRequirements
else pathLevelSecurity
val security = pathLevelSecurity.ifEmpty { globalSecurityRequirements }
val statusToResponseType = operation.responses.mapValues { (statusCode, response) ->
val resposneRef = Overlay.of(response).jsonReference
val responseModel = typeStore.getResponseMapping(TypeStore.PathId(pathString, verb))[statusCode.toInt()]?.type
Expand Down