-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Squashed 'apollo-ios-codegen/' changes from 22e0034b..90ab76be
90ab76be feature: GraphQL execution for `@defer` support (#413) git-subtree-dir: apollo-ios-codegen git-subtree-split: 90ab76bef1f2d2003b3825851ebb23999ca9846c
- Loading branch information
gh-action-runner
authored and
gh-action-runner
committed
Jul 19, 2024
1 parent
f6be3a8
commit 795178a
Showing
11 changed files
with
683 additions
and
82 deletions.
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
Sources/ApolloCodegenLib/Templates/DeferredFragmentsMetadataTemplate.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import GraphQLCompiler | ||
import IR | ||
import TemplateString | ||
|
||
struct DeferredFragmentsMetadataTemplate { | ||
|
||
let operation: IR.Operation | ||
let config: ApolloCodegen.ConfigurationContext | ||
let renderAccessControl: () -> String | ||
|
||
init( | ||
operation: IR.Operation, | ||
config: ApolloCodegen.ConfigurationContext, | ||
renderAccessControl: @autoclosure @escaping () -> String | ||
) { | ||
self.operation = operation | ||
self.config = config | ||
self.renderAccessControl = renderAccessControl | ||
} | ||
|
||
// MARK: Templates | ||
|
||
/// Renders metadata definitions for the deferred fragments of an Operation. | ||
/// | ||
/// - Returns: The `TemplateString` for the deferred fragments metadata definitions. | ||
func render() -> TemplateString { | ||
let deferredFragmentPathTypeInfo = DeferredFragmentsPathTypeInfo( | ||
from: operation.rootField.selectionSet.selections | ||
) | ||
guard !deferredFragmentPathTypeInfo.isEmpty else { return "" } | ||
|
||
return """ | ||
// MARK: Deferred Fragment Metadata | ||
\(renderAccessControl())extension \(operation.generatedDefinitionName) { | ||
\(DeferredFragmentIdentifiersTemplate(deferredFragmentPathTypeInfo)) | ||
\(DeferredFragmentsPropertyTemplate(deferredFragmentPathTypeInfo)) | ||
} | ||
""" | ||
} | ||
|
||
fileprivate func DeferredFragmentIdentifiersTemplate( | ||
_ deferredFragmentPathTypeInfo: [DeferredPathTypeInfo] | ||
) -> TemplateString { | ||
""" | ||
enum DeferredFragmentIdentifiers { | ||
\(deferredFragmentPathTypeInfo.map { | ||
return """ | ||
static let \($0.deferCondition.label) = DeferredFragmentIdentifier(label: \"\($0.deferCondition.label)\", fieldPath: [\ | ||
\($0.path.map { "\"\($0)\"" }, separator: ", ")\ | ||
]) | ||
""" | ||
}, separator: "\n") | ||
} | ||
""" | ||
} | ||
|
||
fileprivate func DeferredFragmentsPropertyTemplate( | ||
_ deferredFragmentPathTypeInfo: [DeferredPathTypeInfo] | ||
) -> TemplateString { | ||
""" | ||
static var deferredFragments: [DeferredFragmentIdentifier: any \(config.ApolloAPITargetName).SelectionSet.Type]? {[ | ||
\(deferredFragmentPathTypeInfo.map { | ||
return """ | ||
DeferredFragmentIdentifiers.\($0.deferCondition.label): \($0.typeName).self, | ||
""" | ||
}, separator: "\n") | ||
]} | ||
""" | ||
} | ||
|
||
// MARK: Helpers | ||
|
||
fileprivate struct DeferredPathTypeInfo { | ||
let path: [String] | ||
let deferCondition: CompilationResult.DeferCondition | ||
let typeName: String | ||
} | ||
|
||
fileprivate func DeferredFragmentsPathTypeInfo( | ||
from directSelections: DirectSelections?, | ||
path: [String] = [] | ||
) -> [DeferredPathTypeInfo] { | ||
guard let directSelections, !directSelections.isEmpty else { return [] } | ||
|
||
var deferredPathTypeInfo: [DeferredPathTypeInfo] = [] | ||
|
||
for field in directSelections.fields.values { | ||
if let field = field as? EntityField { | ||
let fieldPath = path + [(field.alias ?? field.name)] | ||
deferredPathTypeInfo.append(contentsOf: | ||
DeferredFragmentsPathTypeInfo(from: field.selectionSet.selections, path: fieldPath) | ||
) | ||
} | ||
} | ||
|
||
for fragment in directSelections.inlineFragments.values { | ||
if let deferCondition = fragment.typeInfo.deferCondition { | ||
let selectionSetName = SelectionSetNameGenerator.generatedSelectionSetName( | ||
for: fragment.typeInfo, | ||
format: .omittingRoot, | ||
pluralizer: config.pluralizer | ||
) | ||
|
||
deferredPathTypeInfo.append(DeferredPathTypeInfo( | ||
path: path, | ||
deferCondition: deferCondition, | ||
typeName: "Data.\(selectionSetName)" | ||
)) | ||
} | ||
|
||
deferredPathTypeInfo.append(contentsOf: | ||
DeferredFragmentsPathTypeInfo(from: fragment.selectionSet.selections, path: path) | ||
) | ||
} | ||
|
||
for fragment in directSelections.namedFragments.values { | ||
if let deferCondition = fragment.typeInfo.deferCondition { | ||
deferredPathTypeInfo.append(DeferredPathTypeInfo( | ||
path: path, | ||
deferCondition: deferCondition, | ||
typeName: fragment.definition.name.asFragmentName | ||
)) | ||
} | ||
|
||
deferredPathTypeInfo.append(contentsOf: | ||
DeferredFragmentsPathTypeInfo( | ||
from: fragment.fragment.rootField.selectionSet.selections, | ||
path: path | ||
) | ||
) | ||
} | ||
|
||
return deferredPathTypeInfo | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Oops, something went wrong.