@capgo/capacitor-updater 8.45.10 → 8.46.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.
- package/Package.swift +1 -1
- package/README.md +114 -30
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +703 -60
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +85 -16
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +27 -3
- package/dist/docs.json +213 -5
- package/dist/esm/definitions.d.ts +128 -19
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +2 -1
- package/dist/esm/web.js +4 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +4 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/AppHealthTracker.swift +82 -0
- package/ios/Sources/CapacitorUpdaterPlugin/BundleInfo.swift +2 -2
- package/ios/Sources/CapacitorUpdaterPlugin/BundleStatus.swift +78 -2
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +353 -100
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +681 -300
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +32 -0
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +20 -3
- package/ios/Sources/CapacitorUpdaterPlugin/WebViewStatsReporter.swift +276 -0
- package/package.json +12 -2
|
@@ -1088,7 +1088,16 @@ public class CapgoUpdater {
|
|
|
1088
1088
|
this.sendStats("set", bundle.getVersionName(), previousBundleName);
|
|
1089
1089
|
}
|
|
1090
1090
|
|
|
1091
|
+
@Deprecated
|
|
1091
1092
|
public void autoReset() {
|
|
1093
|
+
this.autoReset(this.versionCode == null ? "" : this.versionCode);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
public void autoReset(final String currentNativeBuildVersion) {
|
|
1097
|
+
this.autoReset(currentNativeBuildVersion, true);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
public void autoReset(final String currentNativeBuildVersion, final boolean resetWhenNativeVersionChanged) {
|
|
1092
1101
|
final BundleInfo currentBundle = this.getCurrentBundle();
|
|
1093
1102
|
if (!currentBundle.isBuiltin() && !this.bundleExists(currentBundle.getId())) {
|
|
1094
1103
|
logger.info("Folder at bundle path does not exist. Triggering reset.");
|
|
@@ -1099,7 +1108,36 @@ public class CapgoUpdater {
|
|
|
1099
1108
|
if (shouldResetForForeignBundle(bundlePath, currentBundle.isBuiltin(), this.hasStoredBundleInfo(currentBundle.getId()))) {
|
|
1100
1109
|
logger.info("Current bundle id is not one of the bundle ids stored by this plugin. Triggering reset.");
|
|
1101
1110
|
this.reset();
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
final String previousNativeBuildVersion = this.getStoredNativeBuildVersion();
|
|
1114
|
+
if (
|
|
1115
|
+
resetWhenNativeVersionChanged &&
|
|
1116
|
+
!previousNativeBuildVersion.isEmpty() &&
|
|
1117
|
+
currentNativeBuildVersion != null &&
|
|
1118
|
+
!currentNativeBuildVersion.isEmpty() &&
|
|
1119
|
+
!Objects.equals(previousNativeBuildVersion, currentNativeBuildVersion)
|
|
1120
|
+
) {
|
|
1121
|
+
logger.info(
|
|
1122
|
+
"Stored native build version " +
|
|
1123
|
+
previousNativeBuildVersion +
|
|
1124
|
+
" does not match current native build version " +
|
|
1125
|
+
currentNativeBuildVersion +
|
|
1126
|
+
". Triggering reset."
|
|
1127
|
+
);
|
|
1128
|
+
this.reset();
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
private String getStoredNativeBuildVersion() {
|
|
1133
|
+
if (this.prefs == null) {
|
|
1134
|
+
return "";
|
|
1135
|
+
}
|
|
1136
|
+
String previousNativeBuildVersion = this.prefs.getString("LatestNativeBuildVersion", "");
|
|
1137
|
+
if (previousNativeBuildVersion == null || previousNativeBuildVersion.isEmpty()) {
|
|
1138
|
+
previousNativeBuildVersion = this.prefs.getString("LatestVersionNative", "");
|
|
1102
1139
|
}
|
|
1140
|
+
return previousNativeBuildVersion == null ? "" : previousNativeBuildVersion;
|
|
1103
1141
|
}
|
|
1104
1142
|
|
|
1105
1143
|
public void reset() {
|
|
@@ -1229,6 +1267,7 @@ public class CapgoUpdater {
|
|
|
1229
1267
|
Map<String, Object> retError = new HashMap<>();
|
|
1230
1268
|
retError.put("message", "Request failed: " + e.getMessage());
|
|
1231
1269
|
retError.put("error", "network_error");
|
|
1270
|
+
retError.put("kind", "failed");
|
|
1232
1271
|
callback.callback(retError);
|
|
1233
1272
|
}
|
|
1234
1273
|
|
|
@@ -1236,11 +1275,46 @@ public class CapgoUpdater {
|
|
|
1236
1275
|
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
|
1237
1276
|
try (ResponseBody responseBody = response.body()) {
|
|
1238
1277
|
final int statusCode = response.code();
|
|
1278
|
+
final String responseData = responseBody != null ? responseBody.string() : "";
|
|
1279
|
+
JSONObject jsonResponse = null;
|
|
1280
|
+
if (!responseData.isEmpty()) {
|
|
1281
|
+
try {
|
|
1282
|
+
jsonResponse = new JSONObject(responseData);
|
|
1283
|
+
} catch (JSONException ignored) {
|
|
1284
|
+
// Non-JSON responses are handled as response or parse errors below.
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
if (jsonResponse != null && (jsonResponse.has("error") || jsonResponse.has("kind"))) {
|
|
1289
|
+
if (statusCode == 429) {
|
|
1290
|
+
checkAndHandleRateLimitResponse(response);
|
|
1291
|
+
}
|
|
1292
|
+
Map<String, Object> retError = new HashMap<>();
|
|
1293
|
+
if (jsonResponse.has("error") && !jsonResponse.isNull("error")) {
|
|
1294
|
+
retError.put("error", jsonResponse.getString("error"));
|
|
1295
|
+
}
|
|
1296
|
+
if (jsonResponse.has("kind") && !jsonResponse.isNull("kind")) {
|
|
1297
|
+
retError.put("kind", jsonResponse.getString("kind"));
|
|
1298
|
+
}
|
|
1299
|
+
if (jsonResponse.has("message") && !jsonResponse.isNull("message")) {
|
|
1300
|
+
retError.put("message", jsonResponse.getString("message"));
|
|
1301
|
+
} else {
|
|
1302
|
+
retError.put("message", "server did not provide a message");
|
|
1303
|
+
}
|
|
1304
|
+
if (jsonResponse.has("version") && !jsonResponse.isNull("version")) {
|
|
1305
|
+
retError.put("version", jsonResponse.getString("version"));
|
|
1306
|
+
}
|
|
1307
|
+
retError.put("statusCode", statusCode);
|
|
1308
|
+
callback.callback(retError);
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1239
1312
|
// Check for 429 rate limit
|
|
1240
1313
|
if (checkAndHandleRateLimitResponse(response)) {
|
|
1241
1314
|
Map<String, Object> retError = new HashMap<>();
|
|
1242
1315
|
retError.put("message", "Rate limit exceeded");
|
|
1243
1316
|
retError.put("error", "rate_limit_exceeded");
|
|
1317
|
+
retError.put("kind", "failed");
|
|
1244
1318
|
retError.put("statusCode", statusCode);
|
|
1245
1319
|
callback.callback(retError);
|
|
1246
1320
|
return;
|
|
@@ -1250,27 +1324,14 @@ public class CapgoUpdater {
|
|
|
1250
1324
|
Map<String, Object> retError = new HashMap<>();
|
|
1251
1325
|
retError.put("message", "Server error: " + response.code());
|
|
1252
1326
|
retError.put("error", "response_error");
|
|
1327
|
+
retError.put("kind", "failed");
|
|
1253
1328
|
retError.put("statusCode", statusCode);
|
|
1254
1329
|
callback.callback(retError);
|
|
1255
1330
|
return;
|
|
1256
1331
|
}
|
|
1257
1332
|
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
JSONObject jsonResponse = new JSONObject(responseData);
|
|
1261
|
-
|
|
1262
|
-
// Check for server-side errors first
|
|
1263
|
-
if (jsonResponse.has("error")) {
|
|
1264
|
-
Map<String, Object> retError = new HashMap<>();
|
|
1265
|
-
retError.put("error", jsonResponse.getString("error"));
|
|
1266
|
-
if (jsonResponse.has("message")) {
|
|
1267
|
-
retError.put("message", jsonResponse.getString("message"));
|
|
1268
|
-
} else {
|
|
1269
|
-
retError.put("message", "server did not provide a message");
|
|
1270
|
-
}
|
|
1271
|
-
retError.put("statusCode", statusCode);
|
|
1272
|
-
callback.callback(retError);
|
|
1273
|
-
return;
|
|
1333
|
+
if (jsonResponse == null) {
|
|
1334
|
+
throw new JSONException("Response is not a JSON object");
|
|
1274
1335
|
}
|
|
1275
1336
|
|
|
1276
1337
|
Map<String, Object> ret = new HashMap<>();
|
|
@@ -1292,6 +1353,7 @@ public class CapgoUpdater {
|
|
|
1292
1353
|
Map<String, Object> retError = new HashMap<>();
|
|
1293
1354
|
retError.put("message", "JSON parse error: " + e.getMessage());
|
|
1294
1355
|
retError.put("error", "parse_error");
|
|
1356
|
+
retError.put("kind", "failed");
|
|
1295
1357
|
callback.callback(retError);
|
|
1296
1358
|
}
|
|
1297
1359
|
}
|
|
@@ -1683,6 +1745,10 @@ public class CapgoUpdater {
|
|
|
1683
1745
|
}
|
|
1684
1746
|
|
|
1685
1747
|
public void sendStats(final String action, final String versionName, final String oldVersionName) {
|
|
1748
|
+
this.sendStats(action, versionName, oldVersionName, null);
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
public void sendStats(final String action, final String versionName, final String oldVersionName, final Map<String, String> metadata) {
|
|
1686
1752
|
// Check if rate limit was exceeded
|
|
1687
1753
|
if (rateLimitExceeded) {
|
|
1688
1754
|
logger.debug("Skipping sendStats due to rate limit (429). Stats will resume after app restart.");
|
|
@@ -1701,6 +1767,9 @@ public class CapgoUpdater {
|
|
|
1701
1767
|
json.put("old_version_name", oldVersionName);
|
|
1702
1768
|
json.put("action", action);
|
|
1703
1769
|
json.put("timestamp", System.currentTimeMillis());
|
|
1770
|
+
if (metadata != null && !metadata.isEmpty()) {
|
|
1771
|
+
json.put("metadata", new JSONObject(metadata));
|
|
1772
|
+
}
|
|
1704
1773
|
} catch (JSONException e) {
|
|
1705
1774
|
logger.error("Error preparing stats");
|
|
1706
1775
|
logger.debug("JSONException: " + e.getMessage());
|
|
@@ -448,12 +448,36 @@ public class ShakeMenu implements ShakeDetector.Listener {
|
|
|
448
448
|
}
|
|
449
449
|
|
|
450
450
|
String latestError = getString(latestRes, "error");
|
|
451
|
+
String latestKind = getString(latestRes, "kind");
|
|
452
|
+
String latestMessage = getString(latestRes, "message");
|
|
453
|
+
|
|
454
|
+
String detail = latestMessage != null && !latestMessage.isEmpty()
|
|
455
|
+
? latestMessage
|
|
456
|
+
: latestError != null && !latestError.isEmpty()
|
|
457
|
+
? latestError
|
|
458
|
+
: latestKind != null && !latestKind.isEmpty()
|
|
459
|
+
? latestKind
|
|
460
|
+
: "server did not provide a message";
|
|
451
461
|
|
|
452
462
|
// Handle update errors first (before "no new version" check)
|
|
453
|
-
if (
|
|
463
|
+
if (
|
|
464
|
+
"failed".equals(latestKind) ||
|
|
465
|
+
(latestError != null &&
|
|
466
|
+
!latestError.isEmpty() &&
|
|
467
|
+
!"up_to_date".equals(latestKind) &&
|
|
468
|
+
!"blocked".equals(latestKind))
|
|
469
|
+
) {
|
|
470
|
+
activity.runOnUiThread(() -> {
|
|
471
|
+
progressDialog.dismiss();
|
|
472
|
+
showError("Channel set to " + channelName + ". Update check failed: " + detail);
|
|
473
|
+
});
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if ("blocked".equals(latestKind)) {
|
|
454
478
|
activity.runOnUiThread(() -> {
|
|
455
479
|
progressDialog.dismiss();
|
|
456
|
-
showError("Channel set to " + channelName + ". Update check
|
|
480
|
+
showError("Channel set to " + channelName + ". Update check blocked: " + detail);
|
|
457
481
|
});
|
|
458
482
|
return;
|
|
459
483
|
}
|
|
@@ -461,7 +485,7 @@ public class ShakeMenu implements ShakeDetector.Listener {
|
|
|
461
485
|
String latestUrl = getString(latestRes, "url");
|
|
462
486
|
|
|
463
487
|
// Check if there's an actual update available
|
|
464
|
-
if ("
|
|
488
|
+
if ("up_to_date".equals(latestKind) || latestUrl == null || latestUrl.isEmpty()) {
|
|
465
489
|
activity.runOnUiThread(() -> {
|
|
466
490
|
progressDialog.dismiss();
|
|
467
491
|
showSuccess("Channel set to " + channelName + ". Already on latest version.");
|
package/dist/docs.json
CHANGED
|
@@ -470,6 +470,23 @@
|
|
|
470
470
|
"complexTypes": [],
|
|
471
471
|
"slug": "canceldelay"
|
|
472
472
|
},
|
|
473
|
+
{
|
|
474
|
+
"name": "triggerUpdateCheck",
|
|
475
|
+
"signature": "() => Promise<TriggerUpdateCheckResult>",
|
|
476
|
+
"parameters": [],
|
|
477
|
+
"returns": "Promise<TriggerUpdateCheckResult>",
|
|
478
|
+
"tags": [
|
|
479
|
+
{
|
|
480
|
+
"name": "returns",
|
|
481
|
+
"text": "Whether a native update check was queued."
|
|
482
|
+
}
|
|
483
|
+
],
|
|
484
|
+
"docs": "Trigger the native auto-update check/download pipeline immediately.\n\nThis starts the same background update flow used when the app moves to the\nforeground with auto-update enabled. It is useful for native integrations\nsuch as a silent push notification asking the app to check for a Capgo\nbundle without reimplementing the update protocol in JavaScript.\n\nThe promise resolves after the native background work has been queued, not\nafter the update has been downloaded or installed. Listen to updater events\nsuch as `updateAvailable`, `downloadComplete`, `downloadFailed`, and\n`noNeedUpdate` for the final result.\n\nNative support is available on iOS and Android. On Web, this method returns\na result with `status: 'unavailable'`. Native platforms also return\n`unavailable` when the native auto-update system is disabled.",
|
|
485
|
+
"complexTypes": [
|
|
486
|
+
"TriggerUpdateCheckResult"
|
|
487
|
+
],
|
|
488
|
+
"slug": "triggerupdatecheck"
|
|
489
|
+
},
|
|
473
490
|
{
|
|
474
491
|
"name": "getLatest",
|
|
475
492
|
"signature": "(options?: GetLatestOptions | undefined) => Promise<LatestVersion>",
|
|
@@ -492,14 +509,14 @@
|
|
|
492
509
|
},
|
|
493
510
|
{
|
|
494
511
|
"name": "throws",
|
|
495
|
-
"text": "{Error}
|
|
512
|
+
"text": "{Error} Throws for failed update checks or transport/request failures."
|
|
496
513
|
},
|
|
497
514
|
{
|
|
498
515
|
"name": "since",
|
|
499
516
|
"text": "4.0.0"
|
|
500
517
|
}
|
|
501
518
|
],
|
|
502
|
-
"docs": "Check the update server for the latest available bundle version.\n\nThis queries your configured update URL (or Capgo backend) to see if a newer bundle\nis available for download. It does NOT download the bundle automatically.\n\nThe response includes:\n- `version`: The latest available version identifier\n- `url`: Download URL for the bundle (if available)\n- `breaking`: Whether this update is marked as incompatible (requires native app update)\n- `message`: Optional message from the server\n- `manifest`: File list for delta updates (if using multi-file downloads)\n\nAfter receiving the latest version info, you can:\n1. Compare it with your current version\n2. Download it using {@link download}\n3. Apply it using {@link next} or {@link set}\n\n**Important:
|
|
519
|
+
"docs": "Check the update server for the latest available bundle version.\n\nThis queries your configured update URL (or Capgo backend) to see if a newer bundle\nis available for download. It does NOT download the bundle automatically.\n\nThe response includes:\n- `version`: The latest available version identifier\n- `url`: Download URL for the bundle (if available)\n- `breaking`: Whether this update is marked as incompatible (requires native app update)\n- `message`: Optional message from the server\n- `manifest`: File list for delta updates (if using multi-file downloads)\n\nAfter receiving the latest version info, you can:\n1. Compare it with your current version\n2. Download it using {@link download}\n3. Apply it using {@link next} or {@link set}\n\n**Important: Handling \"no new version available\"**\n\nWhen the device's current version matches the latest version on the server (i.e., the device is already\nup-to-date), the server returns a 200 response with `error: \"no_new_version_available\"` and\n`message: \"No new version available\"`. This is a normal, expected condition and resolves with\n`kind: \"up_to_date\"` when the backend provides that classification.\n\nYou should check `kind` and `error` before attempting to download:\n\n```typescript\nconst latest = await CapacitorUpdater.getLatest();\nif (latest.kind === 'up_to_date') {\n console.log('Already up to date');\n} else if (latest.kind === 'blocked') {\n console.log('Update is blocked:', latest.error);\n} else if (latest.url) {\n // New version is available, proceed with download\n}\n```\n\nIn this scenario, the server:\n- Logs the request with a \"No new version available\" message\n- Sends a \"noNew\" stat action to track that the device checked for updates but was already current (done on the backend)",
|
|
503
520
|
"complexTypes": [
|
|
504
521
|
"LatestVersion",
|
|
505
522
|
"GetLatestOptions"
|
|
@@ -765,7 +782,7 @@
|
|
|
765
782
|
"text": "1.0.0"
|
|
766
783
|
}
|
|
767
784
|
],
|
|
768
|
-
"docs": "Remove all event listeners registered for this plugin.\n\nThis unregisters all listeners added via {@link addListener} for all event types:\n- `download`\n- `noNeedUpdate`\n- `updateAvailable`\n- `downloadComplete`\n- `downloadFailed`\n- `breakingAvailable` / `majorAvailable`\n- `updateFailed`\n- `appReloaded`\n- `appReady`\n\nUse this during cleanup (e.g., when unmounting components or closing screens)\nto prevent memory leaks from lingering event listeners.",
|
|
785
|
+
"docs": "Remove all event listeners registered for this plugin.\n\nThis unregisters all listeners added via {@link addListener} for all event types:\n- `download`\n- `noNeedUpdate`\n- `updateCheckResult`\n- `updateAvailable`\n- `downloadComplete`\n- `downloadFailed`\n- `breakingAvailable` / `majorAvailable`\n- `updateFailed`\n- `appReloaded`\n- `appReady`\n\nUse this during cleanup (e.g., when unmounting components or closing screens)\nto prevent memory leaks from lingering event listeners.",
|
|
769
786
|
"complexTypes": [],
|
|
770
787
|
"slug": "removealllisteners"
|
|
771
788
|
},
|
|
@@ -827,6 +844,35 @@
|
|
|
827
844
|
],
|
|
828
845
|
"slug": "addlistenernoneedupdate-"
|
|
829
846
|
},
|
|
847
|
+
{
|
|
848
|
+
"name": "addListener",
|
|
849
|
+
"signature": "(eventName: 'updateCheckResult', listenerFunc: (state: UpdateCheckResultEvent) => void) => Promise<PluginListenerHandle>",
|
|
850
|
+
"parameters": [
|
|
851
|
+
{
|
|
852
|
+
"name": "eventName",
|
|
853
|
+
"docs": "",
|
|
854
|
+
"type": "'updateCheckResult'"
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
"name": "listenerFunc",
|
|
858
|
+
"docs": "",
|
|
859
|
+
"type": "(state: UpdateCheckResultEvent) => void"
|
|
860
|
+
}
|
|
861
|
+
],
|
|
862
|
+
"returns": "Promise<PluginListenerHandle>",
|
|
863
|
+
"tags": [
|
|
864
|
+
{
|
|
865
|
+
"name": "since",
|
|
866
|
+
"text": "8.45.11"
|
|
867
|
+
}
|
|
868
|
+
],
|
|
869
|
+
"docs": "Listen for update check results before the updater decides whether to download.\nThe backend can classify the UpdateCheckResultEvent payload as `up_to_date`, `blocked`, or `failed`.\n\nThis event is emitted alongside legacy events. For `up_to_date` and `blocked`, it is emitted before\n`noNeedUpdate` and does not emit `downloadFailed`. For `failed`, it is emitted before the legacy\n`downloadFailed` event and keeps the existing failure stats behavior.",
|
|
870
|
+
"complexTypes": [
|
|
871
|
+
"PluginListenerHandle",
|
|
872
|
+
"UpdateCheckResultEvent"
|
|
873
|
+
],
|
|
874
|
+
"slug": "addlistenerupdatecheckresult-"
|
|
875
|
+
},
|
|
830
876
|
{
|
|
831
877
|
"name": "addListener",
|
|
832
878
|
"signature": "(eventName: 'updateAvailable', listenerFunc: (state: UpdateAvailableEvent) => void) => Promise<PluginListenerHandle>",
|
|
@@ -1973,6 +2019,38 @@
|
|
|
1973
2019
|
}
|
|
1974
2020
|
]
|
|
1975
2021
|
},
|
|
2022
|
+
{
|
|
2023
|
+
"name": "TriggerUpdateCheckResult",
|
|
2024
|
+
"slug": "triggerupdatecheckresult",
|
|
2025
|
+
"docs": "Result returned after requesting an immediate native auto-update check.",
|
|
2026
|
+
"tags": [
|
|
2027
|
+
{
|
|
2028
|
+
"text": "status - Native trigger state: `queued` when a check was queued,\n`already_running` when the native update pipeline is already active, or\n`unavailable` on Web or when native auto-update is disabled.",
|
|
2029
|
+
"name": "property"
|
|
2030
|
+
},
|
|
2031
|
+
{
|
|
2032
|
+
"text": "queued - Whether a new native update check was queued. This is\n`true` only when `status` is `queued`; otherwise it is `false`.",
|
|
2033
|
+
"name": "property"
|
|
2034
|
+
}
|
|
2035
|
+
],
|
|
2036
|
+
"methods": [],
|
|
2037
|
+
"properties": [
|
|
2038
|
+
{
|
|
2039
|
+
"name": "status",
|
|
2040
|
+
"tags": [],
|
|
2041
|
+
"docs": "Native trigger state: `queued` when a check was queued, `already_running`\nwhen the native update pipeline is already active, or `unavailable` on Web\nor when native auto-update is disabled.",
|
|
2042
|
+
"complexTypes": [],
|
|
2043
|
+
"type": "'queued' | 'already_running' | 'unavailable'"
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
"name": "queued",
|
|
2047
|
+
"tags": [],
|
|
2048
|
+
"docs": "Whether a new native update check was queued. This is `true` only when\n`status` is `queued`; otherwise it is `false`.",
|
|
2049
|
+
"complexTypes": [],
|
|
2050
|
+
"type": "boolean"
|
|
2051
|
+
}
|
|
2052
|
+
]
|
|
2053
|
+
},
|
|
1976
2054
|
{
|
|
1977
2055
|
"name": "LatestVersion",
|
|
1978
2056
|
"slug": "latestversion",
|
|
@@ -2045,10 +2123,36 @@
|
|
|
2045
2123
|
{
|
|
2046
2124
|
"name": "error",
|
|
2047
2125
|
"tags": [],
|
|
2048
|
-
"docs": "Error code from the server, if any
|
|
2126
|
+
"docs": "Error code from the server, if any. Use `kind` for classification instead of parsing this value.",
|
|
2049
2127
|
"complexTypes": [],
|
|
2050
2128
|
"type": "string | undefined"
|
|
2051
2129
|
},
|
|
2130
|
+
{
|
|
2131
|
+
"name": "kind",
|
|
2132
|
+
"tags": [
|
|
2133
|
+
{
|
|
2134
|
+
"text": "8.45.11",
|
|
2135
|
+
"name": "since"
|
|
2136
|
+
}
|
|
2137
|
+
],
|
|
2138
|
+
"docs": "Classification for this response, provided by the backend.",
|
|
2139
|
+
"complexTypes": [
|
|
2140
|
+
"UpdateResponseKind"
|
|
2141
|
+
],
|
|
2142
|
+
"type": "UpdateResponseKind"
|
|
2143
|
+
},
|
|
2144
|
+
{
|
|
2145
|
+
"name": "statusCode",
|
|
2146
|
+
"tags": [
|
|
2147
|
+
{
|
|
2148
|
+
"text": "8.45.11",
|
|
2149
|
+
"name": "since"
|
|
2150
|
+
}
|
|
2151
|
+
],
|
|
2152
|
+
"docs": "HTTP status code returned by the update server for classified update-check responses.",
|
|
2153
|
+
"complexTypes": [],
|
|
2154
|
+
"type": "number | undefined"
|
|
2155
|
+
},
|
|
2052
2156
|
{
|
|
2053
2157
|
"name": "old",
|
|
2054
2158
|
"tags": [],
|
|
@@ -2480,6 +2584,91 @@
|
|
|
2480
2584
|
}
|
|
2481
2585
|
]
|
|
2482
2586
|
},
|
|
2587
|
+
{
|
|
2588
|
+
"name": "UpdateCheckResultEvent",
|
|
2589
|
+
"slug": "updatecheckresultevent",
|
|
2590
|
+
"docs": "",
|
|
2591
|
+
"tags": [],
|
|
2592
|
+
"methods": [],
|
|
2593
|
+
"properties": [
|
|
2594
|
+
{
|
|
2595
|
+
"name": "kind",
|
|
2596
|
+
"tags": [
|
|
2597
|
+
{
|
|
2598
|
+
"text": "8.45.11",
|
|
2599
|
+
"name": "since"
|
|
2600
|
+
}
|
|
2601
|
+
],
|
|
2602
|
+
"docs": "Classification for the update check result, provided by the backend.",
|
|
2603
|
+
"complexTypes": [
|
|
2604
|
+
"UpdateResponseKind"
|
|
2605
|
+
],
|
|
2606
|
+
"type": "UpdateResponseKind"
|
|
2607
|
+
},
|
|
2608
|
+
{
|
|
2609
|
+
"name": "error",
|
|
2610
|
+
"tags": [
|
|
2611
|
+
{
|
|
2612
|
+
"text": "8.45.11",
|
|
2613
|
+
"name": "since"
|
|
2614
|
+
}
|
|
2615
|
+
],
|
|
2616
|
+
"docs": "Backend error code, when provided.",
|
|
2617
|
+
"complexTypes": [],
|
|
2618
|
+
"type": "string | undefined"
|
|
2619
|
+
},
|
|
2620
|
+
{
|
|
2621
|
+
"name": "message",
|
|
2622
|
+
"tags": [
|
|
2623
|
+
{
|
|
2624
|
+
"text": "8.45.11",
|
|
2625
|
+
"name": "since"
|
|
2626
|
+
}
|
|
2627
|
+
],
|
|
2628
|
+
"docs": "Backend message, when provided.",
|
|
2629
|
+
"complexTypes": [],
|
|
2630
|
+
"type": "string | undefined"
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
"name": "statusCode",
|
|
2634
|
+
"tags": [
|
|
2635
|
+
{
|
|
2636
|
+
"text": "8.45.11",
|
|
2637
|
+
"name": "since"
|
|
2638
|
+
}
|
|
2639
|
+
],
|
|
2640
|
+
"docs": "HTTP status code returned by the update endpoint.",
|
|
2641
|
+
"complexTypes": [],
|
|
2642
|
+
"type": "number | undefined"
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
"name": "version",
|
|
2646
|
+
"tags": [
|
|
2647
|
+
{
|
|
2648
|
+
"text": "8.45.11",
|
|
2649
|
+
"name": "since"
|
|
2650
|
+
}
|
|
2651
|
+
],
|
|
2652
|
+
"docs": "Version referenced by the update check result.",
|
|
2653
|
+
"complexTypes": [],
|
|
2654
|
+
"type": "string | undefined"
|
|
2655
|
+
},
|
|
2656
|
+
{
|
|
2657
|
+
"name": "bundle",
|
|
2658
|
+
"tags": [
|
|
2659
|
+
{
|
|
2660
|
+
"text": "8.45.11",
|
|
2661
|
+
"name": "since"
|
|
2662
|
+
}
|
|
2663
|
+
],
|
|
2664
|
+
"docs": "Current bundle on the device.",
|
|
2665
|
+
"complexTypes": [
|
|
2666
|
+
"BundleInfo"
|
|
2667
|
+
],
|
|
2668
|
+
"type": "BundleInfo"
|
|
2669
|
+
}
|
|
2670
|
+
]
|
|
2671
|
+
},
|
|
2483
2672
|
{
|
|
2484
2673
|
"name": "UpdateAvailableEvent",
|
|
2485
2674
|
"slug": "updateavailableevent",
|
|
@@ -3293,6 +3482,25 @@
|
|
|
3293
3482
|
}
|
|
3294
3483
|
]
|
|
3295
3484
|
},
|
|
3485
|
+
{
|
|
3486
|
+
"name": "UpdateResponseKind",
|
|
3487
|
+
"slug": "updateresponsekind",
|
|
3488
|
+
"docs": "Classification for update-check responses that do not provide a downloadable bundle.\nThe update backend provides this field directly. Missing or unknown values are treated as\nfailed by native clients.",
|
|
3489
|
+
"types": [
|
|
3490
|
+
{
|
|
3491
|
+
"text": "'up_to_date'",
|
|
3492
|
+
"complexTypes": []
|
|
3493
|
+
},
|
|
3494
|
+
{
|
|
3495
|
+
"text": "'blocked'",
|
|
3496
|
+
"complexTypes": []
|
|
3497
|
+
},
|
|
3498
|
+
{
|
|
3499
|
+
"text": "'failed'",
|
|
3500
|
+
"complexTypes": []
|
|
3501
|
+
}
|
|
3502
|
+
]
|
|
3503
|
+
},
|
|
3296
3504
|
{
|
|
3297
3505
|
"name": "BreakingAvailableEvent",
|
|
3298
3506
|
"slug": "breakingavailableevent",
|
|
@@ -3452,7 +3660,7 @@
|
|
|
3452
3660
|
"name": "example"
|
|
3453
3661
|
}
|
|
3454
3662
|
],
|
|
3455
|
-
"docs": "Configure the URL / endpoint to which update statistics are sent.\n\nOnly available for Android and iOS. Set to \"\" to disable stats reporting.",
|
|
3663
|
+
"docs": "Configure the URL / endpoint to which update statistics are sent.\n\nOnly available for Android and iOS. Set to \"\" to disable stats reporting.\nNative stats include update lifecycle events, app health signals such as crashes,\nAndroid ANRs, low-memory exits, iOS memory warnings, and WebView health signals\nsuch as JavaScript errors, unhandled promise rejections, resource load failures,\nWebView renderer exits, and unclean WebView restarts when available.",
|
|
3456
3664
|
"complexTypes": [],
|
|
3457
3665
|
"type": "string | undefined"
|
|
3458
3666
|
},
|