66//
77
88import Foundation
9+ import JavaScriptCore
910import CouchbaseLiteSwift
1011
1112public struct ReplicatorHelper {
12-
13- public static func replicatorConfigFromJson( _ data: [ String : Any ] ) throws -> ReplicatorConfiguration {
14- guard let authenticatorData = data [ " authenticator " ] as? [ String : Any ] ,
15- let target = data [ " target " ] as? [ String : Any ] ,
13+
14+ public static func replicatorConfigFromJson( _ data: [ String : Any ] , collectionConfiguration: [ CollectionConfigItem ] ) throws -> ReplicatorConfiguration {
15+ guard let target = data [ " target " ] as? [ String : Any ] ,
1616 let url = target [ " url " ] as? String ,
1717 let replicatorType = data [ " replicatorType " ] as? String ,
18- let continuous = data [ " continuous " ] as? Bool ,
19- let collectionConfig = data [ " collectionConfig " ] as? [ String : Any ] else {
18+ let continuous = data [ " continuous " ] as? Bool else {
2019 throw ReplicatorError . fatalError ( message: " Invalid JSON data " )
2120 }
22-
21+
2322 let endpoint = URLEndpoint ( url: URL ( string: url) !)
2423 var replConfig = ReplicatorConfiguration ( target: endpoint)
25-
24+
25+ if let authenticatorData = data [ " authenticator " ] , !( authenticatorData is String && authenticatorData as! String == " " ) {
26+ if let authenticatorConfig = authenticatorData as? [ String : Any ] {
27+ if let authenticator = ReplicatorHelper . replicatorAuthenticatorFromConfig ( authenticatorConfig) {
28+ replConfig. authenticator = authenticator
29+ }
30+ }
31+
32+ }
33+
34+ try ReplicatorHelper . replicatorCollectionConfigFromJson ( collectionConfiguration, replicationConfig: & replConfig)
35+
2636 switch replicatorType {
27- case " PUSH_AND_PULL " :
28- replConfig. replicatorType = . pushAndPull
29- case " PULL " :
30- replConfig. replicatorType = . pull
31- case " PUSH " :
32- replConfig. replicatorType = . push
33- default :
34- throw ReplicatorError . fatalError ( message: " Invalid replicatorType " )
37+ case " PUSH_AND_PULL " :
38+ replConfig. replicatorType = . pushAndPull
39+ case " PULL " :
40+ replConfig. replicatorType = . pull
41+ case " PUSH " :
42+ replConfig. replicatorType = . push
43+ default :
44+ throw ReplicatorError . fatalError ( message: " Invalid replicatorType " )
3545 }
36-
46+
3747 replConfig. continuous = continuous
38-
39- if let authenticator = ReplicatorHelper . replicatorAuthenticatorFromConfig ( authenticatorData) {
40- replConfig. authenticator = authenticator
41- }
4248
43- //setup collections
44- let ( collections, colConfig) = try ReplicatorHelper . replicatorCollectionConfigFromJson ( collectionConfig)
45- replConfig. addCollections ( Array ( collections) , config: colConfig)
4649
4750 return replConfig
4851 }
49-
50- private static func replicatorCollectionConfigFromJson( _ data: [ String : Any ] ) throws -> ( Set < Collection > , CollectionConfiguration ) {
52+
53+ public static func replicatorCollectionConfigFromJson( _ data: [ CollectionConfigItem ] , replicationConfig : inout ReplicatorConfiguration ) throws {
5154
5255 //work on the collections sent in as part of the configuration with an array of collectionName, scopeName, and databaseName
53- guard let collectionData = data [ " collections " ] as? [ [ String : String ] ] else {
54- throw ReplicatorError . configurationError ( message: " collections doesn't include collections in the proper format " )
55- }
56- guard let config = data [ " config " ] as? [ String : Any ] else {
57- throw ReplicatorError . configurationError ( message: " ReplicationConfig collection config is incorrect format " )
58- }
59-
60- var collections : Set < Collection > = [ ]
61-
62- for collectionItem in collectionData {
63- guard let collectionName = collectionItem [ " collectionName " ] ,
64- let scopeName = collectionItem [ " scopeName " ] ,
65- let databaseName = collectionItem [ " databaseName " ] else {
66- // Handle the case where any required key is missing
67- throw ReplicatorError . configurationError ( message: " Error: collections missing required key in collection data - collectionName, scopeName, or databaseName " )
56+ for item in data {
57+
58+ var collections : [ Collection ] = [ ]
59+
60+ for col in item. collections {
61+
62+ guard let collection = try CollectionManager . shared. getCollection ( col. collection. name, scopeName: col. collection. scopeName, databaseName: col. collection. databaseName) else {
63+ throw CollectionError . unableToFindCollection ( collectionName: col. collection. name, scopeName: col. collection. scopeName, databaseName: col. collection. databaseName)
64+ }
65+ collections. append ( collection)
6866 }
69- guard let collection = try CollectionManager . shared. getCollection ( collectionName, scopeName: scopeName, databaseName: databaseName) else {
70- throw CollectionError . unableToFindCollection ( collectionName: collectionName, scopeName: scopeName, databaseName: databaseName)
67+
68+ //process the config part of the data
69+ var collectionConfig = CollectionConfiguration ( )
70+
71+ //get the channels and documentIds to filter for the collections
72+ //these are optional
73+ if item. config. channels. count > 0 {
74+ collectionConfig. channels = item. config. channels
7175 }
72- collections. insert ( collection)
73- }
74- //process the config part of the data
75- var collectionConfig = CollectionConfiguration ( )
76-
77- //get the channels and documentIds to filter for the collections
78- //these are optional
79- if let channels = config [ " channels " ] as? [ String ] {
80- collectionConfig. channels = channels
81- }
82- if let documentIds = config [ " documentIds " ] as? [ String ] {
83- collectionConfig. documentIDs = documentIds
76+ if item. config. documentIds. count > 0 {
77+ collectionConfig. documentIDs = item. config. documentIds
78+ }
79+ replicationConfig. addCollections ( collections, config: collectionConfig)
8480 }
85- return ( collections, collectionConfig)
8681 }
87-
82+
8883 private static func replicatorAuthenticatorFromConfig( _ config: [ String : Any ] ? ) -> Authenticator ? {
8984 guard let type = config ? [ " type " ] as? String ,
9085 let data = config ? [ " data " ] as? [ String : Any ] else {
9186 return nil
9287 }
93-
88+
9489 switch type {
95- case " session " :
96- guard let sessionID = data [ " sessionID " ] as? String ,
97- let cookieName = data [ " cookieName " ] as? String else {
90+ case " session " :
91+ guard let sessionID = data [ " sessionID " ] as? String ,
92+ let cookieName = data [ " cookieName " ] as? String else {
93+ return nil
94+ }
95+ return SessionAuthenticator ( sessionID: sessionID, cookieName: cookieName)
96+
97+ case " basic " :
98+ guard let username = data [ " username " ] as? String ,
99+ let password = data [ " password " ] as? String else {
100+ return nil
101+ }
102+ return BasicAuthenticator ( username: username, password: password)
103+
104+ default :
98105 return nil
99- }
100- return SessionAuthenticator ( sessionID: sessionID, cookieName: cookieName)
101-
102- case " basic " :
103- guard let username = data [ " username " ] as? String ,
104- let password = data [ " password " ] as? String else {
105- return nil
106- }
107- return BasicAuthenticator ( username: username, password: password)
108-
109- default :
110- return nil
111106 }
112107 }
113-
108+
114109 public static func generateReplicatorStatusJson( _ status: Replicator . Status ) -> [ String : Any ] {
115110 var errorJson : [ String : Any ] ?
116111 if let error = status. error {
117112 errorJson = [
118113 " message " : error. localizedDescription
119114 ]
120115 }
121-
116+
122117 let progressJson : [ String : Any ] = [
123118 " completed " : status. progress. completed,
124119 " total " : status. progress. total
125120 ]
126-
121+
127122 if let errorJson = errorJson {
128123 return [
129124 " activityLevel " : status. activity. rawValue,
@@ -137,10 +132,10 @@ public struct ReplicatorHelper {
137132 ]
138133 }
139134 }
140-
135+
141136 public static func generateReplicationJson( _ replication: [ ReplicatedDocument ] , isPush: Bool ) -> [ String : Any ] {
142137 var docs = [ [ String: Any] ] ( )
143-
138+
144139 for document in replication {
145140 var flags = [ String] ( )
146141 if document. flags. contains ( . deleted) {
@@ -150,20 +145,20 @@ public struct ReplicatorHelper {
150145 flags. append ( " ACCESS_REMOVED " )
151146 }
152147 var documentDictionary : [ String : Any ] = [ " id " : document. id, " flags " : flags]
153-
148+
154149 if let error = document. error {
155150 documentDictionary [ " error " ] = [
156151 " message " : error. localizedDescription
157152 ]
158153 }
159-
154+
160155 docs. append ( documentDictionary)
161156 }
162-
157+
163158 return [
164159 " direction " : isPush ? " PUSH " : " PULL " ,
165160 " documents " : docs
166161 ]
167162 }
168-
163+
169164}
0 commit comments