Skip to content

Commit a2a8309

Browse files
authored
Support $schema property to identify schema draft to use (#16)
Resolves #13
1 parent 73fa548 commit a2a8309

File tree

5 files changed

+72
-2
lines changed

5 files changed

+72
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ val valid = schema.validate(elementToValidate, errors::add)
155155

156156
## Future plans
157157

158-
- [ ] Add `$schema` property validation (if not set the latest supported will be used)
158+
- [x] Add `$schema` property validation (if not set the latest supported will be used)
159159
- [ ] Add proper `$id` support (for nested schemas and for referencing)
160160
- [ ] Add support for newer drafts
161161
- [ ] [Draft 2019-09 (Draft 8)](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8)

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ kotlin.js.compiler=ir
33
org.gradle.jvmargs=-Xmx1G
44
org.gradle.java.installations.auto-download=false
55

6-
version=0.0.1-SNAPSHOT
6+
version=0.0.2-SNAPSHOT
77
group=io.github.optimumcode

src/commonMain/kotlin/io/github/optimumcode/json/schema/internal/SchemaLoader.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,13 @@ private val factories: List<AssertionFactory> = listOf(
7171
private const val DEFINITIONS_PROPERTY: String = "definitions"
7272
private const val ID_PROPERTY: String = "\$id"
7373
private const val REF_PROPERTY: String = "\$ref"
74+
private const val SCHEMA_PROPERTY: String = "\$schema"
7475

7576
internal const val ROOT_REFERENCE = '#'
7677

7778
internal class SchemaLoader {
7879
fun load(schemaDefinition: JsonElement): JsonSchema {
80+
extractSchemaType(schemaDefinition)
7981
val baseId = extractBaseID(schemaDefinition)
8082
val context = defaultLoadingContext(baseId)
8183
loadDefinitions(schemaDefinition, context)
@@ -84,6 +86,17 @@ internal class SchemaLoader {
8486
return JsonSchema(schemaAssertion, context.references)
8587
}
8688

89+
private fun extractSchemaType(schemaDefinition: JsonElement): SchemaType {
90+
return if (schemaDefinition is JsonObject) {
91+
schemaDefinition[SCHEMA_PROPERTY]?.let {
92+
require(it is JsonPrimitive && it.isString) { "$SCHEMA_PROPERTY must be a string" }
93+
SchemaType.find(it.content) ?: throw IllegalArgumentException("unsupported schema type ${it.content}")
94+
} ?: SchemaType.values().last()
95+
} else {
96+
SchemaType.values().last()
97+
}
98+
}
99+
87100
private fun loadDefinitions(schemaDefinition: JsonElement, context: DefaultLoadingContext) {
88101
if (schemaDefinition !is JsonObject) {
89102
return
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.github.optimumcode.json.schema.internal
2+
3+
import kotlin.jvm.JvmStatic
4+
5+
internal enum class SchemaType(
6+
private val schemaId: String,
7+
) {
8+
DRAFT_7("json-schema.org/draft-07/schema"),
9+
;
10+
11+
companion object {
12+
@JvmStatic
13+
fun find(schemaId: String): SchemaType? {
14+
val id = schemaId.substringAfter("://")
15+
.substringBeforeLast(ROOT_REFERENCE)
16+
return values().find { it.schemaId == id }
17+
}
18+
}
19+
}

src/commonTest/kotlin/io/github/optimumcode/json/schema/base/JsonSchemaTest.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,43 @@ class JsonSchemaTest : FunSpec() {
148148
)
149149
}
150150
}
151+
152+
listOf(
153+
"http://json-schema.org/draft-07/schema#",
154+
"http://json-schema.org/draft-07/schema",
155+
"https://json-schema.org/draft-07/schema#",
156+
"https://json-schema.org/draft-07/schema",
157+
).forEach {
158+
test("loads schema with supported '$it' \$schema property") {
159+
shouldNotThrowAny {
160+
JsonSchema.fromDefinition(
161+
"""
162+
{
163+
"${KEY}schema": "$it",
164+
"type": "string"
165+
}
166+
""".trimIndent(),
167+
)
168+
}
169+
}
170+
}
171+
172+
listOf(
173+
"https://json-schema.org/draft/2020-12/schema",
174+
"http://json-schema.org/draft-07/schema/",
175+
).forEach {
176+
test("reports unsupported '$it' \$schema property") {
177+
shouldThrow<IllegalArgumentException> {
178+
JsonSchema.fromDefinition(
179+
"""
180+
{
181+
"${KEY}schema": "$it",
182+
"type": "string"
183+
}
184+
""".trimIndent(),
185+
)
186+
}.message shouldBe "unsupported schema type $it"
187+
}
188+
}
151189
}
152190
}

0 commit comments

Comments
 (0)