@@ -268,7 +268,7 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
268268 moduleType: ModuleType
269269 ) {
270270 self . path = path
271- self . moduleType = moduleType
271+ self . moduleType = moduleType == . swiftPackageManager ? . swiftPackage ( apolloSDKDependency : . default ) : moduleType
272272 }
273273
274274 /// Compatible dependency manager automation.
@@ -283,7 +283,12 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
283283 case embeddedInTarget( name: String , accessModifier: AccessModifier = . internal)
284284 /// Generates a `Package.swift` file that is suitable for linking the generated schema types
285285 /// files to your project using Swift Package Manager.
286+ /// Attention: This case has been deprecated, use .swiftPackage(apolloSDKVersion:) case instead.
286287 case swiftPackageManager
288+ /// Generates a `Package.swift` file that is suitable for linking then generated schema types
289+ /// files to your project using Swift Package Manager. Uses the `apolloSDKDependency`
290+ /// to determine how to setup the dependency on `apollo-ios`.
291+ case swiftPackage( apolloSDKDependency: ApolloSDKDependency = . default)
287292 /// No module will be created for the generated types and you are required to create the
288293 /// module to support your preferred dependency manager. You must specify the name of the
289294 /// module you will create in the `schemaNamespace` property as this will be used in `import`
@@ -321,12 +326,193 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
321326 self = . embeddedInTarget( name: name, accessModifier: accessModifier)
322327
323328 case . swiftPackageManager:
324- self = . swiftPackageManager
329+ self = . swiftPackage( apolloSDKDependency: . default)
330+
331+ case . swiftPackage:
332+ let nestedContainer = try container. nestedContainer (
333+ keyedBy: SwiftPackageCodingKeys . self,
334+ forKey: . swiftPackage
335+ )
336+
337+ let apolloSDKDependency = try nestedContainer. decodeIfPresent ( ApolloSDKDependency . self, forKey: . apolloSDKDependency) ?? ApolloSDKDependency ( )
338+ self = . swiftPackage( apolloSDKDependency: apolloSDKDependency)
325339
326340 case . other:
327341 self = . other
328342 }
329343 }
344+
345+ /// Configuation for apollo-ios dependency in SPM modules
346+ public struct ApolloSDKDependency : Codable , Equatable {
347+ /// URL for the SPM package dependency, not used for local dependencies.
348+ /// Defaults to 'https://github.com/apollographql/apollo-ios'.
349+ let url : String
350+ /// Type of SPM dependency to use.
351+ let sdkVersion : SDKVersion
352+
353+ public static let `default` = ApolloSDKDependency ( )
354+
355+ public init (
356+ url: String = " https://github.com/apollographql/apollo-ios " ,
357+ sdkVersion: SDKVersion = . default
358+ ) {
359+ self . url = url
360+ self . sdkVersion = sdkVersion
361+ }
362+
363+ enum CodingKeys : CodingKey , CaseIterable {
364+ case url
365+ case sdkVersion
366+ }
367+
368+ public func encode( to encoder: any Encoder ) throws {
369+ var container = encoder. container ( keyedBy: CodingKeys . self)
370+
371+ try container. encode ( self . url, forKey: . url)
372+
373+ switch self . sdkVersion {
374+ case . default:
375+ try container. encode ( self . sdkVersion. stringValue, forKey: . sdkVersion)
376+ default :
377+ try container. encode ( self . sdkVersion, forKey: . sdkVersion)
378+ }
379+ }
380+
381+ public init ( from decoder: any Decoder ) throws {
382+ let values = try decoder. container ( keyedBy: CodingKeys . self)
383+ try throwIfContainsUnexpectedKey (
384+ container: values,
385+ type: Self . self,
386+ decoder: decoder
387+ )
388+
389+ url = try values. decode ( String . self, forKey: . url)
390+
391+ if let version = try ? values. decodeIfPresent ( SDKVersion . self, forKey: . sdkVersion) {
392+ sdkVersion = version
393+ } else if let versionString = try ? values. decodeIfPresent ( String . self, forKey: . sdkVersion) {
394+ let version = try SDKVersion ( fromString: versionString)
395+ sdkVersion = version
396+ } else {
397+ throw DecodingError . typeMismatch ( Self . self, DecodingError . Context. init (
398+ codingPath: values. codingPath,
399+ debugDescription: " No valid 'sdkVersion' provided. " ,
400+ underlyingError: nil
401+ ) )
402+ }
403+ }
404+
405+ /// Type of SPM dependency
406+ public enum SDKVersion : Codable , Equatable {
407+ /// Configures SPM dependency to use the exact version of apollo-ios
408+ /// that matches the code generation library version currently in use.
409+ /// Results in a dependency that looks like:
410+ /// '.package(url: "https://github.com/apollographql/apollo-ios.git", exact: "{version}")'
411+ case `default`
412+ /// Configures SPM dependency to use the given branch name
413+ /// for the apollo-ios dependency.
414+ /// Results in a dependency that looks like:
415+ /// '.package(url: "...", branch: "{name}")'
416+ case branch( name: String )
417+ /// Configures SPM dependency to use the given commit hash
418+ /// for the apollo-ios dependency.
419+ /// Results in a dependency that looks like:
420+ /// '.package(url: "...", revision: "{hash}")'
421+ case commit( hash: String )
422+ /// Configures SPM dependency to use the given exact version
423+ /// for the apollo-ios dependency.
424+ /// Results in a dependency that looks like:
425+ /// '.package(url: "...", exact: "{version}")'
426+ case exact( version: String )
427+ /// Configures SPM dependency to use a version
428+ /// starting at the given version for the apollo-ios dependency.
429+ /// Results in a dependency that looks like:
430+ /// '.package(url: "...", from: "{version}")'
431+ case from( version: String )
432+ /// Configures SPM dependency to use a local
433+ /// path for the apollo-ios dependency.
434+ /// Results in a dependency that looks like:
435+ /// '.package(path: "{path}")'
436+ case local( path: String )
437+
438+ public var stringValue : String {
439+ switch self {
440+ case . default: return " default "
441+ case . branch( _) : return " branch "
442+ case . commit( _) : return " commit "
443+ case . exact( _) : return " exact "
444+ case . from( _) : return " from "
445+ case . local( _) : return " local "
446+ }
447+ }
448+
449+ public init ( fromString str: String ) throws {
450+ switch str {
451+ case Self . default. stringValue:
452+ self = . default
453+ default :
454+ throw ApolloConfigurationError . invalidValueForKey ( key: " sdkVersion " , value: str)
455+ }
456+ }
457+
458+ public init ( from decoder: any Decoder ) throws {
459+ let container = try decoder. container ( keyedBy: CodingKeys . self)
460+
461+ guard let key = container. allKeys. first else {
462+ throw DecodingError . typeMismatch ( Self . self, DecodingError . Context. init (
463+ codingPath: container. codingPath,
464+ debugDescription: " Invalid number of keys found, expected one. " ,
465+ underlyingError: nil
466+ ) )
467+ }
468+
469+ switch key {
470+ case . default:
471+ self = . default
472+ case . branch:
473+ let nestedContainer = try container. nestedContainer (
474+ keyedBy: BranchCodingKeys . self,
475+ forKey: . branch
476+ )
477+
478+ let name = try nestedContainer. decode ( String . self, forKey: . name)
479+ self = . branch( name: name)
480+ case . commit:
481+ let nestedContainer = try container. nestedContainer (
482+ keyedBy: CommitCodingKeys . self,
483+ forKey: . commit
484+ )
485+
486+ let hash = try nestedContainer. decode ( String . self, forKey: . hash)
487+ self = . commit( hash: hash)
488+ case . exact:
489+ let nestedContainer = try container. nestedContainer (
490+ keyedBy: ExactCodingKeys . self,
491+ forKey: . exact
492+ )
493+
494+ let version = try nestedContainer. decode ( String . self, forKey: . version)
495+ self = . exact( version: version)
496+ case . from:
497+ let nestedContainer = try container. nestedContainer (
498+ keyedBy: FromCodingKeys . self,
499+ forKey: . from
500+ )
501+
502+ let version = try nestedContainer. decode ( String . self, forKey: . version)
503+ self = . from( version: version)
504+ case . local:
505+ let nestedContainer = try container. nestedContainer (
506+ keyedBy: LocalCodingKeys . self,
507+ forKey: . local
508+ )
509+
510+ let path = try nestedContainer. decode ( String . self, forKey: . path)
511+ self = . local( path: path)
512+ }
513+ }
514+ }
515+ }
330516 }
331517 }
332518
@@ -1176,6 +1362,24 @@ public struct ApolloCodegenConfiguration: Codable, Equatable {
11761362 operationManifest: operationManifest ?? Default . operationManifest
11771363 )
11781364 }
1365+
1366+ }
1367+
1368+ // MARK: Errors
1369+
1370+ extension ApolloCodegenConfiguration {
1371+ public enum ApolloConfigurationError : Error , LocalizedError {
1372+ case invalidValueForKey( key: String , value: String )
1373+
1374+ public var errorDescription : String ? {
1375+ switch self {
1376+ case . invalidValueForKey( let key, let value) :
1377+ return """
1378+ Invalid value ' \( value) ' provided for key ' \( key) '.
1379+ """
1380+ }
1381+ }
1382+ }
11791383}
11801384
11811385// MARK: - Helpers
@@ -1185,7 +1389,7 @@ extension ApolloCodegenConfiguration.SchemaTypesFileOutput {
11851389 var isInModule : Bool {
11861390 switch moduleType {
11871391 case . embeddedInTarget: return false
1188- case . swiftPackageManager, . other: return true
1392+ case . swiftPackageManager, . swiftPackage , . other: return true
11891393 }
11901394 }
11911395}
0 commit comments