Merge pull request #1 from lg-backbone/feature/petstoreParity
This commit is contained in:
37
.github/workflows/pr_checks.yml
vendored
Normal file
37
.github/workflows/pr_checks.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Run PR Checks
|
||||
on: pull_request
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.14
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.14
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: ${{ runner.os }}-gradle
|
||||
- name: Lint using detekt
|
||||
run: ./gradlew detekt
|
||||
unit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.14
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.14
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: ${{ runner.os }}-gradle
|
||||
- name: Assemble with Gradle
|
||||
run: ./gradlew assemble
|
||||
- name: Run Unit Tests
|
||||
run: ./gradlew test
|
22
.github/workflows/publish.yml
vendored
Normal file
22
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
name: Publish to GitHub Packages
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.14
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: ${{ runner.os }}-gradle
|
||||
- name: Publish package
|
||||
run: ./gradlew publish
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,3 +3,5 @@
|
||||
|
||||
# Ignore Gradle build output directory
|
||||
build
|
||||
|
||||
.idea
|
||||
|
@ -16,6 +16,7 @@ allprojects {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven") }
|
||||
}
|
||||
|
||||
apply(plugin = "org.jetbrains.kotlin.jvm")
|
||||
|
@ -361,7 +361,7 @@ naming:
|
||||
excludes: ['**/test/**', '**/testIntegration/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
classPattern: '[A-Z][a-zA-Z0-9]*'
|
||||
ConstructorParameterNaming:
|
||||
active: true
|
||||
active: false
|
||||
excludes: ['**/test/**', '**/testIntegration/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**']
|
||||
parameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
privateParameterPattern: '[a-z][A-Za-z0-9]*'
|
||||
|
@ -10,3 +10,21 @@ dependencies {
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
|
||||
testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.12.0")
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "GithubPackages"
|
||||
url = uri("https://maven.pkg.github.com/lg-backbone/kompendium")
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_ACTOR")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("kompendium") {
|
||||
from(components["kotlin"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
/*
|
||||
* This Kotlin source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package kompendium
|
||||
|
||||
class Library {
|
||||
fun someLibraryMethod(): String {
|
||||
return "Heya"
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package org.leafygreens.kompendium
|
||||
|
||||
import java.net.URI
|
||||
import org.leafygreens.kompendium.models.OpenApiSpec
|
||||
|
||||
class Kompendium {
|
||||
|
@ -3,10 +3,12 @@ package org.leafygreens.kompendium.models
|
||||
data class OpenApiSpec(
|
||||
val openapi: String = "3.0.3",
|
||||
val info: OpenApiSpecInfo? = null,
|
||||
val servers: List<OpenApiSpecServer> = emptyList(), // TODO Needs to default to server object with url of `/`
|
||||
val paths: Map<String, OpenApiSpecPathItem> = emptyMap(),
|
||||
// TODO Needs to default to server object with url of `/`
|
||||
val servers: List<OpenApiSpecServer>? = null,
|
||||
val paths: Map<String, OpenApiSpecPathItem>? = null,
|
||||
val components: OpenApiSpecComponents? = null,
|
||||
val security: Map<String, String> = emptyMap(), // todo needs to reference objects in the components -> security scheme 🤔
|
||||
val tags: List<OpenApiSpecTag> = emptyList(),
|
||||
// todo needs to reference objects in the components -> security scheme 🤔
|
||||
val security: List<Map<String, List<String>>>? = null,
|
||||
val tags: List<OpenApiSpecTag>? = null,
|
||||
val externalDocs: OpenApiSpecExternalDocumentation? = null
|
||||
)
|
||||
|
@ -2,5 +2,5 @@ package org.leafygreens.kompendium.models
|
||||
|
||||
// TODO I *think* the only thing I need here is the security https://swagger.io/specification/#components-object
|
||||
data class OpenApiSpecComponents(
|
||||
val securitySchemes: Map<String, OpenApiSpecReferencable>
|
||||
val securitySchemes: Map<String, OpenApiSpecSchema>
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ package org.leafygreens.kompendium.models
|
||||
|
||||
// TODO Oof -> https://swagger.io/specification/#media-type-object
|
||||
data class OpenApiSpecMediaType(
|
||||
val schema: OpenApiSpecReferencable, // TODO sheesh -> https://swagger.io/specification/#schema-object needs to be referencable
|
||||
val schema: OpenApiSpecSchema, // TODO sheesh -> https://swagger.io/specification/#schema-object
|
||||
val example: String? = null, // TODO Enforce type? then serialize?
|
||||
val examples: Map<String, String>? = null, // needs to be mutually exclusive with example
|
||||
val encoding: Map<String, String>? = null // todo encoding object -> https://swagger.io/specification/#encoding-object
|
||||
|
@ -3,8 +3,8 @@ package org.leafygreens.kompendium.models
|
||||
import java.net.URI
|
||||
|
||||
data class OpenApiSpecOAuthFlow(
|
||||
val authorizationUrl: URI,
|
||||
val tokenUrl: URI,
|
||||
val refreshUrl: URI,
|
||||
val scopes: Map<String, String>
|
||||
val authorizationUrl: URI? = null,
|
||||
val tokenUrl: URI? = null,
|
||||
val refreshUrl: URI? = null,
|
||||
val scopes: Map<String, String>? = null
|
||||
)
|
||||
|
@ -8,10 +8,12 @@ data class OpenApiSpecPathItemOperation(
|
||||
val operationId: String? = null,
|
||||
val parameters: List<OpenApiSpecReferencable>? = null,
|
||||
val requestBody: OpenApiSpecReferencable? = null,
|
||||
val responses: Map<String, OpenApiSpecReferencable>? = null, // TODO How to enforce `default` requirement
|
||||
// TODO How to enforce `default` requirement 🧐
|
||||
val responses: Map<String, OpenApiSpecReferencable>? = null,
|
||||
val callbacks: Map<String, OpenApiSpecReferencable>? = null,
|
||||
val deprecated: Boolean = false,
|
||||
val security: List<Map<String, List<String>>>? = null, // todo big yikes... also needs to reference objects in the security scheme 🤔
|
||||
// todo big yikes... also needs to reference objects in the security scheme 🤔
|
||||
val security: List<Map<String, List<String>>>? = null,
|
||||
val servers: List<OpenApiSpecServer>? = null,
|
||||
val `x-codegen-request-body-name`: String? = null
|
||||
)
|
||||
|
@ -27,7 +27,10 @@ data class OpenApiSpecParameter(
|
||||
val description: String?,
|
||||
val required: Boolean = true,
|
||||
val deprecated: Boolean = false,
|
||||
val allowEmptyValue: Boolean = false
|
||||
val allowEmptyValue: Boolean = false,
|
||||
val style: String? = null,
|
||||
val explode: Boolean? = false,
|
||||
val schema: OpenApiSpecSchema? = null
|
||||
) : OpenApiSpecReferencable()
|
||||
|
||||
data class OpenApiSpecRequest(
|
||||
|
@ -0,0 +1,31 @@
|
||||
package org.leafygreens.kompendium.models
|
||||
|
||||
sealed class OpenApiSpecSchema
|
||||
|
||||
sealed class OpenApiSpecSchemaTyped(
|
||||
val type: String,
|
||||
) : OpenApiSpecSchema()
|
||||
|
||||
data class OpenApiSpecSchemaArray<T : OpenApiSpecSchema>(
|
||||
val items: T
|
||||
) : OpenApiSpecSchemaTyped("array")
|
||||
|
||||
data class OpenApiSpecSchemaString(
|
||||
val default: String,
|
||||
val `enum`: Set<String>? = null
|
||||
) : OpenApiSpecSchemaTyped("string")
|
||||
|
||||
// TODO In Kt 1.5 Should be able to reference external sealed classes
|
||||
data class OpenApiSpecSchemaRef(
|
||||
val `$ref`: String
|
||||
) : OpenApiSpecSchema()
|
||||
|
||||
data class OpenApiSpecSchemaSecurity(
|
||||
val type: String? = null, // TODO Enum? "apiKey", "http", "oauth2", "openIdConnect"
|
||||
val name: String? = null,
|
||||
val `in`: String? = null,
|
||||
val scheme: String? = null,
|
||||
val flows: OpenApiSpecOAuthFlows? = null,
|
||||
val bearerFormat: String? = null,
|
||||
val description: String? = null,
|
||||
) : OpenApiSpecSchema()
|
@ -1,12 +0,0 @@
|
||||
package org.leafygreens.kompendium.models
|
||||
|
||||
data class OpenApiSpecSecuritySchema(
|
||||
val type: String, // TODO Enum? "apiKey", "http", "oauth2", "openIdConnect"
|
||||
val name: String,
|
||||
val `in`: String,
|
||||
val scheme: String,
|
||||
val flows: OpenApiSpecOAuthFlows,
|
||||
val bearerFormat: String?,
|
||||
val description: String?,
|
||||
)
|
||||
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* This Kotlin source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package kompendium
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class LibraryTest {
|
||||
@Test fun testSomeLibraryMethod() {
|
||||
val classUnderTest = Library()
|
||||
assertEquals(classUnderTest.someLibraryMethod(), "Heya", "someLibraryMethod should return 'true'")
|
||||
}
|
||||
}
|
@ -3,16 +3,23 @@ package org.leafygreens.kompendium.util
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import org.leafygreens.kompendium.models.OpenApiSpec
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecComponents
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecExternalDocumentation
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecInfo
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecInfoContact
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecInfoLicense
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecMediaType
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecOAuthFlow
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecOAuthFlows
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecParameter
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecPathItem
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecPathItemOperation
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecReferenceObject
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecRequest
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecResponse
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecSchemaArray
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecSchemaRef
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecSchemaSecurity
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecSchemaString
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecServer
|
||||
import org.leafygreens.kompendium.models.OpenApiSpecTag
|
||||
|
||||
@ -26,7 +33,11 @@ object TestData {
|
||||
val testSpec = OpenApiSpec(
|
||||
info = OpenApiSpecInfo(
|
||||
title = "Swagger Petstore",
|
||||
description = "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
|
||||
description = """
|
||||
This is a sample server Petstore server. You can find out more about Swagger at
|
||||
[http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).
|
||||
For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||
""".trimIndent(),
|
||||
termsOfService = URI("http://swagger.io/terms/"),
|
||||
contact = OpenApiSpecInfoContact(
|
||||
name = "Team Swag",
|
||||
@ -82,10 +93,10 @@ object TestData {
|
||||
description = "Pet object that needs to be added to the store",
|
||||
content = mapOf(
|
||||
"application/json" to OpenApiSpecMediaType(
|
||||
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
|
||||
schema = OpenApiSpecSchemaRef(`$ref` = "#/components/schemas/Pet")
|
||||
),
|
||||
"application/xml" to OpenApiSpecMediaType(
|
||||
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
|
||||
schema = OpenApiSpecSchemaRef(`$ref` = "#/components/schemas/Pet")
|
||||
)
|
||||
),
|
||||
required = true
|
||||
@ -119,10 +130,10 @@ object TestData {
|
||||
description = "Pet object that needs to be added to the store",
|
||||
content = mapOf(
|
||||
"application/json" to OpenApiSpecMediaType(
|
||||
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
|
||||
schema = OpenApiSpecSchemaRef(`$ref` = "#/components/schemas/Pet")
|
||||
),
|
||||
"application/xml" to OpenApiSpecMediaType(
|
||||
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
|
||||
schema = OpenApiSpecSchemaRef(`$ref` = "#/components/schemas/Pet")
|
||||
)
|
||||
)
|
||||
),
|
||||
@ -139,6 +150,75 @@ object TestData {
|
||||
),
|
||||
`x-codegen-request-body-name` = "body"
|
||||
)
|
||||
),
|
||||
"/pet/findByStatus" to OpenApiSpecPathItem(
|
||||
get = OpenApiSpecPathItemOperation(
|
||||
tags = setOf("pet"),
|
||||
summary = "Find Pets by status",
|
||||
description = "Multiple status values can be provided with comma separated strings",
|
||||
operationId = "findPetsByStatus",
|
||||
parameters = listOf(
|
||||
OpenApiSpecParameter(
|
||||
name = "status",
|
||||
`in` = "query",
|
||||
description = "Status values that need to be considered for filter",
|
||||
required = true,
|
||||
style = "form",
|
||||
explode = true,
|
||||
schema = OpenApiSpecSchemaArray(
|
||||
items = OpenApiSpecSchemaString(
|
||||
default = "available",
|
||||
`enum` = setOf("available", "pending", "sold")
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
responses = mapOf(
|
||||
"200" to OpenApiSpecResponse(
|
||||
description = "successful operation",
|
||||
content = mapOf(
|
||||
"application/xml" to OpenApiSpecMediaType(
|
||||
schema = OpenApiSpecSchemaArray(
|
||||
items = OpenApiSpecSchemaRef("#/components/schemas/Pet")
|
||||
)
|
||||
),
|
||||
"application/json" to OpenApiSpecMediaType(
|
||||
schema = OpenApiSpecSchemaArray(
|
||||
items = OpenApiSpecSchemaRef("#/components/schemas/Pet")
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
"400" to OpenApiSpecResponse(
|
||||
description = "Invalid status value",
|
||||
content = mapOf()
|
||||
)
|
||||
),
|
||||
security = listOf(mapOf(
|
||||
"petstore_auth" to listOf("write:pets", "read:pets")
|
||||
))
|
||||
)
|
||||
)
|
||||
),
|
||||
components = OpenApiSpecComponents(
|
||||
securitySchemes = mapOf(
|
||||
"petstore_auth" to OpenApiSpecSchemaSecurity(
|
||||
type = "oauth2",
|
||||
flows = OpenApiSpecOAuthFlows(
|
||||
implicit = OpenApiSpecOAuthFlow(
|
||||
authorizationUrl = URI("http://petstore.swagger.io/oauth/dialog"),
|
||||
scopes = mapOf(
|
||||
"write:pets" to "modify pets in your account",
|
||||
"read:pets" to "read your pets"
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
"api_key" to OpenApiSpecSchemaSecurity(
|
||||
type = "apiKey",
|
||||
name = "api_key",
|
||||
`in` = "header"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -3,7 +3,7 @@
|
||||
"info" : {
|
||||
"title" : "Swagger Petstore",
|
||||
"version" : "1.0.0",
|
||||
"description" : "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
|
||||
"description" : "This is a sample server Petstore server. You can find out more about Swagger at\n[http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).\nFor this sample, you can use the api key `special-key` to test the authorization filters.",
|
||||
"termsOfService" : "http://swagger.io/terms/",
|
||||
"contact" : {
|
||||
"name" : "Team Swag",
|
||||
@ -93,9 +93,86 @@
|
||||
} ],
|
||||
"x-codegen-request-body-name" : "body"
|
||||
}
|
||||
},
|
||||
"/pet/findByStatus" : {
|
||||
"get" : {
|
||||
"tags" : [ "pet" ],
|
||||
"summary" : "Find Pets by status",
|
||||
"description" : "Multiple status values can be provided with comma separated strings",
|
||||
"operationId" : "findPetsByStatus",
|
||||
"parameters" : [ {
|
||||
"name" : "status",
|
||||
"in" : "query",
|
||||
"description" : "Status values that need to be considered for filter",
|
||||
"required" : true,
|
||||
"deprecated" : false,
|
||||
"allowEmptyValue" : false,
|
||||
"style" : "form",
|
||||
"explode" : true,
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"default" : "available",
|
||||
"enum" : [ "available", "pending", "sold" ],
|
||||
"type" : "string"
|
||||
},
|
||||
"type" : "array"
|
||||
}
|
||||
} ],
|
||||
"responses" : {
|
||||
"200" : {
|
||||
"description" : "successful operation",
|
||||
"content" : {
|
||||
"application/xml" : {
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/Pet"
|
||||
},
|
||||
"type" : "array"
|
||||
}
|
||||
},
|
||||
"application/json" : {
|
||||
"schema" : {
|
||||
"items" : {
|
||||
"$ref" : "#/components/schemas/Pet"
|
||||
},
|
||||
"type" : "array"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400" : {
|
||||
"description" : "Invalid status value",
|
||||
"content" : { }
|
||||
}
|
||||
},
|
||||
"deprecated" : false,
|
||||
"security" : [ {
|
||||
"petstore_auth" : [ "write:pets", "read:pets" ]
|
||||
} ]
|
||||
}
|
||||
}
|
||||
},
|
||||
"components" : {
|
||||
"securitySchemes" : {
|
||||
"petstore_auth" : {
|
||||
"type" : "oauth2",
|
||||
"flows" : {
|
||||
"implicit" : {
|
||||
"authorizationUrl" : "http://petstore.swagger.io/oauth/dialog",
|
||||
"scopes" : {
|
||||
"write:pets" : "modify pets in your account",
|
||||
"read:pets" : "read your pets"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"api_key" : {
|
||||
"type" : "apiKey",
|
||||
"name" : "api_key",
|
||||
"in" : "header"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security" : { },
|
||||
"tags" : [ {
|
||||
"name" : "pet",
|
||||
"description" : "Everything about your Pets",
|
||||
|
@ -8,7 +8,6 @@ import io.ktor.routing.route
|
||||
import io.ktor.routing.routing
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.server.netty.Netty
|
||||
import kompendium.Library
|
||||
|
||||
fun main() {
|
||||
embeddedServer(
|
||||
@ -22,7 +21,7 @@ fun Application.mainModule() {
|
||||
routing {
|
||||
route("/") {
|
||||
get {
|
||||
call.respondText(Library().someLibraryMethod())
|
||||
call.respondText("hi")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user