diff --git a/e2e/polymorphism/src/test/resources/sample.yaml b/e2e/polymorphism/src/test/resources/sample.yaml index eea6eec..405e390 100644 --- a/e2e/polymorphism/src/test/resources/sample.yaml +++ b/e2e/polymorphism/src/test/resources/sample.yaml @@ -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 diff --git a/gradle-plugin/processor/src/main/kotlin/com/dshatz/openapi2ktor/generators/clients/KtorClientGenerator.kt b/gradle-plugin/processor/src/main/kotlin/com/dshatz/openapi2ktor/generators/clients/KtorClientGenerator.kt index 5fdb075..82ade73 100644 --- a/gradle-plugin/processor/src/main/kotlin/com/dshatz/openapi2ktor/generators/clients/KtorClientGenerator.kt +++ b/gradle-plugin/processor/src/main/kotlin/com/dshatz/openapi2ktor/generators/clients/KtorClientGenerator.kt @@ -39,6 +39,10 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa private lateinit var securitySchemes: Map private var globalSecurityRequirements: List = emptyList() + private val ignoreUnknownJson = Json { + ignoreUnknownKeys = true + } + override fun generate(schema: OpenApi3): List { processSecurity(schema) val serversEnum = generateServersEnum(schema) @@ -60,20 +64,6 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa val pathTree = buildPathTree(schema.paths) val clientSpecs = mutableListOf() 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 } @@ -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>(Overlay.of(schema.securitySchemes).toJson().toString()) + securitySchemes = ignoreUnknownJson.decodeFromString>(Overlay.of(schema.securitySchemes).toJson().toString()) .mapValues { (_, scheme) -> if (scheme is ApiKey && scheme.bearerFormat == "bearer") { // Some strange syntax for defining bearer. @@ -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()) @@ -225,9 +218,7 @@ class KtorClientGenerator(override val typeStore: TypeStore, val packages: Packa val funcSpecs: List = 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