-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #145 from mattpolzin/v2/142/schema-dereferencing-v…
…s-resolution allow dereferenced JSON schemas to still contain allOf components
- Loading branch information
Showing
6 changed files
with
275 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
Sources/OpenAPIKit/Schema Object/SimplifiedJSONSchema.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// | ||
// SimplifiedJSONSchema.swift | ||
// | ||
// | ||
// Created by Mathew Polzin on 9/4/20. | ||
// | ||
|
||
import Foundation | ||
|
||
extension JSONSchema { | ||
/// Get a simplified `DereferencedJSONSchema`. | ||
/// | ||
/// A fully simplified JSON Schema is both dereferenced and also | ||
/// reduced to a more normal form where possible. | ||
/// | ||
/// As an example, many compound schemas can be simplified. | ||
/// | ||
/// { | ||
/// "allOf": [ | ||
/// { "type": "object", "description": "Hello World" }, | ||
/// { | ||
/// "properties": [ | ||
/// "name": { "type": "string" } | ||
/// ] | ||
/// } | ||
/// ] | ||
/// } | ||
/// | ||
/// simplifies to -> | ||
/// | ||
/// { | ||
/// "type": "object", | ||
/// "description": "Hello World", | ||
/// "properties": [ | ||
/// "name": { "type": "string" } | ||
/// ] | ||
/// } | ||
/// | ||
/// You can create simplified schemas from the `DereferencedJSONSchema` | ||
/// type with the `simplified()` method or you can create simplified schemas from | ||
/// the `JSONSchema` type with the `simplified(given:)` method (which | ||
/// combines dereferencing and resolving by taking the `OpenAPI.Components` as | ||
/// input). | ||
public func simplified(given components: OpenAPI.Components) throws -> DereferencedJSONSchema { | ||
return try self.dereferenced(in: components).simplified() | ||
} | ||
} | ||
|
||
extension DereferencedJSONSchema { | ||
/// Get a simplified `DereferencedJSONSchema`. | ||
/// | ||
/// A fully simplified JSON Schema is both dereferenced and also | ||
/// reduced to a more normal form where possible. | ||
/// | ||
/// As an example, many compound schemas can be simplified. | ||
/// | ||
/// { | ||
/// "allOf": [ | ||
/// { "type": "object", "description": "Hello World" }, | ||
/// { | ||
/// "properties": [ | ||
/// "name": { "type": "string" } | ||
/// ] | ||
/// } | ||
/// ] | ||
/// } | ||
/// | ||
/// simplifies to -> | ||
/// | ||
/// { | ||
/// "type": "object", | ||
/// "description": "Hello World", | ||
/// "properties": [ | ||
/// "name": { "type": "string" } | ||
/// ] | ||
/// } | ||
/// | ||
/// You can create simplified schemas from the `DereferencedJSONSchema` | ||
/// type with the `simplified()` method or you can create simplified schemas from | ||
/// the `JSONSchema` type with the `simplified(given:)` method (which | ||
/// combines dereferencing and resolving by taking the `OpenAPI.Components` as | ||
/// input). | ||
public func simplified() throws -> DereferencedJSONSchema { | ||
let dereferencedSchema: DereferencedJSONSchema | ||
switch self { | ||
case .all: | ||
var resolver = FragmentCombiner(components: .noComponents) | ||
try resolver.combine(self.jsonSchema) | ||
dereferencedSchema = try resolver.dereferencedSchema() | ||
|
||
// we don't currently have any schema resolution steps other than | ||
// combining allOf schemas. We do need to dig into any other compound | ||
// schemas to attempt to resolve them, though. | ||
|
||
case .object(let core, let object): | ||
let additionalProperties: Either<Bool, DereferencedJSONSchema>? = try object.additionalProperties.map { | ||
switch $0 { | ||
case .a(let bool): | ||
return .a(bool) | ||
case .b(let schema): | ||
return .b(try schema.simplified()) | ||
} | ||
} | ||
dereferencedSchema = .object( | ||
core, | ||
.init( | ||
properties: try object.properties.mapValues { try $0.simplified() }, | ||
additionalProperties: additionalProperties, | ||
maxProperties: object.maxProperties, | ||
minProperties: object._minProperties | ||
) | ||
) | ||
|
||
case .array(let core, let array): | ||
dereferencedSchema = .array( | ||
core, | ||
.init( | ||
items: try array.items.map { try $0.simplified() }, | ||
maxItems: array.maxItems, | ||
minItems: array._minItems, | ||
uniqueItems: array._uniqueItems | ||
) | ||
) | ||
|
||
case .any(of: let schemas, core: let core): | ||
dereferencedSchema = .any(of: try schemas.map { try $0.simplified() }, core: core) | ||
|
||
case .one(of: let schemas, core: let core): | ||
dereferencedSchema = .one(of: try schemas.map { try $0.simplified() }, core: core) | ||
|
||
case .not(let schema, core: let core): | ||
dereferencedSchema = .not(try schema.simplified(), core: core) | ||
|
||
default: | ||
dereferencedSchema = self | ||
} | ||
|
||
return dereferencedSchema | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.