Releases: mattpolzin/OpenAPIKit
Dynamite
What's Changed
- Fix bug where headers were not allowed to define
explode
when decoding (#301)
Full Changelog: 2.6.0...2.6.1
Names are Forever
In this PR, the process of locally dereferencing a document (i.e. document.locallyDereferenced()
) will also use a new vendor extension to keep track of the Component Object name where any locally dereferenced objects used to be found.
For example, when resolving a JSONReference<Example>
, the resulting Example
will have a vendorExtension
with key x-component-name
and value equal to the name where the newly inlined Example
used to be found in the Components.examples
.
Note that there are three types for which this does not currently happen:
Make an Example of Nothing
What's Changed
- make
value
/externalValue
optional for Example Objects. (#286)
Breaking Changes
The OpenAPI.Example
type's value
property has become optional so you will now need to handle a nil
case or use optional chaining in places where you switch-on or otherwise access that property.
Full Changelog: 3.0.0-alpha.9...3.0.0-beta.1
I Refer You To Your Path
What's Changed
- Fix simplified allOf schema optionality.
- Fix lacking support for Path Item Object references.
This release primarily fixes #280 by allowing Path Items to be references as well as inlined Path Item Objects. This applies to both the OpenAPIKit30
(OpenAPI 3.0.x) and OpenAPIKit
(OpenAPI 3.1.x) modules. However, OpenAPI 3.0.x did not allow Path Item Objects to be stored in the Components Object whereas OpenAPI 3.1.x does, so only external JSON References to Path Item Objects are meaningful when working with OpenAPI 3.0.x.
Noteworthy Differences
OpenAPI.Document
helpers that collect information not stored directly in the document now skip over external JSON References to Path Item Objects. The use of these helpers is the same, but the distinction between internal and external references to Path Item Objects is important here (where before references to Path Item Objects were simply not expressible with OpenAPIKit). These helpers arevar routes: [Route]
,var allOperationIds: [String]
,var allServers: [OpenAPI.Server]
, andvar allTags: Set<String>
.- Because the path to anything in a Document that exists as part of a Path Item Object or its children is now potentially behind a JSON Reference, the error messages for improperly formatted Documents have changed in some cases. They still reflect the same underlying problems, but the verbiage has changed.
- It is now possible to write reference entries to Path Item Objects into the Paths dictionary:
paths: [ "/hello": .reference(.component(named: "path1")) ]
. This internal reference to the Components Object would only be valid for OpenAPI 3.1.x; External references like the following are valid for OpenAPI 3.0.x as well as 3.1.x:paths: [ "/hello": .reference(.external(URL(string: "https://website.com/hi")!)) ]
Breaking Changes
Constructing an entry in the Document.paths
dictionary now requires specifying Either
a JSON Reference to a Path Item Object or the Path Item Object itself -- this means that where you used to write something like:
paths: [
"/hello/world": OpenAPI.PathItem(description: "hi", ...)
]
You will now need to wrap it in an Either
constructor like:
paths: [
"/hello/world": .pathItem(OpenAPI.PathItem(description: "hi", ...))
]
There is also a convenience initializer for Either
in this context which means that you can also write:
paths: [
"/hello/world": .init(description: "hi", ...)
]
You may already have been using the .init
shorthand to construct OpenAPI.PathItem
s in which case your code does not need to change.
Accessing an entry in the Document.paths
dictionary now requires digging into an Either
that may be a JSON Reference or a Path Item Object -- this means that where you used to write something like:
let pathItem = document.paths["hello/world"]
You will now need to decide between the following:
// access the path item (ignoring the possibility that it could be a reference)
let pathItemObject = document.paths["hello/world"]?.pathItemValue
// access the reference directly (ignoring the possibility that it could be a path item object):
let pathItemReference = document.paths["hello/world"]?.reference
// look the path item up in the Components Object (OpenAPIKit module only because this requires OpenAPI 3.1.x):
let pathItem = document.paths["hello/world"].flatMap { document.components[$0] }
// switch on the Either and handle it differently depending on the result:
switch document.paths["hello/world"] {
case .a(let reference):
break
case .b(let pathItem):
break
case nil:
break
}
NOTE: The error you will get in places where you need to make the above adjustments will look like:
Cannot convert value of type 'OpenAPI.PathItem' to expected dictionary value type 'Either<JSONReference<OpenAPI.PathItem>, OpenAPI.PathItem>'
Full Changelog: 3.0.0-alpha.8...3.0.0-alpha.9
All of us need this
Fix a bug with simplification by aligning the required
status of all fragments within an allOf
schema.
Ease Into Compatibility
This release simply exposes additional previously internal functions used to convert OpenAPI 3.0 compatible documents into OpenAPI 3.1 compatible documents.
These newly public functions are not intended to be used directly but using them directly can help downstream maintainers migrate code from the OpenAPIKit30
module to the OpenAPIKit
module gradually instead of all at once so they are being exposed publicly for a limited time. They will be made private in a future release, likely either the final OpenAPIKit 3.0.0 release or perhaps not until the OpenAPIKit 4.0.0 releases. Regardless, they aren't to be relied upon for code that is intended to be permanent.
Last, But Not Least (3)
Some APIs differentiate between trailing slash or not for API paths which means that OpenAPIKit should as well. This fix makes the paths /hello/world
and /hello/world/
distinct and, most importantly, if /hello/world/
is read in, then /hello/world/
is written out -- previously, OpenAPIKit would drop the trailing slash.
Last, But Not Least
Some APIs differentiate between trailing slash or not for API paths which means that OpenAPIKit should as well. This fix makes the paths /hello/world
and /hello/world/
distinct and, most importantly, if /hello/world/
is read in, then /hello/world/
is written out -- previously, OpenAPIKit would drop the trailing slash.
Latest and Greatest
With this version, the new OpenAPIKitCompat
module can be used to take an OpenAPIKit30.OpenAPI.Document
and convert it into an OpenAPIKit.OpenAPI.Document
. In other words, you can convert an OpenAPI v3.0 document into an OpenAPI v3.1 document. Equally as importantly, you can create projects with- (or migrate existing projects over to-) the OpenAPIKit
module where they used to use the OpenAPIKit30
module and support the previous version of the OpenAPI standard by decoding to OpenAPIKit30.OpenAPI.Document
and then calling convert(to: .v3_1_0)
on the result.
For example, a (currently unreleased) branch of the OpenAPIDiff project supports both OpenAPI 3.0 and 3.1 in its main executable while most of the project only cares about OpenAPI 3.1 with the following code that decodes and converts v3.0 documents: https://github.com/mattpolzin/OpenAPIDiff/blob/openapikit-3/Sources/openapi-diff/main.swift#L63..L100
Here's the gist:
// import OpenAPIKit30 for OpenAPI 3.0 document support
import OpenAPIKit30
// import OpenAPIKit for OpenAPI 3.1 document support
import OpenAPIKit
// import OpenAPIKitCompat to convert between the versions
import OpenAPIKitCompat
// if most of your project just works with OpenAPI v3.1, most files only need to import OpenAPIKit.
// Only in the file where you are supporting converting from OpenAPI v3.0 to v3.1 do you need the
// other two imports.
// we can support either version by attempting to parse an old version and then a new version if the old version fails
let oldDoc: OpenAPIKit30.OpenAPI.Document?
let newDoc: OpenAPIKit.OpenAPI.Document
oldDoc = try? JSONDecoder().decode(OpenAPI.Document.self, from: someFileData)
newDoc = oldDoc?.convert(to: .v3_1_0) ??
(try! JSONDecoder().decode(OpenAPI.Document.self, from: someFileData))
Relax (3)
Relax the version requirement for the Yams test dependency so that downstream projects can use more than 1 major version of Yams.