@capawesome/capacitor-live-update 8.1.1 → 8.2.1
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/README.md +112 -1
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdate.java +88 -1
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdateHttpClient.java +12 -1
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdatePlugin.java +31 -1
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/api/GetChannelsResponseItem.java +28 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/options/FetchChannelsOptions.java +38 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/ChannelResult.java +28 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/FetchChannelsResult.java +28 -0
- package/dist/docs.json +150 -2
- package/dist/esm/definitions.d.ts +83 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -1
- package/dist/esm/web.js +3 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +3 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/Classes/Options/FetchChannelsOptions.swift +26 -0
- package/ios/Plugin/Classes/Results/ChannelResult.swift +19 -0
- package/ios/Plugin/Classes/Results/FetchChannelsResult.swift +16 -0
- package/ios/Plugin/Enums/CustomError.swift +3 -0
- package/ios/Plugin/LiveUpdate.swift +43 -0
- package/ios/Plugin/LiveUpdateHttpClient.swift +11 -0
- package/ios/Plugin/LiveUpdatePlugin.swift +21 -1
- package/ios/Plugin/Protocols/Api/GetChannelsResponseItem.swift +4 -0
- package/package.json +1 -3
|
@@ -34,6 +34,9 @@ import CommonCrypto
|
|
|
34
34
|
// Check version and reset config if version changed
|
|
35
35
|
checkAndResetConfigIfVersionChanged()
|
|
36
36
|
|
|
37
|
+
// Set the device ID on the HTTP client (after any potential config reset)
|
|
38
|
+
self.httpClient.setDeviceId(getDeviceId())
|
|
39
|
+
|
|
37
40
|
// Start the rollback timer to rollback to the default bundle
|
|
38
41
|
// if the app is not ready after a certain time
|
|
39
42
|
startRollbackTimer()
|
|
@@ -80,6 +83,39 @@ import CommonCrypto
|
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
@objc public func fetchChannels(_ options: FetchChannelsOptions) async throws -> FetchChannelsResult {
|
|
87
|
+
var parameters = [String: String]()
|
|
88
|
+
if let limit = options.getLimit() {
|
|
89
|
+
parameters["limit"] = String(limit)
|
|
90
|
+
}
|
|
91
|
+
if let offset = options.getOffset() {
|
|
92
|
+
parameters["offset"] = String(offset)
|
|
93
|
+
}
|
|
94
|
+
if let query = options.getQuery() {
|
|
95
|
+
parameters["query"] = query
|
|
96
|
+
}
|
|
97
|
+
var urlComponents = URLComponents(string: "https://\(config.serverDomain)/v1/apps/\(getAppId() ?? "")/channels")!
|
|
98
|
+
if !parameters.isEmpty {
|
|
99
|
+
urlComponents.queryItems = parameters.map { URLQueryItem(name: $0.key, value: $0.value) }
|
|
100
|
+
}
|
|
101
|
+
let url = try urlComponents.asURL()
|
|
102
|
+
let response = try await self.httpClient.request(url: url, type: [GetChannelsResponseItem].self)
|
|
103
|
+
if let error = response.error {
|
|
104
|
+
if response.response?.statusCode == 401 {
|
|
105
|
+
throw CustomError.channelDiscoveryNotEnabled
|
|
106
|
+
}
|
|
107
|
+
if let urlError = error.underlyingError as? URLError {
|
|
108
|
+
if urlError.code == .timedOut {
|
|
109
|
+
throw urlError
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
throw error
|
|
113
|
+
}
|
|
114
|
+
let items = response.value ?? []
|
|
115
|
+
let channels = items.map { ChannelResult(id: $0.id, name: $0.name) }
|
|
116
|
+
return FetchChannelsResult(channels: channels)
|
|
117
|
+
}
|
|
118
|
+
|
|
83
119
|
@objc public func fetchLatestBundle(_ options: FetchLatestBundleOptions) async throws -> FetchLatestBundleResult {
|
|
84
120
|
let response: GetLatestBundleResponse? = try await self.fetchLatestBundle(options)
|
|
85
121
|
return FetchLatestBundleResult(artifactType: response?.artifactType, bundleId: response?.bundleId, checksum: response?.checksum, customProperties: response?.customProperties, downloadUrl: response?.url, signature: response?.signature)
|
|
@@ -604,12 +640,19 @@ import CommonCrypto
|
|
|
604
640
|
if let _ = config.defaultChannel {
|
|
605
641
|
channel = config.defaultChannel
|
|
606
642
|
}
|
|
643
|
+
if let nativeChannel = getNativeChannel() {
|
|
644
|
+
channel = nativeChannel
|
|
645
|
+
}
|
|
607
646
|
if let _ = preferences.getChannel() {
|
|
608
647
|
channel = preferences.getChannel()
|
|
609
648
|
}
|
|
610
649
|
return channel
|
|
611
650
|
}
|
|
612
651
|
|
|
652
|
+
private func getNativeChannel() -> String? {
|
|
653
|
+
return Bundle.main.object(forInfoDictionaryKey: "CapawesomeLiveUpdateDefaultChannel") as? String
|
|
654
|
+
}
|
|
655
|
+
|
|
613
656
|
/// - Returns: The sha256 checksum of the file at the given URL.
|
|
614
657
|
private func getChecksumForFile(url: URL) throws -> String {
|
|
615
658
|
let handle = try FileHandle(forReadingFrom: url)
|
|
@@ -5,6 +5,7 @@ import Alamofire
|
|
|
5
5
|
public class LiveUpdateHttpClient: NSObject {
|
|
6
6
|
|
|
7
7
|
private let config: LiveUpdateConfig
|
|
8
|
+
private var deviceId: String?
|
|
8
9
|
|
|
9
10
|
public static func getChecksumFromResponse(response: HTTPURLResponse) -> String? {
|
|
10
11
|
guard let headers = response.allHeaderFields as? [String: String] else { return nil }
|
|
@@ -20,10 +21,17 @@ public class LiveUpdateHttpClient: NSObject {
|
|
|
20
21
|
self.config = config
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
public func setDeviceId(_ deviceId: String) {
|
|
25
|
+
self.deviceId = deviceId
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
public func download(url: URL, destination: @escaping DownloadRequest.Destination, callback: ((Progress) -> Void)?) async throws -> AFDownloadResponse<Data> {
|
|
24
29
|
var request = URLRequest(url: url)
|
|
25
30
|
request.httpMethod = HTTPMethod.get.rawValue
|
|
26
31
|
request.timeoutInterval = Double(config.httpTimeout) / 1000.0
|
|
32
|
+
if let deviceId = deviceId, !deviceId.isEmpty {
|
|
33
|
+
request.setValue(deviceId, forHTTPHeaderField: "X-Capawesome-Device-Id")
|
|
34
|
+
}
|
|
27
35
|
return try await withCheckedThrowingContinuation { continuation in
|
|
28
36
|
AF.download(request, to: destination).downloadProgress { progress in
|
|
29
37
|
if let callback = callback {
|
|
@@ -39,6 +47,9 @@ public class LiveUpdateHttpClient: NSObject {
|
|
|
39
47
|
var request = URLRequest(url: url)
|
|
40
48
|
request.httpMethod = HTTPMethod.get.rawValue
|
|
41
49
|
request.timeoutInterval = Double(config.httpTimeout) / 1000.0
|
|
50
|
+
if let deviceId = deviceId, !deviceId.isEmpty {
|
|
51
|
+
request.setValue(deviceId, forHTTPHeaderField: "X-Capawesome-Device-Id")
|
|
52
|
+
}
|
|
42
53
|
return try await withCheckedThrowingContinuation { continuation in
|
|
43
54
|
AF.request(request).validate().responseDecodable(of: type) { response in
|
|
44
55
|
continuation.resume(returning: response)
|
|
@@ -8,7 +8,7 @@ import Capacitor
|
|
|
8
8
|
@objc(LiveUpdatePlugin)
|
|
9
9
|
public class LiveUpdatePlugin: CAPPlugin, CAPBridgedPlugin {
|
|
10
10
|
public static let tag = "LiveUpdate"
|
|
11
|
-
public static let version = "8.
|
|
11
|
+
public static let version = "8.2.0"
|
|
12
12
|
public static let userDefaultsPrefix = "CapawesomeLiveUpdate" // DO NOT CHANGE
|
|
13
13
|
|
|
14
14
|
public let identifier = "LiveUpdatePlugin"
|
|
@@ -17,6 +17,7 @@ public class LiveUpdatePlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
17
17
|
CAPPluginMethod(name: "clearBlockedBundles", returnType: CAPPluginReturnPromise),
|
|
18
18
|
CAPPluginMethod(name: "deleteBundle", returnType: CAPPluginReturnPromise),
|
|
19
19
|
CAPPluginMethod(name: "downloadBundle", returnType: CAPPluginReturnPromise),
|
|
20
|
+
CAPPluginMethod(name: "fetchChannels", returnType: CAPPluginReturnPromise),
|
|
20
21
|
CAPPluginMethod(name: "fetchLatestBundle", returnType: CAPPluginReturnPromise),
|
|
21
22
|
CAPPluginMethod(name: "getBlockedBundles", returnType: CAPPluginReturnPromise),
|
|
22
23
|
CAPPluginMethod(name: "getBundles", returnType: CAPPluginReturnPromise),
|
|
@@ -111,6 +112,25 @@ public class LiveUpdatePlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
@objc func fetchChannels(_ call: CAPPluginCall) {
|
|
116
|
+
Task {
|
|
117
|
+
do {
|
|
118
|
+
guard let appId = config?.appId, !appId.isEmpty else {
|
|
119
|
+
call.reject(CustomError.appIdMissing.localizedDescription)
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let options = FetchChannelsOptions(call)
|
|
124
|
+
let result = try await implementation?.fetchChannels(options)
|
|
125
|
+
if let result = result?.toJSObject() as? JSObject {
|
|
126
|
+
self.resolveCall(call, result)
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
rejectCall(call, error)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
114
134
|
@objc func fetchLatestBundle(_ call: CAPPluginCall) {
|
|
115
135
|
Task {
|
|
116
136
|
do {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capawesome/capacitor-live-update",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.2.1",
|
|
4
4
|
"description": "Capacitor plugin to update your app remotely in real-time.",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -71,7 +71,6 @@
|
|
|
71
71
|
"@capacitor/docgen": "0.3.1",
|
|
72
72
|
"@capacitor/ios": "8.0.0",
|
|
73
73
|
"@ionic/eslint-config": "0.4.0",
|
|
74
|
-
"@ionic/swiftlint-config": "2.0.0",
|
|
75
74
|
"eslint": "8.57.0",
|
|
76
75
|
"prettier": "3.4.2",
|
|
77
76
|
"prettier-plugin-java": "2.6.7",
|
|
@@ -83,7 +82,6 @@
|
|
|
83
82
|
"peerDependencies": {
|
|
84
83
|
"@capacitor/core": ">=8.0.0"
|
|
85
84
|
},
|
|
86
|
-
"swiftlint": "@ionic/swiftlint-config",
|
|
87
85
|
"eslintConfig": {
|
|
88
86
|
"extends": "@ionic/eslint-config/recommended"
|
|
89
87
|
},
|