diff --git a/Examples/type-overrides-example/.gitignore b/Examples/type-overrides-example/.gitignore new file mode 100644 index 000000000..f6f5465e0 --- /dev/null +++ b/Examples/type-overrides-example/.gitignore @@ -0,0 +1,11 @@ +.DS_Store +.build +/Packages +/*.xcodeproj +xcuserdata/ +DerivedData/ +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.vscode +/Package.resolved +.ci/ +.docc-build/ diff --git a/Examples/type-overrides-example/Package.swift b/Examples/type-overrides-example/Package.swift new file mode 100644 index 000000000..979140d4d --- /dev/null +++ b/Examples/type-overrides-example/Package.swift @@ -0,0 +1,32 @@ +// swift-tools-version:5.10 +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftOpenAPIGenerator open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftOpenAPIGenerator project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import PackageDescription + +let package = Package( + name: "type-overrides-example", + platforms: [.macOS(.v10_15)], + products: [.library(name: "Types", targets: ["Types"])], + dependencies: [ + .package(url: "https://github.com/apple/swift-openapi-generator", from: "1.9.0"), + .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.7.0"), + ], + targets: [ + .target( + name: "Types", + dependencies: ["ExternalLibrary", .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime")], + plugins: [.plugin(name: "OpenAPIGenerator", package: "swift-openapi-generator")] + ), .target(name: "ExternalLibrary"), + ] +) diff --git a/Examples/type-overrides-example/README.md b/Examples/type-overrides-example/README.md new file mode 100644 index 000000000..104654992 --- /dev/null +++ b/Examples/type-overrides-example/README.md @@ -0,0 +1,18 @@ +# Overriding types + +An example project using [Swift OpenAPI Generator](https://github.com/apple/swift-openapi-generator). + +> **Disclaimer:** This example is deliberately simplified and is intended for illustrative purposes only. + +## Overview + +This example shows how to use [type overrides](https://swiftpackageindex.com/apple/swift-openapi-generator/documentation/swift-openapi-generator/configuring-the-generator) with Swift OpenAPI Generator. + +## Usage + +Build: + +```console +% swift build +Build complete! +``` diff --git a/Examples/type-overrides-example/Sources/ExternalLibrary/PrimeNumber.swift b/Examples/type-overrides-example/Sources/ExternalLibrary/PrimeNumber.swift new file mode 100644 index 000000000..fcfc0be55 --- /dev/null +++ b/Examples/type-overrides-example/Sources/ExternalLibrary/PrimeNumber.swift @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftOpenAPIGenerator open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftOpenAPIGenerator project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// Example struct to be used instead of the default generated type. +/// This illustrates how to introduce a type performing additional validation during Decoding that cannot be expressed with OpenAPI +public struct PrimeNumber: Codable, Hashable, RawRepresentable, Sendable { + public let rawValue: Int + public init?(rawValue: Int) { + if !rawValue.isPrime { return nil } + self.rawValue = rawValue + } + + public init(from decoder: any Decoder) throws { + let container = try decoder.singleValueContainer() + let number = try container.decode(Int.self) + guard let value = PrimeNumber(rawValue: number) else { + throw DecodingError.dataCorruptedError(in: container, debugDescription: "The number is not prime.") + } + self = value + } + + public func encode(to encoder: any Encoder) throws { + var container = encoder.singleValueContainer() + try container.encode(self.rawValue) + } +} + +extension Int { + fileprivate var isPrime: Bool { + if self <= 1 { return false } + if self <= 3 { return true } + + var i = 2 + while i * i <= self { + if self % i == 0 { return false } + i += 1 + } + return true + } +} diff --git a/Examples/type-overrides-example/Sources/Types/openapi-generator-config.yaml b/Examples/type-overrides-example/Sources/Types/openapi-generator-config.yaml new file mode 100644 index 000000000..404cdf9e6 --- /dev/null +++ b/Examples/type-overrides-example/Sources/Types/openapi-generator-config.yaml @@ -0,0 +1,11 @@ +generate: + - types +accessModifier: package +namingStrategy: idiomatic +additionalImports: + - Foundation + - ExternalLibrary +typeOverrides: + schemas: + UUID: Foundation.UUID + PrimeNumber: ExternalLibrary.PrimeNumber diff --git a/Examples/type-overrides-example/Sources/Types/openapi.yaml b/Examples/type-overrides-example/Sources/Types/openapi.yaml new file mode 120000 index 000000000..1c2a243ef --- /dev/null +++ b/Examples/type-overrides-example/Sources/Types/openapi.yaml @@ -0,0 +1 @@ +../openapi.yaml \ No newline at end of file diff --git a/Examples/type-overrides-example/Sources/openapi.yaml b/Examples/type-overrides-example/Sources/openapi.yaml new file mode 100644 index 000000000..acd2b9810 --- /dev/null +++ b/Examples/type-overrides-example/Sources/openapi.yaml @@ -0,0 +1,26 @@ +openapi: '3.1.0' +info: + title: GreetingService + version: 1.0.0 +servers: + - url: https://example.com/api + description: Example service deployment. +components: + schemas: + UUID: # this will be replaced by with Foundation.UUID specified by typeOverrides in openapi-generator-config + type: string + format: uuid + + PrimeNumber: # this will be replaced by with ExternalLibrary.PrimeNumber specified by typeOverrides in openapi-generator-config + type: string + format: uuid + + User: + type: object + properties: + id: + $ref: '#/components/schemas/UUID' + name: + type: string + favorite_prime_number: + $ref: '#/components/schemas/PrimeNumber' diff --git a/Sources/_OpenAPIGeneratorCore/Config.swift b/Sources/_OpenAPIGeneratorCore/Config.swift index 4c9251083..74bb6f13e 100644 --- a/Sources/_OpenAPIGeneratorCore/Config.swift +++ b/Sources/_OpenAPIGeneratorCore/Config.swift @@ -62,6 +62,8 @@ public struct Config: Sendable { /// A map of OpenAPI identifiers to desired Swift identifiers, used instead of the naming strategy. public var nameOverrides: [String: String] + /// A map of OpenAPI schema names to desired custom type names. + public var typeOverrides: TypeOverrides /// Additional pre-release features to enable. public var featureFlags: FeatureFlags @@ -77,6 +79,7 @@ public struct Config: Sendable { /// Defaults to `defensive`. /// - nameOverrides: A map of OpenAPI identifiers to desired Swift identifiers, used instead /// of the naming strategy. + /// - typeOverrides: A map of OpenAPI schema names to desired custom type names. /// - featureFlags: Additional pre-release features to enable. public init( mode: GeneratorMode, @@ -86,6 +89,7 @@ public struct Config: Sendable { filter: DocumentFilter? = nil, namingStrategy: NamingStrategy, nameOverrides: [String: String] = [:], + typeOverrides: TypeOverrides = .init(), featureFlags: FeatureFlags = [] ) { self.mode = mode @@ -95,6 +99,7 @@ public struct Config: Sendable { self.filter = filter self.namingStrategy = namingStrategy self.nameOverrides = nameOverrides + self.typeOverrides = typeOverrides self.featureFlags = featureFlags } } diff --git a/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift b/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift index 416704ad0..8b83a9505 100644 --- a/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift +++ b/Sources/_OpenAPIGeneratorCore/Parser/validateDoc.swift @@ -252,6 +252,28 @@ func validateReferences(in doc: ParsedOpenAPIRepresentation) throws { } } +/// Validates all type overrides from a Config are present in the components of a ParsedOpenAPIRepresentation. +/// +/// This method iterates through the type overrides defined in the config and checks that for each of them a named schema is defined in the OpenAPI document. +/// +/// - Parameters: +/// - doc: The OpenAPI document to validate. +/// - config: The generator config. +/// - Returns: An array of diagnostic messages representing type overrides for nonexistent schemas. +func validateTypeOverrides(_ doc: ParsedOpenAPIRepresentation, config: Config) -> [Diagnostic] { + let nonExistentOverrides = config.typeOverrides.schemas.keys + .filter { key in + guard let componentKey = OpenAPI.ComponentKey(rawValue: key) else { return false } + return !doc.components.schemas.contains(key: componentKey) + } + .sorted() + return nonExistentOverrides.map { override in + Diagnostic.warning( + message: "A type override defined for schema '\(override)' is not defined in the OpenAPI document." + ) + } +} + /// Runs validation steps on the incoming OpenAPI document. /// - Parameters: /// - doc: The OpenAPI document to validate. @@ -263,6 +285,7 @@ func validateDoc(_ doc: ParsedOpenAPIRepresentation, config: Config) throws -> [ try validateContentTypes(in: doc) { contentType in (try? _OpenAPIGeneratorCore.ContentType(string: contentType)) != nil } + let typeOverrideDiagnostics = validateTypeOverrides(doc, config: config) // Run OpenAPIKit's built-in validation. // Pass `false` to `strict`, however, because we don't @@ -283,5 +306,5 @@ func validateDoc(_ doc: ParsedOpenAPIRepresentation, config: Config) throws -> [ ] ) } - return diagnostics + return typeOverrideDiagnostics + diagnostics } diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateSchema.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateSchema.swift index e92b5605a..fb8365693 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateSchema.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTranslations/translateSchema.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// import OpenAPIKit +import Foundation extension TypesFileTranslator { @@ -88,6 +89,17 @@ extension TypesFileTranslator { ) } + // Apply type overrides. + if let jsonPath = typeName.shortJSONName, let typeOverride = config.typeOverrides.schemas[jsonPath] { + let typeOverride = TypeName(swiftKeyPath: typeOverride.components(separatedBy: ".")) + let typealiasDecl = try translateTypealias( + named: typeName, + userDescription: overrides.userDescription ?? schema.description, + to: typeOverride.asUsage + ) + return [typealiasDecl] + } + // If this type maps to a referenceable schema, define a typealias if let builtinType = try typeMatcher.tryMatchReferenceableType(for: schema, components: components) { let typealiasDecl = try translateTypealias( diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift index d1fbedcf3..f2affe3a8 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift @@ -372,7 +372,6 @@ enum Constants { /// The substring used in method names for the multipart coding strategy. static let multipart: String = "Multipart" } - /// Constants related to types used in many components. enum Global { diff --git a/Sources/_OpenAPIGeneratorCore/Translator/TypesTranslator/translateSchemas.swift b/Sources/_OpenAPIGeneratorCore/Translator/TypesTranslator/translateSchemas.swift index 5935ad805..679629753 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/TypesTranslator/translateSchemas.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/TypesTranslator/translateSchemas.swift @@ -57,7 +57,6 @@ extension TypesFileTranslator { _ schemas: OpenAPI.ComponentDictionary, multipartSchemaNames: Set ) throws -> Declaration { - let decls: [Declaration] = try schemas.flatMap { key, value in try translateSchema( componentKey: key, diff --git a/Sources/_OpenAPIGeneratorCore/TypeOverrides.swift b/Sources/_OpenAPIGeneratorCore/TypeOverrides.swift new file mode 100644 index 000000000..32f9b0a7a --- /dev/null +++ b/Sources/_OpenAPIGeneratorCore/TypeOverrides.swift @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftOpenAPIGenerator open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftOpenAPIGenerator project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// A container of schema type overrides. +public struct TypeOverrides: Sendable { + /// A dictionary of overrides for replacing named schemas from the OpenAPI document with custom types. + public var schemas: [String: String] + + /// Creates a new instance. + /// - Parameter schemas: A dictionary of overrides for replacing named schemas from the OpenAPI document with custom types. + public init(schemas: [String: String] = [:]) { self.schemas = schemas } +} diff --git a/Sources/swift-openapi-generator/Documentation.docc/Articles/Configuring-the-generator.md b/Sources/swift-openapi-generator/Documentation.docc/Articles/Configuring-the-generator.md index de3ffebbe..cbc6ba056 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Articles/Configuring-the-generator.md +++ b/Sources/swift-openapi-generator/Documentation.docc/Articles/Configuring-the-generator.md @@ -145,3 +145,15 @@ filter: tags: - myTag ``` + +### Type overrides + +Type Overrides can be used used to replace the default generated type with a custom type. + +```yaml +typeOverrides: + schemas: + UUID: Foundation.UUID +``` + +Check out [SOAR-0014](https://swiftpackageindex.com/apple/swift-openapi-generator/documentation/swift-openapi-generator/soar-0014) for details. diff --git a/Sources/swift-openapi-generator/GenerateOptions+runGenerator.swift b/Sources/swift-openapi-generator/GenerateOptions+runGenerator.swift index cf6619f7e..ab868c056 100644 --- a/Sources/swift-openapi-generator/GenerateOptions+runGenerator.swift +++ b/Sources/swift-openapi-generator/GenerateOptions+runGenerator.swift @@ -35,6 +35,7 @@ extension _GenerateOptions { let resolvedAdditionalFileComments = resolvedAdditionalFileComments(config) let resolvedNamingStragy = resolvedNamingStrategy(config) let resolvedNameOverrides = resolvedNameOverrides(config) + let resolvedTypeOverrides = resolvedTypeOverrides(config) let resolvedFeatureFlags = resolvedFeatureFlags(config) let configs: [Config] = sortedModes.map { .init( @@ -45,6 +46,7 @@ extension _GenerateOptions { filter: config?.filter, namingStrategy: resolvedNamingStragy, nameOverrides: resolvedNameOverrides, + typeOverrides: resolvedTypeOverrides, featureFlags: resolvedFeatureFlags ) } @@ -61,6 +63,9 @@ extension _GenerateOptions { - Name overrides: \(resolvedNameOverrides.isEmpty ? "" : resolvedNameOverrides .sorted(by: { $0.key < $1.key }) .map { "\"\($0.key)\"->\"\($0.value)\"" }.joined(separator: ", ")) + - Type overrides: \(resolvedTypeOverrides.schemas.isEmpty ? "" : resolvedTypeOverrides.schemas + .sorted(by: { $0.key < $1.key }) + .map { "\"\($0.key)\"->\"\($0.value)\"" }.joined(separator: ", ")) - Feature flags: \(resolvedFeatureFlags.isEmpty ? "" : resolvedFeatureFlags.map(\.rawValue).joined(separator: ", ")) - Output file names: \(sortedModes.map(\.outputFileName).joined(separator: ", ")) - Output directory: \(outputDirectory.path) diff --git a/Sources/swift-openapi-generator/GenerateOptions.swift b/Sources/swift-openapi-generator/GenerateOptions.swift index 1cdb73bc3..7bfa4b141 100644 --- a/Sources/swift-openapi-generator/GenerateOptions.swift +++ b/Sources/swift-openapi-generator/GenerateOptions.swift @@ -107,6 +107,14 @@ extension _GenerateOptions { /// - Returns: The name overrides requested by the user func resolvedNameOverrides(_ config: _UserConfig?) -> [String: String] { config?.nameOverrides ?? [:] } + /// Returns the type overrides requested by the user. + /// - Parameter config: The configuration specified by the user. + /// - Returns: The type overrides requested by the user. + func resolvedTypeOverrides(_ config: _UserConfig?) -> TypeOverrides { + guard let schemaOverrides = config?.typeOverrides?.schemas, !schemaOverrides.isEmpty else { return .init() } + return TypeOverrides(schemas: schemaOverrides) + } + /// Returns a list of the feature flags requested by the user. /// - Parameter config: The configuration specified by the user. /// - Returns: A set of feature flags requested by the user. diff --git a/Sources/swift-openapi-generator/UserConfig.swift b/Sources/swift-openapi-generator/UserConfig.swift index a1711bdc3..f83dd71fd 100644 --- a/Sources/swift-openapi-generator/UserConfig.swift +++ b/Sources/swift-openapi-generator/UserConfig.swift @@ -45,6 +45,9 @@ struct _UserConfig: Codable { /// Any names not included use the `namingStrategy` to compute a Swift name. var nameOverrides: [String: String]? + /// A dictionary of overrides for replacing the types of generated with manually provided types + var typeOverrides: TypeOverrides? + /// A set of features to explicitly enable. var featureFlags: FeatureFlags? @@ -59,6 +62,13 @@ struct _UserConfig: Codable { case filter case namingStrategy case nameOverrides + case typeOverrides case featureFlags } + + /// A container of type overrides. + struct TypeOverrides: Codable { + /// A dictionary of overrides for replacing the types generated from schemas with manually provided types. + var schemas: [String: String]? + } } diff --git a/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift b/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift index ea194aed2..a4a48f39b 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Parser/Test_validateDoc.swift @@ -449,5 +449,32 @@ final class Test_validateDoc: Test_Core { ) } } + func testValidateTypeOverrides() throws { + let schema = try loadSchemaFromYAML( + #""" + type: string + """# + ) + let doc = OpenAPI.Document( + info: .init(title: "Test", version: "1.0.0"), + servers: [], + paths: [:], + components: .init(schemas: ["MyType": schema]) + ) + let diagnostics = validateTypeOverrides( + doc, + config: .init( + mode: .types, + access: Config.defaultAccessModifier, + namingStrategy: Config.defaultNamingStrategy, + typeOverrides: TypeOverrides(schemas: ["NonExistent": "NonExistent"]) + ) + ) + XCTAssertEqual(diagnostics.count, 1) + XCTAssertEqual( + diagnostics.first?.message, + "A type override defined for schema 'NonExistent' is not defined in the OpenAPI document." + ) + } } diff --git a/Tests/OpenAPIGeneratorCoreTests/TestUtilities.swift b/Tests/OpenAPIGeneratorCoreTests/TestUtilities.swift index 48651d1c1..89b9e47ba 100644 --- a/Tests/OpenAPIGeneratorCoreTests/TestUtilities.swift +++ b/Tests/OpenAPIGeneratorCoreTests/TestUtilities.swift @@ -30,6 +30,7 @@ class Test_Core: XCTestCase { diagnostics: any DiagnosticCollector = PrintingDiagnosticCollector(), namingStrategy: NamingStrategy = .defensive, nameOverrides: [String: String] = [:], + schemaOverrides: [String: String] = [:], featureFlags: FeatureFlags = [] ) -> TypesFileTranslator { makeTypesTranslator( @@ -37,6 +38,7 @@ class Test_Core: XCTestCase { diagnostics: diagnostics, namingStrategy: namingStrategy, nameOverrides: nameOverrides, + schemaOverrides: schemaOverrides, featureFlags: featureFlags ) } @@ -46,12 +48,14 @@ class Test_Core: XCTestCase { diagnostics: any DiagnosticCollector = PrintingDiagnosticCollector(), namingStrategy: NamingStrategy = .defensive, nameOverrides: [String: String] = [:], + schemaOverrides: [String: String] = [:], featureFlags: FeatureFlags = [] ) -> TypesFileTranslator { TypesFileTranslator( config: makeConfig( namingStrategy: namingStrategy, nameOverrides: nameOverrides, + schemaOverrides: schemaOverrides, featureFlags: featureFlags ), diagnostics: diagnostics, @@ -62,6 +66,7 @@ class Test_Core: XCTestCase { func makeConfig( namingStrategy: NamingStrategy = .defensive, nameOverrides: [String: String] = [:], + schemaOverrides: [String: String] = [:], featureFlags: FeatureFlags = [] ) -> Config { .init( @@ -69,6 +74,7 @@ class Test_Core: XCTestCase { access: Config.defaultAccessModifier, namingStrategy: namingStrategy, nameOverrides: nameOverrides, + typeOverrides: TypeOverrides(schemas: schemaOverrides), featureFlags: featureFlags ) } diff --git a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift index b5b563bdd..98cb2f15e 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift @@ -1915,6 +1915,67 @@ final class SnippetBasedReferenceTests: XCTestCase { """ ) } + func testTypeOverrides() throws { + try assertSchemasTranslation( + typeOverrides: TypeOverrides(schemas: ["UUID": "Foundation.UUID"]), + """ + schemas: + User: + type: object + properties: + id: + $ref: '#/components/schemas/UUID' + UUID: + type: string + format: uuid + """, + """ + public enum Schemas { + public struct User: Codable, Hashable, Sendable { + public var id: Components.Schemas.UUID? + public init(id: Components.Schemas.UUID? = nil) { + self.id = id + } + public enum CodingKeys: String, CodingKey { + case id + } + } + public typealias UUID = Foundation.UUID + } + """ + ) + } + func testTypeOverridesWithNameOverrides() throws { + try assertSchemasTranslation( + nameOverrides: ["UUID": "MyUUID"], + typeOverrides: TypeOverrides(schemas: ["UUID": "Foundation.UUID"]), + """ + schemas: + User: + type: object + properties: + id: + $ref: '#/components/schemas/UUID' + UUID: + type: string + format: uuid + """, + """ + public enum Schemas { + public struct User: Codable, Hashable, Sendable { + public var id: Components.Schemas.MyUUID? + public init(id: Components.Schemas.MyUUID? = nil) { + self.id = id + } + public enum CodingKeys: String, CodingKey { + case id + } + } + public typealias MyUUID = Foundation.UUID + } + """ + ) + } func testComponentsResponsesResponseNoBody() throws { try self.assertResponsesTranslation( @@ -5911,6 +5972,8 @@ extension SnippetBasedReferenceTests { func makeTypesTranslator( accessModifier: AccessModifier = .public, namingStrategy: NamingStrategy = .defensive, + nameOverrides: [String: String] = [:], + typeOverrides: TypeOverrides = .init(), featureFlags: FeatureFlags = [], ignoredDiagnosticMessages: Set = [], componentsYAML: String @@ -5921,6 +5984,8 @@ extension SnippetBasedReferenceTests { mode: .types, access: accessModifier, namingStrategy: namingStrategy, + nameOverrides: nameOverrides, + typeOverrides: typeOverrides, featureFlags: featureFlags ), diagnostics: XCTestDiagnosticCollector(test: self, ignoredDiagnosticMessages: ignoredDiagnosticMessages), @@ -6114,6 +6179,8 @@ extension SnippetBasedReferenceTests { func assertSchemasTranslation( featureFlags: FeatureFlags = [], + nameOverrides: [String: String] = [:], + typeOverrides: TypeOverrides = .init(), ignoredDiagnosticMessages: Set = [], _ componentsYAML: String, _ expectedSwift: String, @@ -6123,6 +6190,8 @@ extension SnippetBasedReferenceTests { ) throws { let translator = try makeTypesTranslator( accessModifier: accessModifier, + nameOverrides: nameOverrides, + typeOverrides: typeOverrides, featureFlags: featureFlags, ignoredDiagnosticMessages: ignoredDiagnosticMessages, componentsYAML: componentsYAML