From 3bacaa6cfd70e21a3bbe252c5204c60d0fedf886 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sun, 23 Jul 2023 14:31:33 +0400 Subject: [PATCH 1/3] Update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f640545d..12dc4868 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,5 +3,5 @@ kotlin.js.compiler=ir org.gradle.jvmargs=-Xmx1G org.gradle.java.installations.auto-download=false -version=0.0.1-SNAPSHOT +version=0.0.2-SNAPSHOT group=io.github.optimumcode \ No newline at end of file From c4704622bcb5871b6856e827ac70b28b21115375 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sun, 23 Jul 2023 14:52:51 +0400 Subject: [PATCH 2/3] Exctract value to validated supported type --- .../json/schema/internal/SchemaLoader.kt | 13 +++++++ .../json/schema/internal/SchemaType.kt | 19 ++++++++++ .../json/schema/base/JsonSchemaTest.kt | 38 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaType.kt diff --git a/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaLoader.kt b/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaLoader.kt index 95dba681..9ae4d759 100644 --- a/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaLoader.kt +++ b/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaLoader.kt @@ -71,11 +71,13 @@ private val factories: List = listOf( private const val DEFINITIONS_PROPERTY: String = "definitions" private const val ID_PROPERTY: String = "\$id" private const val REF_PROPERTY: String = "\$ref" +private const val SCHEMA_PROPERTY: String = "\$schema" internal const val ROOT_REFERENCE = '#' internal class SchemaLoader { fun load(schemaDefinition: JsonElement): JsonSchema { + extractSchemaType(schemaDefinition) val baseId = extractBaseID(schemaDefinition) val context = defaultLoadingContext(baseId) loadDefinitions(schemaDefinition, context) @@ -84,6 +86,17 @@ internal class SchemaLoader { return JsonSchema(schemaAssertion, context.references) } + private fun extractSchemaType(schemaDefinition: JsonElement): SchemaType { + return if (schemaDefinition is JsonObject) { + schemaDefinition[SCHEMA_PROPERTY]?.let { + require(it is JsonPrimitive && it.isString) { "$SCHEMA_PROPERTY must be a string" } + SchemaType.find(it.content) ?: throw IllegalArgumentException("unsupported schema type ${it.content}") + } ?: SchemaType.values().last() + } else { + SchemaType.values().last() + } + } + private fun loadDefinitions(schemaDefinition: JsonElement, context: DefaultLoadingContext) { if (schemaDefinition !is JsonObject) { return diff --git a/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaType.kt b/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaType.kt new file mode 100644 index 00000000..a54b2bf0 --- /dev/null +++ b/src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaType.kt @@ -0,0 +1,19 @@ +package io.github.optimumcode.json.schema.internal + +import kotlin.jvm.JvmStatic + +internal enum class SchemaType( + private val schemaId: String, +) { + DRAFT_7("json-schema.org/draft-07/schema"), + ; + + companion object { + @JvmStatic + fun find(schemaId: String): SchemaType? { + val id = schemaId.substringAfter("://") + .substringBeforeLast(ROOT_REFERENCE) + return values().find { it.schemaId == id } + } + } +} \ No newline at end of file diff --git a/src/commonTest/kotlin/io/github/optimumcode/json/schema/base/JsonSchemaTest.kt b/src/commonTest/kotlin/io/github/optimumcode/json/schema/base/JsonSchemaTest.kt index 4af74052..816248b0 100644 --- a/src/commonTest/kotlin/io/github/optimumcode/json/schema/base/JsonSchemaTest.kt +++ b/src/commonTest/kotlin/io/github/optimumcode/json/schema/base/JsonSchemaTest.kt @@ -148,5 +148,43 @@ class JsonSchemaTest : FunSpec() { ) } } + + listOf( + "http://json-schema.org/draft-07/schema#", + "http://json-schema.org/draft-07/schema", + "https://json-schema.org/draft-07/schema#", + "https://json-schema.org/draft-07/schema", + ).forEach { + test("loads schema with supported '$it' \$schema property") { + shouldNotThrowAny { + JsonSchema.fromDefinition( + """ + { + "${KEY}schema": "$it", + "type": "string" + } + """.trimIndent(), + ) + } + } + } + + listOf( + "https://json-schema.org/draft/2020-12/schema", + "http://json-schema.org/draft-07/schema/", + ).forEach { + test("reports unsupported '$it' \$schema property") { + shouldThrow { + JsonSchema.fromDefinition( + """ + { + "${KEY}schema": "$it", + "type": "string" + } + """.trimIndent(), + ) + }.message shouldBe "unsupported schema type $it" + } + } } } \ No newline at end of file From 64c3b5a434c742049d24456bb0e5e89ff1683a6f Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sun, 23 Jul 2023 14:54:02 +0400 Subject: [PATCH 3/3] Tag list point in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a53c9f85..3e4ae132 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ val valid = schema.validate(elementToValidate, errors::add) ## Future plans -- [ ] Add `$schema` property validation (if not set the latest supported will be used) +- [x] Add `$schema` property validation (if not set the latest supported will be used) - [ ] Add proper `$id` support (for nested schemas and for referencing) - [ ] Add support for newer drafts - [ ] [Draft 2019-09 (Draft 8)](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8)