Skip to content

Commit b6d82cd

Browse files
authored
Validate incoming OpenAPI docs using OpenAPIKit's built-in validation (#130)
Validate incoming OpenAPI docs using OpenAPIKit's built-in validation ### Motivation When provided with an OpenAPI document that has recursion, the generator either crashes, or produces Swift code that doesn't compile. We should catch recursion earlier in the process, and emit a descriptive error. ### Modifications This PR adds two validation steps: - OpenAPIKit's `validate` method catches some structural issues in the OpenAPI doc. - OpenAPIKit's `locallyDereferenced()` method is a great way to ensure no reference cycles appear in the document. Catching reference cycles earlier in the process is great, as even if we generate the Swift code, it won't compile until we have some explicit support for recursive types (tracked by #70). ### Result Now, when an OpenAPI document with recursion is provided, instead of crashing or producing non-compiling Swift code, it prints a descriptive error and returns a non-0 code. ### Test Plan Tested manually on the CLI with purposefully malformed documents. But since this isn't our code, I don't want to add detailed tests of the validation details. Reviewed by: simonjbeaumont Builds: ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #130
1 parent 31bb517 commit b6d82cd

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

Sources/_OpenAPIGeneratorCore/GeneratorPipeline.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,39 @@ func makeGeneratorPipeline(
122122
diagnostics: diagnostics
123123
)
124124
},
125-
postTransitionHooks: []
125+
postTransitionHooks: [
126+
{ doc in
127+
128+
// Run OpenAPIKit's built-in validation.
129+
try doc.validate()
130+
131+
// Validate that the document is dereferenceable, which
132+
// catches reference cycles, which we don't yet support.
133+
_ = try doc.locallyDereferenced()
134+
135+
// Also explicitly dereference the parts of components
136+
// that the generator uses. `locallyDereferenced()` above
137+
// only dereferences paths/operations, but not components.
138+
let components = doc.components
139+
try components.schemas.forEach { schema in
140+
_ = try schema.value.dereferenced(in: components)
141+
}
142+
try components.parameters.forEach { schema in
143+
_ = try schema.value.dereferenced(in: components)
144+
}
145+
try components.headers.forEach { schema in
146+
_ = try schema.value.dereferenced(in: components)
147+
}
148+
try components.requestBodies.forEach { schema in
149+
_ = try schema.value.dereferenced(in: components)
150+
}
151+
try components.responses.forEach { schema in
152+
_ = try schema.value.dereferenced(in: components)
153+
}
154+
155+
return doc
156+
}
157+
]
126158
),
127159
translateOpenAPIToStructuredSwiftStage: .init(
128160
preTransitionHooks: [],

0 commit comments

Comments
 (0)