added explicit path calculator interface (#31)
This commit is contained in:
@ -31,7 +31,8 @@ import org.leafygreens.kompendium.models.oas.OpenApiSpecReferenceObject
|
||||
import org.leafygreens.kompendium.models.oas.OpenApiSpecRequest
|
||||
import org.leafygreens.kompendium.models.oas.OpenApiSpecResponse
|
||||
import org.leafygreens.kompendium.models.oas.OpenApiSpecSchemaRef
|
||||
import org.leafygreens.kompendium.util.Helpers.calculatePath
|
||||
import org.leafygreens.kompendium.path.CorePathCalculator
|
||||
import org.leafygreens.kompendium.path.PathCalculator
|
||||
import org.leafygreens.kompendium.util.Helpers.getReferenceSlug
|
||||
|
||||
object Kompendium {
|
||||
@ -44,12 +45,14 @@ object Kompendium {
|
||||
paths = mutableMapOf()
|
||||
)
|
||||
|
||||
var pathCalculator: PathCalculator = CorePathCalculator()
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
inline fun <reified TParam : Any, reified TResp : Any> Route.notarizedGet(
|
||||
info: MethodInfo,
|
||||
noinline body: PipelineInterceptor<Unit, ApplicationCall>
|
||||
): Route = notarizationPreFlight<TParam, Unit, TResp>() { paramType, requestType, responseType ->
|
||||
val path = calculatePath()
|
||||
val path = pathCalculator.calculate(this)
|
||||
openApiSpec.paths.getOrPut(path) { OpenApiSpecPathItem() }
|
||||
openApiSpec.paths[path]?.get = info.parseMethodInfo(HttpMethod.Get, paramType, requestType, responseType)
|
||||
return method(HttpMethod.Get) { handle(body) }
|
||||
@ -59,7 +62,7 @@ object Kompendium {
|
||||
info: MethodInfo,
|
||||
noinline body: PipelineInterceptor<Unit, ApplicationCall>
|
||||
): Route = notarizationPreFlight<TParam, TReq, TResp>() { paramType, requestType, responseType ->
|
||||
val path = calculatePath()
|
||||
val path = pathCalculator.calculate(this)
|
||||
openApiSpec.paths.getOrPut(path) { OpenApiSpecPathItem() }
|
||||
openApiSpec.paths[path]?.post = info.parseMethodInfo(HttpMethod.Post, paramType, requestType, responseType)
|
||||
return method(HttpMethod.Post) { handle(body) }
|
||||
@ -69,7 +72,7 @@ object Kompendium {
|
||||
info: MethodInfo,
|
||||
noinline body: PipelineInterceptor<Unit, ApplicationCall>,
|
||||
): Route = notarizationPreFlight<TParam, TReq, TResp>() { paramType, requestType, responseType ->
|
||||
val path = calculatePath()
|
||||
val path = pathCalculator.calculate(this)
|
||||
openApiSpec.paths.getOrPut(path) { OpenApiSpecPathItem() }
|
||||
openApiSpec.paths[path]?.put = info.parseMethodInfo(HttpMethod.Put, paramType, requestType, responseType)
|
||||
return method(HttpMethod.Put) { handle(body) }
|
||||
@ -79,7 +82,7 @@ object Kompendium {
|
||||
info: MethodInfo,
|
||||
noinline body: PipelineInterceptor<Unit, ApplicationCall>
|
||||
): Route = notarizationPreFlight<TParam, Unit, TResp> { paramType, requestType, responseType ->
|
||||
val path = calculatePath()
|
||||
val path = pathCalculator.calculate(this)
|
||||
openApiSpec.paths.getOrPut(path) { OpenApiSpecPathItem() }
|
||||
openApiSpec.paths[path]?.delete = info.parseMethodInfo(HttpMethod.Delete, paramType, requestType, responseType)
|
||||
return method(HttpMethod.Delete) { handle(body) }
|
||||
|
@ -0,0 +1,48 @@
|
||||
package org.leafygreens.kompendium.path
|
||||
|
||||
import io.ktor.routing.PathSegmentConstantRouteSelector
|
||||
import io.ktor.routing.PathSegmentParameterRouteSelector
|
||||
import io.ktor.routing.RootRouteSelector
|
||||
import io.ktor.routing.Route
|
||||
import io.ktor.util.InternalAPI
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
open class CorePathCalculator : PathCalculator {
|
||||
|
||||
private val logger = LoggerFactory.getLogger(javaClass)
|
||||
|
||||
@OptIn(InternalAPI::class)
|
||||
override fun calculate(
|
||||
route: Route?,
|
||||
tail: String
|
||||
): String = when (route) {
|
||||
null -> tail
|
||||
else -> when (route.selector) {
|
||||
is RootRouteSelector -> {
|
||||
logger.debug("Root route detected, returning path: $tail")
|
||||
tail
|
||||
}
|
||||
is PathSegmentParameterRouteSelector -> {
|
||||
logger.debug("Found segment parameter ${route.selector}, continuing to parent")
|
||||
val newTail = "/${route.selector}$tail"
|
||||
calculate(route.parent, newTail)
|
||||
}
|
||||
is PathSegmentConstantRouteSelector -> {
|
||||
logger.debug("Found segment constant ${route.selector}, continuing to parent")
|
||||
val newTail = "/${route.selector}$tail"
|
||||
calculate(route.parent, newTail)
|
||||
}
|
||||
else -> when (route.selector.javaClass.simpleName) {
|
||||
"TrailingSlashRouteSelector" -> {
|
||||
logger.debug("Found trailing slash route selector")
|
||||
val newTail = tail.ifBlank { "/" }
|
||||
calculate(route.parent, newTail)
|
||||
}
|
||||
else -> handleCustomSelectors(route, tail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleCustomSelectors(route: Route, tail: String): String = error("Unknown selector ${route.selector}")
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.leafygreens.kompendium.path
|
||||
|
||||
import io.ktor.routing.Route
|
||||
|
||||
interface PathCalculator {
|
||||
|
||||
fun calculate(route: Route?, tail: String = ""): String
|
||||
|
||||
fun handleCustomSelectors(route: Route, tail: String): String
|
||||
|
||||
}
|
@ -18,47 +18,6 @@ object Helpers {
|
||||
|
||||
const val COMPONENT_SLUG = "#/components/schemas"
|
||||
|
||||
/**
|
||||
* TODO Explain this
|
||||
*/
|
||||
@OptIn(InternalAPI::class)
|
||||
fun Route.calculatePath(tail: String = ""): String {
|
||||
logger.info("Building path for ${selector::class}")
|
||||
return when (selector) {
|
||||
is RootRouteSelector -> {
|
||||
logger.info("Root route detected, returning path: $tail")
|
||||
tail
|
||||
}
|
||||
is PathSegmentParameterRouteSelector -> {
|
||||
logger.info("Found segment parameter $selector, continuing to parent")
|
||||
val newTail = "/$selector$tail"
|
||||
parent?.calculatePath(newTail) ?: run {
|
||||
logger.info("No parent found, returning current path")
|
||||
newTail
|
||||
}
|
||||
}
|
||||
is PathSegmentConstantRouteSelector -> {
|
||||
logger.info("Found segment constant $selector, continuing to parent")
|
||||
val newTail = "/$selector$tail"
|
||||
parent?.calculatePath(newTail) ?: run {
|
||||
logger.info("No parent found, returning current path")
|
||||
newTail
|
||||
}
|
||||
}
|
||||
else -> when (selector.javaClass.simpleName) {
|
||||
// dumb ass workaround to this object being internal to ktor
|
||||
"TrailingSlashRouteSelector" -> {
|
||||
logger.info("Found trailing slash route selector")
|
||||
val newTail = tail.ifBlank { "/" }
|
||||
parent?.calculatePath(newTail) ?: run {
|
||||
logger.info("No parent found, returning current path")
|
||||
newTail
|
||||
}
|
||||
}
|
||||
else -> error("Unhandled selector type ${selector::class}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple extension function that will take a [Pair] and place it (if absent) into a [MutableMap].
|
||||
|
Reference in New Issue
Block a user