From 135319140a410377661f1d08a9e720f06fb42267 Mon Sep 17 00:00:00 2001 From: Anthony Miller Date: Wed, 20 Mar 2024 15:31:46 -0700 Subject: [PATCH] Field Merging[1/x] Configuration Options --- .../ApolloCodegenConfiguration.swift | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift b/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift index 078b31df5..2ca309611 100644 --- a/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift +++ b/apollo-ios-codegen/Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift @@ -466,6 +466,8 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { public let schemaDocumentation: Composition /// Which generated selection sets should include generated initializers. public let selectionSetInitializers: SelectionSetInitializers + /// Which merged fields and named fragment accessors are generated. Defaults to `.all`. + public let fieldMerging: FieldMerging /// How to generate the operation documents for your generated operations. public let operationDocumentFormat: OperationDocumentFormat /// Generate import statements that are compatible with including `Apollo` via Cocoapods. @@ -513,6 +515,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { public static let deprecatedEnumCases: Composition = .include public static let schemaDocumentation: Composition = .include public static let selectionSetInitializers: SelectionSetInitializers = [.localCacheMutations] + public static let fieldMerging: FieldMerging = [.all] public static let operationDocumentFormat: OperationDocumentFormat = .definition public static let cocoapodsCompatibleImportStatements: Bool = false public static let warningsOnDeprecatedUsage: Composition = .include @@ -530,6 +533,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { /// - schemaDocumentation: Whether schema documentation is added to the generated files. /// - selectionSetInitializers: Which generated selection sets should include /// generated initializers. + /// - fieldMerging: Which merged fields and named fragment accessors are generated. /// - operationDocumentFormat: How to generate the operation documents for your generated operations. /// - cocoapodsCompatibleImportStatements: Generate import statements that are compatible with /// including `Apollo` via Cocoapods. @@ -545,6 +549,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { deprecatedEnumCases: Composition = Default.deprecatedEnumCases, schemaDocumentation: Composition = Default.schemaDocumentation, selectionSetInitializers: SelectionSetInitializers = Default.selectionSetInitializers, + fieldMerging: FieldMerging = Default.fieldMerging, operationDocumentFormat: OperationDocumentFormat = Default.operationDocumentFormat, cocoapodsCompatibleImportStatements: Bool = Default.cocoapodsCompatibleImportStatements, warningsOnDeprecatedUsage: Composition = Default.warningsOnDeprecatedUsage, @@ -556,6 +561,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { self.deprecatedEnumCases = deprecatedEnumCases self.schemaDocumentation = schemaDocumentation self.selectionSetInitializers = selectionSetInitializers + self.fieldMerging = fieldMerging self.operationDocumentFormat = operationDocumentFormat self.cocoapodsCompatibleImportStatements = cocoapodsCompatibleImportStatements self.warningsOnDeprecatedUsage = warningsOnDeprecatedUsage @@ -572,6 +578,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { case deprecatedEnumCases case schemaDocumentation case selectionSetInitializers + case fieldMerging case apqs case operationDocumentFormat case cocoapodsCompatibleImportStatements @@ -605,6 +612,11 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { forKey: .selectionSetInitializers ) ?? Default.selectionSetInitializers + fieldMerging = try values.decodeIfPresent( + FieldMerging.self, + forKey: .fieldMerging + ) ?? Default.fieldMerging + operationDocumentFormat = try values.decodeIfPresent( OperationDocumentFormat.self, forKey: .operationDocumentFormat @@ -648,6 +660,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { try container.encode(self.deprecatedEnumCases, forKey: .deprecatedEnumCases) try container.encode(self.schemaDocumentation, forKey: .schemaDocumentation) try container.encode(self.selectionSetInitializers, forKey: .selectionSetInitializers) + try container.encode(self.fieldMerging, forKey: .fieldMerging) try container.encode(self.operationDocumentFormat, forKey: .operationDocumentFormat) try container.encode(self.cocoapodsCompatibleImportStatements, forKey: .cocoapodsCompatibleImportStatements) try container.encode(self.warningsOnDeprecatedUsage, forKey: .warningsOnDeprecatedUsage) @@ -902,6 +915,43 @@ public struct ApolloCodegenConfiguration: Codable, Equatable { } } + /// The `FieldMerging` configuration is used to determine what merged fields and named fragment + /// accessors are present on the generated selection set models. Field merging generates + /// selection set models that are easier to use, but more verbose. + /// + /// Property accessors are always generated for each field directly included in a selection + /// set in the GraphQL definition. In addition, the code generation engine can compute which + /// selections from a selection set's parents, sibling inline fragments, and named fragment + /// spreads will also be included on the response object, given the selection set's scope. + /// + /// By default, all possible fields and named fragment accessors are merged into each selection + /// set. + public struct FieldMerging: OptionSet, Codable, Equatable { + /// Merges fields and fragment accessors from the selection set's direct ancestors. + public static let ancestors = FieldMerging(rawValue: 1 << 0) + + /// Merges fields and fragment accessors from sibling inline fragments that match the selection + /// set's scope. + public static let siblings = FieldMerging(rawValue: 1 << 1) + + /// Merges fields and fragment accessors from named fragments that have been spread into the + /// selection set. + public static let namedFragments = FieldMerging(rawValue: 1 << 2) + + /// Merges all possible fields and fragment accessors from all sources. + public static let all: FieldMerging = [.ancestors, .siblings, .namedFragments] + + /// Disables field merging entirely. Aside from removal of redundant selections, the shape of + /// the generated models will directly mirror the GraphQL definition. + public static let none: FieldMerging = FieldMerging(rawValue: 0) + + public let rawValue: Int + + public init(rawValue: Int) { + self.rawValue = rawValue + } + } + public struct ExperimentalFeatures: Codable, Equatable { /** * **EXPERIMENTAL**: If enabled, the generated operations will be transformed using a method @@ -1332,6 +1382,7 @@ extension ApolloCodegenConfiguration.OutputOptions { /// - schemaDocumentation: Whether schema documentation is added to the generated files. /// - selectionSetInitializers: Which generated selection sets should include /// generated initializers. + /// - fieldMerging: Which merged fields and named fragment accessors are generated. /// - apqs: Whether the generated operations should use Automatic Persisted Queries. /// - cocoapodsCompatibleImportStatements: Generate import statements that are compatible with /// including `Apollo` via Cocoapods. @@ -1351,6 +1402,7 @@ extension ApolloCodegenConfiguration.OutputOptions { deprecatedEnumCases: ApolloCodegenConfiguration.Composition = Default.deprecatedEnumCases, schemaDocumentation: ApolloCodegenConfiguration.Composition = Default.schemaDocumentation, selectionSetInitializers: ApolloCodegenConfiguration.SelectionSetInitializers = Default.selectionSetInitializers, + fieldMerging: ApolloCodegenConfiguration.FieldMerging = Default.fieldMerging, apqs: ApolloCodegenConfiguration.APQConfig, cocoapodsCompatibleImportStatements: Bool = Default.cocoapodsCompatibleImportStatements, warningsOnDeprecatedUsage: ApolloCodegenConfiguration.Composition = Default.warningsOnDeprecatedUsage, @@ -1362,6 +1414,7 @@ extension ApolloCodegenConfiguration.OutputOptions { self.deprecatedEnumCases = deprecatedEnumCases self.schemaDocumentation = schemaDocumentation self.selectionSetInitializers = selectionSetInitializers + self.fieldMerging = fieldMerging self.operationDocumentFormat = apqs.operationDocumentFormat self.cocoapodsCompatibleImportStatements = cocoapodsCompatibleImportStatements self.warningsOnDeprecatedUsage = warningsOnDeprecatedUsage @@ -1381,6 +1434,7 @@ extension ApolloCodegenConfiguration.OutputOptions { /// - schemaDocumentation: Whether schema documentation is added to the generated files. /// - selectionSetInitializers: Which generated selection sets should include /// generated initializers. + /// - fieldMerging: Which merged fields and named fragment accessors are generated. /// - operationDocumentFormat: How to generate the operation documents for your generated operations. /// - cocoapodsCompatibleImportStatements: Generate import statements that are compatible with /// including `Apollo` via Cocoapods. @@ -1400,6 +1454,7 @@ extension ApolloCodegenConfiguration.OutputOptions { deprecatedEnumCases: ApolloCodegenConfiguration.Composition = Default.deprecatedEnumCases, schemaDocumentation: ApolloCodegenConfiguration.Composition = Default.schemaDocumentation, selectionSetInitializers: ApolloCodegenConfiguration.SelectionSetInitializers = Default.selectionSetInitializers, + fieldMerging: ApolloCodegenConfiguration.FieldMerging = Default.fieldMerging, operationDocumentFormat: ApolloCodegenConfiguration.OperationDocumentFormat = Default.operationDocumentFormat, cocoapodsCompatibleImportStatements: Bool = Default.cocoapodsCompatibleImportStatements, warningsOnDeprecatedUsage: ApolloCodegenConfiguration.Composition = Default.warningsOnDeprecatedUsage, @@ -1411,6 +1466,7 @@ extension ApolloCodegenConfiguration.OutputOptions { self.deprecatedEnumCases = deprecatedEnumCases self.schemaDocumentation = schemaDocumentation self.selectionSetInitializers = selectionSetInitializers + self.fieldMerging = fieldMerging self.operationDocumentFormat = operationDocumentFormat self.cocoapodsCompatibleImportStatements = cocoapodsCompatibleImportStatements self.warningsOnDeprecatedUsage = warningsOnDeprecatedUsage