Skip to content

Commit cb36339

Browse files
authored
Skip type: string + format: binary in object properties (#313)
### Motivation Fixes #312. ### Modifications Explicitly skip binary properties in codable structs. ### Result Remove build failures for projects using multipart. ### Test Plan Created a unit test.
1 parent a243417 commit cb36339

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateObjectStruct.swift

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,29 @@ extension FileTranslator {
3434
try objectContext
3535
.properties
3636
.filter { key, value in
37-
try validateSchemaIsSupported(
37+
38+
let foundIn = "\(typeName.description)/\(key)"
39+
40+
// We need to catch a special case here:
41+
// type: string + format: binary.
42+
// It means binary data (unlike format: byte, which means base64
43+
// and cannot be used in a structured object, such as in JSON.
44+
// It's only valid as the root schema of a request or response.
45+
// However, it _is_ a supported schema, so the following
46+
// filtering would not exclude it.
47+
// Since this is the only place we filter which schemas are
48+
// allowed in object properties, explicitly filter these out
49+
// here.
50+
if value.isString && value.formatString == "binary" {
51+
diagnostics.emitUnsupportedSchema(
52+
reason: "Binary properties in object schemas.",
53+
schema: value,
54+
foundIn: foundIn
55+
)
56+
return false
57+
}
58+
59+
return try validateSchemaIsSupported(
3860
value,
3961
foundIn: "\(typeName.description)/\(key)"
4062
)

Tests/OpenAPIGeneratorReferenceTests/CompatabilityTest.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import Yams
2525
final class CompatibilityTest: XCTestCase {
2626
let compatibilityTestEnabled = getBoolEnv("SWIFT_OPENAPI_COMPATIBILITY_TEST_ENABLE") ?? false
2727
let compatibilityTestSkipBuild = getBoolEnv("SWIFT_OPENAPI_COMPATIBILITY_TEST_SKIP_BUILD") ?? false
28-
let compatibilityTestParralelCodegen = getBoolEnv("SWIFT_OPENAPI_COMPATIBILITY_TEST_PARALLEL_CODEGEN") ?? false
28+
let compatibilityTestParallelCodegen = getBoolEnv("SWIFT_OPENAPI_COMPATIBILITY_TEST_PARALLEL_CODEGEN") ?? false
2929
let compatibilityTestNumBuildJobs = getIntEnv("SWIFT_OPENAPI_COMPATIBILITY_TEST_NUM_BUILD_JOBS")
3030

3131
override func setUp() async throws {
@@ -132,7 +132,9 @@ final class CompatibilityTest: XCTestCase {
132132
try await _test(
133133
"https://raw.githubusercontent.com/openai/openai-openapi/ec0b3953bfa08a92782bdccf34c1931b13402f56/openapi.yaml",
134134
license: .mit,
135-
expectedDiagnostics: [],
135+
expectedDiagnostics: [
136+
"Schema \"string (binary)\" is not supported, reason: \"Binary properties in object schemas.\", skipping"
137+
],
136138
skipBuild: compatibilityTestSkipBuild
137139
)
138140
}
@@ -221,7 +223,7 @@ fileprivate extension CompatibilityTest {
221223
log("Generating Swift code (document size: \(documentSize))")
222224
let input = InMemoryInputFile(absolutePath: URL(string: "openapi.yaml")!, contents: documentData)
223225
let outputs: [GeneratorPipeline.RenderedOutput]
224-
if compatibilityTestParralelCodegen {
226+
if compatibilityTestParallelCodegen {
225227
outputs = try await withThrowingTaskGroup(of: GeneratorPipeline.RenderedOutput.self) { group in
226228
for mode in GeneratorMode.allCases {
227229
group.addTask {

Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,37 @@ final class SnippetBasedReferenceTests: XCTestCase {
292292
)
293293
}
294294

295+
func testComponentsSchemasObjectWithPropertiesBinaryIsSkipped() throws {
296+
try self.assertSchemasTranslation(
297+
ignoredDiagnosticMessages: [
298+
"Schema \"string (binary)\" is not supported, reason: \"Binary properties in object schemas.\", skipping"
299+
],
300+
"""
301+
schemas:
302+
MyObject:
303+
type: object
304+
properties:
305+
actualString:
306+
type: string
307+
binaryProperty:
308+
type: string
309+
format: binary
310+
required:
311+
- actualString
312+
- binaryProperty
313+
""",
314+
"""
315+
public enum Schemas {
316+
public struct MyObject: Codable, Hashable, Sendable {
317+
public var actualString: Swift.String
318+
public init(actualString: Swift.String) { self.actualString = actualString }
319+
public enum CodingKeys: String, CodingKey { case actualString }
320+
}
321+
}
322+
"""
323+
)
324+
}
325+
295326
func testComponentsSchemasAllOf() throws {
296327
try self.assertSchemasTranslation(
297328
"""
@@ -1617,13 +1648,15 @@ extension SnippetBasedReferenceTests {
16171648

16181649
func assertSchemasTranslation(
16191650
featureFlags: FeatureFlags = [],
1651+
ignoredDiagnosticMessages: Set<String> = [],
16201652
_ componentsYAML: String,
16211653
_ expectedSwift: String,
16221654
file: StaticString = #filePath,
16231655
line: UInt = #line
16241656
) throws {
16251657
let translator = try makeTypesTranslator(
16261658
featureFlags: featureFlags,
1659+
ignoredDiagnosticMessages: ignoredDiagnosticMessages,
16271660
componentsYAML: componentsYAML
16281661
)
16291662
let translation = try translator.translateSchemas(translator.components.schemas)

0 commit comments

Comments
 (0)