-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConfiguration.swift
More file actions
98 lines (92 loc) · 3.73 KB
/
Copy pathConfiguration.swift
File metadata and controls
98 lines (92 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import Foundation
/// A `Configuration` controls the behavior of `Codegen.run`. Recommended
/// defaults are provided where applicable, however the options here may be adjusted to
/// your specific needs and provides flexibility over the Swift code generated.
/// Please open an issue on the Github repo if you'd like to add a new configuration option.
public struct Configuration: Sendable {
/// Call this function to create a new `Configuration` instance.
///
/// - Parameters:
/// - input: Options controlling how to ingest the GraphQL schema and GraphQL operations.
/// - output: Options controlling the code that is output by this codegen.
/// - Returns: A `Configuration` to be passed to `Codegen.run`
public static func configuration(
input: Input,
output: Output
) -> Configuration {
Configuration(
input: input,
output: output
)
}
public var input: Input
public var output: Output
func validate() throws {
if case .spaces(let count) = output.indentation, count < 0 {
throw Codegen.Error(description: "The indentation space count must not be negative.")
}
if output.support.HTTPSupport != nil {
try validateHTTPOperationConformances()
}
switch input.schemaSource {
case .JSONSchemaFile(let url):
try verifyLocalURL(
url,
expectedExtension: ["json"],
parameter: "JSONSchemaFile",
configuration: "schema source"
)
case .SDLSchemaFile(let url):
try verifyLocalURL(
url,
expectedExtension: ["graphql", "graphqls", "sdl"],
parameter: "SDLSchemaFile",
configuration: "schema source"
)
case .introspectionEndpoint: break
}
}
private func validateHTTPOperationConformances() throws {
let responseDataConformances = output.documents.operations.responseData.conformances.map {
SwiftConformanceName(source: $0)
}
guard responseDataConformances.contains(where: { $0.includesDecodable }),
responseDataConformances.contains(where: { $0.includesSendable })
else {
throw Codegen.Error(description: """
HTTP support requires output.documents.operations.responseData.conformances to include Decodable and Sendable.
""")
}
let variableConformances = output.documents.operations.variables.conformances.map {
SwiftConformanceName(source: $0)
}
guard variableConformances.contains(where: { $0.includesEncodable }),
variableConformances.contains(where: { $0.includesSendable })
else {
throw Codegen.Error(description: """
HTTP support requires output.documents.operations.variables.conformances to include Encodable and Sendable.
""")
}
}
private func verifyLocalURL(
_ url: URL,
expectedExtension possibleExtensions: [String],
parameter: String,
configuration: String
) throws {
guard url.isFileURL else {
throw Codegen.Error(description: """
The "\(parameter)" URL used in the \(configuration) configuration must be a local file.
\(url)
""")
}
let `extension` = url.pathExtension.lowercased()
for possibleExtension in possibleExtensions where possibleExtension == `extension` {
return
}
throw Codegen.Error(description: """
The "\(parameter)" URL used in the \(configuration) configuration have an extenion in: \(possibleExtensions) file.
\(url)
""")
}
}