Skip to content

Commit

Permalink
Merge pull request #62 from Giuliopime/develop
Browse files Browse the repository at this point in the history
feat: external documentation support
  • Loading branch information
SMILEY4 authored Aug 29, 2023
2 parents e297573 + 5e4ca3e commit e7c937a
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 79 deletions.
2 changes: 1 addition & 1 deletion config/detekt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,6 @@ style:
active: true
ignoreLateinitVar: false
WildcardImport:
active: true
active: false
excludeImports:
- 'java.util.*'
42 changes: 7 additions & 35 deletions src/main/kotlin/io/github/smiley4/ktorswaggerui/SwaggerPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,51 +1,22 @@
package io.github.smiley4.ktorswaggerui

import com.fasterxml.jackson.databind.ObjectMapper
import io.github.smiley4.ktorswaggerui.dsl.SchemaType
import io.github.smiley4.ktorswaggerui.dsl.getSchemaType
import io.github.smiley4.ktorswaggerui.spec.example.ExampleContext
import io.github.smiley4.ktorswaggerui.spec.example.ExampleContextBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ComponentsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ContactBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ContentBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ExampleBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ExternalDocumentationBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.HeaderBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.InfoBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.LicenseBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OAuthFlowsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OpenApiBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OperationBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OperationTagsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ParameterBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.PathBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.PathsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.RequestBodyBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ResponseBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ResponsesBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.SecurityRequirementsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.SecuritySchemesBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ServerBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.TagBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.*
import io.github.smiley4.ktorswaggerui.spec.route.RouteCollector
import io.github.smiley4.ktorswaggerui.spec.route.RouteDocumentationMerger
import io.github.smiley4.ktorswaggerui.spec.route.RouteMeta
import io.github.smiley4.ktorswaggerui.spec.schema.SchemaBuilder
import io.github.smiley4.ktorswaggerui.spec.schema.SchemaContext
import io.github.smiley4.ktorswaggerui.spec.schema.SchemaContextBuilder
import io.github.smiley4.ktorswaggerui.spec.schema.TypeOverwrites
import io.ktor.server.application.Application
import io.ktor.server.application.ApplicationStarted
import io.ktor.server.application.createApplicationPlugin
import io.ktor.server.application.hooks.MonitoringEvent
import io.ktor.server.application.install
import io.ktor.server.application.plugin
import io.ktor.server.application.pluginOrNull
import io.ktor.server.routing.Routing
import io.ktor.server.webjars.Webjars
import io.ktor.server.application.*
import io.ktor.server.application.hooks.*
import io.ktor.server.routing.*
import io.ktor.server.webjars.*
import io.swagger.v3.core.util.Json
import mu.KotlinLogging
import java.io.File

/**
* This version must match the version of the gradle dependency
Expand Down Expand Up @@ -112,9 +83,10 @@ private fun builder(config: SwaggerUIPluginConfig, schemaContext: SchemaContext,
contactBuilder = ContactBuilder(),
licenseBuilder = LicenseBuilder()
),
externalDocumentationBuilder = ExternalDocumentationBuilder(),
serverBuilder = ServerBuilder(),
tagBuilder = TagBuilder(
externalDocumentationBuilder = ExternalDocumentationBuilder()
tagExternalDocumentationBuilder = TagExternalDocumentationBuilder()
),
pathsBuilder = PathsBuilder(
pathBuilder = PathBuilder(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
package io.github.smiley4.ktorswaggerui

import io.github.smiley4.ktorswaggerui.dsl.CustomSchemas
import io.github.smiley4.ktorswaggerui.dsl.EncodingConfig
import io.github.smiley4.ktorswaggerui.dsl.OpenApiDslMarker
import io.github.smiley4.ktorswaggerui.dsl.OpenApiInfo
import io.github.smiley4.ktorswaggerui.dsl.OpenApiResponse
import io.github.smiley4.ktorswaggerui.dsl.OpenApiSecurityScheme
import io.github.smiley4.ktorswaggerui.dsl.OpenApiServer
import io.github.smiley4.ktorswaggerui.dsl.OpenApiTag
import io.github.smiley4.ktorswaggerui.dsl.SwaggerUIDsl
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.server.routing.RouteSelector
import io.github.smiley4.ktorswaggerui.dsl.*
import io.ktor.http.*
import io.ktor.server.routing.*
import kotlin.reflect.KClass

/**
Expand Down Expand Up @@ -101,6 +92,18 @@ class SwaggerUIPluginConfig {
fun getServers(): List<OpenApiServer> = servers


/**
* OpenAPI external docs configuration - link and description of an external documentation
*/
fun externalDocs(block: OpenApiExternalDocs.() -> Unit) {
externalDocs = OpenApiExternalDocs().apply(block)
}

private var externalDocs = OpenApiExternalDocs()

fun getExternalDocs() = externalDocs


/**
* Defines security schemes that can be used by operations
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.smiley4.ktorswaggerui.dsl

/**
* An object representing external documentation.
*/
@OpenApiDslMarker
class OpenApiExternalDocs {
/**
* A short description of the external documentation
*/
var description: String? = null

/**
* A URL to the external documentation
*/
var url: String = "/"
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package io.github.smiley4.ktorswaggerui.spec.openapi

import io.github.smiley4.ktorswaggerui.dsl.OpenApiExternalDocs
import io.swagger.v3.oas.models.ExternalDocumentation


class ExternalDocumentationBuilder {

fun build(url: String, description: String): ExternalDocumentation =
fun build(externalDocs: OpenApiExternalDocs): ExternalDocumentation =
ExternalDocumentation().also {
it.url = url
it.description = description
it.url = externalDocs.url
it.description = externalDocs.description
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class OpenApiBuilder(
private val schemaContext: SchemaContext,
private val exampleContext: ExampleContext,
private val infoBuilder: InfoBuilder,
private val externalDocumentationBuilder: ExternalDocumentationBuilder,
private val serverBuilder: ServerBuilder,
private val tagBuilder: TagBuilder,
private val pathsBuilder: PathsBuilder,
Expand All @@ -20,6 +21,7 @@ class OpenApiBuilder(
fun build(routes: Collection<RouteMeta>): OpenAPI {
return OpenAPI().also {
it.info = infoBuilder.build(config.getInfo())
it.externalDocs = externalDocumentationBuilder.build(config.getExternalDocs())
it.servers = config.getServers().map { server -> serverBuilder.build(server) }
it.tags = config.getTags().map { tag -> tagBuilder.build(tag) }
it.paths = pathsBuilder.build(routes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import io.github.smiley4.ktorswaggerui.dsl.OpenApiTag
import io.swagger.v3.oas.models.tags.Tag

class TagBuilder(
private val externalDocumentationBuilder: ExternalDocumentationBuilder
private val tagExternalDocumentationBuilder: TagExternalDocumentationBuilder
) {

fun build(tag: OpenApiTag): Tag =
Tag().also {
it.name = tag.name
it.description = tag.description
if(tag.externalDocUrl != null && tag.externalDocDescription != null) {
it.externalDocs = externalDocumentationBuilder.build(tag.externalDocUrl!!, tag.externalDocDescription!!)
it.externalDocs = tagExternalDocumentationBuilder.build(tag.externalDocUrl!!, tag.externalDocDescription!!)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.github.smiley4.ktorswaggerui.spec.openapi

import io.swagger.v3.oas.models.ExternalDocumentation

class TagExternalDocumentationBuilder {

fun build(url: String, description: String): ExternalDocumentation =
ExternalDocumentation().also {
it.url = url
it.description = description
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ private fun Application.myModule() {
version = "latest"
description = "Example API for testing and demonstration purposes."
}
externalDocs {
url = "https://github.com/SMILEY4/ktor-swagger-ui/wiki"
description = "Sample external documentation object"
}
server {
url = "http://localhost:8080"
description = "Development Server"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ private fun Application.myModule() {
url = "example.com/license"
}
}
externalDocs {
url = "https://docs.example.com"
description = "Example external documentation description"
}
server {
url = "localhost:8080"
description = "develop server"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.github.smiley4.ktorswaggerui.tests.openapi

import io.github.smiley4.ktorswaggerui.dsl.OpenApiExternalDocs
import io.github.smiley4.ktorswaggerui.spec.openapi.ExternalDocumentationBuilder
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe
import io.swagger.v3.oas.models.ExternalDocumentation

class ExternalDocsBuilderTest : StringSpec({

"default external docs object" {
buildExternalDocsObject {}.also { docs ->
docs.url shouldBe "/"
docs.description shouldBe null
}
}

"complete server object" {
buildExternalDocsObject {
url = "Test URL"
description = "Test Description"
}.also { docs ->
docs.url shouldBe "Test URL"
docs.description shouldBe "Test Description"
}
}

}) {

companion object {

private fun buildExternalDocsObject(builder: OpenApiExternalDocs.() -> Unit): ExternalDocumentation {
return ExternalDocumentationBuilder().build(OpenApiExternalDocs().apply(builder))
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import io.github.smiley4.ktorswaggerui.SwaggerUIPluginConfig
import io.github.smiley4.ktorswaggerui.spec.example.ExampleContext
import io.github.smiley4.ktorswaggerui.spec.example.ExampleContextBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ComponentsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ContactBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ContentBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ExampleBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ExternalDocumentationBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.HeaderBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.InfoBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.LicenseBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OAuthFlowsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OpenApiBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OperationBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.OperationTagsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ParameterBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.PathBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.PathsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.RequestBodyBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ResponseBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ResponsesBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.SecurityRequirementsBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.SecuritySchemesBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.ServerBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.TagBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.*
import io.github.smiley4.ktorswaggerui.spec.route.RouteMeta
import io.github.smiley4.ktorswaggerui.spec.schema.SchemaBuilder
import io.github.smiley4.ktorswaggerui.spec.schema.SchemaContext
Expand All @@ -47,6 +26,7 @@ class OpenApiBuilderTest : StringSpec({
openapi.info shouldNotBe null
openapi.extensions shouldBe null
openapi.servers shouldHaveSize 0
openapi.externalDocs shouldNotBe null
openapi.security shouldBe null
openapi.tags shouldHaveSize 0
openapi.paths shouldHaveSize 0
Expand Down Expand Up @@ -130,9 +110,10 @@ class OpenApiBuilderTest : StringSpec({
contactBuilder = ContactBuilder(),
licenseBuilder = LicenseBuilder()
),
externalDocumentationBuilder = ExternalDocumentationBuilder(),
serverBuilder = ServerBuilder(),
tagBuilder = TagBuilder(
externalDocumentationBuilder = ExternalDocumentationBuilder()
tagExternalDocumentationBuilder = TagExternalDocumentationBuilder()
),
pathsBuilder = PathsBuilder(
pathBuilder = PathBuilder(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.github.smiley4.ktorswaggerui.tests.openapi

import io.github.smiley4.ktorswaggerui.dsl.OpenApiTag
import io.github.smiley4.ktorswaggerui.spec.openapi.ExternalDocumentationBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.TagBuilder
import io.github.smiley4.ktorswaggerui.spec.openapi.TagExternalDocumentationBuilder
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.shouldBe
Expand Down Expand Up @@ -45,7 +45,7 @@ class TagsBuilderTest : StringSpec({

private fun buildTagObject(name: String, builder: OpenApiTag.() -> Unit): Tag {
return TagBuilder(
externalDocumentationBuilder = ExternalDocumentationBuilder()
tagExternalDocumentationBuilder = TagExternalDocumentationBuilder()
).build(OpenApiTag(name).apply(builder))
}

Expand Down

0 comments on commit e7c937a

Please sign in to comment.