Skip to content

Commit

Permalink
Fix inner entity access control for operation-based templates
Browse files Browse the repository at this point in the history
  • Loading branch information
calvincestari committed Apr 1, 2023
1 parent 3054690 commit e9e3a75
Show file tree
Hide file tree
Showing 16 changed files with 791 additions and 158 deletions.
4 changes: 4 additions & 0 deletions Apollo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@
E660A4D529CAEA0F001EA373 /* MockInterceptorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E660A4D429CAEA0F001EA373 /* MockInterceptorProvider.swift */; };
E6630B8C26F0639B002D9E41 /* MockNetworkSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6D79AB926EC05290094434A /* MockNetworkSession.swift */; };
E6630B8E26F071F9002D9E41 /* SchemaRegistryApolloSchemaDownloaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6630B8D26F071F9002D9E41 /* SchemaRegistryApolloSchemaDownloaderTests.swift */; };
E66644F129D7D2AE005E9140 /* MockTemplateRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E66644EF29D7D27C005E9140 /* MockTemplateRenderer.swift */; };
E669352B2803EE11004E1FFC /* CustomScalarTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E669352A2803EE11004E1FFC /* CustomScalarTemplate.swift */; };
E669352D2803EF67004E1FFC /* CustomScalarTemplateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E669352C2803EF67004E1FFC /* CustomScalarTemplateTests.swift */; };
E669352F2803F09C004E1FFC /* CustomScalarFileGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E669352E2803F09C004E1FFC /* CustomScalarFileGenerator.swift */; };
Expand Down Expand Up @@ -1912,6 +1913,7 @@
E660A4D229CA5890001EA373 /* MockHTTPResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockHTTPResponse.swift; sourceTree = "<group>"; };
E660A4D429CAEA0F001EA373 /* MockInterceptorProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockInterceptorProvider.swift; sourceTree = "<group>"; };
E6630B8D26F071F9002D9E41 /* SchemaRegistryApolloSchemaDownloaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SchemaRegistryApolloSchemaDownloaderTests.swift; sourceTree = "<group>"; };
E66644EF29D7D27C005E9140 /* MockTemplateRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTemplateRenderer.swift; sourceTree = "<group>"; };
E669352A2803EE11004E1FFC /* CustomScalarTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomScalarTemplate.swift; sourceTree = "<group>"; };
E669352C2803EF67004E1FFC /* CustomScalarTemplateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomScalarTemplateTests.swift; sourceTree = "<group>"; };
E669352E2803F09C004E1FFC /* CustomScalarFileGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomScalarFileGenerator.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3832,6 +3834,7 @@
DE5FD5FE276922AA0033EE23 /* MockApolloCodegenConfiguration.swift */,
E6BEEFA527FAB1C700D94FF4 /* MockFileGenerator.swift */,
E6EFDD0C27E8377200B17FE5 /* MockFileTemplate.swift */,
E66644EF29D7D27C005E9140 /* MockTemplateRenderer.swift */,
DE5B313F27A482C80051C9D3 /* Resources.swift */,
DECD490E262F81BF00924527 /* Info.plist */,
);
Expand Down Expand Up @@ -5719,6 +5722,7 @@
DEE2060B27E14498002B4B82 /* IR+InclusionConditionsMock.swift in Sources */,
DE01451628A5A971000F6F18 /* MockValidationOptions.swift in Sources */,
E6BF98FC272C8FFC00C1FED8 /* MockFileManager.swift in Sources */,
E66644F129D7D2AE005E9140 /* MockTemplateRenderer.swift in Sources */,
E6BEEFA627FAB1C700D94FF4 /* MockFileGenerator.swift in Sources */,
DECD4921262F81CE00924527 /* CodegenTestHelper.swift in Sources */,
DEAFB78327064F6900BE02F3 /* MockGraphQLType.swift in Sources */,
Expand Down
10 changes: 10 additions & 0 deletions Sources/ApolloCodegenLib/ApolloCodegenConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,17 @@ extension ApolloCodegenConfiguration.OutputOptions {
}
}

extension ApolloCodegenConfiguration.AccessModifier {
var swiftString: String {
switch self {
case .public: return "public "
case .internal: return ""
}
}
}

// MARK: - SelectionSetInitializers - Private Implementation

extension ApolloCodegenConfiguration.SelectionSetInitializers {
struct Options: OptionSet, Codable, Equatable {
let rawValue: Int
Expand Down
5 changes: 3 additions & 2 deletions Sources/ApolloCodegenLib/Templates/FragmentTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ struct FragmentTemplate: TemplateRenderer {
\(embeddedAccessControlModifier(target: target))\
struct \(fragment.name.firstUppercased): \(config.schemaNamespace.firstUppercased)\
.\(if: isMutable, "Mutable")SelectionSet, Fragment {
public static var fragmentDefinition: StaticString { ""\"
static var fragmentDefinition: StaticString { ""\"
\(fragment.definition.source)
""\" }
\(SelectionSetTemplate(
mutable: isMutable,
generateInitializers: config.options.shouldGenerateSelectionSetInitializers(for: fragment),
config: config
config: config,
accessControlRenderer: { embeddedAccessControlModifier(target: target) }()
).BodyTemplate(fragment.rootField.selectionSet))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct LocalCacheMutationDefinitionTemplate: OperationTemplateRenderer {
"""
\(embeddedAccessControlModifier(target: target))\
class \(operation.definition.nameWithSuffix.firstUppercased): LocalCacheMutation {
public static let operationType: GraphQLOperationType = .\(operation.definition.operationType.rawValue)
static let operationType: GraphQLOperationType = .\(operation.definition.operationType.rawValue)
\(section: VariableProperties(operation.definition.variables))
Expand All @@ -24,7 +24,8 @@ struct LocalCacheMutationDefinitionTemplate: OperationTemplateRenderer {
\(SelectionSetTemplate(
mutable: true,
generateInitializers: config.options.shouldGenerateSelectionSetInitializers(for: operation),
config: config
config: config,
accessControlRenderer: { embeddedAccessControlModifier(target: target) }()
).render(for: operation))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ struct OperationDefinitionTemplate: OperationTemplateRenderer {
operation.definition,
identifier: operation.operationIdentifier,
fragments: operation.referencedFragments,
config: config
config: config,
accessControlRenderer: { embeddedAccessControlModifier(target: target) }()
))
\(section: VariableProperties(operation.definition.variables))
Expand All @@ -29,18 +30,21 @@ struct OperationDefinitionTemplate: OperationTemplateRenderer {
\(SelectionSetTemplate(
generateInitializers: config.options.shouldGenerateSelectionSetInitializers(for: operation),
config: config
config: config,
accessControlRenderer: { embeddedAccessControlModifier(target: target) }()
).render(for: operation))
}
""")
}

private func OperationDeclaration(_ operation: CompilationResult.OperationDefinition) -> TemplateString {
let accessControl = embeddedAccessControlModifier(target: target)

return """
\(embeddedAccessControlModifier(target: target))\
\(accessControl)\
class \(operation.nameWithSuffix.firstUppercased): \(operation.operationType.renderedProtocolName) {
public static let operationName: String = "\(operation.name)"
\(accessControl)static let operationName: String = "\(operation.name)"
"""
}

Expand All @@ -49,13 +53,15 @@ struct OperationDefinitionTemplate: OperationTemplateRenderer {
_ operation: CompilationResult.OperationDefinition,
identifier: @autoclosure () -> String,
fragments: OrderedSet<IR.NamedFragment>,
config: ApolloCodegen.ConfigurationContext
config: ApolloCodegen.ConfigurationContext,
accessControlRenderer: @autoclosure () -> String
) -> TemplateString {
let includeFragments = !fragments.isEmpty
let includeDefinition = config.options.apqs != .persistedOperationsOnly

return TemplateString("""
public static let document: \(config.ApolloAPITargetName).DocumentType = .\(config.options.apqs.rendered)(
\(accessControlRenderer())\
static let document: \(config.ApolloAPITargetName).DocumentType = .\(config.options.apqs.rendered)(
\(if: config.options.apqs != .disabled, """
operationIdentifier: \"\(identifier())\"\(if: includeDefinition, ",")
""")
Expand Down
40 changes: 25 additions & 15 deletions Sources/ApolloCodegenLib/Templates/SelectionSetTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ struct SelectionSetTemplate {
let isMutable: Bool
let generateInitializers: Bool
let config: ApolloCodegen.ConfigurationContext
let accessControlRenderer: () -> String

private let nameCache: SelectionSetNameCache

init(
mutable: Bool = false,
generateInitializers: Bool,
config: ApolloCodegen.ConfigurationContext
config: ApolloCodegen.ConfigurationContext,
accessControlRenderer: @autoclosure @escaping () -> String
) {
self.isMutable = mutable
self.generateInitializers = generateInitializers
self.config = config
self.accessControlRenderer = accessControlRenderer

self.nameCache = SelectionSetNameCache(config: config)
}
Expand All @@ -25,7 +28,7 @@ struct SelectionSetTemplate {
func render(for operation: IR.Operation) -> String {
TemplateString(
"""
public struct Data: \(SelectionSetType()) {
\(accessControlRenderer())struct Data: \(SelectionSetType()) {
\(BodyTemplate(operation.rootField.selectionSet))
}
"""
Expand All @@ -37,7 +40,8 @@ struct SelectionSetTemplate {
TemplateString(
"""
\(SelectionSetNameDocumentation(field.selectionSet))
public struct \(field.formattedSelectionSetName(with: config.pluralizer)): \(SelectionSetType()) {
\(accessControlRenderer())\
struct \(field.formattedSelectionSetName(with: config.pluralizer)): \(SelectionSetType()) {
\(BodyTemplate(field.selectionSet))
}
"""
Expand All @@ -49,7 +53,8 @@ struct SelectionSetTemplate {
TemplateString(
"""
\(SelectionSetNameDocumentation(inlineFragment))
public struct \(inlineFragment.renderedTypeName): \(SelectionSetType(asInlineFragment: true)) {
\(accessControlRenderer())\
struct \(inlineFragment.renderedTypeName): \(SelectionSetType(asInlineFragment: true)) {
\(BodyTemplate(inlineFragment))
}
"""
Expand Down Expand Up @@ -114,9 +119,11 @@ struct SelectionSetTemplate {
}

private func DataFieldAndInitializerTemplate() -> String {
"""
public \(isMutable ? "var" : "let") __data: DataDict
public init(_dataDict: DataDict) { __data = _dataDict }
let accessControl = accessControlRenderer()

return """
\(accessControl)\(isMutable ? "var" : "let") __data: DataDict
\(accessControl)init(_dataDict: DataDict) { __data = _dataDict }
"""
}

Expand All @@ -130,13 +137,14 @@ struct SelectionSetTemplate {
pluralizer: config.pluralizer
)
return """
public typealias RootEntityType = \(rootEntityName)
\(accessControlRenderer())typealias RootEntityType = \(rootEntityName)
"""
}

private func ParentTypeTemplate(_ type: GraphQLCompositeType) -> String {
"""
public static var __parentType: \(config.ApolloAPITargetName).ParentType { \
\(accessControlRenderer())\
static var __parentType: \(config.ApolloAPITargetName).ParentType { \
\(GeneratedTypeReference(type)) }
"""
}
Expand All @@ -156,7 +164,8 @@ struct SelectionSetTemplate {
config.options.warningsOnDeprecatedUsage == .include ? [] : nil

let selectionsTemplate = TemplateString("""
public static var __selections: [\(config.ApolloAPITargetName).Selection] { [
\(accessControlRenderer())\
static var __selections: [\(config.ApolloAPITargetName).Selection] { [
\(if: shouldIncludeTypenameSelection(for: scope), ".field(\"__typename\", String.self),")
\(renderedSelections(groupedSelections.unconditionalSelections, &deprecatedArguments), terminator: ",")
\(groupedSelections.inclusionConditionGroups.map {
Expand Down Expand Up @@ -293,7 +302,8 @@ struct SelectionSetTemplate {
return """
\(documentation: field.underlyingField.documentation, config: config)
\(deprecationReason: field.underlyingField.deprecationReason, config: config)
public var \(field.responseKey.firstLowercased.asFieldAccessorPropertyName): \
\(accessControlRenderer())\
var \(field.responseKey.firstLowercased.asFieldAccessorPropertyName): \
\(typeName(for: field, forceOptional: isConditionallyIncluded)) {\
\(if: isMutable,
"""
Expand Down Expand Up @@ -322,7 +332,7 @@ struct SelectionSetTemplate {
private func InlineFragmentAccessorTemplate(_ inlineFragment: IR.SelectionSet) -> TemplateString {
let typeName = inlineFragment.renderedTypeName
return """
public var \(typeName.firstLowercased): \(typeName)? {\
\(accessControlRenderer())var \(typeName.firstLowercased): \(typeName)? {\
\(if: isMutable,
"""
Expand All @@ -345,7 +355,7 @@ struct SelectionSetTemplate {
}

return """
public struct Fragments: FragmentContainer {
\(accessControlRenderer())struct Fragments: FragmentContainer {
\(DataFieldAndInitializerTemplate())
\(ifLet: selections.direct?.fragments.values, {
Expand All @@ -369,7 +379,7 @@ struct SelectionSetTemplate {
!scope.matches(fragment.inclusionConditions.unsafelyUnwrapped)

return """
public var \(propertyName): \(typeName)\
\(accessControlRenderer())var \(propertyName): \(typeName)\
\(if: isOptional, "?") {\
\(if: isMutable,
"""
Expand All @@ -393,7 +403,7 @@ struct SelectionSetTemplate {

private func InitializerTemplate(_ selectionSet: IR.SelectionSet) -> TemplateString {
return """
public init(
\(accessControlRenderer())init(
\(InitializerSelectionParametersTemplate(selectionSet))
) {
self.init(_dataDict: DataDict(data: [
Expand Down
14 changes: 7 additions & 7 deletions Sources/ApolloCodegenLib/Templates/TemplateRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -156,32 +156,32 @@ extension TemplateRenderer {
guard config.output.schemaTypes.isInModule else {
switch config.output.schemaTypes.moduleType {
case .embeddedInTarget(_, .public):
return "\(ApolloCodegenConfiguration.AccessModifier.public) "
return ApolloCodegenConfiguration.AccessModifier.public.swiftString
case .embeddedInTarget(_, .internal), .swiftPackageManager, .other:
return ""
return ApolloCodegenConfiguration.AccessModifier.internal.swiftString
}
}

return "public "
return ApolloCodegenConfiguration.AccessModifier.public.swiftString
}

private var operationTypeEmbeddedAccessControlModifier: String {
switch config.output.operations {
case .inSchemaModule:
return schemaTypeEmbeddedAccessControlModifier
case .absolute(_, .public), .relative(_, .public):
return "\(ApolloCodegenConfiguration.AccessModifier.public) "
return ApolloCodegenConfiguration.AccessModifier.public.swiftString
case .absolute(_, .internal), .relative(_, .internal):
return ""
return ApolloCodegenConfiguration.AccessModifier.internal.swiftString
}
}

private var testMockTypeEmbeddedAccessControlModifier: String {
switch config.config.output.testMocks {
case .none, .absolute(_, .internal):
return ""
return ApolloCodegenConfiguration.AccessModifier.internal.swiftString
case .swiftPackage, .absolute(_, .public):
return "\(ApolloCodegenConfiguration.AccessModifier.public) "
return ApolloCodegenConfiguration.AccessModifier.public.swiftString
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions Tests/ApolloCodegenInternalTestHelpers/MockTemplateRenderer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Foundation
@testable import ApolloCodegenLib

public struct MockTemplateRenderer: TemplateRenderer {
public var target: ApolloCodegenLib.TemplateTarget
public var template: ApolloCodegenLib.TemplateString
public var config: ApolloCodegenLib.ApolloCodegen.ConfigurationContext

public init(
target: TemplateTarget,
template: TemplateString,
config: ApolloCodegen.ConfigurationContext
) {
self.target = target
self.template = template
self.config = config
}
}
Loading

0 comments on commit e9e3a75

Please sign in to comment.