@capgo/capacitor-updater 8.0.0 → 8.1.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.
Files changed (64) hide show
  1. package/CapgoCapacitorUpdater.podspec +7 -5
  2. package/Package.swift +37 -0
  3. package/README.md +1461 -231
  4. package/android/build.gradle +29 -12
  5. package/android/proguard-rules.pro +45 -0
  6. package/android/src/main/AndroidManifest.xml +0 -1
  7. package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +223 -195
  8. package/android/src/main/java/ee/forgr/capacitor_updater/BundleStatus.java +23 -23
  9. package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +13 -0
  10. package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +2159 -1234
  11. package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +1507 -0
  12. package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +330 -121
  13. package/android/src/main/java/ee/forgr/capacitor_updater/DataManager.java +28 -0
  14. package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +43 -49
  15. package/android/src/main/java/ee/forgr/capacitor_updater/DelayUntilNext.java +4 -4
  16. package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +260 -0
  17. package/android/src/main/java/ee/forgr/capacitor_updater/DeviceIdHelper.java +221 -0
  18. package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +808 -117
  19. package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +156 -0
  20. package/android/src/main/java/ee/forgr/capacitor_updater/InternalUtils.java +32 -0
  21. package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +338 -0
  22. package/android/src/main/java/ee/forgr/capacitor_updater/ShakeDetector.java +72 -0
  23. package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +169 -0
  24. package/dist/docs.json +2187 -625
  25. package/dist/esm/definitions.d.ts +1286 -249
  26. package/dist/esm/definitions.js.map +1 -1
  27. package/dist/esm/history.d.ts +1 -0
  28. package/dist/esm/history.js +283 -0
  29. package/dist/esm/history.js.map +1 -0
  30. package/dist/esm/index.d.ts +3 -2
  31. package/dist/esm/index.js +5 -4
  32. package/dist/esm/index.js.map +1 -1
  33. package/dist/esm/web.d.ts +36 -41
  34. package/dist/esm/web.js +94 -35
  35. package/dist/esm/web.js.map +1 -1
  36. package/dist/plugin.cjs.js +376 -35
  37. package/dist/plugin.cjs.js.map +1 -1
  38. package/dist/plugin.js +376 -35
  39. package/dist/plugin.js.map +1 -1
  40. package/ios/Sources/CapacitorUpdaterPlugin/AES.swift +69 -0
  41. package/ios/Sources/CapacitorUpdaterPlugin/BigInt.swift +55 -0
  42. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleInfo.swift +37 -10
  43. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleStatus.swift +1 -1
  44. package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +1605 -0
  45. package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +1526 -0
  46. package/ios/Sources/CapacitorUpdaterPlugin/CryptoCipher.swift +267 -0
  47. package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +220 -0
  48. package/ios/Sources/CapacitorUpdaterPlugin/DeviceIdHelper.swift +120 -0
  49. package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +311 -0
  50. package/ios/Sources/CapacitorUpdaterPlugin/Logger.swift +310 -0
  51. package/ios/Sources/CapacitorUpdaterPlugin/RSA.swift +274 -0
  52. package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +112 -0
  53. package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/UserDefaultsExtension.swift +0 -2
  54. package/package.json +41 -35
  55. package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdater.java +0 -1130
  56. package/ios/Plugin/CapacitorUpdater.swift +0 -858
  57. package/ios/Plugin/CapacitorUpdaterPlugin.h +0 -10
  58. package/ios/Plugin/CapacitorUpdaterPlugin.m +0 -27
  59. package/ios/Plugin/CapacitorUpdaterPlugin.swift +0 -675
  60. package/ios/Plugin/CryptoCipher.swift +0 -240
  61. /package/{LICENCE → LICENSE} +0 -0
  62. /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayCondition.swift +0 -0
  63. /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayUntilNext.swift +0 -0
  64. /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/Info.plist +0 -0
@@ -0,0 +1,274 @@
1
+ import BigInt
2
+ import Foundation
3
+ import CommonCrypto
4
+ import CryptoKit
5
+
6
+ ///
7
+ /// Constants
8
+ ///
9
+ private enum RSAConstants {
10
+ static let rsaKeySizeInBits: NSNumber = 2048
11
+ static let rsaAlgorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA256
12
+ }
13
+
14
+ // We do all this stuff because ios is shit and open source libraries allow to do decryption with public key
15
+ // So we have to do it manually, while in nodejs or Java it's ok and done at language level.
16
+
17
+ ///
18
+ /// The RSA public key.
19
+ ///
20
+ public struct RSAPublicKey {
21
+ private let manualKey: ManualRSAPublicKey
22
+
23
+ fileprivate init(manualKey: ManualRSAPublicKey) {
24
+ self.manualKey = manualKey
25
+ }
26
+
27
+ ///
28
+ /// Takes the data and uses the public key to decrypt it.
29
+ /// Returns the decrypted data.
30
+ ///
31
+ public func decrypt(data: Data) -> Data? {
32
+ return manualKey.decrypt(data)
33
+ }
34
+
35
+ ///
36
+ /// Allows you to load an RSA public key (i.e. one downloaded from the net).
37
+ ///
38
+ public static func load(rsaPublicKey: String) -> RSAPublicKey? {
39
+ // Clean up the key string
40
+ var pubKey: String = rsaPublicKey
41
+ pubKey = pubKey.replacingOccurrences(of: "-----BEGIN RSA PUBLIC KEY-----", with: "")
42
+ pubKey = pubKey.replacingOccurrences(of: "-----END RSA PUBLIC KEY-----", with: "")
43
+ pubKey = pubKey.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----", with: "")
44
+ pubKey = pubKey.replacingOccurrences(of: "-----END PUBLIC KEY-----", with: "")
45
+ pubKey = pubKey.replacingOccurrences(of: "\\n+", with: "", options: .regularExpression)
46
+ pubKey = pubKey.replacingOccurrences(of: "\n", with: "")
47
+ pubKey = pubKey.trimmingCharacters(in: .whitespacesAndNewlines)
48
+
49
+ do {
50
+ guard let rsaPublicKeyData: Data = Data(base64Encoded: String(pubKey)) else {
51
+ throw CustomError.cannotDecode
52
+ }
53
+
54
+ // Try parsing as PKCS#1
55
+ if let manualKey = ManualRSAPublicKey.fromPKCS1(rsaPublicKeyData) {
56
+ return RSAPublicKey(manualKey: manualKey)
57
+ }
58
+
59
+ // Most common public exponent is 65537 (0x010001)
60
+ let commonExponent = Data([0x01, 0x00, 0x01]) // 65537 in big-endian
61
+
62
+ // Assume the entire key data is the modulus
63
+ let lastResortKey = ManualRSAPublicKey(modulus: rsaPublicKeyData, exponent: commonExponent)
64
+ return RSAPublicKey(manualKey: lastResortKey)
65
+ } catch {
66
+ return nil
67
+ }
68
+ }
69
+ }
70
+
71
+ // Manual RSA Public Key Implementation using the BigInt library
72
+ struct ManualRSAPublicKey {
73
+ let modulus: BigInt
74
+ let exponent: BigInt
75
+
76
+ init(modulus: Data, exponent: Data) {
77
+ // Create positive BigInts from Data
78
+ let modulusBytes = [UInt8](modulus)
79
+ var modulusValue = BigUInt(0)
80
+ for byte in modulusBytes {
81
+ modulusValue = (modulusValue << 8) | BigUInt(byte)
82
+ }
83
+ self.modulus = BigInt(modulusValue)
84
+ let exponentBytes = [UInt8](exponent)
85
+ var exponentValue = BigUInt(0)
86
+ for byte in exponentBytes {
87
+ exponentValue = (exponentValue << 8) | BigUInt(byte)
88
+ }
89
+ self.exponent = BigInt(exponentValue)
90
+ }
91
+
92
+ // Parse PKCS#1 format public key
93
+ static func fromPKCS1(_ publicKeyData: Data) -> ManualRSAPublicKey? {
94
+ // Parse ASN.1 DER encoded RSA public key
95
+ // Format: RSAPublicKey ::= SEQUENCE { modulus INTEGER, publicExponent INTEGER }
96
+
97
+ guard publicKeyData.count > 0 else {
98
+ return nil
99
+ }
100
+
101
+ let bytes = [UInt8](publicKeyData)
102
+
103
+ // Check for sequence tag (0x30)
104
+ guard bytes[0] == 0x30 else {
105
+ // Try direct modulus/exponent approach as fallback
106
+ if publicKeyData.count >= 3 {
107
+ // Assume this is a raw RSA public key with modulus + exponent
108
+ // Most common: modulus is 256 bytes (2048 bits), exponent is 3 bytes (0x010001 = 65537)
109
+ let modulusSize = publicKeyData.count - 3
110
+ if modulusSize > 0 {
111
+ let modulusData = publicKeyData.prefix(modulusSize)
112
+ let exponentData = publicKeyData.suffix(3)
113
+ return ManualRSAPublicKey(modulus: modulusData, exponent: exponentData)
114
+ }
115
+ }
116
+
117
+ return nil
118
+ }
119
+
120
+ var index = 1
121
+
122
+ // Skip length
123
+ if bytes[index] & 0x80 != 0 {
124
+ let lenBytes = Int(bytes[index] & 0x7F)
125
+ if (index + 1 + lenBytes) >= bytes.count {
126
+ return nil
127
+ }
128
+ index += 1 + lenBytes
129
+ } else {
130
+ index += 1
131
+ }
132
+
133
+ // Check for INTEGER tag for modulus (0x02)
134
+ if index >= bytes.count {
135
+ return nil
136
+ }
137
+
138
+ guard bytes[index] == 0x02 else {
139
+ return nil
140
+ }
141
+ index += 1
142
+
143
+ // Get modulus length
144
+ if index >= bytes.count {
145
+ return nil
146
+ }
147
+
148
+ var modulusLength = 0
149
+ if bytes[index] & 0x80 != 0 {
150
+ let lenBytes = Int(bytes[index] & 0x7F)
151
+ if (index + 1 + lenBytes) >= bytes.count {
152
+ return nil
153
+ }
154
+ index += 1
155
+ for i in 0..<lenBytes {
156
+ modulusLength = (modulusLength << 8) | Int(bytes[index + i])
157
+ }
158
+ index += lenBytes
159
+ } else {
160
+ modulusLength = Int(bytes[index])
161
+ index += 1
162
+ }
163
+
164
+ // Skip any leading zero in modulus (for unsigned integer)
165
+ if index < bytes.count && bytes[index] == 0x00 {
166
+ index += 1
167
+ modulusLength -= 1
168
+ }
169
+
170
+ // Extract modulus
171
+ if (index + modulusLength) > bytes.count {
172
+ return nil
173
+ }
174
+
175
+ let modulusData = Data(bytes[index..<(index + modulusLength)])
176
+ index += modulusLength
177
+
178
+ // Check for INTEGER tag for exponent
179
+ if index >= bytes.count {
180
+ return nil
181
+ }
182
+
183
+ guard bytes[index] == 0x02 else {
184
+ return nil
185
+ }
186
+ index += 1
187
+
188
+ // Get exponent length
189
+ if index >= bytes.count {
190
+ return nil
191
+ }
192
+
193
+ var exponentLength = 0
194
+ if bytes[index] & 0x80 != 0 {
195
+ let lenBytes = Int(bytes[index] & 0x7F)
196
+ if (index + 1 + lenBytes) >= bytes.count {
197
+ return nil
198
+ }
199
+ index += 1
200
+ for i in 0..<lenBytes {
201
+ exponentLength = (exponentLength << 8) | Int(bytes[index + i])
202
+ }
203
+ index += lenBytes
204
+ } else {
205
+ exponentLength = Int(bytes[index])
206
+ index += 1
207
+ }
208
+
209
+ // Extract exponent
210
+ if (index + exponentLength) > bytes.count {
211
+ return nil
212
+ }
213
+
214
+ let exponentData = Data(bytes[index..<(index + exponentLength)])
215
+ return ManualRSAPublicKey(modulus: modulusData, exponent: exponentData)
216
+ }
217
+
218
+ // Decrypt data using raw RSA operation (c^d mod n)
219
+ func decrypt(_ encryptedData: Data) -> Data? {
220
+ // Create positive BigInt from encrypted data
221
+ let encryptedBytes = [UInt8](encryptedData)
222
+ var encryptedValue = BigUInt(0)
223
+ for byte in encryptedBytes {
224
+ encryptedValue = (encryptedValue << 8) | BigUInt(byte)
225
+ }
226
+ let encrypted = BigInt(encryptedValue)
227
+
228
+ // In Node.js:
229
+ // privateEncrypt uses the private key (d) to encrypt
230
+ // publicDecrypt uses the public key (e) to decrypt
231
+ // The operation we want is: ciphertext^e mod n
232
+
233
+ // RSA operation: c^e mod n
234
+ let decrypted = encrypted.manualPower(exponent, modulus: modulus)
235
+
236
+ // Convert to bytes with proper padding
237
+ guard let bigUIntValue = decrypted.magnitude as? BigUInt else {
238
+ return nil
239
+ }
240
+
241
+ // Convert BigUInt to bytes with padding
242
+ var resultBytes = [UInt8]()
243
+ var tempValue = bigUIntValue
244
+ while tempValue > 0 {
245
+ let byte = UInt8(tempValue & 0xFF)
246
+ resultBytes.insert(byte, at: 0) // Prepend to get big-endian
247
+ tempValue >>= 8
248
+ }
249
+
250
+ // Ensure we have at least 256 bytes (2048 bits) with leading zeros
251
+ let paddedBytes = [UInt8](repeating: 0, count: max(0, 256 - resultBytes.count)) + resultBytes
252
+
253
+ // For PKCS1 padding from Node.js privateEncrypt, the format is:
254
+ // 0x00 || 0x01 || PS || 0x00 || actual data
255
+ // where PS is a string of 0xFF bytes
256
+
257
+ // Check for privateEncrypt padding format (0x00 || 0x01 || PS || 0x00)
258
+ var startIndex = 0
259
+ if paddedBytes.count > 2 && paddedBytes[0] == 0x00 && paddedBytes[1] == 0x01 {
260
+ for i in 2..<paddedBytes.count {
261
+ if paddedBytes[i] == 0x00 {
262
+ startIndex = i + 1
263
+ break
264
+ }
265
+ }
266
+ }
267
+ if startIndex < paddedBytes.count {
268
+ let result = Data(paddedBytes[startIndex...])
269
+ return result
270
+ } else {
271
+ return Data(paddedBytes)
272
+ }
273
+ }
274
+ }
@@ -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,7 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "8.0.0",
4
- "packageManager": "pnpm@8.5.1",
3
+ "version": "8.1.0",
5
4
  "license": "MPL-2.0",
6
5
  "description": "Live update for capacitor apps",
7
6
  "main": "dist/plugin.cjs.js",
@@ -10,12 +9,14 @@
10
9
  "unpkg": "dist/plugin.js",
11
10
  "files": [
12
11
  "android/src/main/",
12
+ "android/proguard-rules.pro",
13
13
  "android/build.gradle",
14
14
  "dist/",
15
- "ios/Plugin/",
16
- "CapgoCapacitorUpdater.podspec"
15
+ "ios/Sources/",
16
+ "CapgoCapacitorUpdater.podspec",
17
+ "Package.swift"
17
18
  ],
18
- "author": "Martin Donadieu",
19
+ "author": "Martin Donadieu <martin@capgo.app>",
19
20
  "repository": {
20
21
  "type": "git",
21
22
  "url": "git+https://github.com/Cap-go/capacitor-updater.git"
@@ -25,56 +26,61 @@
25
26
  },
26
27
  "keywords": [
27
28
  "capacitor",
28
- "plugin",
29
- "OTA",
30
- "manual update",
29
+ "live updates",
31
30
  "live update",
31
+ "updates",
32
32
  "auto update",
33
+ "manual update",
34
+ "capgo",
35
+ "plugin",
36
+ "OTA",
33
37
  "ionic",
34
38
  "appflow alternative",
35
- "capgo",
39
+ "capawesome alternative",
40
+ "@capawesome/capacitor-live-update",
36
41
  "native"
37
42
  ],
38
43
  "scripts": {
39
44
  "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
40
- "verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin && cd ..",
45
+ "verify:ios": "xcodebuild -scheme CapgoCapacitorUpdater -destination generic/platform=iOS",
41
46
  "verify:android": "cd android && ./gradlew clean build test && cd ..",
42
47
  "verify:web": "npm run build",
48
+ "test": "npm run test:ios && npm run test:android",
49
+ "test:ios": "./scripts/test-ios.sh",
50
+ "test:android": "cd android && ./gradlew test && cd ..",
43
51
  "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
44
- "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --autocorrect --format",
45
- "eslint": "eslint . --ext ts",
46
- "prettier": "prettier --config .prettierrc.js \"**/*.{css,html,ts,js,java}\"",
52
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
53
+ "eslint": "eslint . --ext .ts",
54
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
47
55
  "swiftlint": "node-swiftlint",
48
- "docgen": "docgen --api CapacitorUpdaterPlugin --output-readme README.md --output-json dist/docs.json",
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",
56
+ "docgen": "node scripts/generate-docs.js",
50
57
  "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
51
58
  "clean": "rimraf ./dist",
52
59
  "watch": "tsc --watch",
53
60
  "prepublishOnly": "npm run build"
54
61
  },
55
62
  "devDependencies": {
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",
61
- "@ionic/eslint-config": "^0.3.0",
62
- "@ionic/prettier-config": "^3.0.0",
63
- "@ionic/swiftlint-config": "^1.1.2",
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"
63
+ "@capacitor/android": "^8.0.0",
64
+ "@capacitor/cli": "^8.0.0",
65
+ "@capacitor/core": "^8.0.0",
66
+ "@capacitor/docgen": "^0.3.0",
67
+ "@capacitor/ios": "^8.0.0",
68
+ "@ionic/eslint-config": "^0.4.0",
69
+ "@ionic/prettier-config": "^4.0.0",
70
+ "@ionic/swiftlint-config": "^2.0.0",
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",
77
+ "rimraf": "^6.0.1",
78
+ "rollup": "^4.50.0",
79
+ "swiftlint": "^2.0.0",
80
+ "typescript": "^5.9.2"
75
81
  },
76
82
  "peerDependencies": {
77
- "@capacitor/core": "^5.0.0"
83
+ "@capacitor/core": "^8.0.0"
78
84
  },
79
85
  "prettier": "@ionic/prettier-config",
80
86
  "swiftlint": "@ionic/swiftlint-config",