@capgo/capacitor-updater 6.14.26 → 6.14.29
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 +3 -2
- package/Package.swift +2 -2
- package/README.md +341 -74
- package/android/build.gradle +20 -8
- package/android/proguard-rules.pro +22 -5
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +52 -16
- package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +2 -2
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1196 -508
- package/android/src/main/java/ee/forgr/capacitor_updater/{CapacitorUpdater.java → CapgoUpdater.java} +522 -154
- package/android/src/main/java/ee/forgr/capacitor_updater/{CryptoCipher.java → CryptoCipherV1.java} +17 -9
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipherV2.java +15 -26
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +0 -3
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +260 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +300 -119
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +63 -25
- package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +338 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeDetector.java +72 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +169 -0
- package/dist/docs.json +652 -63
- package/dist/esm/definitions.d.ts +265 -15
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/history.d.ts +1 -0
- package/dist/esm/history.js +283 -0
- package/dist/esm/history.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +12 -1
- package/dist/esm/web.js +29 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +311 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +311 -2
- package/dist/plugin.js.map +1 -1
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/AES.swift +6 -3
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +1575 -0
- package/ios/{Plugin/CapacitorUpdater.swift → Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift} +365 -139
- package/ios/{Plugin/CryptoCipher.swift → Sources/CapacitorUpdaterPlugin/CryptoCipherV1.swift} +13 -6
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/CryptoCipherV2.swift +33 -27
- package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +220 -0
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/InternalUtils.swift +47 -0
- package/ios/Sources/CapacitorUpdaterPlugin/Logger.swift +310 -0
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/RSA.swift +1 -0
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +112 -0
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/UserDefaultsExtension.swift +0 -2
- package/package.json +20 -16
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +0 -1030
- /package/{LICENCE → LICENSE} +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BigInt.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleInfo.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleStatus.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayCondition.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayUntilNext.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/Info.plist +0 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import Capacitor
|
|
2
|
+
import Foundation
|
|
3
|
+
import os.log
|
|
4
|
+
import WebKit
|
|
5
|
+
|
|
6
|
+
public class Logger {
|
|
7
|
+
public enum LogLevel: Int {
|
|
8
|
+
case silent = 0
|
|
9
|
+
case error
|
|
10
|
+
case warn
|
|
11
|
+
case info
|
|
12
|
+
case debug
|
|
13
|
+
|
|
14
|
+
public static subscript(_ str: String) -> LogLevel? {
|
|
15
|
+
var index = 0
|
|
16
|
+
|
|
17
|
+
while let item = LogLevel(rawValue: index) {
|
|
18
|
+
if str == "\(item)" {
|
|
19
|
+
return item
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
index += 1
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return nil
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public func asOSLogType() -> OSLogType {
|
|
29
|
+
switch self {
|
|
30
|
+
case .debug:
|
|
31
|
+
return OSLogType.debug
|
|
32
|
+
case .info:
|
|
33
|
+
return OSLogType.info
|
|
34
|
+
case .warn:
|
|
35
|
+
return OSLogType.default
|
|
36
|
+
case .error:
|
|
37
|
+
return OSLogType.error
|
|
38
|
+
case .silent:
|
|
39
|
+
return OSLogType.info // Compiler wants this, it will never be used
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
public func asString() -> String {
|
|
43
|
+
switch self {
|
|
44
|
+
case .debug:
|
|
45
|
+
return "debug"
|
|
46
|
+
case .info:
|
|
47
|
+
return "info"
|
|
48
|
+
case .warn:
|
|
49
|
+
return "warn"
|
|
50
|
+
case .error:
|
|
51
|
+
return "error"
|
|
52
|
+
case .silent:
|
|
53
|
+
return "info"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public struct Options {
|
|
59
|
+
public var level: LogLevel
|
|
60
|
+
public var labels: [String: String]
|
|
61
|
+
public var useSyslog: Bool
|
|
62
|
+
|
|
63
|
+
public init(level: LogLevel = LogLevel.info, labels: [String: String] = [:], useSyslog: Bool = false) {
|
|
64
|
+
self.level = level
|
|
65
|
+
self.labels = labels
|
|
66
|
+
self.useSyslog = useSyslog
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private var _labels: [LogLevel: String] = [
|
|
71
|
+
LogLevel.silent: "",
|
|
72
|
+
LogLevel.error: "🔴",
|
|
73
|
+
LogLevel.warn: "🟠",
|
|
74
|
+
LogLevel.info: "🟢",
|
|
75
|
+
LogLevel.debug: "🔎"
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
public var labels: [String: String] {
|
|
79
|
+
get {
|
|
80
|
+
var result: [String: String] = [:]
|
|
81
|
+
|
|
82
|
+
for (level, label) in _labels {
|
|
83
|
+
result[String(describing: level)] = label
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return result
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
set {
|
|
90
|
+
for (level, label) in newValue {
|
|
91
|
+
if let logLevel = LogLevel[level] {
|
|
92
|
+
_labels[logLevel] = label
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public var level = LogLevel.info
|
|
99
|
+
|
|
100
|
+
public var levelName: String {
|
|
101
|
+
get {
|
|
102
|
+
String(describing: level)
|
|
103
|
+
}
|
|
104
|
+
set {
|
|
105
|
+
if let newLevel = LogLevel[newValue] {
|
|
106
|
+
level = newLevel
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private var _tag = ""
|
|
112
|
+
|
|
113
|
+
public var tag: String {
|
|
114
|
+
get {
|
|
115
|
+
_tag
|
|
116
|
+
}
|
|
117
|
+
set {
|
|
118
|
+
if !newValue.isEmpty {
|
|
119
|
+
_tag = newValue
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private let kDefaultTimerLabel = "default"
|
|
125
|
+
private var timers: [String: Date] = [:]
|
|
126
|
+
public var useSyslog = false
|
|
127
|
+
public var webView: WKWebView?
|
|
128
|
+
|
|
129
|
+
public func setWebView(webView: WKWebView) {
|
|
130
|
+
self.webView = webView
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public init(
|
|
134
|
+
withTag tag: String,
|
|
135
|
+
config: InstanceConfiguration? = nil,
|
|
136
|
+
options: Options? = nil
|
|
137
|
+
) {
|
|
138
|
+
self.tag = tag
|
|
139
|
+
if let config = config {
|
|
140
|
+
// The logger plugin's name is LoggerBridge, we want to look at the config
|
|
141
|
+
// named "Logger", so we can't use plugin.getConfigValue().
|
|
142
|
+
if let configLevel = getConfigValue("level", from: config) as? String,
|
|
143
|
+
let logLevel = LogLevel[configLevel] {
|
|
144
|
+
level = logLevel
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if let configLabels = getConfigValue("labels", from: config) as? [String: String] {
|
|
148
|
+
labels = configLabels
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if let configSyslog = getConfigValue("useSyslog", from: config) as? Bool {
|
|
152
|
+
useSyslog = configSyslog
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if let options = options {
|
|
157
|
+
self.level = options.level
|
|
158
|
+
self.labels = options.labels
|
|
159
|
+
self.useSyslog = options.useSyslog
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private func getConfigValue(_ configKey: String, from config: InstanceConfiguration) -> Any? {
|
|
164
|
+
if let config = config.pluginConfigurations as? JSObject {
|
|
165
|
+
return config[keyPath: KeyPath(stringLiteral: "Logger.\(configKey)")]
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return nil
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public func error(_ message: String) {
|
|
172
|
+
log(atLevel: LogLevel.error, message: message)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
public func warn(_ message: String) {
|
|
176
|
+
log(atLevel: LogLevel.warn, message: message)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
public func info(_ message: String) {
|
|
180
|
+
log(atLevel: LogLevel.info, message: message)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public func log(_ message: String) {
|
|
184
|
+
log(atLevel: LogLevel.info, message: message)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public func debug(_ message: String) {
|
|
188
|
+
log(atLevel: LogLevel.debug, message: message)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public func dir(_ value: Any?) {
|
|
192
|
+
// Check the log level here to avoid conversion to string
|
|
193
|
+
if canLog(atLevel: LogLevel.info) {
|
|
194
|
+
log(atLevel: LogLevel.info, message: String(describing: value))
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
public func log(atLevel level: LogLevel, message: String) {
|
|
199
|
+
// This will never fail, but we have to keep swift happy
|
|
200
|
+
if let label = _labels[level] {
|
|
201
|
+
log(atLevel: level, label: label, tag: tag, message: message)
|
|
202
|
+
if let webView = self.webView {
|
|
203
|
+
DispatchQueue.main.async {
|
|
204
|
+
let combined = "\(label) \(self.tag) : \(message)"
|
|
205
|
+
let jsArg = self.toJSStringLiteral(combined)
|
|
206
|
+
webView.evaluateJavaScript("console.\(level.asString())(\(jsArg))", completionHandler: nil)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private func toJSStringLiteral(_ value: String) -> String {
|
|
213
|
+
// Prefer JSON encoding to produce a valid JS string literal
|
|
214
|
+
if let data = try? JSONEncoder().encode(value),
|
|
215
|
+
let encoded = String(data: data, encoding: .utf8) {
|
|
216
|
+
return encoded
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Fallback manual escaping (unlikely to be used)
|
|
220
|
+
var s = value
|
|
221
|
+
s = s.replacingOccurrences(of: "\\", with: "\\\\")
|
|
222
|
+
s = s.replacingOccurrences(of: "\"", with: "\\\"")
|
|
223
|
+
s = s.replacingOccurrences(of: "'", with: "\\'")
|
|
224
|
+
s = s.replacingOccurrences(of: "\n", with: "\\n")
|
|
225
|
+
s = s.replacingOccurrences(of: "\r", with: "\\r")
|
|
226
|
+
s = s.replacingOccurrences(of: "\u{2028}", with: "\\u2028")
|
|
227
|
+
s = s.replacingOccurrences(of: "\u{2029}", with: "\\u2029")
|
|
228
|
+
return "\"\(s)\""
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public func log(atLevel level: LogLevel, label: String?, tag: String, message: String) {
|
|
232
|
+
// This will never fail, but we have to keep swift happy
|
|
233
|
+
if let label = label ?? _labels[level] {
|
|
234
|
+
print(atLevel: level, label: label, tag: tag, message: message)
|
|
235
|
+
// eval
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private func canLog(atLevel level: LogLevel) -> Bool {
|
|
240
|
+
self.level.rawValue >= level.rawValue
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
private func print(atLevel level: LogLevel, label: String, tag: String, message: String) {
|
|
244
|
+
guard canLog(atLevel: level) else {
|
|
245
|
+
return
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var msg = message
|
|
249
|
+
|
|
250
|
+
if !label.isEmpty {
|
|
251
|
+
// If the label is ASCII, put it after the tag, otherwise before.
|
|
252
|
+
if label[label.startIndex].isASCII {
|
|
253
|
+
msg = "[\(tag)] \(label): \(message)"
|
|
254
|
+
} else {
|
|
255
|
+
msg = "\(label) [\(tag)]: \(message)"
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
msg = "[\(tag)]: \(message)"
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if useSyslog {
|
|
262
|
+
os_log("%{public}@", type: level.asOSLogType(), msg)
|
|
263
|
+
} else {
|
|
264
|
+
Swift.print(msg)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
public func time(_ label: String?) {
|
|
269
|
+
timers[label ?? ""] = Date()
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public func timeLog(_ label: String?) {
|
|
273
|
+
if let timer = timers[label ?? ""] {
|
|
274
|
+
info(formatTimeInterval(timer.timeIntervalSinceNow))
|
|
275
|
+
} else {
|
|
276
|
+
warn("timer \(label ?? kDefaultTimerLabel) does not exist")
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
public func timeEnd(_ label: String?) {
|
|
281
|
+
timeLog(label)
|
|
282
|
+
timers.removeValue(forKey: label ?? kDefaultTimerLabel)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private func formatTimeInterval(_ interval: TimeInterval) -> String {
|
|
286
|
+
let int = Int(interval)
|
|
287
|
+
let millis = Int(((1 + interval.remainder(dividingBy: 1)) * 1000).rounded())
|
|
288
|
+
let seconds = int % 60
|
|
289
|
+
let minutes = (int / 60) % 60
|
|
290
|
+
let hours = (int / 3600)
|
|
291
|
+
|
|
292
|
+
if seconds < 1 {
|
|
293
|
+
return "\(millis)ms"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if minutes < 1 {
|
|
297
|
+
return "\(seconds).\(String(format: "%0.3d", millis))s"
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if hours < 1 {
|
|
301
|
+
return "\(minutes):\(String(format: "%0.2d", seconds)).\(String(format: "%0.3d", millis)) (min:sec.ms)"
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return "\(hours):\(String(format: "%0.2d", minutes)):\(String(format: "%0.2d", seconds)) (hr:min:sec)"
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
public func trace() {
|
|
308
|
+
info(String(format: "%@", Thread.callStackSymbols))
|
|
309
|
+
}
|
|
310
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
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 UIKit
|
|
8
|
+
import Capacitor
|
|
9
|
+
|
|
10
|
+
extension UIApplication {
|
|
11
|
+
public class func topViewController(_ base: UIViewController? = UIApplication.shared.windows.first?.rootViewController) -> UIViewController? {
|
|
12
|
+
if let nav = base as? UINavigationController {
|
|
13
|
+
return topViewController(nav.visibleViewController)
|
|
14
|
+
}
|
|
15
|
+
if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
|
|
16
|
+
return topViewController(selected)
|
|
17
|
+
}
|
|
18
|
+
if let presented = base?.presentedViewController {
|
|
19
|
+
return topViewController(presented)
|
|
20
|
+
}
|
|
21
|
+
return base
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
extension UIWindow {
|
|
26
|
+
override open func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
|
|
27
|
+
if motion == .motionShake {
|
|
28
|
+
// Find the CapacitorUpdaterPlugin instance
|
|
29
|
+
guard let bridge = (rootViewController as? CAPBridgeProtocol),
|
|
30
|
+
let plugin = bridge.plugin(withName: "CapacitorUpdaterPlugin") as? CapacitorUpdaterPlugin else {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Check if shake menu is enabled
|
|
35
|
+
if !plugin.shakeMenuEnabled {
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
showShakeMenu(plugin: plugin, bridge: bridge)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private func showShakeMenu(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
|
|
44
|
+
// Prevent multiple alerts from showing
|
|
45
|
+
if let topVC = UIApplication.topViewController(),
|
|
46
|
+
topVC.isKind(of: UIAlertController.self) {
|
|
47
|
+
plugin.logger.info("UIAlertController is already presented")
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let appName = Bundle.main.infoDictionary?["CFBundleDisplayName"] as? String ?? "App"
|
|
52
|
+
let title = "Preview \(appName) Menu"
|
|
53
|
+
let message = "What would you like to do?"
|
|
54
|
+
let okButtonTitle = "Go Home"
|
|
55
|
+
let reloadButtonTitle = "Reload app"
|
|
56
|
+
let cancelButtonTitle = "Close menu"
|
|
57
|
+
|
|
58
|
+
let updater = plugin.implementation
|
|
59
|
+
|
|
60
|
+
func resetBuiltin() {
|
|
61
|
+
updater.reset()
|
|
62
|
+
bridge.setServerBasePath("")
|
|
63
|
+
DispatchQueue.main.async {
|
|
64
|
+
if let vc = (self.rootViewController as? CAPBridgeViewController) {
|
|
65
|
+
vc.loadView()
|
|
66
|
+
vc.viewDidLoad()
|
|
67
|
+
}
|
|
68
|
+
_ = updater.delete(id: updater.getCurrentBundleId())
|
|
69
|
+
plugin.logger.info("Reset to builtin version")
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let bundleId = updater.getCurrentBundleId()
|
|
74
|
+
if let vc = (self.rootViewController as? CAPBridgeViewController) {
|
|
75
|
+
plugin.logger.info("getServerBasePath: \(vc.getServerBasePath())")
|
|
76
|
+
}
|
|
77
|
+
plugin.logger.info("bundleId: \(bundleId)")
|
|
78
|
+
|
|
79
|
+
let alertShake = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
|
80
|
+
|
|
81
|
+
alertShake.addAction(UIAlertAction(title: okButtonTitle, style: .default) { _ in
|
|
82
|
+
guard let next = updater.getNextBundle() else {
|
|
83
|
+
resetBuiltin()
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
if !next.isBuiltin() {
|
|
87
|
+
plugin.logger.info("Resetting to: \(next.toString())")
|
|
88
|
+
_ = updater.set(bundle: next)
|
|
89
|
+
let destHot = updater.getBundleDirectory(id: next.getId())
|
|
90
|
+
plugin.logger.info("Reloading \(next.toString())")
|
|
91
|
+
bridge.setServerBasePath(destHot.path)
|
|
92
|
+
} else {
|
|
93
|
+
resetBuiltin()
|
|
94
|
+
}
|
|
95
|
+
plugin.logger.info("Reload app done")
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
alertShake.addAction(UIAlertAction(title: cancelButtonTitle, style: .default))
|
|
99
|
+
|
|
100
|
+
alertShake.addAction(UIAlertAction(title: reloadButtonTitle, style: .default) { _ in
|
|
101
|
+
DispatchQueue.main.async {
|
|
102
|
+
bridge.webView?.reload()
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
DispatchQueue.main.async {
|
|
107
|
+
if let topVC = UIApplication.topViewController() {
|
|
108
|
+
topVC.present(alertShake, animated: true)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -34,9 +34,7 @@ extension UserDefaults: ObjectSavable {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
func getObj<Object>(forKey: String, castTo type: Object.Type) throws -> Object where Object: Decodable {
|
|
37
|
-
// print("forKey", forKey)
|
|
38
37
|
guard let data: Data = data(forKey: forKey) else { throw ObjectSavableError.noValue }
|
|
39
|
-
// print("data", data)
|
|
40
38
|
let decoder: JSONDecoder = JSONDecoder()
|
|
41
39
|
do {
|
|
42
40
|
let object: Object = try decoder.decode(type, from: data)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-updater",
|
|
3
|
-
"version": "6.14.
|
|
3
|
+
"version": "6.14.29",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Live update for capacitor apps",
|
|
6
6
|
"main": "dist/plugin.cjs.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"android/proguard-rules.pro",
|
|
13
13
|
"android/build.gradle",
|
|
14
14
|
"dist/",
|
|
15
|
-
"ios/
|
|
15
|
+
"ios/Sources/",
|
|
16
16
|
"CapgoCapacitorUpdater.podspec",
|
|
17
17
|
"Package.swift"
|
|
18
18
|
],
|
|
@@ -41,39 +41,43 @@
|
|
|
41
41
|
],
|
|
42
42
|
"scripts": {
|
|
43
43
|
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
44
|
-
"verify:ios": "
|
|
44
|
+
"verify:ios": "xcodebuild -scheme CapgoCapacitorUpdater -destination generic/platform=iOS",
|
|
45
45
|
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
46
46
|
"verify:web": "npm run build",
|
|
47
|
+
"test": "npm run test:ios && npm run test:android",
|
|
48
|
+
"test:ios": "./scripts/test-ios.sh",
|
|
49
|
+
"test:android": "cd android && ./gradlew test && cd ..",
|
|
47
50
|
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
48
|
-
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --
|
|
51
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
49
52
|
"eslint": "eslint . --ext .ts",
|
|
50
53
|
"prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
|
|
51
54
|
"swiftlint": "node-swiftlint",
|
|
52
55
|
"docgen": "docgen --api CapacitorUpdaterPlugin --output-readme README.md --output-json dist/docs.json",
|
|
53
|
-
"docgen:api": "
|
|
56
|
+
"docgen:api": "node scripts/generate-docs.js",
|
|
54
57
|
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
55
58
|
"clean": "rimraf ./dist",
|
|
56
59
|
"watch": "tsc --watch",
|
|
57
60
|
"prepublishOnly": "npm run build"
|
|
58
61
|
},
|
|
59
62
|
"devDependencies": {
|
|
60
|
-
"@capacitor/android": "^6.2
|
|
61
|
-
"@capacitor/cli": "^6.2
|
|
62
|
-
"@capacitor/core": "^6.2
|
|
63
|
+
"@capacitor/android": "^6.1.2",
|
|
64
|
+
"@capacitor/cli": "^6.1.2",
|
|
65
|
+
"@capacitor/core": "^6.1.2",
|
|
63
66
|
"@capacitor/docgen": "^0.3.0",
|
|
64
|
-
"@capacitor/ios": "^6.2
|
|
67
|
+
"@capacitor/ios": "^6.1.2",
|
|
65
68
|
"@ionic/eslint-config": "^0.4.0",
|
|
66
69
|
"@ionic/prettier-config": "^4.0.0",
|
|
67
70
|
"@ionic/swiftlint-config": "^2.0.0",
|
|
68
|
-
"@types/node": "^
|
|
69
|
-
"eslint": "^8.57.
|
|
70
|
-
"eslint-plugin-import": "^2.
|
|
71
|
-
"
|
|
72
|
-
"prettier
|
|
71
|
+
"@types/node": "^24.3.0",
|
|
72
|
+
"eslint": "^8.57.0",
|
|
73
|
+
"eslint-plugin-import": "^2.32.0",
|
|
74
|
+
"husky": "^9.1.7",
|
|
75
|
+
"prettier": "^3.6.2",
|
|
76
|
+
"prettier-plugin-java": "^2.7.4",
|
|
73
77
|
"rimraf": "^6.0.1",
|
|
74
|
-
"rollup": "^4.
|
|
78
|
+
"rollup": "^4.50.0",
|
|
75
79
|
"swiftlint": "^2.0.0",
|
|
76
|
-
"typescript": "^5.
|
|
80
|
+
"typescript": "^5.9.2"
|
|
77
81
|
},
|
|
78
82
|
"peerDependencies": {
|
|
79
83
|
"@capacitor/core": "^6.0.0"
|