From e85e5991ef5af0fb0fecccf757d61d03a1432a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Tue, 4 Jan 2022 12:18:27 +0100 Subject: [PATCH] Enhancement: Adjust SchemaNormalizer to support anyOf --- CHANGELOG.md | 15 +++++++-- psalm-baseline.xml | 8 +++-- src/SchemaNormalizer.php | 23 +++++++++++++ .../Schema/HasAnyOf/Direct/normalized.json | 11 +++++++ .../Schema/HasAnyOf/Direct/original.json | 11 +++++++ .../Schema/HasAnyOf/Direct/schema.json | 22 +++++++++++++ .../HasAnyOf/HasReference/normalized.json | 11 +++++++ .../HasAnyOf/HasReference/original.json | 11 +++++++ .../Schema/HasAnyOf/HasReference/schema.json | 33 +++++++++++++++++++ .../IsObject/Schema/HasAnyOf/normalized.json | 8 +++++ .../IsObject/Schema/HasAnyOf/original.json | 8 +++++ .../Data/IsObject/Schema/HasAnyOf/schema.json | 31 +++++++++++++++++ 12 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/normalized.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/original.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/schema.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/normalized.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/original.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/schema.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/normalized.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/original.json create mode 100644 test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/schema.json diff --git a/CHANGELOG.md b/CHANGELOG.md index df51aa00..e0dc59f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased -For a full diff see [`2.0.0...main`][2.0.0...main]. +For a full diff see [`2.1.0...main`][2.1.0...main]. + +## [`2.1.0`][2.1.0] + +For a full diff see [`2.0.0...2.1.0`][2.0.0...2.1.0]. + +### Changed + +- Adjusted `SchemaNormalizer` to support `anyOf` ([#623]), by [@localheinz] ## [`2.0.0`][2.0.0] @@ -346,6 +354,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [1.0.2]: https://github.com/ergebnis/json-normalizer/releases/tag/1.0.2 [1.0.3]: https://github.com/ergebnis/json-normalizer/releases/tag/1.0.3 [2.0.0]: https://github.com/ergebnis/json-normalizer/releases/tag/2.0.0 +[2.1.0]: https://github.com/ergebnis/json-normalizer/releases/tag/2.1.0 [5d8b3e2...0.1.0]: https://github.com/ergebnis/json-normalizer/compare/5d8b3e2...0.1.0 [0.1.0...0.2.0]: https://github.com/ergebnis/json-normalizer/compare/0.1.0...0.2.0 @@ -371,7 +380,8 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [1.0.1...1.0.2]: https://github.com/ergebnis/json-normalizer/compare/1.0.1...1.0.2 [1.0.2...1.0.3]: https://github.com/ergebnis/json-normalizer/compare/1.0.2...1.0.3 [1.0.3...2.0.0]: https://github.com/ergebnis/json-normalizer/compare/1.0.3...2.0.0 -[2.0.0...main]: https://github.com/ergebnis/json-normalizer/compare/2.0.0...main +[2.0.0...2.1.0]: https://github.com/ergebnis/json-normalizer/compare/2.0.0...2.1.0 +[2.1.0...main]: https://github.com/ergebnis/json-normalizer/compare/2.1.0...main [#1]: https://github.com/ergebnis/json-normalizer/pull/1 [#2]: https://github.com/ergebnis/json-normalizer/pull/2 @@ -450,6 +460,7 @@ For a full diff see [`5d8b3e2...0.1.0`][5d8b3e2...0.1.0]. [#616]: https://github.com/ergebnis/json-normalizer/pull/616 [#618]: https://github.com/ergebnis/json-normalizer/pull/618 [#619]: https://github.com/ergebnis/json-normalizer/pull/619 +[#623]: https://github.com/ergebnis/json-normalizer/pull/623 [@BackEndTea]: https://github.com/BackEndTea [@dependabot]: https://github.com/dependabot diff --git a/psalm-baseline.xml b/psalm-baseline.xml index cf14d9b9..3fdbb2bc 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + Json @@ -21,7 +21,8 @@ $data - + + $anyOfSchema $item $item $itemSchema @@ -29,7 +30,8 @@ $schema->properties $value - + + $anyOfSchema $itemSchema $oneOfSchema $value diff --git a/src/SchemaNormalizer.php b/src/SchemaNormalizer.php index 8e90f6af..750edc41 100644 --- a/src/SchemaNormalizer.php +++ b/src/SchemaNormalizer.php @@ -222,6 +222,29 @@ private function resolveSchema( $data, \stdClass $schema ): \stdClass { + /** + * @see https://spacetelescope.github.io/understanding-json-schema/reference/combining.html#anyof + */ + if ( + \property_exists($schema, 'anyOf') + && \is_array($schema->anyOf) + ) { + foreach ($schema->anyOf as $anyOfSchema) { + $result = $this->schemaValidator->validate( + SchemaValidator\Json::fromString(\json_encode($data)), + SchemaValidator\Json::fromString(\json_encode($anyOfSchema)), + SchemaValidator\JsonPointer::empty(), + ); + + if ($result->isValid()) { + return $this->resolveSchema( + $data, + $anyOfSchema, + ); + } + } + } + /** * @see https://spacetelescope.github.io/understanding-json-schema/reference/combining.html#oneof */ diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/normalized.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/normalized.json new file mode 100644 index 00000000..6b71f6b8 --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/normalized.json @@ -0,0 +1,11 @@ +[ + { + "type": "Website", + "url": "https://localheinz.com" + }, + "https://github.com/localheinz", + { + "type": "Twitter", + "url": "https://twitter.com/localheinz" + } +] diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/original.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/original.json new file mode 100644 index 00000000..42fbbb2f --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/original.json @@ -0,0 +1,11 @@ +[ + { + "url": "https://localheinz.com", + "type": "Website" + }, + "https://github.com/localheinz", + { + "url": "https://twitter.com/localheinz", + "type": "Twitter" + } +] diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/schema.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/schema.json new file mode 100644 index 00000000..664568cd --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/Direct/schema.json @@ -0,0 +1,22 @@ +{ + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + { + "type": "string" + } + ] + } +} diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/normalized.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/normalized.json new file mode 100644 index 00000000..6b71f6b8 --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/normalized.json @@ -0,0 +1,11 @@ +[ + { + "type": "Website", + "url": "https://localheinz.com" + }, + "https://github.com/localheinz", + { + "type": "Twitter", + "url": "https://twitter.com/localheinz" + } +] diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/original.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/original.json new file mode 100644 index 00000000..42fbbb2f --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/original.json @@ -0,0 +1,11 @@ +[ + { + "url": "https://localheinz.com", + "type": "Website" + }, + "https://github.com/localheinz", + { + "url": "https://twitter.com/localheinz", + "type": "Twitter" + } +] diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/schema.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/schema.json new file mode 100644 index 00000000..5076f5e1 --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsArray/Schema/HasAnyOf/HasReference/schema.json @@ -0,0 +1,33 @@ +{ + "type": "array", + "items": { + "$ref": "#/definitions/url" + }, + "definitions": { + "url": { + "anyOf": [ + { + "$ref": "#/definitions/url-object" + }, + { + "$ref": "#/definitions/url-string" + } + ] + }, + "url-object": { + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "url-string": { + "type": "string" + } + } +} diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/normalized.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/normalized.json new file mode 100644 index 00000000..e29732a3 --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/normalized.json @@ -0,0 +1,8 @@ +{ + "name": "Andreas Möller", + "urls": [ + "https://localheinz.com", + "https://github.com/localheinz", + "https://twitter.com/localheinz" + ] +} diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/original.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/original.json new file mode 100644 index 00000000..00f2aaa7 --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/original.json @@ -0,0 +1,8 @@ +{ + "urls": [ + "https://localheinz.com", + "https://github.com/localheinz", + "https://twitter.com/localheinz" + ], + "name": "Andreas Möller" +} diff --git a/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/schema.json b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/schema.json new file mode 100644 index 00000000..546978ef --- /dev/null +++ b/test/Fixture/SchemaNormalizer/NormalizeNormalizes/Data/IsObject/Schema/HasAnyOf/schema.json @@ -0,0 +1,31 @@ +{ + "anyOf": [ + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "urls": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false + } + ] +}