@capgo/capacitor-updater 7.42.9 → 7.45.10

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.
@@ -330,6 +330,20 @@ declare module '@capacitor/cli' {
330
330
  * @since 7.5.0
331
331
  */
332
332
  shakeMenu?: boolean;
333
+ /**
334
+ * Enable the shake gesture to show a channel selector menu for switching between update channels.
335
+ * When enabled AND `shakeMenu` is true, the shake gesture shows a channel selector
336
+ * instead of the default debug menu (Go Home/Reload/Close).
337
+ *
338
+ * After selecting a channel, the app automatically checks for updates and downloads if available.
339
+ * Only works if channels have `allow_self_set` enabled on the backend.
340
+ *
341
+ * Only available for Android and iOS.
342
+ *
343
+ * @default false
344
+ * @since 8.43.0
345
+ */
346
+ allowShakeChannelSelector?: boolean;
333
347
  };
334
348
  }
335
349
  }
@@ -554,7 +568,10 @@ export interface CapacitorUpdaterPlugin {
554
568
  * - Testing rollback functionality
555
569
  * - Providing users a "reset to factory" option
556
570
  *
557
- * @param options {@link ResetOptions} to control reset behavior. If `toLastSuccessful` is `false` (or omitted), resets to builtin. If `true`, resets to last successful bundle.
571
+ * @param options {@link ResetOptions} to control reset behavior.
572
+ * If `toLastSuccessful` is `false` (or omitted), resets to builtin.
573
+ * If `true`, resets to last successful bundle.
574
+ * If `usePendingBundle` is `true`, applies the pending bundle set via {@link next} and clears it.
558
575
  * @returns {Promise<void>} A promise that may never resolve because the app will be reloaded.
559
576
  * @throws {Error} If the reset operation fails.
560
577
  */
@@ -678,27 +695,23 @@ export interface CapacitorUpdaterPlugin {
678
695
  * 2. Download it using {@link download}
679
696
  * 3. Apply it using {@link next} or {@link set}
680
697
  *
681
- * **Important: Error handling for "no new version available"**
698
+ * **Important: Handling "no new version available"**
682
699
  *
683
700
  * When the device's current version matches the latest version on the server (i.e., the device is already
684
701
  * up-to-date), the server returns a 200 response with `error: "no_new_version_available"` and
685
- * `message: "No new version available"`. **This causes `getLatest()` to throw an error**, even though
686
- * this is a normal, expected condition.
702
+ * `message: "No new version available"`. This is a normal, expected condition and resolves with
703
+ * `kind: "up_to_date"` when the backend provides that classification.
687
704
  *
688
- * You should catch this specific error to handle it gracefully:
705
+ * You should check `kind` and `error` before attempting to download:
689
706
  *
690
707
  * ```typescript
691
- * try {
692
- * const latest = await CapacitorUpdater.getLatest();
708
+ * const latest = await CapacitorUpdater.getLatest();
709
+ * if (latest.kind === 'up_to_date') {
710
+ * console.log('Already up to date');
711
+ * } else if (latest.kind === 'blocked') {
712
+ * console.log('Update is blocked:', latest.error);
713
+ * } else if (latest.url) {
693
714
  * // New version is available, proceed with download
694
- * } catch (error) {
695
- * if (error.message === 'No new version available') {
696
- * // Device is already on the latest version - this is normal
697
- * console.log('Already up to date');
698
- * } else {
699
- * // Actual error occurred
700
- * console.error('Failed to check for updates:', error);
701
- * }
702
715
  * }
703
716
  * ```
704
717
  *
@@ -708,7 +721,7 @@ export interface CapacitorUpdaterPlugin {
708
721
  *
709
722
  * @param options Optional {@link GetLatestOptions} to specify which channel to check.
710
723
  * @returns {Promise<LatestVersion>} Information about the latest available bundle version.
711
- * @throws {Error} Always throws when no new version is available (`error: "no_new_version_available"`), or when the request fails.
724
+ * @throws {Error} Throws for failed update checks or transport/request failures.
712
725
  * @since 4.0.0
713
726
  */
714
727
  getLatest(options?: GetLatestOptions): Promise<LatestVersion>;
@@ -924,6 +937,7 @@ export interface CapacitorUpdaterPlugin {
924
937
  * This unregisters all listeners added via {@link addListener} for all event types:
925
938
  * - `download`
926
939
  * - `noNeedUpdate`
940
+ * - `updateCheckResult`
927
941
  * - `updateAvailable`
928
942
  * - `downloadComplete`
929
943
  * - `downloadFailed`
@@ -952,6 +966,17 @@ export interface CapacitorUpdaterPlugin {
952
966
  * @since 4.0.0
953
967
  */
954
968
  addListener(eventName: 'noNeedUpdate', listenerFunc: (state: NoNeedEvent) => void): Promise<PluginListenerHandle>;
969
+ /**
970
+ * Listen for update check results before the updater decides whether to download.
971
+ * The backend can classify the UpdateCheckResultEvent payload as `up_to_date`, `blocked`, or `failed`.
972
+ *
973
+ * This event is emitted alongside legacy events. For `up_to_date` and `blocked`, it is emitted before
974
+ * `noNeedUpdate` and does not emit `downloadFailed`. For `failed`, it is emitted before the legacy
975
+ * `downloadFailed` event and keeps the existing failure stats behavior.
976
+ *
977
+ * @since 8.45.11
978
+ */
979
+ addListener(eventName: 'updateCheckResult', listenerFunc: (state: UpdateCheckResultEvent) => void): Promise<PluginListenerHandle>;
955
980
  /**
956
981
  * Listen for available update event, useful when you want to force check every time the app is launched
957
982
  *
@@ -984,6 +1009,20 @@ export interface CapacitorUpdaterPlugin {
984
1009
  * @since 2.3.0
985
1010
  */
986
1011
  addListener(eventName: 'updateFailed', listenerFunc: (state: UpdateFailedEvent) => void): Promise<PluginListenerHandle>;
1012
+ /**
1013
+ * Listen for set event in the App, let you know when a bundle has been applied successfully.
1014
+ * This event is retained natively until JavaScript consumes it, so if the app reloads before your
1015
+ * listener is attached, the last pending `set` event is delivered once the listener subscribes.
1016
+ *
1017
+ * @since 8.43.12
1018
+ */
1019
+ addListener(eventName: 'set', listenerFunc: (state: SetEvent) => void): Promise<PluginListenerHandle>;
1020
+ /**
1021
+ * Listen for set next event in the App, let you know when a bundle is queued as the next bundle to install.
1022
+ *
1023
+ * @since 6.14.0
1024
+ */
1025
+ addListener(eventName: 'setNext', listenerFunc: (state: SetNextEvent) => void): Promise<PluginListenerHandle>;
987
1026
  /**
988
1027
  * Listen for download fail event in the App, let you know when a bundle download has failed
989
1028
  *
@@ -997,7 +1036,9 @@ export interface CapacitorUpdaterPlugin {
997
1036
  */
998
1037
  addListener(eventName: 'appReloaded', listenerFunc: () => void): Promise<PluginListenerHandle>;
999
1038
  /**
1000
- * Listen for app ready event in the App, let you know when app is ready to use, this event is retain till consumed.
1039
+ * Listen for app ready event in the App, let you know when app is ready to use.
1040
+ * This event is retained natively until JavaScript consumes it, so it can still be delivered after
1041
+ * a reload even if the listener is attached later in app startup.
1001
1042
  *
1002
1043
  * @since 5.1.0
1003
1044
  */
@@ -1143,6 +1184,35 @@ export interface CapacitorUpdaterPlugin {
1143
1184
  * @since 7.5.0
1144
1185
  */
1145
1186
  isShakeMenuEnabled(): Promise<ShakeMenuEnabled>;
1187
+ /**
1188
+ * Enable or disable the shake channel selector at runtime.
1189
+ *
1190
+ * When enabled AND shakeMenu is true, shaking the device shows a channel
1191
+ * selector instead of the debug menu. This allows users to switch between
1192
+ * update channels by shaking their device.
1193
+ *
1194
+ * After selecting a channel, the app automatically checks for updates
1195
+ * and downloads if available.
1196
+ *
1197
+ * Can also be configured via {@link PluginsConfig.CapacitorUpdater.allowShakeChannelSelector}.
1198
+ *
1199
+ * @param options {@link SetShakeChannelSelectorOptions} with `enabled: true` to enable or `enabled: false` to disable.
1200
+ * @returns {Promise<void>} Resolves when the setting is applied.
1201
+ * @throws {Error} If the operation fails.
1202
+ * @since 8.43.0
1203
+ */
1204
+ setShakeChannelSelector(options: SetShakeChannelSelectorOptions): Promise<void>;
1205
+ /**
1206
+ * Check if the shake channel selector is currently enabled.
1207
+ *
1208
+ * Returns the current state of the shake channel selector feature that can be toggled via
1209
+ * {@link setShakeChannelSelector} or configured via {@link PluginsConfig.CapacitorUpdater.allowShakeChannelSelector}.
1210
+ *
1211
+ * @returns {Promise<ShakeChannelSelectorEnabled>} Object with `enabled: true` or `enabled: false`.
1212
+ * @throws {Error} If the operation fails.
1213
+ * @since 8.43.0
1214
+ */
1215
+ isShakeChannelSelectorEnabled(): Promise<ShakeChannelSelectorEnabled>;
1146
1216
  /**
1147
1217
  * Get the currently configured App ID used for update server communication.
1148
1218
  *
@@ -1314,6 +1384,14 @@ export interface CapacitorUpdaterPlugin {
1314
1384
  */
1315
1385
  export type BundleStatus = 'success' | 'error' | 'pending' | 'downloading';
1316
1386
  export type DelayUntilNext = 'background' | 'kill' | 'nativeVersion' | 'date';
1387
+ /**
1388
+ * Classification for update-check responses that do not provide a downloadable bundle.
1389
+ * The update backend provides this field directly. Missing or unknown values are treated as
1390
+ * failed by native clients.
1391
+ *
1392
+ * @since 8.45.11
1393
+ */
1394
+ export type UpdateResponseKind = 'up_to_date' | 'blocked' | 'failed';
1317
1395
  export interface NoNeedEvent {
1318
1396
  /**
1319
1397
  * Current status of download, between 0 and 100.
@@ -1322,6 +1400,44 @@ export interface NoNeedEvent {
1322
1400
  */
1323
1401
  bundle: BundleInfo;
1324
1402
  }
1403
+ export interface UpdateCheckResultEvent {
1404
+ /**
1405
+ * Classification for the update check result, provided by the backend.
1406
+ *
1407
+ * @since 8.45.11
1408
+ */
1409
+ kind: UpdateResponseKind;
1410
+ /**
1411
+ * Backend error code, when provided.
1412
+ *
1413
+ * @since 8.45.11
1414
+ */
1415
+ error?: string;
1416
+ /**
1417
+ * Backend message, when provided.
1418
+ *
1419
+ * @since 8.45.11
1420
+ */
1421
+ message?: string;
1422
+ /**
1423
+ * HTTP status code returned by the update endpoint.
1424
+ *
1425
+ * @since 8.45.11
1426
+ */
1427
+ statusCode?: number;
1428
+ /**
1429
+ * Version referenced by the update check result.
1430
+ *
1431
+ * @since 8.45.11
1432
+ */
1433
+ version?: string;
1434
+ /**
1435
+ * Current bundle on the device.
1436
+ *
1437
+ * @since 8.45.11
1438
+ */
1439
+ bundle: BundleInfo;
1440
+ }
1325
1441
  export interface UpdateAvailableEvent {
1326
1442
  /**
1327
1443
  * Current status of download, between 0 and 100.
@@ -1434,9 +1550,27 @@ export interface UpdateFailedEvent {
1434
1550
  */
1435
1551
  bundle: BundleInfo;
1436
1552
  }
1553
+ export interface SetEvent {
1554
+ /**
1555
+ * Emit when a bundle has been applied successfully.
1556
+ * This event uses native `retainUntilConsumed` behavior.
1557
+ *
1558
+ * @since 8.43.12
1559
+ */
1560
+ bundle: BundleInfo;
1561
+ }
1562
+ export interface SetNextEvent {
1563
+ /**
1564
+ * Emit when a bundle is queued as the next bundle to install.
1565
+ *
1566
+ * @since 6.14.0
1567
+ */
1568
+ bundle: BundleInfo;
1569
+ }
1437
1570
  export interface AppReadyEvent {
1438
1571
  /**
1439
1572
  * Emitted when the app is ready to use.
1573
+ * This event uses native `retainUntilConsumed` behavior.
1440
1574
  *
1441
1575
  * @since 5.2.0
1442
1576
  */
@@ -1485,12 +1619,21 @@ export interface LatestVersion {
1485
1619
  message?: string;
1486
1620
  sessionKey?: string;
1487
1621
  /**
1488
- * Error code from the server, if any.
1489
- * Common values:
1490
- * - `"no_new_version_available"`: Device is already on the latest version (not a failure)
1491
- * - Other error codes indicate actual failures in the update process
1622
+ * Error code from the server, if any. Use `kind` for classification instead of parsing this value.
1492
1623
  */
1493
1624
  error?: string;
1625
+ /**
1626
+ * Classification for this response, provided by the backend.
1627
+ *
1628
+ * @since 8.45.11
1629
+ */
1630
+ kind?: UpdateResponseKind;
1631
+ /**
1632
+ * HTTP status code returned by the update server for classified update-check responses.
1633
+ *
1634
+ * @since 8.45.11
1635
+ */
1636
+ statusCode?: number;
1494
1637
  /**
1495
1638
  * The previous/current version name (provided for reference).
1496
1639
  */
@@ -1603,7 +1746,19 @@ export interface BundleListResult {
1603
1746
  bundles: BundleInfo[];
1604
1747
  }
1605
1748
  export interface ResetOptions {
1606
- toLastSuccessful: boolean;
1749
+ /**
1750
+ * Reset to the last successfully loaded bundle instead of the builtin one.
1751
+ * @default false
1752
+ */
1753
+ toLastSuccessful?: boolean;
1754
+ /**
1755
+ * Apply the pending bundle set via {@link next} while resetting.
1756
+ *
1757
+ * When `true`, the plugin will switch to the pending bundle immediately and clear the pending flag.
1758
+ * If no pending bundle exists, the reset will fail.
1759
+ * @default false
1760
+ */
1761
+ usePendingBundle?: boolean;
1607
1762
  }
1608
1763
  export interface ListOptions {
1609
1764
  /**
@@ -1641,6 +1796,12 @@ export interface SetShakeMenuOptions {
1641
1796
  export interface ShakeMenuEnabled {
1642
1797
  enabled: boolean;
1643
1798
  }
1799
+ export interface SetShakeChannelSelectorOptions {
1800
+ enabled: boolean;
1801
+ }
1802
+ export interface ShakeChannelSelectorEnabled {
1803
+ enabled: boolean;
1804
+ }
1644
1805
  export interface GetAppIdRes {
1645
1806
  appId: string;
1646
1807
  }