All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
main.io.github.tabilzad.ktor.Utils.kt Maven / Gradle / Ivy
package io.github.tabilzad.ktor
import io.github.tabilzad.ktor.k2.ClassIds.TRANSIENT_ANNOTATION_FQ
import io.github.tabilzad.ktor.output.OpenApiSpec
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import java.io.OutputStream
fun Boolean.byFeatureFlag(flag: Boolean): Boolean = if (flag) {
this
} else {
true
}
@Deprecated("K1 only", replaceWith = ReplaceWith("ConeKotlinType.getMembers"))
internal fun MemberScope.forEachVariable(configuration: PluginConfiguration, predicate: (PropertyDescriptor) -> Unit) {
getDescriptorsFiltered(DescriptorKindFilter.VARIABLES)
.asSequence()
.map { it.original }
.filterIsInstance()
.filter {
it.isEffectivelyPublicApi.byFeatureFlag(configuration.hidePrivateFields)
}
.filter {
(!it.annotations.hasAnnotation(TRANSIENT_ANNOTATION_FQ)).byFeatureFlag(configuration.hideTransients)
}
.filter {
(!(it.backingField?.annotations?.hasAnnotation(TRANSIENT_ANNOTATION_FQ) == true
|| it.delegateField?.annotations?.hasAnnotation(TRANSIENT_ANNOTATION_FQ) == true
|| it.setter?.annotations?.hasAnnotation(TRANSIENT_ANNOTATION_FQ) == true
|| it.getter?.annotations?.hasAnnotation(TRANSIENT_ANNOTATION_FQ) == true
)
).byFeatureFlag(
configuration.hideTransients
)
}
.toList().forEach { predicate(it) }
}
internal val Iterable.names get() = mapNotNull { it.fqName }
fun String?.addLeadingSlash() = when {
this == null -> null
else -> if (this.startsWith("/")) this else "/$this"
}
internal fun reduce(e: DocRoute): List = e.children.flatMap { child ->
when (child) {
is DocRoute -> {
reduce(
child.copy(
path = e.path + child.path.addLeadingSlash(),
tags = e.tags merge child.tags
)
)
}
is EndPoint -> {
listOf(
KtorRouteSpec(
path = e.path + (child.path.addLeadingSlash() ?: ""),
method = child.method,
body = child.body ?: OpenApiSpec.ObjectType("object"),
summary = child.summary,
description = child.description,
parameters = child.parameters?.toList(),
responses = child.responses,
tags = e.tags merge child.tags
)
)
}
}
}
internal fun List.cleanPaths() = map {
it.copy(
path = it.path
.replace("//", "/")
.replace("?", "")
)
}
internal fun List.convertToSpec(): Map> = groupBy { it ->
it.path
}.mapValues { (key, value) ->
value.associate {
it.method to OpenApiSpec.Path(
summary = it.summary,
description = it.description,
tags = it.tags?.toList()?.sorted(),
parameters = addPathParams(it) merge addQueryParams(it),
requestBody = addPostBody(it),
responses = it.responses
)
}
}
infix fun List?.merge(params: List?): List? = this?.plus(params ?: emptyList()) ?: params
infix fun Set?.merge(params: Set?): Set? = this?.plus(params ?: emptyList()) ?: params
private fun addPathParams(spec: KtorRouteSpec): List? {
val params = "\\{([^}]*)}".toRegex().findAll(spec.path).toList()
return if (params.isNotEmpty()) {
params.mapNotNull {
val pathParamName = it.groups[1]?.value
if (pathParamName.isNullOrBlank() || spec.parameters
?.filterIsInstance()
?.any { it.name == pathParamName } == true
) {
spec.parameters?.find { it.name == pathParamName }?.let {
OpenApiSpec.PathParam(
name = it.name,
`in` = "path",
required = pathParamName?.contains("?") != true,
schema = OpenApiSpec.SchemaType("string"),
description = it.description
)
}
} else {
OpenApiSpec.PathParam(
name = pathParamName.replace("?", ""),
`in` = "path",
required = !pathParamName.contains("?"),
schema = OpenApiSpec.SchemaType("string")
)
}
}
} else {
null
}
}
private fun addQueryParams(it: KtorRouteSpec): List? {
return it.parameters?.filterIsInstance()?.map {
OpenApiSpec.PathParam(
name = it.name,
`in` = "query",
required = it.isRequired,
schema = OpenApiSpec.SchemaType("string"),
description = it.description
)
}
}
private fun addPostBody(it: KtorRouteSpec): OpenApiSpec.RequestBody? {
return if (it.method != "get" && it.body.contentBodyRef != null) {
OpenApiSpec.RequestBody(
required = true,
content = mapOf(
ContentType.APPLICATION_JSON to mapOf(
"schema" to OpenApiSpec.SchemaType(
`$ref` = "${it.body.contentBodyRef}"
)
)
)
)
} else if (it.method != "get" && it.body.isPrimitive()) {
OpenApiSpec.RequestBody(
required = true,
content = mapOf(
ContentType.TEXT_PLAIN to mapOf(
"schema" to OpenApiSpec.SchemaType(
type = "${it.body.type}"
)
)
)
)
} else {
null
}
}
private fun OpenApiSpec.ObjectType.isPrimitive() = listOf("string", "number", "integer").contains(type)
internal fun CompilerConfiguration?.buildPluginConfiguration(): PluginConfiguration = PluginConfiguration.createDefault(
isEnabled = this?.get(SwaggerConfigurationKeys.ARG_ENABLED),
format = this?.get(SwaggerConfigurationKeys.ARG_FORMAT),
title = this?.get(SwaggerConfigurationKeys.ARG_TITLE),
description = this?.get(SwaggerConfigurationKeys.ARG_DESCR),
version = this?.get(SwaggerConfigurationKeys.ARG_VER),
filePath = this?.get(SwaggerConfigurationKeys.ARG_PATH),
requestBody = this?.get(SwaggerConfigurationKeys.ARG_REQUEST_FEATURE),
hideTransients = this?.get(SwaggerConfigurationKeys.ARG_HIDE_TRANSIENTS),
hidePrivateFields = this?.get(SwaggerConfigurationKeys.ARG_HIDE_PRIVATE),
deriveFieldRequirementFromTypeNullability = this?.get(SwaggerConfigurationKeys.ARG_DERIVE_PROP_REQ),
servers = this?.get(SwaggerConfigurationKeys.ARG_SERVERS) ?: emptyList()
)
operator fun OutputStream.plusAssign(str: String) {
this.write(str.toByteArray())
}