@otakit/capacitor-updater 1.2.0 → 2.0.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 +23 -18
- package/android/src/main/java/com/updatekit/updater/{StatsClient.java → DeviceEventClient.java} +30 -19
- package/android/src/main/java/com/updatekit/updater/HostedManifestKeys.java +5 -6
- package/android/src/main/java/com/updatekit/updater/ManifestClient.java +33 -47
- package/android/src/main/java/com/updatekit/updater/ManifestVerifier.java +1 -75
- package/android/src/main/java/com/updatekit/updater/UpdaterPlugin.java +160 -99
- package/dist/esm/definitions.d.ts +9 -25
- package/dist/esm/definitions.d.ts.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +0 -4
- package/dist/esm/web.d.ts.map +1 -1
- package/dist/esm/web.js +0 -8
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +0 -10
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +0 -10
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/UpdaterPlugin/{StatsClient.swift → DeviceEventClient.swift} +21 -21
- package/ios/Sources/UpdaterPlugin/HostedManifestKeys.swift +5 -5
- package/ios/Sources/UpdaterPlugin/ManifestClient.swift +32 -52
- package/ios/Sources/UpdaterPlugin/ManifestVerifier.swift +2 -56
- package/ios/Sources/UpdaterPlugin/UpdaterPlugin.m +0 -2
- package/ios/Sources/UpdaterPlugin/UpdaterPlugin.swift +139 -99
- package/package.json +1 -1
|
@@ -23,8 +23,6 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
23
23
|
CAPPluginMethod(name: "download", returnType: CAPPluginReturnPromise),
|
|
24
24
|
CAPPluginMethod(name: "apply", returnType: CAPPluginReturnPromise),
|
|
25
25
|
CAPPluginMethod(name: "debugGetState", returnType: CAPPluginReturnPromise),
|
|
26
|
-
CAPPluginMethod(name: "debugCheck", returnType: CAPPluginReturnPromise),
|
|
27
|
-
CAPPluginMethod(name: "debugDownload", returnType: CAPPluginReturnPromise),
|
|
28
26
|
CAPPluginMethod(name: "notifyAppReady", returnType: CAPPluginReturnPromise),
|
|
29
27
|
CAPPluginMethod(name: "debugReset", returnType: CAPPluginReturnPromise),
|
|
30
28
|
CAPPluginMethod(name: "debugListBundles", returnType: CAPPluginReturnPromise),
|
|
@@ -40,7 +38,8 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
40
38
|
private var appReadyTimeoutMs = 10_000
|
|
41
39
|
private var allowInsecureUrls = false
|
|
42
40
|
private var updateMode: UpdateMode = .nextLaunch
|
|
43
|
-
private var
|
|
41
|
+
private var ingestUrl = UpdaterPlugin.defaultIngestURL
|
|
42
|
+
private var cdnUrl = UpdaterPlugin.defaultCdnURL
|
|
44
43
|
private var appId: String?
|
|
45
44
|
private var channel: String?
|
|
46
45
|
private var runtimeVersion: String?
|
|
@@ -50,15 +49,21 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
50
49
|
private let isCheckInProgress = NSLock()
|
|
51
50
|
private var checkInProgress = false
|
|
52
51
|
private var foregroundObserver: NSObjectProtocol?
|
|
53
|
-
private static let
|
|
54
|
-
private static let
|
|
52
|
+
private static let defaultIngestURL = "https://ingest.otakit.app/v1"
|
|
53
|
+
private static let defaultCdnURL = "https://cdn.otakit.app"
|
|
54
|
+
private static let ingestPathSuffix = "/v1"
|
|
55
55
|
private static let lastCheckTimestampKey = "otakit_last_check_timestamp"
|
|
56
56
|
|
|
57
57
|
public override func load() {
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
let envIngestUrl = ProcessInfo.processInfo.environment["OTAKIT_INGEST_URL"]
|
|
59
|
+
let envCdnUrl = ProcessInfo.processInfo.environment["OTAKIT_CDN_URL"]
|
|
60
|
+
ingestUrl = resolveIngestUrl(
|
|
61
|
+
configured: getConfig().getString("ingestUrl"),
|
|
62
|
+
env: envIngestUrl
|
|
63
|
+
)
|
|
64
|
+
cdnUrl = resolveCdnUrl(
|
|
65
|
+
configured: getConfig().getString("cdnUrl"),
|
|
66
|
+
env: envCdnUrl
|
|
62
67
|
)
|
|
63
68
|
appId = getConfig().getString("appId")
|
|
64
69
|
channel = trimToNil(getConfig().getString("channel"))
|
|
@@ -88,7 +93,7 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
88
93
|
manifestKeys = [(kid: "_invalid_", key: Data())]
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
if manifestKeys.isEmpty && HostedManifestKeys.
|
|
96
|
+
if manifestKeys.isEmpty && HostedManifestKeys.matchesManagedManifestURL(cdnUrl) {
|
|
92
97
|
manifestKeys = HostedManifestKeys.defaults
|
|
93
98
|
}
|
|
94
99
|
|
|
@@ -154,7 +159,11 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
154
159
|
return
|
|
155
160
|
}
|
|
156
161
|
|
|
157
|
-
if shouldThrottleCheck() { return }
|
|
162
|
+
if updateMode != .immediate && shouldThrottleCheck() { return }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if trigger == .launch && updateMode != .immediate && shouldThrottleCheck() {
|
|
166
|
+
return
|
|
158
167
|
}
|
|
159
168
|
|
|
160
169
|
// Acquire in-flight guard (submit-time)
|
|
@@ -166,7 +175,6 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
166
175
|
defer { releaseCheckInProgress() }
|
|
167
176
|
do {
|
|
168
177
|
let result = try await performCheckAndDownload(channel: nil, emitEvents: true)
|
|
169
|
-
recordCheckTimestamp()
|
|
170
178
|
if result != nil {
|
|
171
179
|
activateStagedBundleForReload()
|
|
172
180
|
reloadWebView()
|
|
@@ -184,7 +192,6 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
184
192
|
defer { releaseCheckInProgress() }
|
|
185
193
|
do {
|
|
186
194
|
let result = try await performCheckAndDownload(channel: nil, emitEvents: true)
|
|
187
|
-
recordCheckTimestamp()
|
|
188
195
|
if result != nil {
|
|
189
196
|
activateStagedBundleForReload()
|
|
190
197
|
reloadWebView()
|
|
@@ -282,27 +289,8 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
282
289
|
call.resolve(payload)
|
|
283
290
|
}
|
|
284
291
|
|
|
285
|
-
@objc func debugCheck(_ call: CAPPluginCall) {
|
|
286
|
-
let requestedChannel = call.getString("channel")
|
|
287
|
-
let targetChannel = resolveTargetChannel(requestedChannel)
|
|
288
|
-
Task {
|
|
289
|
-
do {
|
|
290
|
-
let latest = try await fetchLatest(channel: targetChannel)
|
|
291
|
-
if let latest {
|
|
292
|
-
let staged = findMatchingStagedBundle(latest: latest, targetChannel: targetChannel)
|
|
293
|
-
call.resolve(manifestToDictionary(latest, downloaded: staged != nil))
|
|
294
|
-
} else {
|
|
295
|
-
call.resolve()
|
|
296
|
-
}
|
|
297
|
-
} catch {
|
|
298
|
-
call.reject("debugCheck failed: \(error.localizedDescription)")
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
292
|
@objc func check(_ call: CAPPluginCall) {
|
|
304
|
-
|
|
305
|
-
if shouldThrottleCheck() || !claimCheckInProgress() {
|
|
293
|
+
if !claimCheckInProgress() {
|
|
306
294
|
if let stagedId = store.getStagedBundleId(),
|
|
307
295
|
let staged = store.getBundle(id: stagedId) {
|
|
308
296
|
var payload: [String: Any] = [
|
|
@@ -329,9 +317,11 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
329
317
|
defer { releaseCheckInProgress() }
|
|
330
318
|
do {
|
|
331
319
|
let latest = try await fetchLatest(channel: targetChannel)
|
|
332
|
-
// check() does NOT record timestamp — only download() and automatic paths do.
|
|
333
|
-
// This keeps check() -> download() working without the throttle blocking download().
|
|
334
320
|
if let latest {
|
|
321
|
+
if isCurrentBundleLatest(latest: latest, targetChannel: targetChannel) {
|
|
322
|
+
call.resolve()
|
|
323
|
+
return
|
|
324
|
+
}
|
|
335
325
|
let staged = findMatchingStagedBundle(latest: latest, targetChannel: targetChannel)
|
|
336
326
|
call.resolve(manifestToDictionary(latest, downloaded: staged != nil))
|
|
337
327
|
} else {
|
|
@@ -343,28 +333,8 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
343
333
|
}
|
|
344
334
|
}
|
|
345
335
|
|
|
346
|
-
@objc func debugDownload(_ call: CAPPluginCall) {
|
|
347
|
-
let requestedChannel = call.getString("channel")
|
|
348
|
-
Task {
|
|
349
|
-
do {
|
|
350
|
-
let bundle = try await performCheckAndDownload(
|
|
351
|
-
channel: requestedChannel,
|
|
352
|
-
emitEvents: true
|
|
353
|
-
)
|
|
354
|
-
if let bundle {
|
|
355
|
-
call.resolve(bundle.toDictionary())
|
|
356
|
-
} else {
|
|
357
|
-
call.resolve()
|
|
358
|
-
}
|
|
359
|
-
} catch {
|
|
360
|
-
call.reject("debugDownload failed: \(error.localizedDescription)")
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
336
|
@objc func download(_ call: CAPPluginCall) {
|
|
366
|
-
|
|
367
|
-
if shouldThrottleCheck() || !claimCheckInProgress() {
|
|
337
|
+
if !claimCheckInProgress() {
|
|
368
338
|
if let stagedId = store.getStagedBundleId(),
|
|
369
339
|
let staged = store.getBundle(id: stagedId) {
|
|
370
340
|
call.resolve(staged.toDictionary())
|
|
@@ -377,7 +347,6 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
377
347
|
defer { releaseCheckInProgress() }
|
|
378
348
|
do {
|
|
379
349
|
let bundle = try await performCheckAndDownload(channel: nil, emitEvents: true)
|
|
380
|
-
recordCheckTimestamp()
|
|
381
350
|
if let bundle {
|
|
382
351
|
call.resolve(bundle.toDictionary())
|
|
383
352
|
} else {
|
|
@@ -424,9 +393,10 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
424
393
|
notifyListeners("appReady", data: current.toDictionary())
|
|
425
394
|
}
|
|
426
395
|
|
|
427
|
-
|
|
396
|
+
sendDeviceEvent(
|
|
428
397
|
action: .applied,
|
|
429
398
|
bundleVersion: current.version,
|
|
399
|
+
runtimeVersion: current.runtimeVersion,
|
|
430
400
|
channel: current.channel,
|
|
431
401
|
releaseId: current.releaseId
|
|
432
402
|
)
|
|
@@ -504,15 +474,11 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
504
474
|
throw NSError(domain: "OtaKit", code: 1, userInfo: [NSLocalizedDescriptionKey: "Missing appId in plugin config"])
|
|
505
475
|
}
|
|
506
476
|
|
|
507
|
-
let current = store.getCurrentBundle()
|
|
508
477
|
return try await ManifestClient.fetchLatest(
|
|
509
|
-
|
|
478
|
+
cdnUrl: cdnUrl,
|
|
510
479
|
appId: appId,
|
|
511
480
|
channel: channel,
|
|
512
|
-
currentVersion: current.version,
|
|
513
|
-
currentReleaseId: current.releaseId,
|
|
514
481
|
runtimeVersion: runtimeVersion,
|
|
515
|
-
platform: "ios",
|
|
516
482
|
allowInsecureUrls: allowInsecureUrls,
|
|
517
483
|
manifestKeys: manifestKeys.map {
|
|
518
484
|
ManifestKey(kid: $0.kid, derData: $0.key)
|
|
@@ -542,6 +508,13 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
542
508
|
)
|
|
543
509
|
}
|
|
544
510
|
|
|
511
|
+
if isCurrentBundleLatest(latest: manifest, targetChannel: targetChannel) {
|
|
512
|
+
if emitEvents {
|
|
513
|
+
notifyListeners("noUpdateAvailable", data: [:])
|
|
514
|
+
}
|
|
515
|
+
return nil
|
|
516
|
+
}
|
|
517
|
+
|
|
545
518
|
let staged = findMatchingStagedBundle(latest: manifest, targetChannel: targetChannel)
|
|
546
519
|
if emitEvents {
|
|
547
520
|
notifyListeners("updateAvailable", data: manifestToDictionary(manifest, downloaded: staged != nil))
|
|
@@ -620,12 +593,13 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
620
593
|
code: 1,
|
|
621
594
|
userInfo: [NSLocalizedDescriptionKey: "Insufficient disk space"]
|
|
622
595
|
)
|
|
623
|
-
|
|
596
|
+
sendDeviceEvent(
|
|
624
597
|
action: .downloadError,
|
|
625
598
|
bundleVersion: version,
|
|
599
|
+
runtimeVersion: runtimeVersion,
|
|
626
600
|
channel: channel,
|
|
627
601
|
releaseId: releaseId,
|
|
628
|
-
|
|
602
|
+
detail: "insufficient_disk_space"
|
|
629
603
|
)
|
|
630
604
|
throw error
|
|
631
605
|
}
|
|
@@ -686,9 +660,10 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
686
660
|
cleanupSupersededStagedBundle(previousStagedId: previousStagedId, replacementId: bundleId)
|
|
687
661
|
|
|
688
662
|
notifyListeners("downloadComplete", data: info.toDictionary())
|
|
689
|
-
|
|
663
|
+
sendDeviceEvent(
|
|
690
664
|
action: .downloaded,
|
|
691
665
|
bundleVersion: version,
|
|
666
|
+
runtimeVersion: runtimeVersion,
|
|
692
667
|
channel: channel,
|
|
693
668
|
releaseId: releaseId
|
|
694
669
|
)
|
|
@@ -698,12 +673,13 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
698
673
|
"version": version,
|
|
699
674
|
"error": error.localizedDescription,
|
|
700
675
|
])
|
|
701
|
-
|
|
676
|
+
sendDeviceEvent(
|
|
702
677
|
action: .downloadError,
|
|
703
678
|
bundleVersion: version,
|
|
679
|
+
runtimeVersion: runtimeVersion,
|
|
704
680
|
channel: channel,
|
|
705
681
|
releaseId: releaseId,
|
|
706
|
-
|
|
682
|
+
detail: error.localizedDescription
|
|
707
683
|
)
|
|
708
684
|
throw error
|
|
709
685
|
}
|
|
@@ -835,12 +811,13 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
835
811
|
store.setFailedBundle(failed)
|
|
836
812
|
store.setStagedBundleId(nil)
|
|
837
813
|
|
|
838
|
-
|
|
814
|
+
sendDeviceEvent(
|
|
839
815
|
action: .rollback,
|
|
840
816
|
bundleVersion: current.version,
|
|
817
|
+
runtimeVersion: current.runtimeVersion,
|
|
841
818
|
channel: current.channel,
|
|
842
819
|
releaseId: current.releaseId,
|
|
843
|
-
|
|
820
|
+
detail: reason
|
|
844
821
|
)
|
|
845
822
|
|
|
846
823
|
let fallback = store.getFallbackBundle()
|
|
@@ -933,12 +910,45 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
933
910
|
if let runtimeVersion = latest.runtimeVersion {
|
|
934
911
|
payload["runtimeVersion"] = runtimeVersion
|
|
935
912
|
}
|
|
936
|
-
|
|
937
|
-
payload["releaseId"] = releaseId
|
|
938
|
-
}
|
|
913
|
+
payload["releaseId"] = latest.releaseId
|
|
939
914
|
return payload
|
|
940
915
|
}
|
|
941
916
|
|
|
917
|
+
private func isCurrentBundleLatest(
|
|
918
|
+
latest: LatestManifest,
|
|
919
|
+
targetChannel: String?
|
|
920
|
+
) -> Bool {
|
|
921
|
+
doesBundleMatchLatest(store.getCurrentBundle(), latest: latest, targetChannel: targetChannel)
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
private func doesBundleMatchLatest(
|
|
925
|
+
_ bundle: BundleInfo,
|
|
926
|
+
latest: LatestManifest,
|
|
927
|
+
targetChannel: String?
|
|
928
|
+
) -> Bool {
|
|
929
|
+
if trimToNil(bundle.channel) != targetChannel {
|
|
930
|
+
return false
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
if trimToNil(bundle.runtimeVersion) != trimToNil(latest.runtimeVersion) {
|
|
934
|
+
return false
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if let bundleReleaseId = bundle.releaseId,
|
|
938
|
+
latest.releaseId == bundleReleaseId {
|
|
939
|
+
return true
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
if !latest.sha256.isEmpty,
|
|
943
|
+
let bundleSha = bundle.sha256,
|
|
944
|
+
!bundleSha.isEmpty,
|
|
945
|
+
latest.sha256 == bundleSha {
|
|
946
|
+
return true
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
return latest.version == bundle.version
|
|
950
|
+
}
|
|
951
|
+
|
|
942
952
|
private func findMatchingStagedBundle(
|
|
943
953
|
latest: LatestManifest,
|
|
944
954
|
targetChannel: String?
|
|
@@ -959,18 +969,7 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
959
969
|
return nil
|
|
960
970
|
}
|
|
961
971
|
|
|
962
|
-
|
|
963
|
-
let stagedReleaseId = staged.releaseId,
|
|
964
|
-
latestReleaseId == stagedReleaseId {
|
|
965
|
-
return staged
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
if latest.version == staged.version,
|
|
969
|
-
latest.sha256 == staged.sha256 {
|
|
970
|
-
return staged
|
|
971
|
-
}
|
|
972
|
-
|
|
973
|
-
return nil
|
|
972
|
+
return doesBundleMatchLatest(staged, latest: latest, targetChannel: targetChannel) ? staged : nil
|
|
974
973
|
}
|
|
975
974
|
|
|
976
975
|
private func pruneIncompatibleBundles() {
|
|
@@ -1025,26 +1024,41 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1025
1024
|
return "\(normalized)-\(suffix)"
|
|
1026
1025
|
}
|
|
1027
1026
|
|
|
1028
|
-
private func
|
|
1029
|
-
action:
|
|
1027
|
+
private func sendDeviceEvent(
|
|
1028
|
+
action: DeviceEventAction,
|
|
1030
1029
|
bundleVersion: String? = nil,
|
|
1030
|
+
runtimeVersion: String? = nil,
|
|
1031
1031
|
channel: String? = nil,
|
|
1032
1032
|
releaseId: String? = nil,
|
|
1033
|
-
|
|
1033
|
+
detail: String? = nil
|
|
1034
1034
|
) {
|
|
1035
1035
|
guard let appId else {
|
|
1036
1036
|
return
|
|
1037
1037
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1038
|
+
guard let bundleVersion = trimToNil(bundleVersion) else {
|
|
1039
|
+
print("[UpdateKit] Skipping device event without bundleVersion")
|
|
1040
|
+
return
|
|
1041
|
+
}
|
|
1042
|
+
guard let releaseId = trimToNil(releaseId) else {
|
|
1043
|
+
print("[UpdateKit] Skipping device event without releaseId")
|
|
1044
|
+
return
|
|
1045
|
+
}
|
|
1046
|
+
let nativeBuild = store.nativeBuild.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1047
|
+
guard !nativeBuild.isEmpty else {
|
|
1048
|
+
print("[UpdateKit] Skipping device event without nativeBuild")
|
|
1049
|
+
return
|
|
1050
|
+
}
|
|
1051
|
+
DeviceEventClient.send(
|
|
1052
|
+
ingestUrl: ingestUrl,
|
|
1040
1053
|
appId: appId,
|
|
1041
1054
|
platform: "ios",
|
|
1042
1055
|
action: action,
|
|
1043
1056
|
bundleVersion: bundleVersion,
|
|
1044
1057
|
channel: channel,
|
|
1058
|
+
runtimeVersion: trimToNil(runtimeVersion),
|
|
1045
1059
|
releaseId: releaseId,
|
|
1046
|
-
nativeBuild:
|
|
1047
|
-
|
|
1060
|
+
nativeBuild: nativeBuild,
|
|
1061
|
+
detail: detail
|
|
1048
1062
|
)
|
|
1049
1063
|
}
|
|
1050
1064
|
|
|
@@ -1063,21 +1077,41 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1063
1077
|
return trimmed.isEmpty ? nil : trimmed
|
|
1064
1078
|
}
|
|
1065
1079
|
|
|
1066
|
-
private func
|
|
1080
|
+
private func resolveIngestUrl(
|
|
1081
|
+
configured: String?,
|
|
1082
|
+
env: String?
|
|
1083
|
+
) -> String {
|
|
1084
|
+
let configuredValue = configured?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1085
|
+
if let configuredValue, !configuredValue.isEmpty {
|
|
1086
|
+
return normalizeIngestUrl(configuredValue)
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
let envValue = env?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1090
|
+
if let envValue, !envValue.isEmpty {
|
|
1091
|
+
return normalizeIngestUrl(envValue)
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
return UpdaterPlugin.defaultIngestURL
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
private func resolveCdnUrl(
|
|
1098
|
+
configured: String?,
|
|
1099
|
+
env: String?
|
|
1100
|
+
) -> String {
|
|
1067
1101
|
let configuredValue = configured?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1068
1102
|
if let configuredValue, !configuredValue.isEmpty {
|
|
1069
|
-
return
|
|
1103
|
+
return normalizeCdnUrl(configuredValue)
|
|
1070
1104
|
}
|
|
1071
1105
|
|
|
1072
1106
|
let envValue = env?.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1073
1107
|
if let envValue, !envValue.isEmpty {
|
|
1074
|
-
return
|
|
1108
|
+
return normalizeCdnUrl(envValue)
|
|
1075
1109
|
}
|
|
1076
1110
|
|
|
1077
|
-
return UpdaterPlugin.
|
|
1111
|
+
return UpdaterPlugin.defaultCdnURL
|
|
1078
1112
|
}
|
|
1079
1113
|
|
|
1080
|
-
private func
|
|
1114
|
+
private func normalizeIngestUrl(_ raw: String) -> String {
|
|
1081
1115
|
let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1082
1116
|
let withoutTrailingSlash = trimmed.replacingOccurrences(
|
|
1083
1117
|
of: "/+$",
|
|
@@ -1085,11 +1119,17 @@ public class UpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
1085
1119
|
options: .regularExpression
|
|
1086
1120
|
)
|
|
1087
1121
|
|
|
1088
|
-
if withoutTrailingSlash.lowercased().hasSuffix(UpdaterPlugin.
|
|
1122
|
+
if withoutTrailingSlash.lowercased().hasSuffix(UpdaterPlugin.ingestPathSuffix) {
|
|
1089
1123
|
return withoutTrailingSlash
|
|
1090
1124
|
}
|
|
1091
1125
|
|
|
1092
|
-
return withoutTrailingSlash + UpdaterPlugin.
|
|
1126
|
+
return withoutTrailingSlash + UpdaterPlugin.ingestPathSuffix
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
private func normalizeCdnUrl(_ raw: String) -> String {
|
|
1130
|
+
raw
|
|
1131
|
+
.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
1132
|
+
.replacingOccurrences(of: "/+$", with: "", options: .regularExpression)
|
|
1093
1133
|
}
|
|
1094
1134
|
|
|
1095
1135
|
private func getFreeDiskSpace() -> Int64 {
|