Skip to content

Commit

Permalink
Merge branch 'develop' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
SMILEY4 committed Aug 7, 2024
2 parents 021dd41 + e6df87d commit d63964c
Show file tree
Hide file tree
Showing 35 changed files with 2,105 additions and 149 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kotlin.code.style=official
# project id
projectGroupId=io.github.smiley4
projectArtifactIdBase=schema-kenerator
projectVersion=1.0.1
projectVersion=1.1.0

# publishing information
projectNameBase=Schema-Kenerator
Expand Down
3 changes: 3 additions & 0 deletions schema-kenerator-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ repositories {
}

dependencies {
val versionKotlinxSerializationJson: String by project
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:$versionKotlinxSerializationJson")

val versionKotest: String by project
val versionKotlinTest: String by project
testImplementation("io.kotest:kotest-runner-junit5:$versionKotest")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo

/**
* Specifies a default value for the annotated object.
*/
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@Retention(AnnotationRetention.RUNTIME)
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Default(val default: String)
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo


/**
* Specifies whether the annotated object is deprecated.
* @param deprecated whether the object is deprecated
*/
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@Retention(AnnotationRetention.RUNTIME)
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Deprecated(val deprecated: Boolean = true)
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo

/**
* Specifies a description of the annotated object.
* @param description a short description
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Description(val description: String)
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo

/**
* Specifies an example value for the annotated object. Add annotation multiple times for multiple different example values.
* @param example the example value as a string
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
@Repeatable
annotation class Example(val example: String)
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo

/**
* Specify a name for the annotated class.
* @param name the name
* @param qualifiedName the qualified name (optional, leave as empty string to use [name])
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.CLASS,
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Name(val name: String, val qualifiedName: String = "")
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo


/**
* Specifies that the annotated object is optional, i.e. not required.
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Optional
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo


/**
* Specifies that the annotated object is required.
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.PROPERTY,
AnnotationTarget.FIELD,
AnnotationTarget.FUNCTION
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Required
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package io.github.smiley4.schemakenerator.core.annotations

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialInfo

/**
* Specify a title for the annotated class.
* @param title the title
*/
@OptIn(ExperimentalSerializationApi::class)
@Target(
AnnotationTarget.CLASS,
)
@SerialInfo
@Retention(AnnotationRetention.RUNTIME)
annotation class Title(val title: String)
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ open class ObjectTypeData(
* list of members, e.g. properties, functions
*/
var members: MutableList<PropertyData> = mutableListOf(),
/**
* whether the type is an inline value class
*/
var isInlineValue: Boolean = false
) : BaseTypeData(id, simpleName, qualifiedName, typeParameters, annotations)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ data class PropertyData(
* whether the (return) type is nullable
*/
var nullable: Boolean,
/**
* whether the property is optional (i.e. when a default value is provided)
*/
var optional: Boolean,
/**
* the general visibility of this property
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import io.github.smiley4.schemakenerator.core.data.Bundle
import io.github.smiley4.schemakenerator.core.data.ObjectTypeData
import io.github.smiley4.schemakenerator.core.data.PropertyData
import io.github.smiley4.schemakenerator.core.data.PropertyType
import javax.swing.text.html.HTML.Tag.U

/**
* Merges getters with their matching property;
Expand Down Expand Up @@ -35,21 +36,24 @@ class MergeGettersStep {
.filter { it.kind == PropertyType.GETTER }
.forEach { getter ->

// find matching property
val propertyName = getterNameToPropertyName(getter.name)

val property = typeData.members
.filter { it.kind == PropertyType.PROPERTY }
.find { it.name == propertyName && it.type == getter.type }

if(property != null) {
// copy some information from getter to property
property.annotations.addAll(getter.annotations)
property.nullable = getter.nullable
property.visibility = getter.visibility
} else {
// create new property from getter
toAdd.add(PropertyData(
name = propertyName,
type = getter.type,
nullable = getter.nullable,
optional = getter.optional,
visibility = getter.visibility,
kind = PropertyType.PROPERTY,
annotations = getter.annotations
Expand All @@ -58,6 +62,7 @@ class MergeGettersStep {

}

// remove all getters, add created members
typeData.members.removeIf { it.kind == PropertyType.GETTER }
typeData.members.addAll(toAdd)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package io.github.smiley4.schemakenerator.jsonschema

import io.github.smiley4.schemakenerator.core.data.BaseTypeData
import io.github.smiley4.schemakenerator.core.data.Bundle
import io.github.smiley4.schemakenerator.core.data.PropertyData
import io.github.smiley4.schemakenerator.jsonschema.data.CompiledJsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.JsonSchema
import io.github.smiley4.schemakenerator.jsonschema.data.RefType
import io.github.smiley4.schemakenerator.jsonschema.data.TitleType
import io.github.smiley4.schemakenerator.jsonschema.jsonDsl.JsonNode
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaAnnotationTypeHintStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaAutoTitleStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCompileInlineStep
Expand All @@ -15,14 +17,39 @@ import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotati
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotationDeprecatedStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotationDescriptionStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotationExamplesStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotationOptionalAndRequiredStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCoreAnnotationTitleStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaCustomizeStep
import io.github.smiley4.schemakenerator.jsonschema.steps.JsonSchemaGenerationStep

enum class OptionalHandling {
REQUIRED,
NON_REQUIRED
}

class JsonSchemaGenerationStepConfig {
/**
* How to handle optional parameters
*
* Example:
* ```
* class MyExample(val someValue: String = "hello")
* ```
* - with `optionalHandling = REQUIRED` => "someValue" is required (because is not nullable)
* - with `optionalHandling = NON_REQUIRED` => "someValue" is not required (because a default value is provided)
*/
var optionalHandling = OptionalHandling.REQUIRED
}


/**
* See [JsonSchemaGenerationStep]
*/
fun Bundle<BaseTypeData>.generateJsonSchema(): Bundle<JsonSchema> {
return JsonSchemaGenerationStep().generate(this)
fun Bundle<BaseTypeData>.generateJsonSchema(configBlock: JsonSchemaGenerationStepConfig.() -> Unit = {}): Bundle<JsonSchema> {
val config = JsonSchemaGenerationStepConfig().apply(configBlock)
return JsonSchemaGenerationStep(
optionalAsNonRequired = config.optionalHandling == OptionalHandling.NON_REQUIRED,
).generate(this)
}


Expand All @@ -36,10 +63,11 @@ fun Bundle<JsonSchema>.withAutoTitle(type: TitleType = TitleType.FULL): Bundle<J

/**
* See [JsonSchemaCoreAnnotationDefaultStep], [JsonSchemaCoreAnnotationDeprecatedStep], [JsonSchemaCoreAnnotationDescriptionStep],
* [JsonSchemaCoreAnnotationExamplesStep], [JsonSchemaCoreAnnotationTitleStep]
* [JsonSchemaCoreAnnotationExamplesStep], [JsonSchemaCoreAnnotationTitleStep], [JsonSchemaCoreAnnotationOptionalAndRequiredStep]
*/
fun Bundle<JsonSchema>.handleCoreAnnotations(): Bundle<JsonSchema> {
return this
.let { JsonSchemaCoreAnnotationOptionalAndRequiredStep().process(this) }
.let { JsonSchemaCoreAnnotationDefaultStep().process(this) }
.let { JsonSchemaCoreAnnotationDeprecatedStep().process(this) }
.let { JsonSchemaCoreAnnotationDescriptionStep().process(this) }
Expand Down Expand Up @@ -79,3 +107,19 @@ fun Bundle<JsonSchema>.compileReferencing(pathType: RefType = RefType.FULL): Com
fun Bundle<JsonSchema>.compileReferencingRoot(pathType: RefType = RefType.FULL): CompiledJsonSchema {
return JsonSchemaCompileReferenceRootStep(pathType).compile(this)
}


/**
* See [JsonSchemaCustomizeStep.customizeTypes]
*/
fun Bundle<JsonSchema>.customizeTypes(action: (typeData: BaseTypeData, typeSchema: JsonNode) -> Unit): Bundle<JsonSchema> {
return JsonSchemaCustomizeStep().customizeTypes(this, action)
}


/**
* See [JsonSchemaCustomizeStep.customizeProperties]
*/
fun Bundle<JsonSchema>.customizeProperties(action: (propertyData: PropertyData, propertySchema: JsonNode) -> Unit): Bundle<JsonSchema> {
return JsonSchemaCustomizeStep().customizeProperties(this, action)
}
Loading

0 comments on commit d63964c

Please sign in to comment.