@capgo/capacitor-updater 5.0.0-alpha.0 → 7.0.0
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.
- package/CapgoCapacitorUpdater.podspec +1 -1
- package/LICENCE +373 -661
- package/README.md +339 -75
- package/android/build.gradle +13 -12
- package/android/src/main/AndroidManifest.xml +4 -2
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +205 -121
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +32 -24
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +1041 -441
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1217 -536
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +153 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +62 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUntilNext.java +14 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +126 -0
- package/dist/docs.json +727 -171
- package/dist/esm/definitions.d.ts +234 -45
- package/dist/esm/definitions.js +5 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +9 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +12 -6
- package/dist/esm/web.js +64 -20
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +70 -23
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +70 -23
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/BundleInfo.swift +38 -19
- package/ios/Plugin/BundleStatus.swift +11 -4
- package/ios/Plugin/CapacitorUpdater.swift +520 -192
- package/ios/Plugin/CapacitorUpdaterPlugin.m +8 -1
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +447 -190
- package/ios/Plugin/CryptoCipher.swift +240 -0
- package/ios/Plugin/DelayCondition.swift +74 -0
- package/ios/Plugin/DelayUntilNext.swift +30 -0
- package/ios/Plugin/UserDefaultsExtension.swift +48 -0
- package/package.json +26 -20
- package/ios/Plugin/ObjectPreferences.swift +0 -97
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
import CommonCrypto
|
|
9
|
+
|
|
10
|
+
///
|
|
11
|
+
/// Constants
|
|
12
|
+
///
|
|
13
|
+
private enum CryptoCipherConstants {
|
|
14
|
+
static let rsaKeySizeInBits: NSNumber = 2048
|
|
15
|
+
static let aesAlgorithm: CCAlgorithm = CCAlgorithm(kCCAlgorithmAES)
|
|
16
|
+
static let aesOptions: CCOptions = CCOptions(kCCOptionPKCS7Padding)
|
|
17
|
+
static let rsaAlgorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA256
|
|
18
|
+
}
|
|
19
|
+
///
|
|
20
|
+
/// The AES key. Contains both the initialization vector and secret key.
|
|
21
|
+
///
|
|
22
|
+
public struct AES128Key {
|
|
23
|
+
/// Initialization vector
|
|
24
|
+
private let iv: Data
|
|
25
|
+
private let aes128Key: Data
|
|
26
|
+
#if DEBUG
|
|
27
|
+
public var __debug_iv: Data { iv }
|
|
28
|
+
public var __debug_aes128Key: Data { aes128Key }
|
|
29
|
+
#endif
|
|
30
|
+
init(iv: Data, aes128Key: Data) {
|
|
31
|
+
self.iv = iv
|
|
32
|
+
self.aes128Key = aes128Key
|
|
33
|
+
}
|
|
34
|
+
///
|
|
35
|
+
/// Takes the data and uses the private key to decrypt it. Will call `CCCrypt` in CommonCrypto
|
|
36
|
+
/// and provide it `ivData` for the initialization vector. Will use cipher block chaining (CBC) as
|
|
37
|
+
/// the mode of operation.
|
|
38
|
+
///
|
|
39
|
+
/// Returns the decrypted data.
|
|
40
|
+
///
|
|
41
|
+
public func decrypt(data: Data) -> Data? {
|
|
42
|
+
let encryptedData: UnsafePointer<UInt8> = (data as NSData).bytes.bindMemory(to: UInt8.self, capacity: data.count)
|
|
43
|
+
let encryptedDataLength: Int = data.count
|
|
44
|
+
|
|
45
|
+
if let result: NSMutableData = NSMutableData(length: encryptedDataLength) {
|
|
46
|
+
let keyData: UnsafePointer<UInt8> = (self.aes128Key as NSData).bytes.bindMemory(to: UInt8.self, capacity: self.aes128Key.count)
|
|
47
|
+
let keyLength: size_t = size_t(self.aes128Key.count)
|
|
48
|
+
let ivData: UnsafePointer<UInt8> = (iv as NSData).bytes.bindMemory(to: UInt8.self, capacity: self.iv.count)
|
|
49
|
+
|
|
50
|
+
let decryptedData: UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(result.mutableBytes.assumingMemoryBound(to: UInt8.self))
|
|
51
|
+
let decryptedDataLength: size_t = size_t(result.length)
|
|
52
|
+
|
|
53
|
+
var decryptedLength: size_t = 0
|
|
54
|
+
|
|
55
|
+
let status: CCCryptorStatus = CCCrypt(CCOperation(kCCDecrypt), CryptoCipherConstants.aesAlgorithm, CryptoCipherConstants.aesOptions, keyData, keyLength, ivData, encryptedData, encryptedDataLength, decryptedData, decryptedDataLength, &decryptedLength)
|
|
56
|
+
|
|
57
|
+
if UInt32(status) == UInt32(kCCSuccess) {
|
|
58
|
+
result.length = Int(decryptedLength)
|
|
59
|
+
return result as Data
|
|
60
|
+
} else {
|
|
61
|
+
return nil
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
return nil
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
///
|
|
70
|
+
/// The RSA keypair. Includes both private and public key.
|
|
71
|
+
///
|
|
72
|
+
public struct RSAKeyPair {
|
|
73
|
+
private let privateKey: SecKey
|
|
74
|
+
private let publicKey: SecKey
|
|
75
|
+
|
|
76
|
+
#if DEBUG
|
|
77
|
+
public var __debug_privateKey: SecKey { self.privateKey }
|
|
78
|
+
public var __debug_publicKey: SecKey { self.publicKey }
|
|
79
|
+
#endif
|
|
80
|
+
|
|
81
|
+
fileprivate init(privateKey: SecKey, publicKey: SecKey) {
|
|
82
|
+
self.privateKey = privateKey
|
|
83
|
+
self.publicKey = publicKey
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public func extractPublicKey() -> RSAPublicKey {
|
|
87
|
+
RSAPublicKey(publicKey: publicKey)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
///
|
|
91
|
+
/// Takes the data and uses the private key to decrypt it.
|
|
92
|
+
/// Returns the decrypted data.
|
|
93
|
+
///
|
|
94
|
+
public func decrypt(data: Data) -> Data? {
|
|
95
|
+
var error: Unmanaged<CFError>?
|
|
96
|
+
if let decryptedData: CFData = SecKeyCreateDecryptedData(self.privateKey, CryptoCipherConstants.rsaAlgorithm, data as CFData, &error) {
|
|
97
|
+
if error != nil {
|
|
98
|
+
return nil
|
|
99
|
+
} else {
|
|
100
|
+
return decryptedData as Data
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
return nil
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
///
|
|
109
|
+
/// The RSA public key.
|
|
110
|
+
///
|
|
111
|
+
public struct RSAPublicKey {
|
|
112
|
+
private let publicKey: SecKey
|
|
113
|
+
|
|
114
|
+
#if DEBUG
|
|
115
|
+
public var __debug_publicKey: SecKey { self.publicKey }
|
|
116
|
+
#endif
|
|
117
|
+
|
|
118
|
+
fileprivate init(publicKey: SecKey) {
|
|
119
|
+
self.publicKey = publicKey
|
|
120
|
+
}
|
|
121
|
+
///
|
|
122
|
+
/// Takes the data and uses the public key to encrypt it.
|
|
123
|
+
/// Returns the encrypted data.
|
|
124
|
+
///
|
|
125
|
+
public func encrypt(data: Data) -> Data? {
|
|
126
|
+
var error: Unmanaged<CFError>?
|
|
127
|
+
if let encryptedData: CFData = SecKeyCreateEncryptedData(self.publicKey, CryptoCipherConstants.rsaAlgorithm, data as CFData, &error) {
|
|
128
|
+
if error != nil {
|
|
129
|
+
return nil
|
|
130
|
+
} else {
|
|
131
|
+
return encryptedData as Data
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
return nil
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
///
|
|
138
|
+
/// Allows you to export the RSA public key to a format (so you can send over the net).
|
|
139
|
+
///
|
|
140
|
+
public func export() -> Data? {
|
|
141
|
+
return publicKey.exportToData()
|
|
142
|
+
}
|
|
143
|
+
//
|
|
144
|
+
|
|
145
|
+
///
|
|
146
|
+
/// Allows you to load an RSA public key (i.e. one downloaded from the net).
|
|
147
|
+
///
|
|
148
|
+
public static func load(rsaPublicKeyData: Data) -> RSAPublicKey? {
|
|
149
|
+
if let publicKey: SecKey = .loadPublicFromData(rsaPublicKeyData) {
|
|
150
|
+
return RSAPublicKey(publicKey: publicKey)
|
|
151
|
+
} else {
|
|
152
|
+
return nil
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
///
|
|
157
|
+
/// The RSA public key.
|
|
158
|
+
///
|
|
159
|
+
public struct RSAPrivateKey {
|
|
160
|
+
private let privateKey: SecKey
|
|
161
|
+
|
|
162
|
+
#if DEBUG
|
|
163
|
+
public var __debug_privateKey: SecKey { self.privateKey }
|
|
164
|
+
#endif
|
|
165
|
+
|
|
166
|
+
fileprivate init(privateKey: SecKey) {
|
|
167
|
+
self.privateKey = privateKey
|
|
168
|
+
}
|
|
169
|
+
///
|
|
170
|
+
/// Takes the data and uses the private key to decrypt it.
|
|
171
|
+
/// Returns the decrypted data.
|
|
172
|
+
///
|
|
173
|
+
public func decrypt(data: Data) -> Data? {
|
|
174
|
+
var error: Unmanaged<CFError>?
|
|
175
|
+
if let decryptedData: CFData = SecKeyCreateDecryptedData(self.privateKey, CryptoCipherConstants.rsaAlgorithm, data as CFData, &error) {
|
|
176
|
+
if error != nil {
|
|
177
|
+
return nil
|
|
178
|
+
} else {
|
|
179
|
+
return decryptedData as Data
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
return nil
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
///
|
|
187
|
+
/// Allows you to export the RSA public key to a format (so you can send over the net).
|
|
188
|
+
///
|
|
189
|
+
public func export() -> Data? {
|
|
190
|
+
return privateKey.exportToData()
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
///
|
|
194
|
+
/// Allows you to load an RSA public key (i.e. one downloaded from the net).
|
|
195
|
+
///
|
|
196
|
+
public static func load(rsaPrivateKey: String) -> RSAPrivateKey? {
|
|
197
|
+
var privKey: String = rsaPrivateKey
|
|
198
|
+
privKey = privKey.replacingOccurrences(of: "-----BEGIN RSA PRIVATE KEY-----", with: "")
|
|
199
|
+
privKey = privKey.replacingOccurrences(of: "-----END RSA PRIVATE KEY-----", with: "")
|
|
200
|
+
privKey = privKey.replacingOccurrences(of: "\\n+", with: "", options: .regularExpression)
|
|
201
|
+
privKey = privKey.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
202
|
+
let rsaPrivateKeyData: Data = Data(base64Encoded: privKey)!
|
|
203
|
+
if let privateKey: SecKey = .loadPrivateFromData(rsaPrivateKeyData) {
|
|
204
|
+
return RSAPrivateKey(privateKey: privateKey)
|
|
205
|
+
} else {
|
|
206
|
+
return nil
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
fileprivate extension SecKey {
|
|
212
|
+
func exportToData() -> Data? {
|
|
213
|
+
var error: Unmanaged<CFError>?
|
|
214
|
+
if let cfData: CFData = SecKeyCopyExternalRepresentation(self, &error) {
|
|
215
|
+
if error != nil {
|
|
216
|
+
return nil
|
|
217
|
+
} else {
|
|
218
|
+
return cfData as Data
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
return nil
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
static func loadPublicFromData(_ data: Data) -> SecKey? {
|
|
225
|
+
let keyDict: [NSObject: NSObject] = [
|
|
226
|
+
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
|
227
|
+
kSecAttrKeyClass: kSecAttrKeyClassPublic,
|
|
228
|
+
kSecAttrKeySizeInBits: CryptoCipherConstants.rsaKeySizeInBits
|
|
229
|
+
]
|
|
230
|
+
return SecKeyCreateWithData(data as CFData, keyDict as CFDictionary, nil)
|
|
231
|
+
}
|
|
232
|
+
static func loadPrivateFromData(_ data: Data) -> SecKey? {
|
|
233
|
+
let keyDict: [NSObject: NSObject] = [
|
|
234
|
+
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
|
235
|
+
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
|
236
|
+
kSecAttrKeySizeInBits: CryptoCipherConstants.rsaKeySizeInBits
|
|
237
|
+
]
|
|
238
|
+
return SecKeyCreateWithData(data as CFData, keyDict as CFDictionary, nil)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// DelayCondition.swift
|
|
9
|
+
// Plugin
|
|
10
|
+
//
|
|
11
|
+
// Created by Luca Peruzzo on 12/09/22.
|
|
12
|
+
// Copyright © 2022 Capgo. All rights reserved.
|
|
13
|
+
//
|
|
14
|
+
|
|
15
|
+
import Foundation
|
|
16
|
+
|
|
17
|
+
private func delayUntilNextValue(value: String) -> DelayUntilNext {
|
|
18
|
+
switch value {
|
|
19
|
+
case "background": return .background
|
|
20
|
+
case "kill": return .kill
|
|
21
|
+
case "nativeVersion": return .nativeVersion
|
|
22
|
+
case "date": return .date
|
|
23
|
+
default:
|
|
24
|
+
return .background
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@objc public class DelayCondition: NSObject, Decodable, Encodable {
|
|
29
|
+
private let kind: DelayUntilNext
|
|
30
|
+
private let value: String?
|
|
31
|
+
|
|
32
|
+
convenience init(kind: String, value: String?) {
|
|
33
|
+
self.init(kind: delayUntilNextValue(value: kind), value: value)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
init(kind: DelayUntilNext, value: String?) {
|
|
37
|
+
self.kind = kind
|
|
38
|
+
self.value = value
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public required init(from decoder: Decoder) throws {
|
|
42
|
+
let values: KeyedDecodingContainer<DelayCondition.CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
|
|
43
|
+
kind = try values.decode(DelayUntilNext.self, forKey: .kind)
|
|
44
|
+
value = try values.decode(String.self, forKey: .value)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
enum CodingKeys: String, CodingKey {
|
|
48
|
+
case kind, value
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public func getKind() -> String {
|
|
52
|
+
return self.kind.description
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public func getValue() -> String? {
|
|
56
|
+
return self.value
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public func toJSON() -> [String: String] {
|
|
60
|
+
return [
|
|
61
|
+
"kind": self.getKind(),
|
|
62
|
+
"value": self.getValue() ?? ""
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public static func == (lhs: DelayCondition, rhs: DelayCondition) -> Bool {
|
|
67
|
+
return lhs.getKind() == rhs.getKind() && lhs.getValue() == rhs.getValue()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public func toString() -> String {
|
|
71
|
+
return "{ \"kind\": \"\(self.getKind())\", \"value\": \"\(self.getValue() ?? "")\"}"
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// DelayUntilNext.swift
|
|
9
|
+
// Plugin
|
|
10
|
+
//
|
|
11
|
+
// Created by Luca Peruzzo on 12/09/22.
|
|
12
|
+
// Copyright © 2022 Capgo. All rights reserved.
|
|
13
|
+
//
|
|
14
|
+
|
|
15
|
+
import Foundation
|
|
16
|
+
enum DelayUntilNext: Decodable, Encodable, CustomStringConvertible {
|
|
17
|
+
case background
|
|
18
|
+
case kill
|
|
19
|
+
case nativeVersion
|
|
20
|
+
case date
|
|
21
|
+
|
|
22
|
+
var description: String {
|
|
23
|
+
switch self {
|
|
24
|
+
case .background: return "background"
|
|
25
|
+
case .kill: return "kill"
|
|
26
|
+
case .nativeVersion: return "nativeVersion"
|
|
27
|
+
case .date: return "date"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Foundation
|
|
8
|
+
|
|
9
|
+
protocol ObjectSavable {
|
|
10
|
+
func setObj<Object>(_ object: Object, forKey: String) throws where Object: Encodable
|
|
11
|
+
func getObj<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
enum ObjectSavableError: String, LocalizedError {
|
|
15
|
+
case unableToEncode = "Unable to encode object into data"
|
|
16
|
+
case noValue = "No data object found for the given key"
|
|
17
|
+
case unableToDecode = "Unable to decode object into given type"
|
|
18
|
+
case checksum = "Checksum failed"
|
|
19
|
+
|
|
20
|
+
var errorDescription: String? {
|
|
21
|
+
rawValue
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
extension UserDefaults: ObjectSavable {
|
|
26
|
+
func setObj<Object>(_ object: Object, forKey: String) throws where Object: Encodable {
|
|
27
|
+
let encoder: JSONEncoder = JSONEncoder()
|
|
28
|
+
do {
|
|
29
|
+
let data: Data = try encoder.encode(object)
|
|
30
|
+
set(data, forKey: forKey)
|
|
31
|
+
} catch {
|
|
32
|
+
throw ObjectSavableError.unableToEncode
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
func getObj<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable {
|
|
37
|
+
// print("forKey", forKey)
|
|
38
|
+
guard let data: Data = data(forKey: forKey) else { throw ObjectSavableError.noValue }
|
|
39
|
+
// print("data", data)
|
|
40
|
+
let decoder: JSONDecoder = JSONDecoder()
|
|
41
|
+
do {
|
|
42
|
+
let object: Object = try decoder.decode(type, from: data)
|
|
43
|
+
return object
|
|
44
|
+
} catch {
|
|
45
|
+
throw ObjectSavableError.unableToDecode
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-updater",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "7.0.0",
|
|
4
|
+
"packageManager": "pnpm@8.5.1",
|
|
5
|
+
"license": "MPL-2.0",
|
|
6
|
+
"description": "Live update for capacitor apps",
|
|
6
7
|
"main": "dist/plugin.cjs.js",
|
|
7
8
|
"module": "dist/esm/index.js",
|
|
8
9
|
"types": "dist/esm/index.d.ts",
|
|
@@ -40,35 +41,40 @@
|
|
|
40
41
|
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
41
42
|
"verify:web": "npm run build",
|
|
42
43
|
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
43
|
-
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- autocorrect --format",
|
|
44
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --autocorrect --format",
|
|
44
45
|
"eslint": "eslint . --ext ts",
|
|
45
|
-
"prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
|
|
46
|
+
"prettier": "prettier --config .prettierrc.js \"**/*.{css,html,ts,js,java}\"",
|
|
46
47
|
"swiftlint": "node-swiftlint",
|
|
47
48
|
"docgen": "docgen --api CapacitorUpdaterPlugin --output-readme README.md --output-json dist/docs.json",
|
|
48
|
-
"
|
|
49
|
+
"docgen:api": "docgen --api CapacitorUpdaterPlugin --output-readme api.md --output-json dist/docs.json && awk '{sub(/###/,\"##\")}1' api.md > temp.txt && mv temp.txt api.md",
|
|
50
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
49
51
|
"clean": "rimraf ./dist",
|
|
50
52
|
"watch": "tsc --watch",
|
|
51
53
|
"prepublishOnly": "npm run build"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
|
-
"@capacitor/android": "^
|
|
55
|
-
"@capacitor/
|
|
56
|
-
"@capacitor/
|
|
57
|
-
"@capacitor/docgen": "^0.
|
|
58
|
-
"@capacitor/ios": "^
|
|
56
|
+
"@capacitor/android": "^5.0.3",
|
|
57
|
+
"@capacitor/cli": "^5.0.3",
|
|
58
|
+
"@capacitor/core": "^5.0.3",
|
|
59
|
+
"@capacitor/docgen": "^0.2.1",
|
|
60
|
+
"@capacitor/ios": "^5.0.3",
|
|
59
61
|
"@ionic/eslint-config": "^0.3.0",
|
|
60
|
-
"@ionic/prettier-config": "^
|
|
62
|
+
"@ionic/prettier-config": "^3.0.0",
|
|
61
63
|
"@ionic/swiftlint-config": "^1.1.2",
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
64
|
+
"@types/node": "^20.2.3",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^5.59.7",
|
|
66
|
+
"@typescript-eslint/parser": "^5.59.7",
|
|
67
|
+
"eslint": "^8.41.0",
|
|
68
|
+
"eslint-plugin-import": "^2.27.5",
|
|
69
|
+
"prettier": "^2.8.8",
|
|
70
|
+
"prettier-plugin-java": "^2.1.0",
|
|
71
|
+
"rimraf": "^5.0.1",
|
|
72
|
+
"rollup": "^3.23.0",
|
|
73
|
+
"swiftlint": "^1.0.2",
|
|
74
|
+
"typescript": "^5.0.4"
|
|
69
75
|
},
|
|
70
76
|
"peerDependencies": {
|
|
71
|
-
"@capacitor/core": "^
|
|
77
|
+
"@capacitor/core": "^5.0.0"
|
|
72
78
|
},
|
|
73
79
|
"prettier": "@ionic/prettier-config",
|
|
74
80
|
"swiftlint": "@ionic/swiftlint-config",
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
|
|
3
|
-
protocol ObjectSavable {
|
|
4
|
-
func setObj<Object>(_ object: Object, forKey: String) throws where Object: Encodable
|
|
5
|
-
func getObj<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
enum ObjectSavableError: String, LocalizedError {
|
|
9
|
-
case unableToEncode = "Unable to encode object into data"
|
|
10
|
-
case noValue = "No data object found for the given key"
|
|
11
|
-
case unableToDecode = "Unable to decode object into given type"
|
|
12
|
-
|
|
13
|
-
var errorDescription: String? {
|
|
14
|
-
rawValue
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
extension UserDefaults: ObjectSavable {
|
|
19
|
-
func setObj<Object>(_ object: Object, forKey: String) throws where Object: Encodable {
|
|
20
|
-
let encoder = JSONEncoder()
|
|
21
|
-
do {
|
|
22
|
-
let data = try encoder.encode(object)
|
|
23
|
-
set(data, forKey: forKey)
|
|
24
|
-
} catch {
|
|
25
|
-
throw ObjectSavableError.unableToEncode
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
func getObj<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable {
|
|
30
|
-
print("forKey", forKey)
|
|
31
|
-
guard let data = data(forKey: forKey) else { throw ObjectSavableError.noValue }
|
|
32
|
-
print("data", data)
|
|
33
|
-
let decoder = JSONDecoder()
|
|
34
|
-
do {
|
|
35
|
-
let object = try decoder.decode(type, from: data)
|
|
36
|
-
return object
|
|
37
|
-
} catch {
|
|
38
|
-
throw ObjectSavableError.unableToDecode
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
//// MARK: - Methods
|
|
45
|
-
//public extension UserDefaults {
|
|
46
|
-
// /// SwifterSwift: get object from UserDefaults by using subscript.
|
|
47
|
-
// ///
|
|
48
|
-
// /// - Parameter key: key in the current user's defaults database.
|
|
49
|
-
// subscript(key: String) -> Any? {
|
|
50
|
-
// get {
|
|
51
|
-
// return object(forKey: key)
|
|
52
|
-
// }
|
|
53
|
-
// set {
|
|
54
|
-
// set(newValue, forKey: key)
|
|
55
|
-
// }
|
|
56
|
-
// }
|
|
57
|
-
//
|
|
58
|
-
// /// SwifterSwift: Float from UserDefaults.
|
|
59
|
-
// ///
|
|
60
|
-
// /// - Parameter key: key to find float for.
|
|
61
|
-
// /// - Returns: Float object for key (if exists).
|
|
62
|
-
// func float(forKey key: String) -> Float? {
|
|
63
|
-
// return object(forKey: key) as? Float
|
|
64
|
-
// }
|
|
65
|
-
//
|
|
66
|
-
// /// SwifterSwift: Date from UserDefaults.
|
|
67
|
-
// ///
|
|
68
|
-
// /// - Parameter key: key to find date for.
|
|
69
|
-
// /// - Returns: Date object for key (if exists).
|
|
70
|
-
// func date(forKey key: String) -> Date? {
|
|
71
|
-
// return object(forKey: key) as? Date
|
|
72
|
-
// }
|
|
73
|
-
//
|
|
74
|
-
// /// SwifterSwift: Retrieves a Codable object from UserDefaults.
|
|
75
|
-
// ///
|
|
76
|
-
// /// - Parameters:
|
|
77
|
-
// /// - type: Class that conforms to the Codable protocol.
|
|
78
|
-
// /// - key: Identifier of the object.
|
|
79
|
-
// /// - decoder: Custom JSONDecoder instance. Defaults to `JSONDecoder()`.
|
|
80
|
-
// /// - Returns: Codable object for key (if exists).
|
|
81
|
-
// func object<T: Codable>(_ type: T.Type, with key: String, usingDecoder decoder: JSONDecoder = JSONDecoder()) -> T? {
|
|
82
|
-
// guard let data = value(forKey: key) as? Data else { return nil }
|
|
83
|
-
// return try? decoder.decode(type.self, from: data)
|
|
84
|
-
// }
|
|
85
|
-
//
|
|
86
|
-
// /// SwifterSwift: Allows storing of Codable objects to UserDefaults.
|
|
87
|
-
// ///
|
|
88
|
-
// /// - Parameters:
|
|
89
|
-
// /// - object: Codable object to store.
|
|
90
|
-
// /// - key: Identifier of the object.
|
|
91
|
-
// /// - encoder: Custom JSONEncoder instance. Defaults to `JSONEncoder()`.
|
|
92
|
-
// func set<T: Codable>(object: T, forKey key: String, usingEncoder encoder: JSONEncoder = JSONEncoder()) {
|
|
93
|
-
// let data = try? encoder.encode(object)
|
|
94
|
-
// set(data, forKey: key)
|
|
95
|
-
// }
|
|
96
|
-
//}
|
|
97
|
-
//
|