diff --git a/CHANGELOG.md b/CHANGELOG.md index 763055594..cd81a2565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,6 @@ ## Unreleased ### Added -- Ability to override serializer via custom route ### Changed @@ -13,6 +12,13 @@ ## Released +## [2.1.0] - February 18th, 2022 +### Added +- Ability to override serializer via custom route +### Changed +- All complex types are now represented by reference schemas +- Deprecated `@Referenced` since all complex types now create references + ## [2.0.4] - February 10th, 2022 ### Added - Custom Type example to playground diff --git a/gradle.properties b/gradle.properties index 819d9e4ae..10e9a49e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Kompendium -project.version=2.0.4 +project.version=2.1.0 # Kotlin kotlin.code.style=official # Gradle diff --git a/kompendium-annotations/src/main/kotlin/io/bkbn/kompendium/annotations/Referenced.kt b/kompendium-annotations/src/main/kotlin/io/bkbn/kompendium/annotations/Referenced.kt index 60853a46e..f9b46cc67 100644 --- a/kompendium-annotations/src/main/kotlin/io/bkbn/kompendium/annotations/Referenced.kt +++ b/kompendium-annotations/src/main/kotlin/io/bkbn/kompendium/annotations/Referenced.kt @@ -6,6 +6,7 @@ package io.bkbn.kompendium.annotations * If you do not annotate a recursive class with [Referenced], you will * get a stack overflow error when you try to launch your API */ +@Deprecated("This annotation now does nothing, as all complex objects are stored as references") @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS) annotation class Referenced diff --git a/kompendium-auth/src/test/resources/notarized_basic_authenticated_get.json b/kompendium-auth/src/test/resources/notarized_basic_authenticated_get.json index e098961c5..61b521d06 100644 --- a/kompendium-auth/src/test/resources/notarized_basic_authenticated_get.json +++ b/kompendium-auth/src/test/resources/notarized_basic_authenticated_get.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -82,7 +74,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": { "basic": { "type": "http", diff --git a/kompendium-auth/src/test/resources/notarized_jwt_authenticated_get.json b/kompendium-auth/src/test/resources/notarized_jwt_authenticated_get.json index 661bf8057..09d0c93ea 100644 --- a/kompendium-auth/src/test/resources/notarized_jwt_authenticated_get.json +++ b/kompendium-auth/src/test/resources/notarized_jwt_authenticated_get.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -82,7 +74,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": { "jwt": { "bearerFormat": "JWT", diff --git a/kompendium-auth/src/test/resources/notarized_oauth_all_flows.json b/kompendium-auth/src/test/resources/notarized_oauth_all_flows.json index ed2b82bd1..8b8f8c4af 100644 --- a/kompendium-auth/src/test/resources/notarized_oauth_all_flows.json +++ b/kompendium-auth/src/test/resources/notarized_oauth_all_flows.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -82,7 +74,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": { "oauth": { "flows": { diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kompendium.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kompendium.kt index c2b5fee94..5e7d46752 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kompendium.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kompendium.kt @@ -20,7 +20,6 @@ class Kompendium(val config: Configuration) { class Configuration { lateinit var spec: OpenApiSpec - var cache: SchemaMap = mutableMapOf() var openApiJson: Routing.(OpenApiSpec) -> Unit = { spec -> route("/openapi.json") { get { @@ -29,9 +28,12 @@ class Kompendium(val config: Configuration) { } } + var bodyCache: SchemaMap = mutableMapOf() + var parameterCache: SchemaMap = mutableMapOf() + // TODO Add tests for this!! fun addCustomTypeSchema(clazz: KClass<*>, schema: TypedSchema) { - cache[clazz.simpleName!!] = schema + bodyCache[clazz.simpleName!!] = schema } } diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/KompendiumPreFlight.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/KompendiumPreFlight.kt index a693a4e78..f39a4c7bd 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/KompendiumPreFlight.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/KompendiumPreFlight.kt @@ -1,16 +1,7 @@ package io.bkbn.kompendium.core -import io.bkbn.kompendium.core.util.Helpers.COMPONENT_SLUG -import io.bkbn.kompendium.oas.schema.AnyOfSchema -import io.bkbn.kompendium.oas.schema.ArraySchema -import io.bkbn.kompendium.oas.schema.ComponentSchema -import io.bkbn.kompendium.oas.schema.DictionarySchema import io.bkbn.kompendium.oas.schema.EnumSchema -import io.bkbn.kompendium.oas.schema.FormattedSchema -import io.bkbn.kompendium.oas.schema.FreeFormSchema import io.bkbn.kompendium.oas.schema.ObjectSchema -import io.bkbn.kompendium.oas.schema.ReferencedSchema -import io.bkbn.kompendium.oas.schema.SimpleSchema import io.ktor.application.feature import io.ktor.routing.Route import io.ktor.routing.application @@ -43,35 +34,17 @@ object KompendiumPreFlight { } fun addToCache(paramType: KType, requestType: KType, responseType: KType, feature: Kompendium) { - Kontent.generateKontent(requestType, feature.config.cache) - Kontent.generateKontent(responseType, feature.config.cache) - Kontent.generateKontent(paramType, feature.config.cache) - feature.updateReferences() + Kontent.generateKontent(requestType, feature.config.bodyCache) + Kontent.generateKontent(responseType, feature.config.bodyCache) + Kontent.generateKontent(paramType, feature.config.parameterCache) + feature.generateReferences() } - private fun Kompendium.updateReferences() { - val references = config.cache.values - .asSequence() - .map { flattenSchema(it) } - .flatten() - .filterIsInstance() - .map { it.`$ref` } - .map { it.replace(COMPONENT_SLUG.plus("/"), "") } - .toList() - references.forEach { ref -> - config.spec.components.schemas[ref] = config.cache[ref] ?: error("$ref does not exist in cache 😱") - } - } - - private fun flattenSchema(schema: ComponentSchema): List = when (schema) { - is AnyOfSchema -> schema.anyOf.map { flattenSchema(it) }.flatten() - is ReferencedSchema -> listOf(schema) - is ArraySchema -> flattenSchema(schema.items) - is DictionarySchema -> flattenSchema(schema.additionalProperties) - is EnumSchema -> listOf(schema) - is FormattedSchema -> listOf(schema) - is FreeFormSchema -> listOf(schema) - is ObjectSchema -> schema.properties.values.map { flattenSchema(it) }.flatten() - is SimpleSchema -> listOf(schema) + fun Kompendium.generateReferences() { + config.bodyCache + .filterValues { it is ObjectSchema || it is EnumSchema } + .forEach { (k, v) -> + config.spec.components.schemas[k] = v + } } } diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kontent.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kontent.kt index 7f4883eb3..8a06fce49 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kontent.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/Kontent.kt @@ -1,10 +1,10 @@ package io.bkbn.kompendium.core import io.bkbn.kompendium.core.metadata.SchemaMap -import io.bkbn.kompendium.core.schema.CollectionHandler -import io.bkbn.kompendium.core.schema.EnumHandler -import io.bkbn.kompendium.core.schema.MapHandler -import io.bkbn.kompendium.core.schema.ObjectHandler +import io.bkbn.kompendium.core.handler.CollectionHandler +import io.bkbn.kompendium.core.handler.EnumHandler +import io.bkbn.kompendium.core.handler.MapHandler +import io.bkbn.kompendium.core.handler.ObjectHandler import io.bkbn.kompendium.core.util.Helpers.logged import io.bkbn.kompendium.oas.schema.FormattedSchema import io.bkbn.kompendium.oas.schema.SimpleSchema diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/constraint/ConstraintScanner.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/constraint/ConstraintScanner.kt index 31ff7f06e..6c30df2f3 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/constraint/ConstraintScanner.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/constraint/ConstraintScanner.kt @@ -102,10 +102,17 @@ fun SimpleSchema.scanForConstraints(prop: KProperty1<*, *>): SimpleSchema { } fun ObjectSchema.scanForConstraints(clazz: KClass<*>, prop: KProperty1<*, *>): ObjectSchema { + var schema = this.adjustForRequiredParams(clazz) + if (prop.returnType.isMarkedNullable) { + schema = schema.copy(nullable = true) + } + + return schema +} + +fun ObjectSchema.adjustForRequiredParams(clazz: KClass<*>): ObjectSchema { val requiredParams = clazz.primaryConstructor?.parameters?.filterNot { it.isOptional } ?: emptyList() var schema = this - - // todo dedup this if (requiredParams.isNotEmpty()) { schema = schema.copy(required = requiredParams.map { param -> clazz.memberProperties.first { it.name == param.name }.findAnnotation() @@ -113,10 +120,5 @@ fun ObjectSchema.scanForConstraints(clazz: KClass<*>, prop: KProperty1<*, *>): O ?: param.name!! }) } - - if (prop.returnType.isMarkedNullable) { - schema = schema.copy(nullable = true) - } - return schema } diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/CollectionHandler.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/CollectionHandler.kt similarity index 78% rename from kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/CollectionHandler.kt rename to kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/CollectionHandler.kt index 037759e4d..101b455f9 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/CollectionHandler.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/CollectionHandler.kt @@ -1,4 +1,4 @@ -package io.bkbn.kompendium.core.schema +package io.bkbn.kompendium.core.handler import io.bkbn.kompendium.core.Kontent import io.bkbn.kompendium.core.Kontent.generateKTypeKontent @@ -33,10 +33,16 @@ object CollectionHandler : SchemaHandler { val subTypes = gatherSubTypes(collectionType) AnyOfSchema(subTypes.map { generateKTypeKontent(it, cache) - cache[it.getSimpleSlug()] ?: error("${it.getSimpleSlug()} not found") + val schema = cache[it.getSimpleSlug()] ?: error("${it.getSimpleSlug()} not found") + val slug = it.getSimpleSlug() + postProcessSchema(schema, slug) }) } - false -> cache[collectionClass.simpleName] ?: error("${collectionClass.simpleName} not found") + false -> { + val schema = cache[collectionClass.simpleName] ?: error("${collectionClass.simpleName} not found") + val slug = collectionClass.simpleName!! + postProcessSchema(schema, slug) + } } val schema = ArraySchema(items = valueReference) Kontent.generateKontent(collectionType, cache) diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/EnumHandler.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/EnumHandler.kt similarity index 93% rename from kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/EnumHandler.kt rename to kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/EnumHandler.kt index b273df055..70255b0ba 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/EnumHandler.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/EnumHandler.kt @@ -1,4 +1,4 @@ -package io.bkbn.kompendium.core.schema +package io.bkbn.kompendium.core.handler import io.bkbn.kompendium.core.metadata.SchemaMap import io.bkbn.kompendium.oas.schema.EnumSchema diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/MapHandler.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/MapHandler.kt similarity index 82% rename from kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/MapHandler.kt rename to kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/MapHandler.kt index cfe65ada3..f2351804f 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/MapHandler.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/MapHandler.kt @@ -1,4 +1,4 @@ -package io.bkbn.kompendium.core.schema +package io.bkbn.kompendium.core.handler import io.bkbn.kompendium.core.Kontent.generateKTypeKontent import io.bkbn.kompendium.core.Kontent.generateKontent @@ -37,10 +37,15 @@ object MapHandler : SchemaHandler { val subTypes = gatherSubTypes(valType) AnyOfSchema(subTypes.map { generateKTypeKontent(it, cache) - cache[it.getSimpleSlug()] ?: error("${it.getSimpleSlug()} not found") + val schema = cache[it.getSimpleSlug()] ?: error("${it.getSimpleSlug()} not found") + val slug = it.getSimpleSlug() + postProcessSchema(schema, slug) }) } - false -> cache[valClassName] ?: error("$valClassName not found") + false -> { + val schema = cache[valClassName] ?: error("$valClassName not found") + postProcessSchema(schema, valClassName!!) + } } val schema = DictionarySchema(additionalProperties = valueReference) generateKontent(valType, cache) diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/ObjectHandler.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/ObjectHandler.kt similarity index 72% rename from kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/ObjectHandler.kt rename to kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/ObjectHandler.kt index f4c52ab35..7db7912ae 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/ObjectHandler.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/ObjectHandler.kt @@ -1,13 +1,13 @@ -package io.bkbn.kompendium.core.schema +package io.bkbn.kompendium.core.handler import io.bkbn.kompendium.annotations.Field import io.bkbn.kompendium.annotations.FreeFormObject -import io.bkbn.kompendium.annotations.Referenced import io.bkbn.kompendium.annotations.UndeclaredField import io.bkbn.kompendium.annotations.constraint.MaxProperties import io.bkbn.kompendium.annotations.constraint.MinProperties import io.bkbn.kompendium.core.Kontent import io.bkbn.kompendium.core.Kontent.generateKontent +import io.bkbn.kompendium.core.constraint.adjustForRequiredParams import io.bkbn.kompendium.core.constraint.scanForConstraints import io.bkbn.kompendium.core.metadata.SchemaMap import io.bkbn.kompendium.core.metadata.TypeMap @@ -24,9 +24,7 @@ import kotlin.reflect.KProperty1 import kotlin.reflect.KType import kotlin.reflect.full.createType import kotlin.reflect.full.findAnnotation -import kotlin.reflect.full.hasAnnotation import kotlin.reflect.full.memberProperties -import kotlin.reflect.full.primaryConstructor import kotlin.reflect.jvm.javaField import org.slf4j.LoggerFactory @@ -46,67 +44,53 @@ object ObjectHandler : SchemaHandler { // Only analyze if component has not already been stored in the cache if (!cache.containsKey(slug)) { logger.debug("$slug was not found in cache, generating now") - // TODO Replace with something better! - // If referenced, add tie from simple slug to schema slug - if (clazz.hasAnnotation()) { - cache[type.getSimpleSlug()] = ReferencedSchema(type.getReferenceSlug()) - } - // Grabs any type parameters mapped to the corresponding type argument(s) + // todo this should be some kind of empty schema at this point, then throw error if not updated eventually + cache[type.getSimpleSlug()] = ReferencedSchema(type.getReferenceSlug()) val typeMap: TypeMap = clazz.typeParameters.zip(type.arguments).toMap() - // associates each member with a Pair of prop name to property schema - val fieldMap = clazz.memberProperties.associate { prop -> - logger.debug("Analyzing $prop in class $clazz") - - // Grab the field of the current property - val field = prop.javaField?.type?.kotlin ?: error("Unable to parse field type from $prop") - - // Short circuit if data is free form - val freeForm = prop.findAnnotation() - var name = prop.name - - when (freeForm) { - null -> { - val bleh = handleDefault(typeMap, prop, cache) - bleh.first - } - else -> handleFreeForm(prop) + val fieldMap = clazz.generateFieldMap(typeMap, cache) + .plus(clazz.generateUndeclaredFieldMap(cache)) + .mapValues { (_, fieldSchema) -> + val fieldSlug = cache.filter { (_, vv) -> vv == fieldSchema }.keys.firstOrNull() + postProcessSchema(fieldSchema, fieldSlug ?: "Fine if blank, will be ignored") } - } - logger.debug("Looking for undeclared fields") - val undeclaredFieldMap = clazz.annotations.filterIsInstance().associate { - val undeclaredType = it.clazz.createType() - generateKontent(undeclaredType, cache) - it.field to cache[undeclaredType.getSimpleSlug()]!! - } logger.debug("$slug contains $fieldMap") - var schema = ObjectSchema(fieldMap.plus(undeclaredFieldMap)) - val requiredParams = clazz.primaryConstructor?.parameters?.filterNot { it.isOptional } ?: emptyList() - // todo de-dup this logic - if (requiredParams.isNotEmpty()) { - schema = schema.copy(required = requiredParams.map { param -> - clazz.memberProperties.first { it.name == param.name }.findAnnotation() - ?.let { field -> field.name.ifBlank { param.name!! } } - ?: param.name!! - }) - } + val schema = ObjectSchema(fieldMap).adjustForRequiredParams(clazz) logger.debug("$slug schema: $schema") cache[slug] = schema } } - // TODO Better type, or just make map mutable + /** + * Associates each member with a Pair of prop name to property schema + */ + private fun KClass<*>.generateFieldMap(typeMap: TypeMap, cache: SchemaMap) = memberProperties.associate { prop -> + logger.debug("Analyzing $prop in class $this") + // Short circuit if data is free form + when (prop.findAnnotation()) { + null -> handleDefault(typeMap, prop, cache) + else -> handleFreeForm(prop) + } + } + + private fun KClass<*>.generateUndeclaredFieldMap(cache: SchemaMap) = + annotations.filterIsInstance().associate { + logger.debug("Identified undeclared field $it") + val undeclaredType = it.clazz.createType() + generateKontent(undeclaredType, cache) + it.field to cache[undeclaredType.getSimpleSlug()]!! + } + private fun handleDefault( typeMap: TypeMap, prop: KProperty1<*, *>, cache: SchemaMap - ): Pair, SchemaMap> { - var name = prop.name + ): Pair { val field = prop.javaField?.type?.kotlin ?: error("Unable to parse field type from $prop") val baseType = scanForGeneric(typeMap, prop) val baseClazz = baseType.classifier as KClass<*> val allTypes = scanForSealed(baseClazz, baseType) updateCache(cache, field, allTypes) - var propSchema = constructComponentSchema( + val propSchema = constructComponentSchema( typeMap = typeMap, prop = prop, fieldClazz = field, @@ -114,16 +98,20 @@ object ObjectHandler : SchemaHandler { type = baseType, cache = cache ) - // todo move to helper + return propSchema.adjustForFieldOverrides(prop) + } + + private fun ComponentSchema.adjustForFieldOverrides(prop: KProperty1<*, *>): Pair { + var name = prop.name prop.findAnnotation()?.let { fieldOverrides -> if (fieldOverrides.description.isNotBlank()) { - propSchema = propSchema.setDescription(fieldOverrides.description) + this.setDescription(fieldOverrides.description) } if (fieldOverrides.name.isNotBlank()) { name = fieldOverrides.name } } - return Pair(Pair(name, propSchema), cache) + return Pair(name, this) } private fun handleFreeForm(prop: KProperty1<*, *>): Pair { diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/SchemaHandler.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/SchemaHandler.kt new file mode 100644 index 000000000..5ef27abe0 --- /dev/null +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/handler/SchemaHandler.kt @@ -0,0 +1,32 @@ +package io.bkbn.kompendium.core.handler + +import io.bkbn.kompendium.core.metadata.SchemaMap +import io.bkbn.kompendium.core.util.Helpers.COMPONENT_SLUG +import io.bkbn.kompendium.oas.schema.ComponentSchema +import io.bkbn.kompendium.oas.schema.EnumSchema +import io.bkbn.kompendium.oas.schema.ObjectSchema +import io.bkbn.kompendium.oas.schema.ReferencedSchema +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.full.createType + +interface SchemaHandler { + fun handle(type: KType, clazz: KClass<*>, cache: SchemaMap) + + fun gatherSubTypes(type: KType): List { + val classifier = type.classifier as KClass<*> + return if (classifier.isSealed) { + classifier.sealedSubclasses.map { + it.createType(type.arguments) + } + } else { + listOf(type) + } + } + + fun postProcessSchema(schema: ComponentSchema, slug: String): ComponentSchema = when (schema) { + is ObjectSchema -> ReferencedSchema(COMPONENT_SLUG.plus("/").plus(slug)) + is EnumSchema -> ReferencedSchema(COMPONENT_SLUG.plus("/").plus(slug)) + else -> schema + } +} diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/parser/IMethodParser.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/parser/IMethodParser.kt index 1784aab3a..1359c0d89 100644 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/parser/IMethodParser.kt +++ b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/parser/IMethodParser.kt @@ -2,16 +2,19 @@ package io.bkbn.kompendium.core.parser import io.bkbn.kompendium.annotations.Param import io.bkbn.kompendium.core.Kompendium +import io.bkbn.kompendium.core.KompendiumPreFlight.generateReferences import io.bkbn.kompendium.core.Kontent import io.bkbn.kompendium.core.metadata.ExceptionInfo import io.bkbn.kompendium.core.metadata.ParameterExample import io.bkbn.kompendium.core.metadata.RequestInfo import io.bkbn.kompendium.core.metadata.ResponseInfo import io.bkbn.kompendium.core.metadata.method.MethodInfo +import io.bkbn.kompendium.core.metadata.method.PatchInfo import io.bkbn.kompendium.core.metadata.method.PostInfo import io.bkbn.kompendium.core.metadata.method.PutInfo import io.bkbn.kompendium.core.util.Helpers import io.bkbn.kompendium.core.util.Helpers.capitalized +import io.bkbn.kompendium.core.util.Helpers.getReferenceSlug import io.bkbn.kompendium.core.util.Helpers.getSimpleSlug import io.bkbn.kompendium.oas.path.PathOperation import io.bkbn.kompendium.oas.payload.MediaType @@ -20,6 +23,7 @@ import io.bkbn.kompendium.oas.payload.Request import io.bkbn.kompendium.oas.payload.Response import io.bkbn.kompendium.oas.schema.AnyOfSchema import io.bkbn.kompendium.oas.schema.ObjectSchema +import io.bkbn.kompendium.oas.schema.ReferencedSchema import io.ktor.routing.Route import kotlin.reflect.KClass import kotlin.reflect.KParameter @@ -59,6 +63,7 @@ interface IMethodParser { requestBody = when (info) { is PutInfo<*, *, *> -> requestType.toRequestSpec(info.requestInfo, feature) is PostInfo<*, *, *> -> requestType.toRequestSpec(info.requestInfo, feature) + is PatchInfo<*, *, *> -> requestType.toRequestSpec(info.requestInfo, feature) else -> null }, security = if (info.securitySchemes.isNotEmpty()) listOf( @@ -77,7 +82,8 @@ interface IMethodParser { exceptionInfo: Set>, feature: Kompendium, ): Map = exceptionInfo.associate { info -> - Kontent.generateKontent(info.responseType, feature.config.cache) + Kontent.generateKontent(info.responseType, feature.config.bodyCache) + feature.generateReferences() val response = Response( description = info.description, content = feature.resolveContent(info.responseType, info.mediaTypes, info.examples) @@ -140,12 +146,14 @@ interface IMethodParser { val schema = if (classifier.isSealed) { val refs = classifier.sealedSubclasses .map { it.createType(type.arguments) } - .map { it.getSimpleSlug() } - .map { config.cache[it] ?: error("$it not available") } + .map { ReferencedSchema(it.getReferenceSlug()) } AnyOfSchema(refs) } else { - val ref = type.getSimpleSlug() - config.cache[ref] ?: error("$ref not available") + if (config.spec.components.schemas.containsKey(type.getSimpleSlug())) { + ReferencedSchema(type.getReferenceSlug()) + } else { + config.bodyCache[type.getSimpleSlug()] ?: error("REEEE") + } } MediaType( schema = schema, @@ -175,7 +183,7 @@ interface IMethodParser { parentClazz: KClass<*>, feature: Kompendium ): Parameter { - val wrapperSchema = feature.config.cache[parentType.getSimpleSlug()]!! as ObjectSchema + val wrapperSchema = feature.config.parameterCache[parentType.getSimpleSlug()]!! as ObjectSchema val anny = this.findAnnotation() ?: error("Field $name is not annotated with KompendiumParam") val schema = wrapperSchema.properties[name] diff --git a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/SchemaHandler.kt b/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/SchemaHandler.kt deleted file mode 100644 index 98ba19654..000000000 --- a/kompendium-core/src/main/kotlin/io/bkbn/kompendium/core/schema/SchemaHandler.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.bkbn.kompendium.core.schema - -import io.bkbn.kompendium.core.metadata.SchemaMap -import kotlin.reflect.KClass -import kotlin.reflect.KType -import kotlin.reflect.full.createType - -interface SchemaHandler { - fun handle(type: KType, clazz: KClass<*>, cache: SchemaMap) - - fun gatherSubTypes(type: KType): List { - val classifier = type.classifier as KClass<*> - return if (classifier.isSealed) { - classifier.sealedSubclasses.map { - it.createType(type.arguments) - } - } else { - listOf(type) - } - } -} diff --git a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/core/KompendiumTest.kt b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/core/KompendiumTest.kt index 6aefbfb07..94d51c1ac 100644 --- a/kompendium-core/src/test/kotlin/io/bkbn/kompendium/core/KompendiumTest.kt +++ b/kompendium-core/src/test/kotlin/io/bkbn/kompendium/core/KompendiumTest.kt @@ -232,7 +232,7 @@ class KompendiumTest : DescribeSpec({ it("Can override field values via annotation") { openApiTestAllSerializers("field_override.json") { overrideFieldInfo() } } - it("Can serialize a recursive type using references") { + it("Can serialize a recursive type") { openApiTestAllSerializers("simple_recursive.json") { simpleRecursive() } } } diff --git a/kompendium-core/src/test/resources/complex_type.json b/kompendium-core/src/test/resources/complex_type.json index 9aa3f0dc8..58da5a221 100644 --- a/kompendium-core/src/test/resources/complex_type.json +++ b/kompendium-core/src/test/resources/complex_type.json @@ -37,53 +37,7 @@ "content": { "application/json": { "schema": { - "properties": { - "amazing_field": { - "type": "string" - }, - "org": { - "type": "string" - }, - "tables": { - "items": { - "properties": { - "alias": { - "additionalProperties": { - "properties": { - "enumeration": { - "enum": [ - "ONE", - "TWO" - ], - "type": "string" - } - }, - "required": [ - "enumeration" - ], - "type": "object" - }, - "type": "object" - }, - "name": { - "type": "string" - } - }, - "required": [ - "name", - "alias" - ], - "type": "object" - }, - "type": "array" - } - }, - "required": [ - "org", - "amazing_field", - "tables" - ], - "type": "object" + "$ref": "#/components/schemas/ComplexRequest" } } }, @@ -95,20 +49,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - }, - "id": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "id", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestCreatedResponse" } } } @@ -119,7 +60,82 @@ } }, "components": { - "schemas": {}, + "schemas": { + "ComplexRequest": { + "properties": { + "amazing_field": { + "type": "string" + }, + "org": { + "type": "string" + }, + "tables": { + "items": { + "$ref": "#/components/schemas/NestedComplexItem" + }, + "type": "array" + } + }, + "required": [ + "org", + "amazing_field", + "tables" + ], + "type": "object" + }, + "NestedComplexItem": { + "properties": { + "alias": { + "additionalProperties": { + "$ref": "#/components/schemas/CrazyItem" + }, + "type": "object" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "alias" + ], + "type": "object" + }, + "CrazyItem": { + "properties": { + "enumeration": { + "$ref": "#/components/schemas/SimpleEnum" + } + }, + "required": [ + "enumeration" + ], + "type": "object" + }, + "SimpleEnum": { + "enum": [ + "ONE", + "TWO" + ], + "type": "string" + }, + "TestCreatedResponse": { + "properties": { + "c": { + "type": "string" + }, + "id": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "id", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/crazy_polymorphic_example.json b/kompendium-core/src/test/resources/crazy_polymorphic_example.json index bd1041171..3e071bd90 100644 --- a/kompendium-core/src/test/resources/crazy_polymorphic_example.json +++ b/kompendium-core/src/test/resources/crazy_polymorphic_example.json @@ -40,46 +40,10 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/Gibbity-TestNested" }, { - "properties": { - "b": { - "type": "string" - }, - "f": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "b", - "f" - ], - "type": "object" + "$ref": "#/components/schemas/Bibbity-TestNested" } ] } @@ -104,86 +68,10 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "anyOf": [ - { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" - }, - { - "properties": { - "b": { - "type": "string" - }, - "c": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b", - "c" - ], - "type": "object" - } - ] - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/Gibbity-FlibbityGibbit" }, { - "properties": { - "b": { - "type": "string" - }, - "f": { - "anyOf": [ - { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" - }, - { - "properties": { - "b": { - "type": "string" - }, - "c": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b", - "c" - ], - "type": "object" - } - ] - } - }, - "required": [ - "b", - "f" - ], - "type": "object" + "$ref": "#/components/schemas/Bibbity-FlibbityGibbit" } ] } @@ -196,7 +84,154 @@ } }, "components": { - "schemas": {}, + "schemas": { + "Gibbity-TestNested": { + "properties": { + "a": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "TestNested": { + "properties": { + "nesty": { + "type": "string" + } + }, + "required": [ + "nesty" + ], + "type": "object" + }, + "Bibbity-TestNested": { + "properties": { + "b": { + "type": "string" + }, + "f": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "b", + "f" + ], + "type": "object" + }, + "Gibbity-FlibbityGibbit": { + "properties": { + "a": { + "anyOf": [ + { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + } + ] + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "SimpleGibbit": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "ComplexGibbit": { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + }, + "Bibbity-FlibbityGibbit": { + "properties": { + "b": { + "type": "string" + }, + "f": { + "anyOf": [ + { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + } + ] + } + }, + "required": [ + "b", + "f" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/default_field.json b/kompendium-core/src/test/resources/default_field.json index 07479ddb1..619d9420a 100644 --- a/kompendium-core/src/test/resources/default_field.json +++ b/kompendium-core/src/test/resources/default_field.json @@ -37,19 +37,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "type": "string" - }, - "b": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b" - ], - "type": "object" + "$ref": "#/components/schemas/DefaultField" } } }, @@ -61,15 +49,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -80,7 +60,34 @@ } }, "components": { - "schemas": {}, + "schemas": { + "DefaultField": { + "properties": { + "a": { + "type": "string" + }, + "b": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b" + ], + "type": "object" + }, + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/default_param.json b/kompendium-core/src/test/resources/default_param.json index 63fda08b8..343ba5419 100644 --- a/kompendium-core/src/test/resources/default_param.json +++ b/kompendium-core/src/test/resources/default_param.json @@ -49,15 +49,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -68,7 +60,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/example_parameters.json b/kompendium-core/src/test/resources/example_parameters.json index f1720753d..d3e44336a 100644 --- a/kompendium-core/src/test/resources/example_parameters.json +++ b/kompendium-core/src/test/resources/example_parameters.json @@ -71,15 +71,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -90,7 +82,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/example_req_and_resp.json b/kompendium-core/src/test/resources/example_req_and_resp.json index ec643b959..04a8b16a6 100644 --- a/kompendium-core/src/test/resources/example_req_and_resp.json +++ b/kompendium-core/src/test/resources/example_req_and_resp.json @@ -37,36 +37,7 @@ "content": { "application/json": { "schema": { - "properties": { - "aaa": { - "items": { - "format": "int64", - "type": "integer" - }, - "type": "array" - }, - "b": { - "format": "double", - "type": "number" - }, - "field_name": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "field_name", - "b", - "aaa" - ], - "type": "object" + "$ref": "#/components/schemas/TestRequest" }, "examples": { "one": { @@ -100,15 +71,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" }, "examples": { "test": { @@ -126,7 +89,54 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestRequest": { + "properties": { + "aaa": { + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + }, + "b": { + "format": "double", + "type": "number" + }, + "field_name": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "field_name", + "b", + "aaa" + ], + "type": "object" + }, + "TestNested": { + "properties": { + "nesty": { + "type": "string" + } + }, + "required": [ + "nesty" + ], + "type": "object" + }, + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/exclusive_min_max.json b/kompendium-core/src/test/resources/exclusive_min_max.json index 3bc913330..3880314f8 100644 --- a/kompendium-core/src/test/resources/exclusive_min_max.json +++ b/kompendium-core/src/test/resources/exclusive_min_max.json @@ -38,20 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "format": "int32", - "type": "integer", - "minimum": 5, - "maximum": 100, - "exclusiveMinimum": true, - "exclusiveMaximum": true - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/ExclusiveMinMax" } } } @@ -62,7 +49,24 @@ } }, "components": { - "schemas": {}, + "schemas": { + "ExclusiveMinMax": { + "properties": { + "a": { + "format": "int32", + "type": "integer", + "minimum": 5, + "maximum": 100, + "exclusiveMinimum": true, + "exclusiveMaximum": true + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/field_override.json b/kompendium-core/src/test/resources/field_override.json index 263ef3282..693526eaa 100644 --- a/kompendium-core/src/test/resources/field_override.json +++ b/kompendium-core/src/test/resources/field_override.json @@ -38,16 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "real_name": { - "type": "boolean", - "description": "A Field that is super important!" - } - }, - "required": [ - "real_name" - ], - "type": "object" + "$ref": "#/components/schemas/TestFieldOverride" } } } @@ -58,7 +49,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestFieldOverride": { + "properties": { + "real_name": { + "type": "boolean" + } + }, + "required": [ + "real_name" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/formatted_param_type.json b/kompendium-core/src/test/resources/formatted_param_type.json index 8f8c4e292..21612b070 100644 --- a/kompendium-core/src/test/resources/formatted_param_type.json +++ b/kompendium-core/src/test/resources/formatted_param_type.json @@ -49,15 +49,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -68,7 +60,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/free_form_object.json b/kompendium-core/src/test/resources/free_form_object.json index 5330de253..8eae097a3 100644 --- a/kompendium-core/src/test/resources/free_form_object.json +++ b/kompendium-core/src/test/resources/free_form_object.json @@ -38,16 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "data": { - "additionalProperties": true, - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" + "$ref": "#/components/schemas/FreeFormData" } } } @@ -58,7 +49,20 @@ } }, "components": { - "schemas": {}, + "schemas": { + "FreeFormData": { + "properties": { + "data": { + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "data" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/generic_exception.json b/kompendium-core/src/test/resources/generic_exception.json index f0ee642c1..7258b1152 100644 --- a/kompendium-core/src/test/resources/generic_exception.json +++ b/kompendium-core/src/test/resources/generic_exception.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -78,30 +70,10 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/Gibbity-String" }, { - "properties": { - "b": { - "type": "string" - }, - "f": { - "type": "string" - } - }, - "required": [ - "b", - "f" - ], - "type": "object" + "$ref": "#/components/schemas/Bibbity-String" } ] } @@ -114,7 +86,45 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + }, + "Gibbity-String": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "Bibbity-String": { + "properties": { + "b": { + "type": "string" + }, + "f": { + "type": "string" + } + }, + "required": [ + "b", + "f" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/generic_response.json b/kompendium-core/src/test/resources/generic_response.json index c68948d55..23fbdf233 100644 --- a/kompendium-core/src/test/resources/generic_response.json +++ b/kompendium-core/src/test/resources/generic_response.json @@ -38,20 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "messy": { - "type": "string" - }, - "potato": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "messy", - "potato" - ], - "type": "object" + "$ref": "#/components/schemas/TestGeneric-Int" } } } @@ -62,7 +49,24 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestGeneric-Int": { + "properties": { + "messy": { + "type": "string" + }, + "potato": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "messy", + "potato" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/min_max_array.json b/kompendium-core/src/test/resources/min_max_array.json index 3b6bfb307..68e58e156 100644 --- a/kompendium-core/src/test/resources/min_max_array.json +++ b/kompendium-core/src/test/resources/min_max_array.json @@ -38,20 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "items": { - "type": "string" - }, - "minItems": 1, - "maxItems": 10, - "type": "array" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/MinMaxArray" } } } @@ -62,7 +49,24 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MinMaxArray": { + "properties": { + "a": { + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 10, + "type": "array" + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/min_max_double_field.json b/kompendium-core/src/test/resources/min_max_double_field.json index 06db3702d..ae7c842e0 100644 --- a/kompendium-core/src/test/resources/min_max_double_field.json +++ b/kompendium-core/src/test/resources/min_max_double_field.json @@ -38,20 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "format": "double", - "type": "number", - "minimum": 5.5, - "maximum": 13.37, - "exclusiveMinimum": false, - "exclusiveMaximum": false - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/MinMaxDouble" } } } @@ -62,7 +49,24 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MinMaxDouble": { + "properties": { + "a": { + "format": "double", + "type": "number", + "minimum": 5.5, + "maximum": 13.37, + "exclusiveMinimum": false, + "exclusiveMaximum": false + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/min_max_free_form.json b/kompendium-core/src/test/resources/min_max_free_form.json index 1353df134..423664e9b 100644 --- a/kompendium-core/src/test/resources/min_max_free_form.json +++ b/kompendium-core/src/test/resources/min_max_free_form.json @@ -38,18 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "data": { - "minProperties": 5, - "maxProperties": 10, - "additionalProperties": true, - "type": "object" - } - }, - "required": [ - "data" - ], - "type": "object" + "$ref": "#/components/schemas/MinMaxFreeForm" } } } @@ -60,7 +49,22 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MinMaxFreeForm": { + "properties": { + "data": { + "minProperties": 5, + "maxProperties": 10, + "additionalProperties": true, + "type": "object" + } + }, + "required": [ + "data" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/min_max_int_field.json b/kompendium-core/src/test/resources/min_max_int_field.json index 59bf2d7f0..217089441 100644 --- a/kompendium-core/src/test/resources/min_max_int_field.json +++ b/kompendium-core/src/test/resources/min_max_int_field.json @@ -38,20 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "format": "int32", - "type": "integer", - "minimum": 5, - "maximum": 100, - "exclusiveMinimum": false, - "exclusiveMaximum": false - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/MinMaxInt" } } } @@ -62,7 +49,24 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MinMaxInt": { + "properties": { + "a": { + "format": "int32", + "type": "integer", + "minimum": 5, + "maximum": 100, + "exclusiveMinimum": false, + "exclusiveMaximum": false + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/min_max_string.json b/kompendium-core/src/test/resources/min_max_string.json index 9a88a35b4..c48873fd0 100644 --- a/kompendium-core/src/test/resources/min_max_string.json +++ b/kompendium-core/src/test/resources/min_max_string.json @@ -38,17 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "type": "string", - "minLength": 42, - "maxLength": 1337 - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/MinMaxString" } } } @@ -59,7 +49,21 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MinMaxString": { + "properties": { + "a": { + "type": "string", + "minLength": 42, + "maxLength": 1337 + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/multiple_of_double.json b/kompendium-core/src/test/resources/multiple_of_double.json index e23ca0ed0..3a6df7403 100644 --- a/kompendium-core/src/test/resources/multiple_of_double.json +++ b/kompendium-core/src/test/resources/multiple_of_double.json @@ -38,17 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "format": "double", - "type": "number", - "multipleOf": 2.5 - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/MultipleOfDouble" } } } @@ -59,7 +49,21 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MultipleOfDouble": { + "properties": { + "a": { + "format": "double", + "type": "number", + "multipleOf": 2.5 + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/multiple_of_int.json b/kompendium-core/src/test/resources/multiple_of_int.json index 70eaa522a..4e8aca700 100644 --- a/kompendium-core/src/test/resources/multiple_of_int.json +++ b/kompendium-core/src/test/resources/multiple_of_int.json @@ -38,17 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "format": "int32", - "type": "integer", - "multipleOf": 5 - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/MultipleOfInt" } } } @@ -59,7 +49,21 @@ } }, "components": { - "schemas": {}, + "schemas": { + "MultipleOfInt": { + "properties": { + "a": { + "format": "int32", + "type": "integer", + "multipleOf": 5 + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/nested_under_root.json b/kompendium-core/src/test/resources/nested_under_root.json index 947a6e684..3ae55a7ea 100644 --- a/kompendium-core/src/test/resources/nested_under_root.json +++ b/kompendium-core/src/test/resources/nested_under_root.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +69,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_get.json b/kompendium-core/src/test/resources/notarized_get.json index be4848ab2..5d327bc67 100644 --- a/kompendium-core/src/test/resources/notarized_get.json +++ b/kompendium-core/src/test/resources/notarized_get.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +69,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_get_with_exception_response.json b/kompendium-core/src/test/resources/notarized_get_with_exception_response.json index 2a53e7ad2..6425c0f4b 100644 --- a/kompendium-core/src/test/resources/notarized_get_with_exception_response.json +++ b/kompendium-core/src/test/resources/notarized_get_with_exception_response.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -76,15 +68,7 @@ "content": { "application/json": { "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" + "$ref": "#/components/schemas/ExceptionResponse" } } } @@ -95,7 +79,30 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + }, + "ExceptionResponse": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_get_with_multiple_exception_responses.json b/kompendium-core/src/test/resources/notarized_get_with_multiple_exception_responses.json index 0cf741368..5b31493e4 100644 --- a/kompendium-core/src/test/resources/notarized_get_with_multiple_exception_responses.json +++ b/kompendium-core/src/test/resources/notarized_get_with_multiple_exception_responses.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -76,15 +68,7 @@ "content": { "application/json": { "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" + "$ref": "#/components/schemas/ExceptionResponse" } } } @@ -94,15 +78,7 @@ "content": { "application/json": { "schema": { - "properties": { - "message": { - "type": "string" - } - }, - "required": [ - "message" - ], - "type": "object" + "$ref": "#/components/schemas/ExceptionResponse" } } } @@ -113,7 +89,30 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + }, + "ExceptionResponse": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_get_with_operation_id.json b/kompendium-core/src/test/resources/notarized_get_with_operation_id.json index 49a29eaf3..e5a207037 100644 --- a/kompendium-core/src/test/resources/notarized_get_with_operation_id.json +++ b/kompendium-core/src/test/resources/notarized_get_with_operation_id.json @@ -59,15 +59,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -78,7 +70,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_options.json b/kompendium-core/src/test/resources/notarized_options.json index fbbcc34d9..0c53ad55a 100644 --- a/kompendium-core/src/test/resources/notarized_options.json +++ b/kompendium-core/src/test/resources/notarized_options.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +69,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_patch.json b/kompendium-core/src/test/resources/notarized_patch.json index 04d8b61c2..434738426 100644 --- a/kompendium-core/src/test/resources/notarized_patch.json +++ b/kompendium-core/src/test/resources/notarized_patch.json @@ -32,21 +32,24 @@ "summary": "Test patch endpoint", "description": "patch your tests here!", "parameters": [], + "requestBody": { + "description": "A Test request", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestRequest" + } + } + }, + "required": true + }, "responses": { "201": { "description": "A Successful Endeavor", "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -57,7 +60,54 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestRequest": { + "properties": { + "aaa": { + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + }, + "b": { + "format": "double", + "type": "number" + }, + "field_name": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "field_name", + "b", + "aaa" + ], + "type": "object" + }, + "TestNested": { + "properties": { + "nesty": { + "type": "string" + } + }, + "required": [ + "nesty" + ], + "type": "object" + }, + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_post.json b/kompendium-core/src/test/resources/notarized_post.json index 62081c701..bd3184d33 100644 --- a/kompendium-core/src/test/resources/notarized_post.json +++ b/kompendium-core/src/test/resources/notarized_post.json @@ -57,36 +57,7 @@ "content": { "application/json": { "schema": { - "properties": { - "aaa": { - "items": { - "format": "int64", - "type": "integer" - }, - "type": "array" - }, - "b": { - "format": "double", - "type": "number" - }, - "field_name": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "field_name", - "b", - "aaa" - ], - "type": "object" + "$ref": "#/components/schemas/TestRequest" } } }, @@ -98,20 +69,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - }, - "id": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "id", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestCreatedResponse" } } } @@ -122,7 +80,59 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestRequest": { + "properties": { + "aaa": { + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + }, + "b": { + "format": "double", + "type": "number" + }, + "field_name": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "field_name", + "b", + "aaa" + ], + "type": "object" + }, + "TestNested": { + "properties": { + "nesty": { + "type": "string" + } + }, + "required": [ + "nesty" + ], + "type": "object" + }, + "TestCreatedResponse": { + "properties": { + "c": { + "type": "string" + }, + "id": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "id", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/notarized_put.json b/kompendium-core/src/test/resources/notarized_put.json index b4590ae8c..4447fa9c3 100644 --- a/kompendium-core/src/test/resources/notarized_put.json +++ b/kompendium-core/src/test/resources/notarized_put.json @@ -57,36 +57,7 @@ "content": { "application/json": { "schema": { - "properties": { - "aaa": { - "items": { - "format": "int64", - "type": "integer" - }, - "type": "array" - }, - "b": { - "format": "double", - "type": "number" - }, - "field_name": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "field_name", - "b", - "aaa" - ], - "type": "object" + "$ref": "#/components/schemas/TestRequest" } } }, @@ -98,20 +69,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - }, - "id": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "id", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestCreatedResponse" } } } @@ -122,7 +80,59 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestRequest": { + "properties": { + "aaa": { + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + }, + "b": { + "format": "double", + "type": "number" + }, + "field_name": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "field_name", + "b", + "aaa" + ], + "type": "object" + }, + "TestNested": { + "properties": { + "nesty": { + "type": "string" + } + }, + "required": [ + "nesty" + ], + "type": "object" + }, + "TestCreatedResponse": { + "properties": { + "c": { + "type": "string" + }, + "id": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "id", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/nullable_field.json b/kompendium-core/src/test/resources/nullable_field.json index ae05c8e69..dfd4c8e63 100644 --- a/kompendium-core/src/test/resources/nullable_field.json +++ b/kompendium-core/src/test/resources/nullable_field.json @@ -37,16 +37,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "type": "string", - "nullable": true - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/NullableField" } } }, @@ -58,15 +49,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +60,31 @@ } }, "components": { - "schemas": {}, + "schemas": { + "NullableField": { + "properties": { + "a": { + "type": "string", + "nullable": true + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/override_parameter_name.json b/kompendium-core/src/test/resources/override_parameter_name.json index 5451afebb..8cd72f1de 100644 --- a/kompendium-core/src/test/resources/override_parameter_name.json +++ b/kompendium-core/src/test/resources/override_parameter_name.json @@ -48,15 +48,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -67,7 +59,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/path_parser.json b/kompendium-core/src/test/resources/path_parser.json index 504a5c6d5..0bc1caa6d 100644 --- a/kompendium-core/src/test/resources/path_parser.json +++ b/kompendium-core/src/test/resources/path_parser.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +69,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/polymorphic_error_status_codes.json b/kompendium-core/src/test/resources/polymorphic_error_status_codes.json index cc97fa4a0..7e168a8a1 100644 --- a/kompendium-core/src/test/resources/polymorphic_error_status_codes.json +++ b/kompendium-core/src/test/resources/polymorphic_error_status_codes.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -78,31 +70,10 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleGibbit" }, { - "properties": { - "b": { - "type": "string" - }, - "c": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/ComplexGibbit" } ] } @@ -115,7 +86,46 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + }, + "SimpleGibbit": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "ComplexGibbit": { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/polymorphic_list_response.json b/kompendium-core/src/test/resources/polymorphic_list_response.json index 6d0e8dd69..8dc0f4807 100644 --- a/kompendium-core/src/test/resources/polymorphic_list_response.json +++ b/kompendium-core/src/test/resources/polymorphic_list_response.json @@ -41,31 +41,10 @@ "items": { "anyOf": [ { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleGibbit" }, { - "properties": { - "b": { - "type": "string" - }, - "c": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/ComplexGibbit" } ] }, @@ -80,7 +59,39 @@ } }, "components": { - "schemas": {}, + "schemas": { + "FlibbityGibbit": { + "properties": {}, + "type": "object" + }, + "SimpleGibbit": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "ComplexGibbit": { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/polymorphic_map_response.json b/kompendium-core/src/test/resources/polymorphic_map_response.json index d72cc8558..d3e12afdd 100644 --- a/kompendium-core/src/test/resources/polymorphic_map_response.json +++ b/kompendium-core/src/test/resources/polymorphic_map_response.json @@ -41,31 +41,10 @@ "additionalProperties": { "anyOf": [ { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleGibbit" }, { - "properties": { - "b": { - "type": "string" - }, - "c": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/ComplexGibbit" } ] }, @@ -80,7 +59,39 @@ } }, "components": { - "schemas": {}, + "schemas": { + "FlibbityGibbit": { + "properties": {}, + "type": "object" + }, + "SimpleGibbit": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "ComplexGibbit": { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/polymorphic_response.json b/kompendium-core/src/test/resources/polymorphic_response.json index 420c3d65a..a427970c5 100644 --- a/kompendium-core/src/test/resources/polymorphic_response.json +++ b/kompendium-core/src/test/resources/polymorphic_response.json @@ -40,31 +40,10 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "type": "string" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleGibbit" }, { - "properties": { - "b": { - "type": "string" - }, - "c": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "b", - "c" - ], - "type": "object" + "$ref": "#/components/schemas/ComplexGibbit" } ] } @@ -77,7 +56,35 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleGibbit": { + "properties": { + "a": { + "type": "string" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "ComplexGibbit": { + "properties": { + "b": { + "type": "string" + }, + "c": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "b", + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/polymorphic_response_with_generics.json b/kompendium-core/src/test/resources/polymorphic_response_with_generics.json index d30af8d76..03628789f 100644 --- a/kompendium-core/src/test/resources/polymorphic_response_with_generics.json +++ b/kompendium-core/src/test/resources/polymorphic_response_with_generics.json @@ -40,46 +40,10 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/Gibbity-TestNested" }, { - "properties": { - "b": { - "type": "string" - }, - "f": { - "properties": { - "nesty": { - "type": "string" - } - }, - "required": [ - "nesty" - ], - "type": "object" - } - }, - "required": [ - "b", - "f" - ], - "type": "object" + "$ref": "#/components/schemas/Bibbity-TestNested" } ] } @@ -92,7 +56,45 @@ } }, "components": { - "schemas": {}, + "schemas": { + "Gibbity-TestNested": { + "properties": { + "a": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "TestNested": { + "properties": { + "nesty": { + "type": "string" + } + }, + "required": [ + "nesty" + ], + "type": "object" + }, + "Bibbity-TestNested": { + "properties": { + "b": { + "type": "string" + }, + "f": { + "$ref": "#/components/schemas/TestNested" + } + }, + "required": [ + "b", + "f" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/query_with_default_parameter.json b/kompendium-core/src/test/resources/query_with_default_parameter.json index ebc370a70..85dcdd60e 100644 --- a/kompendium-core/src/test/resources/query_with_default_parameter.json +++ b/kompendium-core/src/test/resources/query_with_default_parameter.json @@ -69,15 +69,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -88,7 +80,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/regex_string.json b/kompendium-core/src/test/resources/regex_string.json index c1265c20b..8b110d231 100644 --- a/kompendium-core/src/test/resources/regex_string.json +++ b/kompendium-core/src/test/resources/regex_string.json @@ -38,16 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "type": "string", - "pattern": "^\\d{3}-\\d{2}-\\d{4}$" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/RegexString" } } } @@ -58,7 +49,20 @@ } }, "components": { - "schemas": {}, + "schemas": { + "RegexString": { + "properties": { + "a": { + "type": "string", + "pattern": "^\\d{3}-\\d{2}-\\d{4}$" + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/required_param.json b/kompendium-core/src/test/resources/required_param.json index de5cb302d..fdbec4100 100644 --- a/kompendium-core/src/test/resources/required_param.json +++ b/kompendium-core/src/test/resources/required_param.json @@ -48,15 +48,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -67,7 +59,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/response_list.json b/kompendium-core/src/test/resources/response_list.json index 3c34c6aee..fbc08577b 100644 --- a/kompendium-core/src/test/resources/response_list.json +++ b/kompendium-core/src/test/resources/response_list.json @@ -59,15 +59,7 @@ "application/json": { "schema": { "items": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" }, "type": "array" } @@ -80,7 +72,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/root_route.json b/kompendium-core/src/test/resources/root_route.json index 897fe155b..b4fc750ea 100644 --- a/kompendium-core/src/test/resources/root_route.json +++ b/kompendium-core/src/test/resources/root_route.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +69,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/sealed_interface_response.json b/kompendium-core/src/test/resources/sealed_interface_response.json index 6be4c4285..363838de7 100644 --- a/kompendium-core/src/test/resources/sealed_interface_response.json +++ b/kompendium-core/src/test/resources/sealed_interface_response.json @@ -40,67 +40,13 @@ "schema": { "anyOf": [ { - "properties": { - "a": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/OneJamma" }, { - "properties": { - "b": { - "format": "float", - "type": "number" - } - }, - "required": [ - "b" - ], - "type": "object" + "$ref": "#/components/schemas/AnothaJamma" }, { - "properties": { - "c": { - "anyOf": [ - { - "properties": { - "a": { - "format": "int32", - "type": "integer" - } - }, - "required": [ - "a" - ], - "type": "object" - }, - { - "properties": { - "b": { - "format": "float", - "type": "number" - } - }, - "required": [ - "b" - ], - "type": "object" - }, - { - "$ref": "#/components/schemas/InsaneJamma" - } - ] - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/InsaneJamma" } ] } @@ -114,6 +60,30 @@ }, "components": { "schemas": { + "OneJamma": { + "properties": { + "a": { + "format": "int32", + "type": "integer" + } + }, + "required": [ + "a" + ], + "type": "object" + }, + "AnothaJamma": { + "properties": { + "b": { + "format": "float", + "type": "number" + } + }, + "required": [ + "b" + ], + "type": "object" + }, "InsaneJamma": { "properties": { "c": { diff --git a/kompendium-core/src/test/resources/simple_recursive.json b/kompendium-core/src/test/resources/simple_recursive.json index b67fcdd3f..ac93c586c 100644 --- a/kompendium-core/src/test/resources/simple_recursive.json +++ b/kompendium-core/src/test/resources/simple_recursive.json @@ -38,38 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "description": { - "type": "string" - }, - "mode": { - "enum": [ - "NULLABLE", - "REQUIRED", - "REPEATED" - ], - "type": "string" - }, - "name": { - "type": "string" - }, - "subColumns": { - "items": { - "$ref": "#/components/schemas/ColumnSchema" - }, - "type": "array" - }, - "type": { - "type": "string" - } - }, - "required": [ - "name", - "type", - "description", - "mode" - ], - "type": "object" + "$ref": "#/components/schemas/ColumnSchema" } } } @@ -87,12 +56,7 @@ "type": "string" }, "mode": { - "enum": [ - "NULLABLE", - "REQUIRED", - "REPEATED" - ], - "type": "string" + "$ref": "#/components/schemas/ColumnMode" }, "name": { "type": "string" @@ -114,6 +78,14 @@ "mode" ], "type": "object" + }, + "ColumnMode": { + "enum": [ + "NULLABLE", + "REQUIRED", + "REPEATED" + ], + "type": "string" } }, "securitySchemes": {} diff --git a/kompendium-core/src/test/resources/trailing_slash.json b/kompendium-core/src/test/resources/trailing_slash.json index 3ec8075eb..bcfd906f0 100644 --- a/kompendium-core/src/test/resources/trailing_slash.json +++ b/kompendium-core/src/test/resources/trailing_slash.json @@ -58,15 +58,7 @@ "content": { "application/json": { "schema": { - "properties": { - "c": { - "type": "string" - } - }, - "required": [ - "c" - ], - "type": "object" + "$ref": "#/components/schemas/TestResponse" } } } @@ -77,7 +69,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "TestResponse": { + "properties": { + "c": { + "type": "string" + } + }, + "required": [ + "c" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/undeclared_field.json b/kompendium-core/src/test/resources/undeclared_field.json index be6b1ce2e..0ee4c3e46 100644 --- a/kompendium-core/src/test/resources/undeclared_field.json +++ b/kompendium-core/src/test/resources/undeclared_field.json @@ -38,22 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "nowYouSeeMe": { - "type": "string" - }, - "nowYouDont": { - "enum": [ - "HAHA", - "HOHO" - ], - "type": "string" - } - }, - "required": [ - "nowYouSeeMe" - ], - "type": "object" + "$ref": "#/components/schemas/Mysterious" } } } @@ -64,7 +49,29 @@ } }, "components": { - "schemas": {}, + "schemas": { + "Mysterious": { + "properties": { + "nowYouSeeMe": { + "type": "string" + }, + "nowYouDont": { + "$ref": "#/components/schemas/Hehe" + } + }, + "required": [ + "nowYouSeeMe" + ], + "type": "object" + }, + "Hehe": { + "enum": [ + "HAHA", + "HOHO" + ], + "type": "string" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/test/resources/unique_array.json b/kompendium-core/src/test/resources/unique_array.json index 51e67341f..eb2cd584a 100644 --- a/kompendium-core/src/test/resources/unique_array.json +++ b/kompendium-core/src/test/resources/unique_array.json @@ -38,20 +38,7 @@ "content": { "application/json": { "schema": { - "properties": { - "a": { - "items": { - "format": "int32", - "type": "integer" - }, - "uniqueItems": true, - "type": "array" - } - }, - "required": [ - "a" - ], - "type": "object" + "$ref": "#/components/schemas/UniqueArray" } } } @@ -62,7 +49,24 @@ } }, "components": { - "schemas": {}, + "schemas": { + "UniqueArray": { + "properties": { + "a": { + "items": { + "format": "int32", + "type": "integer" + }, + "uniqueItems": true, + "type": "array" + } + }, + "required": [ + "a" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-core/src/testFixtures/kotlin/io/bkbn/kompendium/core/fixtures/TestModels.kt b/kompendium-core/src/testFixtures/kotlin/io/bkbn/kompendium/core/fixtures/TestModels.kt index d9c969569..d13608443 100644 --- a/kompendium-core/src/testFixtures/kotlin/io/bkbn/kompendium/core/fixtures/TestModels.kt +++ b/kompendium-core/src/testFixtures/kotlin/io/bkbn/kompendium/core/fixtures/TestModels.kt @@ -4,7 +4,6 @@ import io.bkbn.kompendium.annotations.Field import io.bkbn.kompendium.annotations.FreeFormObject import io.bkbn.kompendium.annotations.Param import io.bkbn.kompendium.annotations.ParamType -import io.bkbn.kompendium.annotations.Referenced import io.bkbn.kompendium.annotations.UndeclaredField import io.bkbn.kompendium.annotations.constraint.Format import io.bkbn.kompendium.annotations.constraint.MaxItems @@ -204,7 +203,6 @@ sealed interface SlammaJamma data class OneJamma(val a: Int) : SlammaJamma data class AnothaJamma(val b: Float) : SlammaJamma -@Referenced data class InsaneJamma(val c: SlammaJamma) : SlammaJamma sealed interface Flibbity @@ -230,7 +228,6 @@ enum class ColumnMode { REPEATED } -@Referenced data class ColumnSchema( val name: String, val type: String, diff --git a/kompendium-locations/src/test/resources/notarized_delete_nested_location.json b/kompendium-locations/src/test/resources/notarized_delete_nested_location.json index f1b934990..3e1149c76 100644 --- a/kompendium-locations/src/test/resources/notarized_delete_nested_location.json +++ b/kompendium-locations/src/test/resources/notarized_delete_nested_location.json @@ -57,15 +57,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -76,7 +68,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_delete_simple_location.json b/kompendium-locations/src/test/resources/notarized_delete_simple_location.json index e46e06ec2..bfc884be6 100644 --- a/kompendium-locations/src/test/resources/notarized_delete_simple_location.json +++ b/kompendium-locations/src/test/resources/notarized_delete_simple_location.json @@ -48,15 +48,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -67,7 +59,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_get_nested_location.json b/kompendium-locations/src/test/resources/notarized_get_nested_location.json index 4ea378ba4..4a9adabcc 100644 --- a/kompendium-locations/src/test/resources/notarized_get_nested_location.json +++ b/kompendium-locations/src/test/resources/notarized_get_nested_location.json @@ -57,15 +57,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -76,7 +68,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_get_simple_location.json b/kompendium-locations/src/test/resources/notarized_get_simple_location.json index 487540c48..6be4779f5 100644 --- a/kompendium-locations/src/test/resources/notarized_get_simple_location.json +++ b/kompendium-locations/src/test/resources/notarized_get_simple_location.json @@ -48,15 +48,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -67,7 +59,19 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_post_nested_location.json b/kompendium-locations/src/test/resources/notarized_post_nested_location.json index 183c5e7d0..7f182e7a2 100644 --- a/kompendium-locations/src/test/resources/notarized_post_nested_location.json +++ b/kompendium-locations/src/test/resources/notarized_post_nested_location.json @@ -56,15 +56,7 @@ "content": { "application/json": { "schema": { - "properties": { - "input": { - "type": "string" - } - }, - "required": [ - "input" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleRequest" } } }, @@ -76,15 +68,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -95,7 +79,30 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleRequest": { + "properties": { + "input": { + "type": "string" + } + }, + "required": [ + "input" + ], + "type": "object" + }, + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_post_simple_location.json b/kompendium-locations/src/test/resources/notarized_post_simple_location.json index 1be3e3911..6d0a2b8ee 100644 --- a/kompendium-locations/src/test/resources/notarized_post_simple_location.json +++ b/kompendium-locations/src/test/resources/notarized_post_simple_location.json @@ -47,15 +47,7 @@ "content": { "application/json": { "schema": { - "properties": { - "input": { - "type": "string" - } - }, - "required": [ - "input" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleRequest" } } }, @@ -67,15 +59,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -86,7 +70,30 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleRequest": { + "properties": { + "input": { + "type": "string" + } + }, + "required": [ + "input" + ], + "type": "object" + }, + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_put_nested_location.json b/kompendium-locations/src/test/resources/notarized_put_nested_location.json index 5b1fca574..49f0a29b0 100644 --- a/kompendium-locations/src/test/resources/notarized_put_nested_location.json +++ b/kompendium-locations/src/test/resources/notarized_put_nested_location.json @@ -56,15 +56,7 @@ "content": { "application/json": { "schema": { - "properties": { - "input": { - "type": "string" - } - }, - "required": [ - "input" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleRequest" } } }, @@ -76,15 +68,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -95,7 +79,30 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleRequest": { + "properties": { + "input": { + "type": "string" + } + }, + "required": [ + "input" + ], + "type": "object" + }, + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [], diff --git a/kompendium-locations/src/test/resources/notarized_put_simple_location.json b/kompendium-locations/src/test/resources/notarized_put_simple_location.json index bdc0ea73a..c7e758620 100644 --- a/kompendium-locations/src/test/resources/notarized_put_simple_location.json +++ b/kompendium-locations/src/test/resources/notarized_put_simple_location.json @@ -47,15 +47,7 @@ "content": { "application/json": { "schema": { - "properties": { - "input": { - "type": "string" - } - }, - "required": [ - "input" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleRequest" } } }, @@ -67,15 +59,7 @@ "content": { "application/json": { "schema": { - "properties": { - "result": { - "type": "boolean" - } - }, - "required": [ - "result" - ], - "type": "object" + "$ref": "#/components/schemas/SimpleResponse" } } } @@ -86,7 +70,30 @@ } }, "components": { - "schemas": {}, + "schemas": { + "SimpleRequest": { + "properties": { + "input": { + "type": "string" + } + }, + "required": [ + "input" + ], + "type": "object" + }, + "SimpleResponse": { + "properties": { + "result": { + "type": "boolean" + } + }, + "required": [ + "result" + ], + "type": "object" + } + }, "securitySchemes": {} }, "security": [],