Skip to content

Commit

Permalink
Merge branch 'misc-improvements' into pre-release-5-0-0
Browse files Browse the repository at this point in the history
  • Loading branch information
SMILEY4 committed Feb 5, 2025
2 parents a614516 + a91a551 commit b4a1046
Show file tree
Hide file tree
Showing 9 changed files with 426 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,6 @@ private fun Application.myModule() {
.withTitle(TitleType.SIMPLE)
.compileReferencingRoot()
}
overwrite<File>(Schema<Any>().also {
it.type = "string"
it.format = "binary"
})
}
examples {
example("Id 1") {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.smiley4.ktoropenapi.examples

import io.github.smiley4.ktoropenapi.OpenApi
import io.github.smiley4.ktoropenapi.config.SchemaGenerator
import io.github.smiley4.ktoropenapi.post
import io.github.smiley4.ktoropenapi.openApi
import io.github.smiley4.ktorredoc.redoc
Expand All @@ -14,7 +15,6 @@ import io.ktor.server.netty.Netty
import io.ktor.server.response.respond
import io.ktor.server.routing.route
import io.ktor.server.routing.routing
import io.swagger.v3.oas.models.media.Schema
import java.io.File

fun main() {
Expand All @@ -27,10 +27,9 @@ private fun Application.myModule() {
install(OpenApi) {
schemas {
// overwrite type "File" with custom schema for binary data
overwrite<File>(Schema<Any>().also {
it.type = "string"
it.format = "binary"
})
generator = SchemaGenerator.reflection {
overwrite(SchemaGenerator.TypeOverwrites.File())
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,14 @@ package io.github.smiley4.ktoropenapi.examples

import com.fasterxml.jackson.annotation.JsonSubTypes
import io.github.smiley4.ktoropenapi.OpenApi
import io.github.smiley4.ktoropenapi.config.SchemaGenerator
import io.github.smiley4.ktoropenapi.config.anyOf
import io.github.smiley4.ktoropenapi.config.array
import io.github.smiley4.ktoropenapi.config.ref
import io.github.smiley4.ktoropenapi.get
import io.github.smiley4.ktoropenapi.openApi
import io.github.smiley4.ktorredoc.redoc
import io.github.smiley4.ktorswaggerui.swaggerUI
import io.github.smiley4.schemakenerator.core.addMissingSupertypeSubtypeRelations
import io.github.smiley4.schemakenerator.jackson.collectJacksonSubTypes
import io.github.smiley4.schemakenerator.reflection.analyseTypeUsingReflection
import io.github.smiley4.schemakenerator.swagger.compileReferencingRoot
import io.github.smiley4.schemakenerator.swagger.data.TitleType
import io.github.smiley4.schemakenerator.swagger.generateSwaggerSchema
import io.github.smiley4.schemakenerator.swagger.withTitle
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.engine.embeddedServer
Expand Down Expand Up @@ -45,21 +39,10 @@ private fun Application.myModule() {
// add a type to the component section of the api spec with the id "type-schema"
schema<MySchemaClass>("type-schema")

// overwrite 'LocalDateTime' with custom schema (root only)
overwrite<LocalDateTime>(Schema<Any>().also {
it.title = "timestamp"
it.type = "integer"
})

// customized schema generation pipeline
generator = { type ->
type
.collectJacksonSubTypes(typeProcessing = { types -> types.analyseTypeUsingReflection() }) // include types from jackson subtype-annotation
.analyseTypeUsingReflection()
.addMissingSupertypeSubtypeRelations()
.generateSwaggerSchema()
.withTitle(TitleType.SIMPLE)
.compileReferencingRoot()
// customized schema generation
generator = SchemaGenerator.reflection {
// overwrite default schema generation with one specific for LocalDateTime that correctly handles "type" and "format"
overwrite(SchemaGenerator.TypeOverwrites.LocalDateTime())
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,9 @@ internal class SchemaContextImpl(private val schemaConfig: SchemaConfigData) : S
private fun generateSchema(typeDescriptor: TypeDescriptor): CompiledSwaggerSchema {
return when (typeDescriptor) {
is KTypeDescriptor -> {
if (schemaConfig.overwrite.containsKey(typeDescriptor.type)) {
generateSchema(schemaConfig.overwrite[typeDescriptor.type]!!)
} else {
generateSchema(typeDescriptor.type)
}
generateSchema(typeDescriptor.type)
}
is SerialTypeDescriptor -> {
// todo: support schemaConfig.overwrite
generateSchema(typeDescriptor.descriptor)
}
is SwaggerTypeDescriptor -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package io.github.smiley4.ktoropenapi.config

import io.github.smiley4.ktoropenapi.data.*
import io.github.smiley4.schemakenerator.core.data.AnnotationData
import io.github.smiley4.schemakenerator.core.data.InputType
import io.github.smiley4.schemakenerator.swagger.data.CompiledSwaggerSchema
import io.swagger.v3.oas.models.media.Schema
import kotlin.reflect.KType
import kotlin.reflect.typeOf
Expand All @@ -21,47 +18,6 @@ class SchemaConfig {

private val schemas = mutableMapOf<String, TypeDescriptor>()

private val overwrite = mutableMapOf<KType, TypeDescriptor>()


/**
* Overwrite the given [type] with the given [replacement].
* When the type is specified as the type of a schema, the replacement is used instead.
* This only works for "root"-types and not types of e.g. nested fields.
*/
fun overwrite(type: KType, replacement: TypeDescriptor) {
overwrite[type] = replacement
}

/**
* Overwrite the given type [T] with the given [replacement].
* When the type is specified as the type of a schema, the replacement is used instead.
* This only works for "root"-types and not types of e.g. nested fields.
*/
inline fun <reified T> overwrite(replacement: TypeDescriptor) = overwrite(typeOf<T>(), replacement)

/**
* Overwrite the given type [T] with the given [replacement].
* When the type is specified as the type of a schema, the replacement is used instead.
* This only works for "root"-types and not types of e.g. nested fields.
*/
inline fun <reified T> overwrite(replacement: Schema<*>) = overwrite(typeOf<T>(), SwaggerTypeDescriptor(replacement))

/**
* Overwrite the given type [T] with the given [replacement].
* When the type is specified as the type of a schema, the replacement is used instead.
* This only works for "root"-types and not types of e.g. nested fields.
*/
inline fun <reified T> overwrite(replacement: KType) = overwrite(typeOf<T>(), KTypeDescriptor(replacement))

/**
* Overwrite the given type [T] with the given replacement [R].
* When the type is specified as the type of a schema, the replacement is used instead.
* This only works for "root"-types and not types of e.g. nested fields.
*/
inline fun <reified T, reified R> overwrite() = overwrite(typeOf<T>(), KTypeDescriptor(typeOf<R>()))


/**
* Add a shared schema that can be referenced by all routes by the given id.
*/
Expand Down Expand Up @@ -91,7 +47,6 @@ class SchemaConfig {
internal fun build(securityConfig: SecurityData) = SchemaConfigData(
generator = generator,
schemas = schemas,
overwrite = overwrite,
securitySchemas = securityConfig.defaultUnauthorizedResponse?.body?.let { body ->
when (body) {
is SimpleBodyData -> listOf(body.type)
Expand Down
Loading

0 comments on commit b4a1046

Please sign in to comment.