@capgo/capacitor-updater 6.42.3 → 6.43.3
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/Package.swift +1 -1
- package/README.md +104 -41
- package/android/build.gradle +1 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +153 -49
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +60 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +23 -6
- package/android/src/main/java/ee/forgr/capacitor_updater/InternalUtils.java +13 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +436 -2
- package/dist/docs.json +116 -4
- package/dist/esm/definitions.d.ts +54 -4
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +3 -1
- package/dist/esm/web.js +6 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +6 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +6 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +97 -6
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +23 -11
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +1 -0
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +330 -2
- package/package.json +3 -2
|
@@ -579,10 +579,15 @@ import UIKit
|
|
|
579
579
|
|
|
580
580
|
for entry in manifest {
|
|
581
581
|
guard let fileName = entry.file_name,
|
|
582
|
-
var fileHash = entry.file_hash,
|
|
583
582
|
let downloadUrl = entry.download_url else {
|
|
584
583
|
continue
|
|
585
584
|
}
|
|
585
|
+
guard let entryFileHash = entry.file_hash, !entryFileHash.isEmpty else {
|
|
586
|
+
logger.error("Missing file_hash for manifest entry: \(entry.file_name ?? "unknown")")
|
|
587
|
+
hasError.value = true
|
|
588
|
+
continue
|
|
589
|
+
}
|
|
590
|
+
var fileHash = entryFileHash
|
|
586
591
|
|
|
587
592
|
// Decrypt checksum if needed (done before creating operation)
|
|
588
593
|
if !self.publicKey.isEmpty && !sessionKey.isEmpty {
|
|
@@ -749,16 +754,14 @@ import UIKit
|
|
|
749
754
|
// Write to destination
|
|
750
755
|
try finalData.write(to: destFilePath)
|
|
751
756
|
|
|
752
|
-
//
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
throw NSError(domain: "ChecksumError", code: 1, userInfo: [NSLocalizedDescriptionKey: "Computed checksum is not equal to required checksum (\(calculatedChecksum) != \(fileHash)) for file \(fileName) at url \(downloadUrl)"])
|
|
761
|
-
}
|
|
757
|
+
// Always verify checksum when file_hash is present
|
|
758
|
+
let calculatedChecksum = CryptoCipher.calcChecksum(filePath: destFilePath)
|
|
759
|
+
CryptoCipher.logChecksumInfo(label: "Calculated checksum", hexChecksum: calculatedChecksum)
|
|
760
|
+
CryptoCipher.logChecksumInfo(label: "Expected checksum", hexChecksum: fileHash)
|
|
761
|
+
if calculatedChecksum != fileHash {
|
|
762
|
+
try? FileManager.default.removeItem(at: destFilePath)
|
|
763
|
+
self.sendStats(action: "download_manifest_checksum_fail", versionName: "\(version):\(destFileName)")
|
|
764
|
+
throw NSError(domain: "ChecksumError", code: 1, userInfo: [NSLocalizedDescriptionKey: "Computed checksum is not equal to required checksum (\(calculatedChecksum) != \(fileHash)) for file \(fileName) at url \(downloadUrl)"])
|
|
762
765
|
}
|
|
763
766
|
|
|
764
767
|
// Save to cache
|
|
@@ -1554,6 +1557,15 @@ import UIKit
|
|
|
1554
1557
|
if let responseValue = response.value {
|
|
1555
1558
|
if let error = responseValue.error {
|
|
1556
1559
|
setChannel.error = error
|
|
1560
|
+
} else if responseValue.unset == true {
|
|
1561
|
+
// Server requested to unset channel (public channel was requested)
|
|
1562
|
+
// Clear persisted defaultChannel and revert to config value
|
|
1563
|
+
UserDefaults.standard.removeObject(forKey: defaultChannelKey)
|
|
1564
|
+
UserDefaults.standard.synchronize()
|
|
1565
|
+
self.logger.info("Public channel requested, channel override removed")
|
|
1566
|
+
|
|
1567
|
+
setChannel.status = responseValue.status ?? "ok"
|
|
1568
|
+
setChannel.message = responseValue.message ?? "Public channel requested, channel override removed. Device will use public channel automatically."
|
|
1557
1569
|
} else {
|
|
1558
1570
|
// Success - persist defaultChannel
|
|
1559
1571
|
self.defaultChannel = channel
|
|
@@ -37,11 +37,16 @@ extension UIWindow {
|
|
|
37
37
|
return
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
// Check if channel selector mode is enabled
|
|
41
|
+
if plugin.shakeChannelSelectorEnabled {
|
|
42
|
+
showChannelSelector(plugin: plugin, bridge: bridge)
|
|
43
|
+
} else {
|
|
44
|
+
showDefaultMenu(plugin: plugin, bridge: bridge)
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
private func
|
|
49
|
+
private func showDefaultMenu(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
|
|
45
50
|
// Prevent multiple alerts from showing
|
|
46
51
|
if let topVC = UIApplication.topViewController(),
|
|
47
52
|
topVC.isKind(of: UIAlertController.self) {
|
|
@@ -110,4 +115,327 @@ extension UIWindow {
|
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
}
|
|
118
|
+
|
|
119
|
+
private func showChannelSelector(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
|
|
120
|
+
// Prevent multiple alerts from showing
|
|
121
|
+
if let topVC = UIApplication.topViewController(),
|
|
122
|
+
topVC.isKind(of: UIAlertController.self) {
|
|
123
|
+
plugin.logger.info("UIAlertController is already presented")
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let updater = plugin.implementation
|
|
128
|
+
|
|
129
|
+
// Show loading indicator
|
|
130
|
+
let loadingAlert = UIAlertController(title: "Loading Channels...", message: nil, preferredStyle: .alert)
|
|
131
|
+
var didCancel = false
|
|
132
|
+
let loadingIndicator = UIActivityIndicatorView(style: .medium)
|
|
133
|
+
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
|
|
134
|
+
loadingIndicator.startAnimating()
|
|
135
|
+
loadingAlert.view.addSubview(loadingIndicator)
|
|
136
|
+
|
|
137
|
+
NSLayoutConstraint.activate([
|
|
138
|
+
loadingIndicator.centerXAnchor.constraint(equalTo: loadingAlert.view.centerXAnchor),
|
|
139
|
+
loadingIndicator.bottomAnchor.constraint(equalTo: loadingAlert.view.bottomAnchor, constant: -20)
|
|
140
|
+
])
|
|
141
|
+
|
|
142
|
+
// Add cancel button to loading alert
|
|
143
|
+
loadingAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
|
|
144
|
+
didCancel = true
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
DispatchQueue.main.async {
|
|
148
|
+
if let topVC = UIApplication.topViewController() {
|
|
149
|
+
topVC.present(loadingAlert, animated: true) {
|
|
150
|
+
// Fetch channels in background
|
|
151
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
152
|
+
let result = updater.listChannels()
|
|
153
|
+
|
|
154
|
+
DispatchQueue.main.async {
|
|
155
|
+
loadingAlert.dismiss(animated: true) {
|
|
156
|
+
guard !didCancel else { return }
|
|
157
|
+
if !result.error.isEmpty {
|
|
158
|
+
self.showError(message: "Failed to load channels: \(result.error)", plugin: plugin)
|
|
159
|
+
} else if result.channels.isEmpty {
|
|
160
|
+
self.showError(message: "No channels available for self-assignment", plugin: plugin)
|
|
161
|
+
} else {
|
|
162
|
+
self.presentChannelPicker(channels: result.channels, plugin: plugin, bridge: bridge)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private func presentChannelPicker(channels: [[String: Any]], plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
|
|
173
|
+
let alert = UIAlertController(title: "Select Channel", message: "Choose a channel to switch to", preferredStyle: .actionSheet)
|
|
174
|
+
|
|
175
|
+
// Get channel names
|
|
176
|
+
let channelNames = channels.compactMap { $0["name"] as? String }
|
|
177
|
+
|
|
178
|
+
// Show first 5 channels as actions
|
|
179
|
+
let channelsToShow = Array(channelNames.prefix(5))
|
|
180
|
+
|
|
181
|
+
for channelName in channelsToShow {
|
|
182
|
+
alert.addAction(UIAlertAction(title: channelName, style: .default) { [weak self] _ in
|
|
183
|
+
self?.selectChannel(name: channelName, plugin: plugin, bridge: bridge)
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// If there are more channels, add a "More..." option
|
|
188
|
+
if channelNames.count > 5 {
|
|
189
|
+
alert.addAction(UIAlertAction(title: "More channels...", style: .default) { [weak self] _ in
|
|
190
|
+
self?.showSearchableChannelPicker(channels: channels, plugin: plugin, bridge: bridge)
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
|
|
195
|
+
|
|
196
|
+
// For iPad support
|
|
197
|
+
if let popoverController = alert.popoverPresentationController {
|
|
198
|
+
popoverController.sourceView = self
|
|
199
|
+
popoverController.sourceRect = CGRect(x: self.bounds.midX, y: self.bounds.midY, width: 0, height: 0)
|
|
200
|
+
popoverController.permittedArrowDirections = []
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
DispatchQueue.main.async {
|
|
204
|
+
if let topVC = UIApplication.topViewController() {
|
|
205
|
+
topVC.present(alert, animated: true)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private func showSearchableChannelPicker(channels: [[String: Any]], plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
|
|
211
|
+
let alert = UIAlertController(title: "Search Channels", message: "Enter channel name to search", preferredStyle: .alert)
|
|
212
|
+
|
|
213
|
+
alert.addTextField { textField in
|
|
214
|
+
textField.placeholder = "Channel name..."
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let channelNames = channels.compactMap { $0["name"] as? String }
|
|
218
|
+
|
|
219
|
+
alert.addAction(UIAlertAction(title: "Search", style: .default) { [weak self, weak alert] _ in
|
|
220
|
+
guard let searchText = alert?.textFields?.first?.text?.lowercased(), !searchText.isEmpty else {
|
|
221
|
+
// If empty, show first 5
|
|
222
|
+
self?.presentChannelPicker(channels: channels, plugin: plugin, bridge: bridge)
|
|
223
|
+
return
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Filter channels
|
|
227
|
+
let filtered = channelNames.filter { $0.lowercased().contains(searchText) }
|
|
228
|
+
|
|
229
|
+
if filtered.isEmpty {
|
|
230
|
+
self?.showError(message: "No channels found matching '\(searchText)'", plugin: plugin)
|
|
231
|
+
} else if filtered.count == 1 {
|
|
232
|
+
// Directly select if only one match
|
|
233
|
+
self?.selectChannel(name: filtered[0], plugin: plugin, bridge: bridge)
|
|
234
|
+
} else {
|
|
235
|
+
// Show filtered results
|
|
236
|
+
let filteredChannels = channels.filter { channel in
|
|
237
|
+
if let name = channel["name"] as? String {
|
|
238
|
+
return name.lowercased().contains(searchText)
|
|
239
|
+
}
|
|
240
|
+
return false
|
|
241
|
+
}
|
|
242
|
+
self?.presentChannelPicker(channels: filteredChannels, plugin: plugin, bridge: bridge)
|
|
243
|
+
}
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
|
|
247
|
+
|
|
248
|
+
DispatchQueue.main.async {
|
|
249
|
+
if let topVC = UIApplication.topViewController() {
|
|
250
|
+
topVC.present(alert, animated: true)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private func selectChannel(name: String, plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) {
|
|
256
|
+
let updater = plugin.implementation
|
|
257
|
+
|
|
258
|
+
// Show progress indicator
|
|
259
|
+
let progressAlert = UIAlertController(title: "Switching to \(name)", message: "Setting channel...", preferredStyle: .alert)
|
|
260
|
+
let indicator = UIActivityIndicatorView(style: .medium)
|
|
261
|
+
indicator.translatesAutoresizingMaskIntoConstraints = false
|
|
262
|
+
indicator.startAnimating()
|
|
263
|
+
progressAlert.view.addSubview(indicator)
|
|
264
|
+
|
|
265
|
+
NSLayoutConstraint.activate([
|
|
266
|
+
indicator.centerXAnchor.constraint(equalTo: progressAlert.view.centerXAnchor),
|
|
267
|
+
indicator.bottomAnchor.constraint(equalTo: progressAlert.view.bottomAnchor, constant: -20)
|
|
268
|
+
])
|
|
269
|
+
|
|
270
|
+
DispatchQueue.main.async {
|
|
271
|
+
if let topVC = UIApplication.topViewController() {
|
|
272
|
+
topVC.present(progressAlert, animated: true) {
|
|
273
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
274
|
+
// Set the channel - respect plugin's allowSetDefaultChannel config
|
|
275
|
+
let setResult = updater.setChannel(
|
|
276
|
+
channel: name,
|
|
277
|
+
defaultChannelKey: "CapacitorUpdater.defaultChannel",
|
|
278
|
+
allowSetDefaultChannel: plugin.allowSetDefaultChannel
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
if !setResult.error.isEmpty {
|
|
282
|
+
DispatchQueue.main.async {
|
|
283
|
+
progressAlert.dismiss(animated: true) {
|
|
284
|
+
self.showError(message: "Failed to set channel: \(setResult.error)", plugin: plugin)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Update progress message
|
|
291
|
+
DispatchQueue.main.async {
|
|
292
|
+
progressAlert.message = "Checking for updates..."
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Check for updates with the new channel
|
|
296
|
+
let pluginUpdateUrl = plugin.getUpdateUrl()
|
|
297
|
+
let updateUrlStr = pluginUpdateUrl.isEmpty ? CapacitorUpdaterPlugin.updateUrlDefault : pluginUpdateUrl
|
|
298
|
+
guard let updateUrl = URL(string: updateUrlStr) else {
|
|
299
|
+
DispatchQueue.main.async {
|
|
300
|
+
progressAlert.dismiss(animated: true) {
|
|
301
|
+
self.showError(
|
|
302
|
+
message: "Channel set to \(name). Invalid update URL, could not check for updates.",
|
|
303
|
+
plugin: plugin
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let latest = updater.getLatest(url: updateUrl, channel: name)
|
|
311
|
+
|
|
312
|
+
// Handle update errors first (before "no new version" check)
|
|
313
|
+
if let error = latest.error, !error.isEmpty && error != "no_new_version_available" {
|
|
314
|
+
DispatchQueue.main.async {
|
|
315
|
+
progressAlert.dismiss(animated: true) {
|
|
316
|
+
self.showError(message: "Channel set to \(name). Update check failed: \(error)", plugin: plugin)
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Check if there's an actual update available
|
|
323
|
+
if latest.error == "no_new_version_available" || latest.url.isEmpty {
|
|
324
|
+
DispatchQueue.main.async {
|
|
325
|
+
progressAlert.dismiss(animated: true) {
|
|
326
|
+
self.showSuccess(message: "Channel set to \(name). Already on latest version.", plugin: plugin)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Update message
|
|
333
|
+
DispatchQueue.main.async {
|
|
334
|
+
progressAlert.message = "Downloading update \(latest.version)..."
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Download the update
|
|
338
|
+
do {
|
|
339
|
+
let bundle: BundleInfo
|
|
340
|
+
if let manifest = latest.manifest, !manifest.isEmpty {
|
|
341
|
+
bundle = try updater.downloadManifest(
|
|
342
|
+
manifest: manifest,
|
|
343
|
+
version: latest.version,
|
|
344
|
+
sessionKey: latest.sessionKey ?? ""
|
|
345
|
+
)
|
|
346
|
+
} else {
|
|
347
|
+
// Safe unwrap URL
|
|
348
|
+
guard let downloadUrl = URL(string: latest.url) else {
|
|
349
|
+
DispatchQueue.main.async {
|
|
350
|
+
progressAlert.dismiss(animated: true) {
|
|
351
|
+
self.showError(message: "Failed to download update: invalid update URL.", plugin: plugin)
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return
|
|
355
|
+
}
|
|
356
|
+
bundle = try updater.download(
|
|
357
|
+
url: downloadUrl,
|
|
358
|
+
version: latest.version,
|
|
359
|
+
sessionKey: latest.sessionKey ?? ""
|
|
360
|
+
)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Set as next bundle
|
|
364
|
+
_ = updater.setNextBundle(next: bundle.getId())
|
|
365
|
+
|
|
366
|
+
DispatchQueue.main.async {
|
|
367
|
+
progressAlert.dismiss(animated: true) {
|
|
368
|
+
self.showSuccessWithReload(
|
|
369
|
+
message: "Update downloaded! Reload to apply version \(latest.version)?",
|
|
370
|
+
plugin: plugin,
|
|
371
|
+
bridge: bridge,
|
|
372
|
+
onReload: { [weak plugin] in
|
|
373
|
+
_ = updater.set(bundle: bundle)
|
|
374
|
+
_ = plugin?._reload()
|
|
375
|
+
}
|
|
376
|
+
)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
} catch {
|
|
380
|
+
DispatchQueue.main.async {
|
|
381
|
+
progressAlert.dismiss(animated: true) {
|
|
382
|
+
self.showError(message: "Failed to download update: \(error.localizedDescription)", plugin: plugin)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
private func showError(message: String, plugin: CapacitorUpdaterPlugin) {
|
|
393
|
+
plugin.logger.error(message)
|
|
394
|
+
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
|
|
395
|
+
alert.addAction(UIAlertAction(title: "OK", style: .default))
|
|
396
|
+
|
|
397
|
+
DispatchQueue.main.async {
|
|
398
|
+
if let topVC = UIApplication.topViewController() {
|
|
399
|
+
topVC.present(alert, animated: true)
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private func showSuccess(message: String, plugin: CapacitorUpdaterPlugin) {
|
|
405
|
+
plugin.logger.info(message)
|
|
406
|
+
let alert = UIAlertController(title: "Success", message: message, preferredStyle: .alert)
|
|
407
|
+
alert.addAction(UIAlertAction(title: "OK", style: .default))
|
|
408
|
+
|
|
409
|
+
DispatchQueue.main.async {
|
|
410
|
+
if let topVC = UIApplication.topViewController() {
|
|
411
|
+
topVC.present(alert, animated: true)
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
private func showSuccessWithReload(
|
|
417
|
+
message: String,
|
|
418
|
+
plugin: CapacitorUpdaterPlugin,
|
|
419
|
+
bridge: CAPBridgeProtocol,
|
|
420
|
+
onReload: (() -> Void)? = nil
|
|
421
|
+
) {
|
|
422
|
+
plugin.logger.info(message)
|
|
423
|
+
let alert = UIAlertController(title: "Update Ready", message: message, preferredStyle: .alert)
|
|
424
|
+
alert.addAction(UIAlertAction(title: "Later", style: .cancel))
|
|
425
|
+
alert.addAction(UIAlertAction(title: "Reload Now", style: .default) { _ in
|
|
426
|
+
if let onReload = onReload {
|
|
427
|
+
onReload()
|
|
428
|
+
} else {
|
|
429
|
+
DispatchQueue.main.async {
|
|
430
|
+
bridge.webView?.reload()
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
})
|
|
434
|
+
|
|
435
|
+
DispatchQueue.main.async {
|
|
436
|
+
if let topVC = UIApplication.topViewController() {
|
|
437
|
+
topVC.present(alert, animated: true)
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
113
441
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-updater",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.43.3",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Live update for capacitor apps",
|
|
6
6
|
"main": "dist/plugin.cjs.js",
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
58
58
|
"clean": "rimraf ./dist",
|
|
59
59
|
"watch": "tsc --watch",
|
|
60
|
-
"prepublishOnly": "npm run build"
|
|
60
|
+
"prepublishOnly": "npm run build",
|
|
61
|
+
"check:wiring": "node scripts/check-capacitor-plugin-wiring.mjs"
|
|
61
62
|
},
|
|
62
63
|
"devDependencies": {
|
|
63
64
|
"@capacitor/android": "^6.1.2",
|