forked from apollographql/apollo-ios
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add note about acceptable extensions for types of schema file. (apoll…
- Loading branch information
1 parent
5dc4094
commit 6642b36
Showing
1 changed file
with
208 additions
and
0 deletions.
There are no files selected for viewing
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,208 @@ | ||
import Foundation | ||
|
||
/// An object to hold all the various options for running codegen | ||
public struct ApolloCodegenOptions { | ||
|
||
/// Enum to select how you want to export your API files. | ||
public enum OutputFormat { | ||
/// Outputs everything into a single file at the given URL. | ||
/// NOTE: URL must be a file URL | ||
case singleFile(atFileURL: URL) | ||
/// Outputs everything into individual files in a folder a the given URL | ||
/// NOTE: URL must be a folder URL | ||
case multipleFiles(inFolderAtURL: URL) | ||
} | ||
|
||
/// Enum to select which code generation you wish to use | ||
public enum CodeGenerationEngine: Equatable { | ||
/// The default, tried and true code generation engine | ||
case typescript | ||
|
||
/// The current default for the code generation engine. | ||
public static var `default`: CodeGenerationEngine { | ||
.typescript | ||
} | ||
|
||
var targetForApolloTools: String { | ||
switch self { | ||
case .typescript: | ||
return "swift" | ||
} | ||
} | ||
} | ||
|
||
/// The possible access modifiers for code generated by this tool. | ||
public enum AccessModifier { | ||
case `public` | ||
case `internal` | ||
case `none` | ||
|
||
/// The prefix which should be used for classes, enums, and structs generated by this tool. | ||
public var prefixValue: String { | ||
switch self { | ||
case .public: return "public " | ||
case .internal: return "internal " | ||
case .none: return "" | ||
} | ||
} | ||
} | ||
|
||
/// Enum to select how to handle properties using a custom scalar from the schema. | ||
public enum CustomScalarFormat: Equatable { | ||
/// Uses a default type instead of a custom scalar. | ||
case none | ||
/// Use your own types for custom scalars. | ||
case passthrough | ||
/// Use your own types for custom scalars with a prefix. | ||
case passthroughWithPrefix(String) | ||
} | ||
|
||
let codegenEngine: CodeGenerationEngine | ||
let includes: String | ||
let mergeInFieldsFromFragmentSpreads: Bool | ||
let namespace: String? | ||
let modifier: AccessModifier | ||
let only: URL? | ||
let omitDeprecatedEnumCases: Bool | ||
let operationIDsURL: URL? | ||
let outputFormat: OutputFormat | ||
let customScalarFormat: CustomScalarFormat | ||
let suppressSwiftMultilineStringLiterals: Bool | ||
let urlToSchemaFile: URL | ||
|
||
let downloadTimeout: Double | ||
|
||
/// Designated initializer. | ||
/// | ||
/// - Parameters: | ||
/// - codegenEngine: The code generation engine to use. Defaults to `CodeGenerationEngine.default` | ||
/// - includes: Glob of files to search for GraphQL operations. This should be used to find queries *and* any client schema extensions. Defaults to `./**/*.graphql`, which will search for `.graphql` files throughout all subfolders of the folder where the script is run. | ||
/// - mergeInFieldsFromFragmentSpreads: Set true to merge fragment fields onto its enclosing type. Defaults to true. | ||
/// - modifier: [EXPERIMENTAL SWIFT CODEGEN ONLY] - The access modifier to use on everything created by this tool. Defaults to `.public`. | ||
/// - namespace: [optional] The namespace to emit generated code into. Defaults to nil. | ||
/// - omitDeprecatedEnumCases: Whether deprecated enum cases should be omitted from generated code. Defaults to false. | ||
/// - only: [optional] Parse all input files, but only output generated code for the file at this URL if non-nil. Defaults to nil. | ||
/// - operationIDsURL: [optional] Path to an operation id JSON map file. If specified, also stores the operation ids (hashes) as properties on operation types. Defaults to nil. | ||
/// - outputFormat: The `OutputFormat` enum option to use to output generated code. | ||
/// - customScalarFormat: How to handle properties using a custom scalar from the schema. | ||
/// - suppressSwiftMultilineStringLiterals: Don't use multi-line string literals when generating code. Defaults to false. | ||
/// - urlToSchemaFile: The URL to your schema file. Accepted file types are `.json` for JSON files, or either `.graphqls` or `.sdl` for Schema Definition Language files. | ||
/// - downloadTimeout: The maximum time to wait before indicating that the download timed out, in seconds. Defaults to 30 seconds. | ||
public init(codegenEngine: CodeGenerationEngine = .default, | ||
includes: String = "./**/*.graphql", | ||
mergeInFieldsFromFragmentSpreads: Bool = true, | ||
modifier: AccessModifier = .public, | ||
namespace: String? = nil, | ||
omitDeprecatedEnumCases: Bool = false, | ||
only: URL? = nil, | ||
operationIDsURL: URL? = nil, | ||
outputFormat: OutputFormat, | ||
customScalarFormat: CustomScalarFormat = .none, | ||
suppressSwiftMultilineStringLiterals: Bool = false, | ||
urlToSchemaFile: URL, | ||
downloadTimeout: Double = 30.0) { | ||
self.codegenEngine = codegenEngine | ||
self.includes = includes | ||
self.mergeInFieldsFromFragmentSpreads = mergeInFieldsFromFragmentSpreads | ||
self.modifier = modifier | ||
self.namespace = namespace | ||
self.omitDeprecatedEnumCases = omitDeprecatedEnumCases | ||
self.only = only | ||
self.operationIDsURL = operationIDsURL | ||
self.outputFormat = outputFormat | ||
self.customScalarFormat = customScalarFormat | ||
self.suppressSwiftMultilineStringLiterals = suppressSwiftMultilineStringLiterals | ||
self.urlToSchemaFile = urlToSchemaFile | ||
self.downloadTimeout = downloadTimeout | ||
} | ||
|
||
/// Convenience initializer that takes the root folder of a target and generates | ||
/// code with some default assumptions. | ||
/// Makes the following assumptions: | ||
/// - Schema is at [folder]/schema.json | ||
/// - Output is a single file to [folder]/API.swift | ||
/// - You want operation IDs generated and output to [folder]/operationIDs.json | ||
/// | ||
/// - Parameters: | ||
/// - folder: The root of the target. | ||
/// - codegenEngine: The code generation engine to use. Defaults to `CodeGenerationEngine.default` | ||
/// - downloadTimeout: The maximum time to wait before indicating that the download timed out, in seconds. Defaults to 30 seconds | ||
public init(targetRootURL folder: URL, | ||
codegenEngine: CodeGenerationEngine = .default, | ||
downloadTimeout: Double = 30.0) { | ||
let schema = folder.appendingPathComponent("schema.graphqls") | ||
|
||
let outputFileURL: URL | ||
switch codegenEngine { | ||
case .typescript: | ||
outputFileURL = folder.appendingPathComponent("API.swift") | ||
} | ||
|
||
let operationIDsURL = folder.appendingPathComponent("operationIDs.json") | ||
|
||
self.init(codegenEngine: codegenEngine, | ||
operationIDsURL: operationIDsURL, | ||
outputFormat: .singleFile(atFileURL: outputFileURL), | ||
urlToSchemaFile: schema, | ||
downloadTimeout: downloadTimeout) | ||
} | ||
|
||
var arguments: [String] { | ||
var arguments = [ | ||
"codegen:generate", | ||
"--target=\(self.codegenEngine.targetForApolloTools)", | ||
"--addTypename", | ||
"--includes='\(self.includes)'", | ||
"--localSchemaFile='\(self.urlToSchemaFile.path)'" | ||
] | ||
|
||
if let namespace = self.namespace { | ||
arguments.append("--namespace=\(namespace)") | ||
} | ||
|
||
if let only = only { | ||
arguments.append("--only='\(only.path)'") | ||
} | ||
|
||
if let idsURL = self.operationIDsURL { | ||
arguments.append("--operationIdsPath='\(idsURL.path)'") | ||
} | ||
|
||
if self.omitDeprecatedEnumCases { | ||
arguments.append("--omitDeprecatedEnumCases") | ||
} | ||
|
||
switch customScalarFormat { | ||
case .none: | ||
break | ||
case .passthrough: | ||
arguments.append("--passthroughCustomScalars") | ||
case .passthroughWithPrefix(let prefix): | ||
arguments.append("--passthroughCustomScalars") | ||
arguments.append("--customScalarsPrefix='\(prefix)'") | ||
} | ||
|
||
if self.mergeInFieldsFromFragmentSpreads { | ||
arguments.append("--mergeInFieldsFromFragmentSpreads") | ||
} | ||
|
||
if self.suppressSwiftMultilineStringLiterals { | ||
arguments.append("--suppressSwiftMultilineStringLiterals") | ||
} | ||
|
||
switch self.outputFormat { | ||
case .singleFile(let fileURL): | ||
arguments.append("'\(fileURL.path)'") | ||
case .multipleFiles(let folderURL): | ||
arguments.append("'\(folderURL.path)'") | ||
} | ||
|
||
return arguments | ||
} | ||
} | ||
|
||
extension ApolloCodegenOptions: CustomDebugStringConvertible { | ||
public var debugDescription: String { | ||
self.arguments.joined(separator: "\n") | ||
} | ||
} |