@onekeyfe/react-native-cloud-kit-module 1.1.19 → 1.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,7 @@ Pod::Spec.new do |s|
21
21
 
22
22
  s.dependency 'React-jsi'
23
23
  s.dependency 'React-callinvoker'
24
+ s.dependency 'ReactNativeNativeLogger'
24
25
 
25
26
  load 'nitrogen/generated/ios/CloudKitModule+autolinking.rb'
26
27
  add_nitrogen_files(s)
@@ -1,6 +1,7 @@
1
1
  import Foundation
2
2
  import CloudKit
3
3
  import NitroModules
4
+ import ReactNativeNativeLogger
4
5
 
5
6
  class CloudKitModule: HybridCloudKitModuleSpec {
6
7
 
@@ -8,11 +9,31 @@ class CloudKitModule: HybridCloudKitModuleSpec {
8
9
  private let container = CKContainer.default()
9
10
  private lazy var database = container.privateCloudDatabase
10
11
 
12
+ // MARK: - Input Validation
13
+
14
+ private static let recordIDMaxLength = 255
15
+ private static let recordTypePattern = try! NSRegularExpression(pattern: "^[a-zA-Z][a-zA-Z0-9_]{0,254}$")
16
+ private static let queryResultsLimit = 200
17
+
18
+ private func validateRecordID(_ recordID: String) throws {
19
+ guard !recordID.isEmpty, recordID.count <= Self.recordIDMaxLength else {
20
+ throw NSError(domain: "CloudKitModule", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid record ID"])
21
+ }
22
+ }
23
+
24
+ private func validateRecordType(_ recordType: String) throws {
25
+ let range = NSRange(recordType.startIndex..., in: recordType)
26
+ guard Self.recordTypePattern.firstMatch(in: recordType, range: range) != nil else {
27
+ throw NSError(domain: "CloudKitModule", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid record type"])
28
+ }
29
+ }
30
+
11
31
  // MARK: - Check Availability
12
32
 
13
33
  public func isAvailable() throws -> Promise<Bool> {
14
34
  return Promise.async {
15
35
  let status = try await self.container.accountStatus()
36
+ OneKeyLog.info("CloudKit", "Account status: \(status.rawValue), available: \(status == .available)")
16
37
  return status == .available
17
38
  }
18
39
  }
@@ -28,6 +49,7 @@ class CloudKitModule: HybridCloudKitModuleSpec {
28
49
  let userRecordID = try await self.container.userRecordID()
29
50
  userId = userRecordID.recordName
30
51
  } catch {
52
+ OneKeyLog.warn("CloudKit", "Failed to get user record ID: \(error.localizedDescription)")
31
53
  userId = nil
32
54
  }
33
55
  }
@@ -50,7 +72,10 @@ class CloudKitModule: HybridCloudKitModuleSpec {
50
72
  // MARK: - Save Record
51
73
 
52
74
  public func saveRecord(params: SaveRecordParams) throws -> Promise<SaveRecordResult> {
75
+ try validateRecordID(params.recordID)
76
+ try validateRecordType(params.recordType)
53
77
  return Promise.async {
78
+ OneKeyLog.debug("CloudKit", "Saving record: \(params.recordID), type: \(params.recordType)")
54
79
  let ckRecordID = CKRecord.ID(recordName: params.recordID)
55
80
  let recordToSave: CKRecord
56
81
  do {
@@ -65,6 +90,7 @@ class CloudKitModule: HybridCloudKitModuleSpec {
65
90
  recordToSave[CloudKitConstants.recordDataField] = params.data as CKRecordValue
66
91
  recordToSave[CloudKitConstants.recordMetaField] = params.meta as CKRecordValue
67
92
  let savedRecord = try await self.database.save(recordToSave)
93
+ OneKeyLog.debug("CloudKit", "Record saved: \(savedRecord.recordID.recordName)")
68
94
  let createdAt = Int64((savedRecord.creationDate?.timeIntervalSince1970 ?? 0) * 1000)
69
95
  let result = SaveRecordResult(
70
96
  recordID: savedRecord.recordID.recordName,
@@ -77,11 +103,13 @@ class CloudKitModule: HybridCloudKitModuleSpec {
77
103
  // MARK: - Fetch Record
78
104
 
79
105
  public func fetchRecord(params: FetchRecordParams) throws -> Promise<Variant_NullType_RecordResult> {
106
+ try validateRecordID(params.recordID)
80
107
  return Promise.async {
81
108
  let ckRecordID = CKRecord.ID(recordName: params.recordID)
82
109
 
83
110
  do {
84
111
  let record = try await self.database.record(for: ckRecordID)
112
+ OneKeyLog.debug("CloudKit", "Record fetched: \(params.recordID)")
85
113
 
86
114
  let data = record[CloudKitConstants.recordDataField] as? String ?? ""
87
115
  let meta = record[CloudKitConstants.recordMetaField] as? String ?? ""
@@ -97,6 +125,7 @@ class CloudKitModule: HybridCloudKitModuleSpec {
97
125
  modifiedAt: Double(modifiedAt)
98
126
  ))
99
127
  } catch let error as CKError where error.code == .unknownItem {
128
+ OneKeyLog.debug("CloudKit", "Record not found: \(params.recordID)")
100
129
  return Variant_NullType_RecordResult.first(NullType.null)
101
130
  }
102
131
  }
@@ -105,14 +134,16 @@ class CloudKitModule: HybridCloudKitModuleSpec {
105
134
  // MARK: - Delete Record
106
135
 
107
136
  public func deleteRecord(params: DeleteRecordParams) throws -> Promise<Void> {
137
+ try validateRecordID(params.recordID)
108
138
  return Promise.async {
109
139
  let ckRecordID = CKRecord.ID(recordName: params.recordID)
110
140
 
111
141
  do {
112
142
  _ = try await self.database.deleteRecord(withID: ckRecordID)
143
+ OneKeyLog.debug("CloudKit", "Record deleted: \(params.recordID)")
113
144
  return Void()
114
145
  } catch let error as CKError where error.code == .unknownItem {
115
- // Item not found is considered success for delete
146
+ OneKeyLog.debug("CloudKit", "Record not found for delete (OK): \(params.recordID)")
116
147
  return Void()
117
148
  }
118
149
  }
@@ -121,6 +152,7 @@ class CloudKitModule: HybridCloudKitModuleSpec {
121
152
  // MARK: - Record Exists
122
153
 
123
154
  public func recordExists(params: RecordExistsParams) throws -> Promise<Bool> {
155
+ try validateRecordID(params.recordID)
124
156
  return Promise.async {
125
157
  let ckRecordID = CKRecord.ID(recordName: params.recordID)
126
158
 
@@ -136,6 +168,7 @@ class CloudKitModule: HybridCloudKitModuleSpec {
136
168
  // MARK: - Query Records
137
169
 
138
170
  public func queryRecords(params: QueryRecordsParams) throws -> Promise<QueryRecordsResult> {
171
+ try validateRecordType(params.recordType)
139
172
  return Promise.async {
140
173
  let predicate = NSPredicate(value: true)
141
174
  let query = CKQuery(recordType: params.recordType, predicate: predicate)
@@ -145,7 +178,7 @@ class CloudKitModule: HybridCloudKitModuleSpec {
145
178
  var results: [RecordResult] = []
146
179
  let operation = CKQueryOperation(query: query)
147
180
  operation.desiredKeys = [CloudKitConstants.recordMetaField]
148
- // operation.resultsLimit = 500 // Optional: tune as needed
181
+ operation.resultsLimit = Self.queryResultsLimit
149
182
 
150
183
  operation.recordMatchedBlock = { _, result in
151
184
  switch result {
@@ -172,9 +205,11 @@ class CloudKitModule: HybridCloudKitModuleSpec {
172
205
  case .success:
173
206
  // Sort by modification time descending to return latest first
174
207
  let sorted = results.sorted { $0.modifiedAt > $1.modifiedAt }
208
+ OneKeyLog.info("CloudKit", "Query returned \(sorted.count) records for type: \(params.recordType)")
175
209
  let queryResult = QueryRecordsResult(records: sorted)
176
210
  continuation.resume(returning: queryResult)
177
211
  case .failure(let error):
212
+ OneKeyLog.error("CloudKit", "Query failed for type \(params.recordType): \(error.localizedDescription)")
178
213
  continuation.resume(throwing: error)
179
214
  }
180
215
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-cloud-kit-module",
3
- "version": "1.1.19",
3
+ "version": "1.1.21",
4
4
  "description": "react-native-cloud-kit-module",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",