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 ,
1818 let continuous = data [ " continuous " ] as? Bool ,
19- let collectionConfig = data [ " collectionConfig " ] as? [ String : Any ] else {
19+ let acceptParentDomainCookies = data [ " acceptParentDomainCookies " ] as? Bool ,
20+ let acceptSelfSignedCerts = data [ " acceptSelfSignedCerts " ] as? Bool ,
21+ let allowReplicationInBackground = data [ " allowReplicationInBackground " ] as? Bool ,
22+ let autoPurgeEnabled = data [ " autoPurgeEnabled " ] as? Bool ,
23+ let heartbeat = data [ " heartbeat " ] as? NSNumber ,
24+ let maxAttempts = data [ " maxAttempts " ] as? NSNumber ,
25+ let maxAttemptWaitTime = data [ " maxAttemptWaitTime " ] as? NSNumber
26+ else {
2027 throw ReplicatorError . fatalError ( message: " Invalid JSON data " )
2128 }
22-
29+
2330 let endpoint = URLEndpoint ( url: URL ( string: url) !)
31+
32+ //set values from data
2433 var replConfig = ReplicatorConfiguration ( target: endpoint)
25-
26- 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 " )
35- }
36-
34+ replConfig. acceptParentDomainCookie = acceptSelfSignedCerts
35+ replConfig. acceptParentDomainCookie = acceptParentDomainCookies
36+ replConfig. allowReplicatingInBackground = allowReplicationInBackground
3737 replConfig. continuous = continuous
38-
39- if let authenticator = ReplicatorHelper . replicatorAuthenticatorFromConfig ( authenticatorData) {
40- replConfig. authenticator = authenticator
38+ replConfig. enableAutoPurge = autoPurgeEnabled
39+
40+ replConfig. heartbeat = TimeInterval ( exactly: heartbeat. int64Value) ?? 300
41+ replConfig. maxAttemptWaitTime = TimeInterval ( exactly: maxAttemptWaitTime. int64Value) ?? 0
42+ replConfig. maxAttempts = maxAttempts. uintValue
43+
44+ //check for headers
45+ if let headers = data [ " headers " ] as? [ String : String ] {
46+ replConfig. headers = headers
4147 }
4248
43- //setup collections
44- let ( collections, colConfig) = try ReplicatorHelper . replicatorCollectionConfigFromJson ( collectionConfig)
45- replConfig. addCollections ( Array ( collections) , config: colConfig)
49+ if let authenticatorData = data [ " authenticator " ] , !( authenticatorData is String && authenticatorData as! String == " " ) {
50+ if let authenticatorConfig = authenticatorData as? [ String : Any ] {
51+ if let authenticator = ReplicatorHelper . replicatorAuthenticatorFromConfig ( authenticatorConfig) {
52+ replConfig. authenticator = authenticator
53+ }
54+ }
55+
56+ }
4657
58+ try ReplicatorHelper . replicatorCollectionConfigFromJson ( collectionConfiguration, replicationConfig: & replConfig)
59+
60+ switch replicatorType {
61+ case " PUSH_AND_PULL " :
62+ replConfig. replicatorType = . pushAndPull
63+ case " PULL " :
64+ replConfig. replicatorType = . pull
65+ case " PUSH " :
66+ replConfig. replicatorType = . push
67+ default :
68+ throw ReplicatorError . fatalError ( message: " Invalid replicatorType " )
69+ }
4770 return replConfig
4871 }
49-
50- private static func replicatorCollectionConfigFromJson( _ data: [ String : Any ] ) throws -> ( Set < Collection > , CollectionConfiguration ) {
72+
73+ public static func replicatorCollectionConfigFromJson( _ data: [ CollectionConfigItem ] , replicationConfig : inout ReplicatorConfiguration ) throws {
5174
5275 //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 " )
76+ for item in data {
77+
78+ var collections : [ Collection ] = [ ]
79+
80+ for col in item. collections {
81+
82+ guard let collection = try CollectionManager . shared. getCollection ( col. collection. name, scopeName: col. collection. scopeName, databaseName: col. collection. databaseName) else {
83+ throw CollectionError . unableToFindCollection ( collectionName: col. collection. name, scopeName: col. collection. scopeName, databaseName: col. collection. databaseName)
84+ }
85+ collections. append ( collection)
6886 }
69- guard let collection = try CollectionManager . shared. getCollection ( collectionName, scopeName: scopeName, databaseName: databaseName) else {
70- throw CollectionError . unableToFindCollection ( collectionName: collectionName, scopeName: scopeName, databaseName: databaseName)
87+
88+ //process the config part of the data
89+ var collectionConfig = CollectionConfiguration ( )
90+
91+ //get the channels and documentIds to filter for the collections
92+ //these are optional
93+ if item. config. channels. count > 0 {
94+ collectionConfig. channels = item. config. channels
7195 }
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
96+ if item. config. documentIds. count > 0 {
97+ collectionConfig. documentIDs = item. config. documentIds
98+ }
99+ replicationConfig. addCollections ( collections, config: collectionConfig)
84100 }
85- return ( collections, collectionConfig)
86101 }
87-
102+
88103 private static func replicatorAuthenticatorFromConfig( _ config: [ String : Any ] ? ) -> Authenticator ? {
89104 guard let type = config ? [ " type " ] as? String ,
90105 let data = config ? [ " data " ] as? [ String : Any ] else {
91106 return nil
92107 }
93-
108+
94109 switch type {
95- case " session " :
96- guard let sessionID = data [ " sessionID " ] as? String ,
97- let cookieName = data [ " cookieName " ] as? String else {
98- 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 {
110+ case " session " :
111+ guard let sessionID = data [ " sessionID " ] as? String ,
112+ let cookieName = data [ " cookieName " ] as? String else {
113+ return nil
114+ }
115+ return SessionAuthenticator ( sessionID: sessionID, cookieName: cookieName)
116+
117+ case " basic " :
118+ guard let username = data [ " username " ] as? String ,
119+ let password = data [ " password " ] as? String else {
120+ return nil
121+ }
122+ return BasicAuthenticator ( username: username, password: password)
123+
124+ default :
105125 return nil
106- }
107- return BasicAuthenticator ( username: username, password: password)
108-
109- default :
110- return nil
111126 }
112127 }
113-
128+
114129 public static func generateReplicatorStatusJson( _ status: Replicator . Status ) -> [ String : Any ] {
115130 var errorJson : [ String : Any ] ?
116131 if let error = status. error {
117132 errorJson = [
118133 " message " : error. localizedDescription
119134 ]
120135 }
121-
136+
122137 let progressJson : [ String : Any ] = [
123138 " completed " : status. progress. completed,
124139 " total " : status. progress. total
125140 ]
126-
141+
127142 if let errorJson = errorJson {
128143 return [
129144 " activityLevel " : status. activity. rawValue,
@@ -137,10 +152,10 @@ public struct ReplicatorHelper {
137152 ]
138153 }
139154 }
140-
155+
141156 public static func generateReplicationJson( _ replication: [ ReplicatedDocument ] , isPush: Bool ) -> [ String : Any ] {
142157 var docs = [ [ String: Any] ] ( )
143-
158+
144159 for document in replication {
145160 var flags = [ String] ( )
146161 if document. flags. contains ( . deleted) {
@@ -149,21 +164,21 @@ public struct ReplicatorHelper {
149164 if document. flags. contains ( . accessRemoved) {
150165 flags. append ( " ACCESS_REMOVED " )
151166 }
152- var documentDictionary : [ String : Any ] = [ " id " : document. id, " flags " : flags]
153-
167+ var documentDictionary : [ String : Any ] = [ " id " : document. id, " flags " : flags, " scopeName " : document . scope , " collectionName " : document . collection ]
168+
154169 if let error = document. error {
155170 documentDictionary [ " error " ] = [
156171 " message " : error. localizedDescription
157172 ]
158173 }
159-
174+
160175 docs. append ( documentDictionary)
161176 }
162-
177+
163178 return [
164- " direction " : isPush ? " PUSH " : " PULL " ,
179+ " isPush " : isPush ? true : false ,
165180 " documents " : docs
166181 ]
167182 }
168-
183+
169184}
0 commit comments