Compare commits

..

19 Commits

Author SHA1 Message Date
9364fb19e4 chore: prep for 3.14.0 release 2023-04-06 15:49:07 -04:00
ca1f632665 feat: Introduce Support for Response Headers (#446) 2023-04-06 19:47:48 +00:00
9bb3184735 docs: add showcase link to readme 2023-04-03 19:44:42 -04:00
9a139b5713 chore(deps): update plugin org.jetbrains.kotlin.plugin.serialization to v1.8.20 (#440)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 10:54:36 -04:00
9861c8e258 chore(deps): update plugin org.jetbrains.kotlin.jvm to v1.8.20 (#439)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 13:10:37 +00:00
02f8ed04f2 fix(deps): update dependency dev.forst:ktor-api-key to v2.2.4 (#442)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-03 12:54:06 +00:00
3e23939386 fix(deps): update dependency joda-time:joda-time to v2.12.5 (#441)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-31 00:21:18 +00:00
d0575944db fix(deps): update dependency org.jetbrains.kotlin:kotlin-reflect to v1.8.20 (#438)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-30 11:17:39 +00:00
ccc81c2813 fix(deps): update dependency joda-time:joda-time to v2.12.4 (#436)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-24 10:20:45 +00:00
e8da52fd75 fix(deps): update dependency joda-time:joda-time to v2.12.3 (#435)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-23 12:49:37 +00:00
34c14e26da fix(deps): update dependency org.slf4j:slf4j-simple to v2.0.7 (#434)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-18 01:17:47 +00:00
209b5e38a3 fix(deps): update dependency org.slf4j:slf4j-api to v2.0.7 (#433)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-17 23:50:21 +00:00
902faa9471 fix(deps): update dependency io.gitlab.arturbosch.detekt:detekt-formatting to v1.22.0 (#388) 2023-03-16 12:53:15 +00:00
c7ef70a844 fix(deps): update dependency org.jetbrains.kotlinx:kotlinx-serialization-json to v1.5.0 (#432)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 12:25:44 +00:00
f83c3d203d fix(deps): update ktor to v2.2.4 (#430)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 10:38:18 +00:00
bd05dbcfcb chore(deps): update plugin io.github.gradle-nexus.publish-plugin to v1.3.0 (#431)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 08:48:23 +00:00
cb5c0e71a3 fix(deps): update dependency com.google.protobuf:protobuf-java to v3.22.2 (#429)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 08:45:44 +00:00
a209cafa74 chore(deps): update dependency gradle to v7.6.1 (#428)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-16 07:27:45 +00:00
3d27d30a31 feat: support no request body for post, put and patch (#427) 2023-03-15 12:39:35 +00:00
29 changed files with 333 additions and 53 deletions

View File

@ -12,6 +12,18 @@
## Released
## [3.14.0] - April 6th, 2023
### Added
- Add support for response headers
## [3.13.0] - March 15th, 2023
### Changed
- Post, Put, and Patch now support not providing request info
## [3.12.0] - March 14th, 2023
### Added

View File

@ -3,3 +3,7 @@
[![version](https://img.shields.io/maven-central/v/io.bkbn/kompendium-core?style=flat-square)](https://search.maven.org/search?q=io.bkbn%20kompendium)
Documentation is stored in the `docs` folder and is hosted [here](https://bkbn.gitbook.io/kompendium)
## Showcase
If you would like to showcase docs that you build using Kompendium, add them to [the showcase discussion](https://github.com/bkbnio/kompendium/discussions/444)

View File

@ -1,12 +1,12 @@
plugins {
kotlin("jvm") version "1.8.10" apply false
kotlin("plugin.serialization") version "1.8.10" apply false
kotlin("jvm") version "1.8.20" apply false
kotlin("plugin.serialization") version "1.8.20" apply false
id("io.bkbn.sourdough.library.jvm") version "0.12.0" apply false
id("io.bkbn.sourdough.application.jvm") version "0.12.0" apply false
id("io.bkbn.sourdough.root") version "0.12.0"
id("com.github.jakemarsden.git-hooks") version "0.0.2"
id("org.jetbrains.kotlinx.kover") version "0.6.1"
id("io.github.gradle-nexus.publish-plugin") version "1.2.0"
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
}
gitHooks {

View File

@ -57,9 +57,9 @@ dependencies {
testFixturesApi("io.ktor:ktor-client:$ktorVersion")
testFixturesApi("io.ktor:ktor-client-cio:$ktorVersion")
testFixturesApi("dev.forst:ktor-api-key:2.2.2")
testFixturesApi("dev.forst:ktor-api-key:2.2.4")
testFixturesApi("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
testFixturesApi("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
}
testing {

View File

@ -1,7 +1,7 @@
package io.bkbn.kompendium.core.metadata
sealed interface MethodInfoWithRequest : MethodInfo {
val request: RequestInfo
val request: RequestInfo?
abstract class Builder<T : MethodInfoWithRequest> : MethodInfo.Builder<T>() {
internal var request: RequestInfo? = null

View File

@ -4,7 +4,7 @@ import io.bkbn.kompendium.oas.common.ExternalDocumentation
import io.bkbn.kompendium.oas.payload.Parameter
class PatchInfo private constructor(
override val request: RequestInfo,
override val request: RequestInfo?,
override val errors: MutableList<ResponseInfo>,
override val response: ResponseInfo,
override val tags: Set<String>,
@ -26,7 +26,7 @@ class PatchInfo private constructor(
class Builder : MethodInfoWithRequest.Builder<PatchInfo>() {
override fun build() = PatchInfo(
request = request ?: error("request info must be present"),
request = request,
errors = errors,
response = response ?: error("response info must be present"),
tags = tags,

View File

@ -4,7 +4,7 @@ import io.bkbn.kompendium.oas.common.ExternalDocumentation
import io.bkbn.kompendium.oas.payload.Parameter
class PostInfo private constructor(
override val request: RequestInfo,
override val request: RequestInfo?,
override val errors: MutableList<ResponseInfo>,
override val response: ResponseInfo,
override val tags: Set<String>,
@ -26,7 +26,7 @@ class PostInfo private constructor(
class Builder : MethodInfoWithRequest.Builder<PostInfo>() {
override fun build() = PostInfo(
request = request ?: error("request info must be present"),
request = request,
errors = errors,
response = response ?: error("response info must be present"),
tags = tags,

View File

@ -4,7 +4,7 @@ import io.bkbn.kompendium.oas.common.ExternalDocumentation
import io.bkbn.kompendium.oas.payload.Parameter
class PutInfo private constructor(
override val request: RequestInfo,
override val request: RequestInfo?,
override val errors: MutableList<ResponseInfo>,
override val response: ResponseInfo,
override val tags: Set<String>,
@ -26,7 +26,7 @@ class PutInfo private constructor(
class Builder : MethodInfoWithRequest.Builder<PutInfo>() {
override fun build() = PutInfo(
request = request ?: error("request info must be present"),
request = request,
errors = errors,
response = response ?: error("response info must be present"),
tags = tags,

View File

@ -1,6 +1,7 @@
package io.bkbn.kompendium.core.metadata
import io.bkbn.kompendium.enrichment.TypeEnrichment
import io.bkbn.kompendium.oas.payload.Header
import io.bkbn.kompendium.oas.payload.MediaType
import io.ktor.http.HttpStatusCode
import kotlin.reflect.KType
@ -12,7 +13,8 @@ class ResponseInfo private constructor(
val typeEnrichment: TypeEnrichment<*>?,
val description: String,
val examples: Map<String, MediaType.Example>?,
val mediaTypes: Set<String>
val mediaTypes: Set<String>,
val responseHeaders: Map<String, Header>?
) {
companion object {
@ -30,6 +32,11 @@ class ResponseInfo private constructor(
private var description: String? = null
private var examples: Map<String, MediaType.Example>? = null
private var mediaTypes: Set<String>? = null
private var responseHeaders: Map<String, Header>? = null
fun responseHeaders(headers: Map<String, Header>) = apply {
this.responseHeaders = headers
}
fun responseCode(code: HttpStatusCode) = apply {
this.responseCode = code
@ -64,7 +71,8 @@ class ResponseInfo private constructor(
description = description ?: error("You must provide a description in order to build a Response!"),
typeEnrichment = typeEnrichment,
examples = examples,
mediaTypes = mediaTypes ?: setOf("application/json")
mediaTypes = mediaTypes ?: setOf("application/json"),
responseHeaders = responseHeaders
)
}
}

View File

@ -72,13 +72,15 @@ object Helpers {
when (this) {
is MethodInfoWithRequest -> {
SchemaGenerator.fromTypeOrUnit(
type = this.request.requestType,
cache = spec.components.schemas,
schemaConfigurator = schemaConfigurator,
enrichment = this.request.typeEnrichment,
)?.let { schema ->
spec.components.schemas[this.request.requestType.getSlug(this.request.typeEnrichment)] = schema
this.request?.let { reqInfo ->
SchemaGenerator.fromTypeOrUnit(
type = reqInfo.requestType,
cache = spec.components.schemas,
schemaConfigurator = schemaConfigurator,
enrichment = reqInfo.typeEnrichment,
)?.let { schema ->
spec.components.schemas[reqInfo.requestType.getSlug(reqInfo.typeEnrichment)] = schema
}
}
}
@ -121,21 +123,24 @@ object Helpers {
?.map { listOf(it).toMap() }
?.toMutableList(),
requestBody = when (this) {
is MethodInfoWithRequest -> Request(
description = this.request.description,
content = this.request.requestType.toReferenceContent(
examples = this.request.examples,
mediaTypes = this.request.mediaTypes,
enrichment = this.request.typeEnrichment
),
required = true
)
is MethodInfoWithRequest -> this.request?.let { reqInfo ->
Request(
description = reqInfo.description,
content = reqInfo.requestType.toReferenceContent(
examples = reqInfo.examples,
mediaTypes = reqInfo.mediaTypes,
enrichment = reqInfo.typeEnrichment
),
required = true
)
}
else -> null
},
responses = mapOf(
this.response.responseCode.value to Response(
description = this.response.description,
headers = this.response.responseHeaders,
content = this.response.responseType.toReferenceContent(
examples = this.response.examples,
mediaTypes = this.response.mediaTypes,
@ -148,6 +153,7 @@ object Helpers {
private fun List<ResponseInfo>.toResponseMap(): Map<Int, Response> = associate { error ->
error.responseCode.value to Response(
description = error.description,
headers = error.responseHeaders,
content = error.responseType.toReferenceContent(
examples = error.examples,
mediaTypes = error.mediaTypes,

View File

@ -48,9 +48,11 @@ import io.bkbn.kompendium.core.util.polymorphicCollectionResponse
import io.bkbn.kompendium.core.util.polymorphicException
import io.bkbn.kompendium.core.util.polymorphicMapResponse
import io.bkbn.kompendium.core.util.polymorphicResponse
import io.bkbn.kompendium.core.util.postNoReqBody
import io.bkbn.kompendium.core.util.primitives
import io.bkbn.kompendium.core.util.reqRespExamples
import io.bkbn.kompendium.core.util.requiredParams
import io.bkbn.kompendium.core.util.responseHeaders
import io.bkbn.kompendium.core.util.returnsList
import io.bkbn.kompendium.core.util.rootRoute
import io.bkbn.kompendium.core.util.samePathDifferentMethodsAndAuth
@ -129,6 +131,12 @@ class KompendiumTest : DescribeSpec({
it("Can override media types") {
openApiTestAllSerializers("T0052__override_media_types.json") { overrideMediaTypes() }
}
it("Can support a post request with no request body") {
openApiTestAllSerializers("T0065__post_no_req_body.json") { postNoReqBody() }
}
it("Can notarize a route with response headers") {
openApiTestAllSerializers("T0066__notarized_get_with_response_headers.json") { responseHeaders() }
}
}
describe("Route Parsing") {
it("Can parse a simple path and store it under the expected route") {

View File

@ -20,7 +20,9 @@ import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
import io.bkbn.kompendium.core.util.TestModules.rootPath
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
import io.bkbn.kompendium.oas.payload.Header
import io.bkbn.kompendium.oas.payload.Parameter
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.call
import io.ktor.server.application.install
@ -56,6 +58,38 @@ fun Routing.notarizedGet() {
}
}
fun Routing.responseHeaders() {
route(defaultPath) {
install(NotarizedRoute()) {
parameters = defaultParams
get = GetInfo.builder {
response {
responseCode(HttpStatusCode.OK)
responseType<TestResponse>()
description(defaultResponseDescription)
responseHeaders(
mapOf(
HttpHeaders.ETag to Header(
TypeDefinition.STRING,
"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag"
),
HttpHeaders.LastModified to Header(
TypeDefinition.STRING,
"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified"
),
)
)
}
summary(defaultPathSummary)
description(defaultPathDescription)
}
}
get {
call.respondText { "hey dude ‼️ congrats on the get request" }
}
}
}
fun Routing.notarizedPost() {
route(defaultPath) {
install(NotarizedRoute()) {
@ -299,3 +333,19 @@ fun Routing.overrideMediaTypes() {
}
}
}
fun Routing.postNoReqBody() {
route("/no_req_body") {
install(NotarizedRoute()) {
post = PostInfo.builder {
summary(defaultPathSummary)
description(defaultPathDescription)
response {
responseType<TestResponse>()
description("Cool response")
responseCode(HttpStatusCode.Created)
}
}
}
}
}

View File

@ -0,0 +1,72 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/no_req_body": {
"post": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"responses": {
"201": {
"description": "Cool response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TestResponse"
}
}
}
}
},
"deprecated": false
},
"parameters": []
}
},
"webhooks": {},
"components": {
"schemas": {
"TestResponse": {
"type": "object",
"properties": {
"c": {
"type": "string"
}
},
"required": [
"c"
]
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}

View File

@ -0,0 +1,110 @@
{
"openapi": "3.1.0",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "Test API",
"version": "1.33.7",
"description": "An amazing, fully-ish 😉 generated API spec",
"termsOfService": "https://example.com",
"contact": {
"name": "Homer Simpson",
"url": "https://gph.is/1NPUDiM",
"email": "chunkylover53@aol.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
}
},
"servers": [
{
"url": "https://myawesomeapi.com",
"description": "Production instance of my API"
},
{
"url": "https://staging.myawesomeapi.com",
"description": "Where the fun stuff happens"
}
],
"paths": {
"/test/{a}": {
"get": {
"tags": [],
"summary": "Great Summary!",
"description": "testing more",
"parameters": [],
"responses": {
"200": {
"description": "A Successful Endeavor",
"headers": {
"ETag": {
"schema": {
"type": "string"
},
"description": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag",
"required": true,
"deprecated": false
},
"Last-Modified": {
"schema": {
"type": "string"
},
"description": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified",
"required": true,
"deprecated": false
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TestResponse"
}
}
}
}
},
"deprecated": false
},
"parameters": [
{
"name": "a",
"in": "path",
"schema": {
"type": "string"
},
"required": true,
"deprecated": false
},
{
"name": "aa",
"in": "query",
"schema": {
"type": "number",
"format": "int32"
},
"required": true,
"deprecated": false
}
]
}
},
"webhooks": {},
"components": {
"schemas": {
"TestResponse": {
"type": "object",
"properties": {
"c": {
"type": "string"
}
},
"required": [
"c"
]
}
},
"securitySchemes": {}
},
"security": [],
"tags": []
}

View File

@ -22,6 +22,8 @@ formatting:
indentSize: 2
ImportOrdering:
active: false
EnumEntryNameCase:
active: false
naming:
ConstructorParameterNaming:
active: false

View File

@ -1,5 +1,5 @@
# Kompendium
project.version=3.12.0
project.version=3.14.0
# Kotlin
kotlin.code.style=official
# Gradle
@ -9,6 +9,6 @@ org.gradle.jvmargs=-Xmx2000m
org.gradle.parallel=true
# Dependencies
ktorVersion=2.2.3
ktorVersion=2.2.4
kotestVersion=5.5.5
detektVersion=1.21.0
detektVersion=1.22.0

Binary file not shown.

View File

@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

12
gradlew vendored
View File

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -80,10 +80,10 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
@ -143,12 +143,16 @@ fi
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac

1
gradlew.bat vendored
View File

@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

View File

@ -23,8 +23,8 @@ dependencies {
// Kompendium
api(projects.kompendiumEnrichment)
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.20")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
// Formatting
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:$detektVersion")

View File

@ -34,7 +34,6 @@ object SimpleObjectHandler {
schemaConfigurator: SchemaConfigurator,
enrichment: TypeEnrichment<*>?,
): JsonSchema {
cache[type.getSlug(enrichment)] = ReferenceDefinition(type.getReferenceSlug(enrichment))
val typeMap = clazz.typeParameters.zip(type.arguments).toMap()
@ -176,6 +175,7 @@ object SimpleObjectHandler {
maxItems = maxItems,
uniqueItems = uniqueItems,
)
is EnumDefinition -> schema.copy(deprecated = deprecated, description = description)
is MapDefinition -> schema.copy(deprecated = deprecated, description = description)
is NullableDefinition -> schema.copy(deprecated = deprecated, description = description)

View File

@ -22,8 +22,8 @@ dependencies {
// IMPLEMENTATION
implementation(projects.kompendiumCore)
implementation("io.ktor:ktor-server-core:2.2.3")
implementation("io.ktor:ktor-server-locations:2.2.3")
implementation("io.ktor:ktor-server-core:2.2.4")
implementation("io.ktor:ktor-server-locations:2.2.4")
// TESTING

View File

@ -7,6 +7,7 @@ data class Listing(val name: String, val page: Int)
data class Type(val name: String) {
@Location("/edit")
data class Edit(val parent: Type)
@Location("/other/{page}")
data class Other(val parent: Type, val page: Int)
}

View File

@ -22,7 +22,7 @@ dependencies {
api(projects.kompendiumJsonSchema)
api(projects.kompendiumEnrichment)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
// Formatting
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:$detektVersion")

View File

@ -37,12 +37,12 @@ dependencies {
implementation("org.apache.logging.log4j:log4j-api-kotlin:1.2.0")
implementation("org.apache.logging.log4j:log4j-api:2.20.0")
implementation("org.apache.logging.log4j:log4j-core:2.20.0")
implementation("org.slf4j:slf4j-api:2.0.6")
implementation("org.slf4j:slf4j-simple:2.0.6")
implementation("org.slf4j:slf4j-api:2.0.7")
implementation("org.slf4j:slf4j-simple:2.0.7")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
implementation("joda-time:joda-time:2.12.2")
implementation("joda-time:joda-time:2.12.5")
}

View File

@ -22,9 +22,9 @@ dependencies {
implementation(projects.kompendiumJsonSchema)
implementation("com.google.protobuf:protobuf-java:3.22.0")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("com.google.protobuf:protobuf-java:3.22.2")
implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.20")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
// Formatting
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:$detektVersion")

View File

@ -22,8 +22,8 @@ dependencies {
// IMPLEMENTATION
implementation(projects.kompendiumCore)
implementation("io.ktor:ktor-server-core:2.2.3")
implementation("io.ktor:ktor-server-resources:2.2.3")
implementation("io.ktor:ktor-server-core:2.2.4")
implementation("io.ktor:ktor-server-resources:2.2.4")
// TESTING

View File

@ -11,6 +11,7 @@ data class Type(val name: String) {
@Serializable
@Resource("/edit")
data class Edit(val parent: Type)
@Serializable
@Resource("/other/{page}")
data class Other(val parent: Type, val page: Int)