Skip to content

Commit

Permalink
Support patternProperties when converting to a dynamic object
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelmior committed Mar 7, 2024
1 parent aa2078e commit 15b97e3
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- Support `patternProperties` when converting to a dynamic object

### Fixed
- Fix some anomaly checking with `patternProperties`
- Fix some anomaly checking with `additionalProperties`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,26 @@ final case class ObjectSchema(
super.collectAnomalies(value, path)(p, tag)
}
}

def toDynamicObjectSchema()(implicit
p: JsonoidParams
): DynamicObjectSchema = {
// Get all types from objects and patterns
val objectTypes = properties.get[ObjectTypesProperty].objectTypes.values
val patternTypes = properties
.getOrNone[PatternTypesProperty]
.map(_.patternTypes.values)
.getOrElse(Iterator.empty)

// Combine all types into a single schema
val valueType =
(objectTypes ++ patternTypes).fold(ZeroSchema())(_.merge(_)(p))

// Generate the new schema
val props = SchemaProperties.empty[Map[String, JsonSchema[_]]]
props.add(DynamicObjectTypeProperty(valueType))
DynamicObjectSchema(props)(p)
}
}

/** The types of all keys in an object schema.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,7 @@ object DynamicObjectTransformer extends SchemaWalker[ObjectSchema] {
objects.foreach { case (path, objSchema) =>
// Construct thew new final type
val pointer = pathToInexactPointer(path)
val objectTypes =
objSchema.properties.get[ObjectTypesProperty].objectTypes
val valueType = objectTypes.values.fold(ZeroSchema())(_.merge(_))

// Generate the new schema
val props = SchemaProperties.empty[Map[String, JsonSchema[_]]]
props.add(DynamicObjectTypeProperty(valueType))
val newSchema = DynamicObjectSchema(props)(p)
val newSchema = objSchema.toDynamicObjectSchema()(p)

finalSchema = finalSchema.replaceWithSchema(pointer, newSchema)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ class DynamicObjectTransformerSpec extends UnitSpec {
.valueType shouldBe a[StringSchema]
}

it should "replace dynamic objects with patternProperties" in {
var props = ObjectSchema().properties
props.add(PatternTypesProperty(Map("foo.*".r -> IntegerSchema())))
for (i <- 1 to 11) {
props = props.mergeValue(Map("a" * i -> StringSchema()))
}

val transformedSchema =
DynamicObjectTransformer.transformSchema(ObjectSchema(props))
transformedSchema shouldBe a[DynamicObjectSchema]
transformedSchema
.asInstanceOf[DynamicObjectSchema]
.properties
.get[DynamicObjectTypeProperty]
.valueType shouldBe a[ProductSchema]
}

it should "not replace objects with static keys" in {
var props = ObjectSchema().properties
for (_ <- 1 to 11) {
Expand Down

0 comments on commit 15b97e3

Please sign in to comment.