Skip to content

Commit 0872835

Browse files
authored
Merge pull request #7 from mattpolzin/resolved-openapi
Update OpenAPIKit and used ResolvedRoute + ResolvedEndpoint
2 parents 64a2d2b + 0a3ee75 commit 0872835

20 files changed

+757
-345
lines changed

Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
"repositoryURL": "https://github.com/mattpolzin/OpenAPIKit",
5252
"state": {
5353
"branch": null,
54-
"revision": "b1b2ad648ca983bd012391ad61d3ab246a104836",
55-
"version": "1.1.0"
54+
"revision": "201586db9dcce99d148eed12cc556a0c86c3355e",
55+
"version": "1.4.0"
5656
}
5757
},
5858
{

Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ let package = Package(
1818
dependencies: [
1919
.package(url: "https://github.com/mattpolzin/Sampleable", from: "2.0.0"),
2020
.package(url: "https://github.com/mattpolzin/JSONAPI", from: "4.0.0"),
21-
.package(url: "https://github.com/mattpolzin/OpenAPIKit", from: "1.0.0"),
21+
.package(url: "https://github.com/mattpolzin/OpenAPIKit", from: "1.4.0"),
2222
.package(url: "https://github.com/mattpolzin/OpenAPIReflection", .upToNextMinor(from: "0.3.0")),
2323
.package(url: "https://github.com/typelift/SwiftCheck", .upToNextMinor(from: "0.12.0")),
2424
.package(url: "https://github.com/apple/swift-format", from: "0.50200.1"),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// Optional+ZipWith.swift
3+
// JSONAPIOpenAPI
4+
//
5+
// Created by Mathew Polzin on 1/19/19.
6+
//
7+
8+
/// Zip two optionals together with the given operation performed on
9+
/// the unwrapped contents. If either optional is nil, the zip
10+
/// yields nil.
11+
func zip<X, Y, Z>(_ left: X?, _ right: Y?, with fn: (X, Y) -> Z) -> Z? {
12+
return left.flatMap { lft in right.map { rght in fn(lft, rght) }}
13+
}

Sources/JSONAPISwiftGen/ResourceObjectSwiftGenCollection.swift

+7-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import OpenAPIKit
1010
public struct ResourceObjectSwiftGenCollection {
1111
public let resourceObjectGenerators: [ResourceObjectSwiftGen]
1212

13-
public init(_ doc: OpenAPI.Document, testSuiteConfiguration: TestSuiteConfiguration) throws {
13+
public init(_ doc: DereferencedDocument, testSuiteConfiguration: TestSuiteConfiguration) throws {
1414
let pathItems = doc.paths
1515

1616
resourceObjectGenerators = OpenAPI.HttpMethod.allCases
@@ -30,7 +30,7 @@ public struct ResourceObjectSwiftGenCollection {
3030
for: httpVerb,
3131
at: path,
3232
on: doc.servers.first!,
33-
given: parameters.compactMap { $0.b },
33+
given: parameters,
3434
testSuiteConfiguration: testSuiteConfiguration
3535
).values.flatMap { Array($0.resourceObjectGenerators) }
3636
}
@@ -41,23 +41,21 @@ public struct ResourceObjectSwiftGenCollection {
4141
}
4242

4343
func documents(
44-
from responses: OpenAPI.Response.Map,
44+
from responses: DereferencedResponse.Map,
4545
for httpVerb: OpenAPI.HttpMethod,
4646
at path: OpenAPI.Path,
4747
on server: OpenAPI.Server,
48-
given params: [OpenAPI.Parameter],
48+
given params: [DereferencedParameter],
4949
testSuiteConfiguration: TestSuiteConfiguration
5050
) -> [OpenAPI.Response.StatusCode: DataDocumentSwiftGen] {
5151
var responseDocuments = [OpenAPI.Response.StatusCode: DataDocumentSwiftGen]()
5252
for (statusCode, response) in responses {
5353

54-
guard let jsonResponse = response.b?.content[.json] else {
54+
guard let jsonResponse = response.content[.json] else {
5555
continue
5656
}
5757

58-
guard let responseSchema = jsonResponse.schema.b else {
59-
continue
60-
}
58+
let responseSchema = jsonResponse.schema
6159

6260
guard case .object = responseSchema else {
6361
print("Found non-object response schema root (expected JSON:API 'data' object). Skipping '\(String(describing: responseSchema.jsonTypeFormat?.jsonType))'.")
@@ -78,7 +76,7 @@ func documents(
7876
example = nil
7977
}
8078

81-
let testExampleFuncs: [SwiftFunctionGenerator]
79+
let testExampleFuncs: [TestFunctionGenerator]
8280
do {
8381
let responseBodyType = SwiftTypeRep(.init(name: responseBodyTypeName))
8482
if let testPropertiesDict = jsonResponse.vendorExtensions["x-tests"]?.value as? [String: Any] {

Sources/JSONAPISwiftGen/Swift Generators/DocumentSwiftGen.swift

+124-62
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ import JSONAPI
1414
/// and build a representation of a JSON:API Document that can handle both
1515
/// Data and Error cases.
1616
public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
17-
public let structure: JSONSchema
17+
public let structure: DereferencedJSONSchema
1818
public let decls: [Decl]
1919
public let swiftTypeName: String
2020
public let resourceObjectGenerators: Set<ResourceObjectSwiftGen>
2121
public let exampleGenerator: ExampleSwiftGen?
22-
public let testExampleFuncs: [SwiftFunctionGenerator]
22+
public let testExampleFuncs: [TestFunctionGenerator]
2323

2424
/// Generate Swift code not just for this Document's declaration but
2525
/// also for all declarations required for this Document to compile.
@@ -30,23 +30,29 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
3030
.joined(separator: "\n")
3131
}
3232

33-
public init(swiftTypeName: String,
34-
structure: JSONSchema,
35-
allowPlaceholders: Bool = true,
36-
example: ExampleSwiftGen? = nil,
37-
testExampleFuncs: [SwiftFunctionGenerator] = []) throws {
33+
public init(
34+
swiftTypeName: String,
35+
structure: DereferencedJSONSchema,
36+
allowPlaceholders: Bool = true,
37+
example: ExampleSwiftGen? = nil,
38+
testExampleFuncs: [TestFunctionGenerator] = []
39+
) throws {
3840
self.swiftTypeName = swiftTypeName
3941
self.structure = structure
4042
self.exampleGenerator = example
4143
self.testExampleFuncs = testExampleFuncs
4244

43-
(decls, resourceObjectGenerators) = try DataDocumentSwiftGen.swiftDecls(from: structure,
44-
swiftTypeName: swiftTypeName,
45-
allowPlaceholders: allowPlaceholders)
45+
(decls, resourceObjectGenerators) = try DataDocumentSwiftGen.swiftDecls(
46+
from: structure,
47+
swiftTypeName: swiftTypeName,
48+
allowPlaceholders: allowPlaceholders
49+
)
4650
}
4751

48-
static func swiftDeclsForErrorDocument(from resourceObjectContext: JSONSchema.ObjectContext,
49-
swiftTypeName: String) throws -> [Decl] {
52+
static func swiftDeclsForErrorDocument(
53+
from resourceObjectContext: DereferencedJSONSchema.ObjectContext,
54+
swiftTypeName: String
55+
) throws -> [Decl] {
5056
guard let errorsSchema = resourceObjectContext.properties["errors"],
5157
case .array(_, let arrayContext) = errorsSchema,
5258
let errorsItems = arrayContext.items else {
@@ -58,35 +64,53 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
5864

5965
let errorsItemsDecls: [Decl]
6066
do { //GenericJSONAPIError<ErrorPayload>
61-
let errorTypealias = Typealias(alias: .def(.init(name: errorTypeName)),
62-
existingType: .def(.init(name: "GenericJSONAPIError",
63-
specializationReps: [.def(.init(name: errorPayloadTypeName))])))
67+
let errorTypealias = Typealias(
68+
alias: .def(
69+
.init(name: errorTypeName)
70+
),
71+
existingType: .def(
72+
.init(
73+
name: "GenericJSONAPIError",
74+
specializationReps: [.def(.init(name: errorPayloadTypeName))]
75+
)
76+
)
77+
)
6478

65-
errorsItemsDecls = try StructureSwiftGen(swiftTypeName: errorPayloadTypeName,
66-
structure: errorsItems,
67-
cascadingConformances: ["Codable", "Equatable"]).decls
79+
errorsItemsDecls = try StructureSwiftGen(
80+
swiftTypeName: errorPayloadTypeName,
81+
structure: errorsItems,
82+
cascadingConformances: ["Codable", "Equatable"]
83+
).decls
6884
+ [errorTypealias]
6985
} catch let error {
7086
throw Error.failedToCreateErrorsStructure(underlyingError: error)
7187
}
7288

73-
let documentTypealiasDecl = Typealias(alias: .def(.init(name: swiftTypeName)),
74-
existingType: .def(.init(name: "JSONAPI.Document",
75-
specializationReps: [
76-
.init(NoResourceBody.self),
77-
.init(NoMetadata.self),
78-
.init(NoLinks.self),
79-
.init(NoIncludes.self),
80-
.init(NoAPIDescription.self),
81-
.def(.init(name: errorTypeName))
82-
])))
89+
let documentTypealiasDecl = Typealias(
90+
alias: .def(.init(name: swiftTypeName)),
91+
existingType: .def(
92+
.init(
93+
name: "JSONAPI.Document",
94+
specializationReps: [
95+
.init(NoResourceBody.self),
96+
.init(NoMetadata.self),
97+
.init(NoLinks.self),
98+
.init(NoIncludes.self),
99+
.init(NoAPIDescription.self),
100+
.def(.init(name: errorTypeName))
101+
]
102+
)
103+
)
104+
)
83105

84106
return errorsItemsDecls + [documentTypealiasDecl]
85107
}
86108

87-
static func swiftDecls(from structure: JSONSchema,
88-
swiftTypeName: String,
89-
allowPlaceholders: Bool) throws -> ([Decl], Set<ResourceObjectSwiftGen>) {
109+
static func swiftDecls(
110+
from structure: DereferencedJSONSchema,
111+
swiftTypeName: String,
112+
allowPlaceholders: Bool
113+
) throws -> ([Decl], Set<ResourceObjectSwiftGen>) {
90114
guard case let .object(_, resourceObjectContextB) = structure else {
91115
throw Error.rootNotJSONObject
92116
}
@@ -115,19 +139,29 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
115139
let primaryResourceTypeName: String
116140
switch data {
117141
case .object:
118-
let resourceObject = try ResourceObjectSwiftGen(structure: data,
119-
allowPlaceholders: allowPlaceholders)
142+
let resourceObject = try ResourceObjectSwiftGen(
143+
structure: data,
144+
allowPlaceholders: allowPlaceholders
145+
)
120146
primaryResourceTypeName = resourceObject.resourceTypeName
121147

122148
let isNullablePrimaryResource = data.nullable
123149

124150
// SingleResourceBody<PrimaryResource>
125-
primaryResourceBodyType = .def(.init(name: "SingleResourceBody",
126-
specializationReps: [
127-
.def(.init(name: primaryResourceTypeName,
128-
specializationReps: [],
129-
optional: isNullablePrimaryResource))
130-
]))
151+
primaryResourceBodyType = .def(
152+
.init(
153+
name: "SingleResourceBody",
154+
specializationReps: [
155+
.def(
156+
.init(
157+
name: primaryResourceTypeName,
158+
specializationReps: [],
159+
optional: isNullablePrimaryResource
160+
)
161+
)
162+
]
163+
)
164+
)
131165

132166
allResourceObjectGenerators.insert(resourceObject)
133167

@@ -137,15 +171,25 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
137171
throw Error.expectedDataArrayToDefineItems
138172
}
139173

140-
let resourceObject = try ResourceObjectSwiftGen(structure: dataItem,
141-
allowPlaceholders: allowPlaceholders)
174+
let resourceObject = try ResourceObjectSwiftGen(
175+
structure: dataItem,
176+
allowPlaceholders: allowPlaceholders
177+
)
142178
primaryResourceTypeName = resourceObject.resourceTypeName
143179

144-
primaryResourceBodyType = .def(.init(name: "ManyResourceBody",
145-
specializationReps: [
146-
.def(.init(name: primaryResourceTypeName,
147-
specializationReps: []))
148-
]))
180+
primaryResourceBodyType = .def(
181+
.init(
182+
name: "ManyResourceBody",
183+
specializationReps: [
184+
.def(
185+
.init(
186+
name: primaryResourceTypeName,
187+
specializationReps: []
188+
)
189+
)
190+
]
191+
)
192+
)
149193

150194
allResourceObjectGenerators.insert(resourceObject)
151195

@@ -169,35 +213,53 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
169213
switch items {
170214
case .one(of: let resourceTypeSchemas, _):
171215
resources = try Array(Set(resourceTypeSchemas.map {
172-
try ResourceObjectSwiftGen(structure: $0,
173-
allowPlaceholders: allowPlaceholders)
216+
try ResourceObjectSwiftGen(
217+
structure: $0,
218+
allowPlaceholders: allowPlaceholders
219+
)
174220
})).sorted { $0.resourceTypeName < $1.resourceTypeName }
175221
default:
176-
resources = [try ResourceObjectSwiftGen(structure: items,
177-
allowPlaceholders: allowPlaceholders)]
222+
resources = [
223+
try ResourceObjectSwiftGen(
224+
structure: items,
225+
allowPlaceholders: allowPlaceholders
226+
)
227+
]
178228
}
179229

180230
let resourceTypes = resources.map { SwiftTypeRep.def(.init(name: $0.resourceTypeName)) }
181231

182-
includeType = .def(.init(name: "Include\(resourceTypes.count)",
183-
specializationReps: resourceTypes))
232+
includeType = .def(
233+
.init(
234+
name: "Include\(resourceTypes.count)",
235+
specializationReps: resourceTypes
236+
)
237+
)
184238

185239

186240
allResourceObjectGenerators = allResourceObjectGenerators.union(resources)
187241
} else {
188242
includeType = .rep(NoIncludes.self)
189243
}
190244

191-
allDecls.append(Typealias(alias: .def(.init(name: swiftTypeName)),
192-
existingType: .def(.init(name: "JSONAPI.Document",
193-
specializationReps: [
194-
primaryResourceBodyType,
195-
.init(NoMetadata.self),
196-
.init(NoLinks.self),
197-
includeType,
198-
.init(NoAPIDescription.self),
199-
"BasicJSONAPIError<AnyCodable>"
200-
]))))
245+
allDecls.append(
246+
Typealias(
247+
alias: .def(.init(name: swiftTypeName)),
248+
existingType: .def(
249+
.init(
250+
name: "JSONAPI.Document",
251+
specializationReps: [
252+
primaryResourceBodyType,
253+
.init(NoMetadata.self),
254+
.init(NoLinks.self),
255+
includeType,
256+
.init(NoAPIDescription.self),
257+
"BasicJSONAPIError<AnyCodable>"
258+
]
259+
)
260+
)
261+
)
262+
)
201263

202264
return (allDecls, allResourceObjectGenerators)
203265
}

0 commit comments

Comments
 (0)