@capgo/capacitor-updater 7.43.3 → 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.
package/Package.swift CHANGED
@@ -11,7 +11,7 @@ let package = Package(
11
11
  ],
12
12
  dependencies: [
13
13
  .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
14
- .package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.11.1")),
14
+ .package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.11.2")),
15
15
  .package(url: "https://github.com/weichsel/ZIPFoundation.git", from: "0.9.20"),
16
16
  .package(url: "https://github.com/mrackwitz/Version.git", exact: "0.8.0"),
17
17
  .package(url: "https://github.com/attaswift/BigInt.git", from: "5.7.0")
@@ -30,7 +30,10 @@ let package = Package(
30
30
  path: "ios/Sources/CapacitorUpdaterPlugin"),
31
31
  .testTarget(
32
32
  name: "CapacitorUpdaterPluginTests",
33
- dependencies: ["CapacitorUpdaterPlugin"],
33
+ dependencies: [
34
+ "CapacitorUpdaterPlugin",
35
+ .product(name: "Version", package: "Version")
36
+ ],
34
37
  path: "ios/Tests/CapacitorUpdaterPluginTests")
35
38
  ],
36
39
  swiftLanguageVersions: [.v5]
package/README.md CHANGED
@@ -50,7 +50,7 @@ Perfect for fixing bugs immediately, A/B testing features, and maintaining contr
50
50
  - ⚔️ **Battle-Tested**: Used in more than 3000 projects.
51
51
  - 📊 View your deployment statistics
52
52
  - 🔋 Supports Android and iOS
53
- - ⚡️ Capacitor 6/7 support
53
+ - ⚡️ Capacitor 4/5/6/7/8 support
54
54
  - 🌐 **Open Source**: Licensed under the Mozilla Public License 2.0
55
55
  - 🌐 **Open Source Backend**: Self install [our backend](https://github.com/Cap-go/capgo) in your infra
56
56
 
@@ -96,11 +96,11 @@ Starting from v8, the plugin uses [ZIPFoundation](https://github.com/weichsel/ZI
96
96
  | v7.\*.\* | v7.\*.\* | ✅ |
97
97
  | v6.\*.\* | v6.\*.\* | ✅ |
98
98
  | v5.\*.\* | v5.\*.\* | ✅ |
99
- | v4.\*.\* | v4.\*.\* | ⚠️ Deprecated |
99
+ | v4.\*.\* | v4.\*.\* | |
100
100
  | v3.\*.\* | v3.\*.\* | ⚠️ Deprecated |
101
101
  | > 7 | v4.\*.\* | ⚠️ Deprecated, our CI got crazy and bumped too much version |
102
102
 
103
- > **Note:** Versions 5, 6, 7, and 8 all share the same features. The major version simply follows your Capacitor version. You can safely use any of these versions that matches your Capacitor installation.
103
+ > **Note:** Versions 4, 5, 6, 7, and 8 all share the same features. The major version simply follows your Capacitor version. You can safely use any of these versions that matches your Capacitor installation.
104
104
 
105
105
  ### iOS
106
106
 
@@ -158,6 +158,9 @@ npm install @capgo/capacitor-updater@lts-v6
158
158
 
159
159
  # For Capacitor 5
160
160
  npm install @capgo/capacitor-updater@lts-v5
161
+
162
+ # For Capacitor 4
163
+ npm install @capgo/capacitor-updater@lts-v4
161
164
  ```
162
165
 
163
166
  ## Auto-update setup
@@ -459,11 +462,14 @@ export default config;
459
462
  * [`removeAllListeners()`](#removealllisteners)
460
463
  * [`addListener('download', ...)`](#addlistenerdownload-)
461
464
  * [`addListener('noNeedUpdate', ...)`](#addlistenernoneedupdate-)
465
+ * [`addListener('updateCheckResult', ...)`](#addlistenerupdatecheckresult-)
462
466
  * [`addListener('updateAvailable', ...)`](#addlistenerupdateavailable-)
463
467
  * [`addListener('downloadComplete', ...)`](#addlistenerdownloadcomplete-)
464
468
  * [`addListener('breakingAvailable', ...)`](#addlistenerbreakingavailable-)
465
469
  * [`addListener('majorAvailable', ...)`](#addlistenermajoravailable-)
466
470
  * [`addListener('updateFailed', ...)`](#addlistenerupdatefailed-)
471
+ * [`addListener('set', ...)`](#addlistenerset-)
472
+ * [`addListener('setNext', ...)`](#addlistenersetnext-)
467
473
  * [`addListener('downloadFailed', ...)`](#addlistenerdownloadfailed-)
468
474
  * [`addListener('appReloaded', ...)`](#addlistenerappreloaded-)
469
475
  * [`addListener('appReady', ...)`](#addlistenerappready-)
@@ -924,27 +930,23 @@ After receiving the latest version info, you can:
924
930
  2. Download it using {@link download}
925
931
  3. Apply it using {@link next} or {@link set}
926
932
 
927
- **Important: Error handling for "no new version available"**
933
+ **Important: Handling "no new version available"**
928
934
 
929
935
  When the device's current version matches the latest version on the server (i.e., the device is already
930
936
  up-to-date), the server returns a 200 response with `error: "no_new_version_available"` and
931
- `message: "No new version available"`. **This causes `getLatest()` to throw an error**, even though
932
- this is a normal, expected condition.
937
+ `message: "No new version available"`. This is a normal, expected condition and resolves with
938
+ `kind: "up_to_date"` when the backend provides that classification.
933
939
 
934
- You should catch this specific error to handle it gracefully:
940
+ You should check `kind` and `error` before attempting to download:
935
941
 
936
942
  ```typescript
937
- try {
938
- const latest = await CapacitorUpdater.getLatest();
943
+ const latest = await CapacitorUpdater.getLatest();
944
+ if (latest.kind === 'up_to_date') {
945
+ console.log('Already up to date');
946
+ } else if (latest.kind === 'blocked') {
947
+ console.log('Update is blocked:', latest.error);
948
+ } else if (latest.url) {
939
949
  // New version is available, proceed with download
940
- } catch (error) {
941
- if (error.message === 'No new version available') {
942
- // Device is already on the latest version - this is normal
943
- console.log('Already up to date');
944
- } else {
945
- // Actual error occurred
946
- console.error('Failed to check for updates:', error);
947
- }
948
950
  }
949
951
  ```
950
952
 
@@ -1246,6 +1248,7 @@ Remove all event listeners registered for this plugin.
1246
1248
  This unregisters all listeners added via {@link addListener} for all event types:
1247
1249
  - `download`
1248
1250
  - `noNeedUpdate`
1251
+ - `updateCheckResult`
1249
1252
  - `updateAvailable`
1250
1253
  - `downloadComplete`
1251
1254
  - `downloadFailed`
@@ -1303,6 +1306,31 @@ Listen for no need to update event, useful when you want force check every time
1303
1306
  --------------------
1304
1307
 
1305
1308
 
1309
+ #### addListener('updateCheckResult', ...)
1310
+
1311
+ ```typescript
1312
+ addListener(eventName: 'updateCheckResult', listenerFunc: (state: UpdateCheckResultEvent) => void) => Promise<PluginListenerHandle>
1313
+ ```
1314
+
1315
+ Listen for update check results before the updater decides whether to download.
1316
+ The backend can classify the <a href="#updatecheckresultevent">UpdateCheckResultEvent</a> payload as `up_to_date`, `blocked`, or `failed`.
1317
+
1318
+ This event is emitted alongside legacy events. For `up_to_date` and `blocked`, it is emitted before
1319
+ `noNeedUpdate` and does not emit `downloadFailed`. For `failed`, it is emitted before the legacy
1320
+ `downloadFailed` event and keeps the existing failure stats behavior.
1321
+
1322
+ | Param | Type |
1323
+ | ------------------ | --------------------------------------------------------------------------------------------- |
1324
+ | **`eventName`** | <code>'updateCheckResult'</code> |
1325
+ | **`listenerFunc`** | <code>(state: <a href="#updatecheckresultevent">UpdateCheckResultEvent</a>) =&gt; void</code> |
1326
+
1327
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1328
+
1329
+ **Since:** 8.45.11
1330
+
1331
+ --------------------
1332
+
1333
+
1306
1334
  #### addListener('updateAvailable', ...)
1307
1335
 
1308
1336
  ```typescript
@@ -1404,6 +1432,48 @@ Listen for update fail event in the App, let you know when update has fail to in
1404
1432
  --------------------
1405
1433
 
1406
1434
 
1435
+ #### addListener('set', ...)
1436
+
1437
+ ```typescript
1438
+ addListener(eventName: 'set', listenerFunc: (state: SetEvent) => void) => Promise<PluginListenerHandle>
1439
+ ```
1440
+
1441
+ Listen for set event in the App, let you know when a bundle has been applied successfully.
1442
+ This event is retained natively until JavaScript consumes it, so if the app reloads before your
1443
+ listener is attached, the last pending `set` event is delivered once the listener subscribes.
1444
+
1445
+ | Param | Type |
1446
+ | ------------------ | ----------------------------------------------------------------- |
1447
+ | **`eventName`** | <code>'set'</code> |
1448
+ | **`listenerFunc`** | <code>(state: <a href="#setevent">SetEvent</a>) =&gt; void</code> |
1449
+
1450
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1451
+
1452
+ **Since:** 8.43.12
1453
+
1454
+ --------------------
1455
+
1456
+
1457
+ #### addListener('setNext', ...)
1458
+
1459
+ ```typescript
1460
+ addListener(eventName: 'setNext', listenerFunc: (state: SetNextEvent) => void) => Promise<PluginListenerHandle>
1461
+ ```
1462
+
1463
+ Listen for set next event in the App, let you know when a bundle is queued as the next bundle to install.
1464
+
1465
+ | Param | Type |
1466
+ | ------------------ | ------------------------------------------------------------------------- |
1467
+ | **`eventName`** | <code>'setNext'</code> |
1468
+ | **`listenerFunc`** | <code>(state: <a href="#setnextevent">SetNextEvent</a>) =&gt; void</code> |
1469
+
1470
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
1471
+
1472
+ **Since:** 6.14.0
1473
+
1474
+ --------------------
1475
+
1476
+
1407
1477
  #### addListener('downloadFailed', ...)
1408
1478
 
1409
1479
  ```typescript
@@ -1450,7 +1520,9 @@ Listen for reload event in the App, let you know when reload has happened
1450
1520
  addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise<PluginListenerHandle>
1451
1521
  ```
1452
1522
 
1453
- Listen for app ready event in the App, let you know when app is ready to use, this event is retain till consumed.
1523
+ Listen for app ready event in the App, let you know when app is ready to use.
1524
+ This event is retained natively until JavaScript consumes it, so it can still be delivered after
1525
+ a reload even if the listener is attached later in app startup.
1454
1526
 
1455
1527
  | Param | Type |
1456
1528
  | ------------------ | --------------------------------------------------------------------------- |
@@ -2014,9 +2086,10 @@ If you don't use backend, you need to provide the URL and version of the bundle.
2014
2086
 
2015
2087
  ##### ResetOptions
2016
2088
 
2017
- | Prop | Type |
2018
- | ---------------------- | -------------------- |
2019
- | **`toLastSuccessful`** | <code>boolean</code> |
2089
+ | Prop | Type | Description | Default |
2090
+ | ---------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ |
2091
+ | **`toLastSuccessful`** | <code>boolean</code> | Reset to the last successfully loaded bundle instead of the builtin one. | <code>false</code> |
2092
+ | **`usePendingBundle`** | <code>boolean</code> | Apply the pending bundle set via {@link next} while resetting. When `true`, the plugin will switch to the pending bundle immediately and clear the pending flag. If no pending bundle exists, the reset will fail. | <code>false</code> |
2020
2093
 
2021
2094
 
2022
2095
  ##### CurrentBundleResult
@@ -2044,20 +2117,22 @@ If you don't use backend, you need to provide the URL and version of the bundle.
2044
2117
 
2045
2118
  ##### LatestVersion
2046
2119
 
2047
- | Prop | Type | Description | Since |
2048
- | ---------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
2049
- | **`version`** | <code>string</code> | Result of getLatest method | 4.0.0 |
2050
- | **`checksum`** | <code>string</code> | | 6 |
2051
- | **`breaking`** | <code>boolean</code> | Indicates whether the update was flagged as breaking by the backend. | 7.22.0 |
2052
- | **`major`** | <code>boolean</code> | | |
2053
- | **`message`** | <code>string</code> | Optional message from the server. When no new version is available, this will be "No new version available". | |
2054
- | **`sessionKey`** | <code>string</code> | | |
2055
- | **`error`** | <code>string</code> | Error code from the server, if any. Common values: - `"no_new_version_available"`: Device is already on the latest version (not a failure) - Other error codes indicate actual failures in the update process | |
2056
- | **`old`** | <code>string</code> | The previous/current version name (provided for reference). | |
2057
- | **`url`** | <code>string</code> | Download URL for the bundle (when a new version is available). | |
2058
- | **`manifest`** | <code>ManifestEntry[]</code> | File list for delta updates (when using multi-file downloads). | 6.1 |
2059
- | **`link`** | <code>string</code> | Optional link associated with this bundle version (e.g., release notes URL, changelog, GitHub release). | 7.35.0 |
2060
- | **`comment`** | <code>string</code> | Optional comment or description for this bundle version. | 7.35.0 |
2120
+ | Prop | Type | Description | Since |
2121
+ | ---------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------- |
2122
+ | **`version`** | <code>string</code> | Result of getLatest method | 4.0.0 |
2123
+ | **`checksum`** | <code>string</code> | | 6 |
2124
+ | **`breaking`** | <code>boolean</code> | Indicates whether the update was flagged as breaking by the backend. | 7.22.0 |
2125
+ | **`major`** | <code>boolean</code> | | |
2126
+ | **`message`** | <code>string</code> | Optional message from the server. When no new version is available, this will be "No new version available". | |
2127
+ | **`sessionKey`** | <code>string</code> | | |
2128
+ | **`error`** | <code>string</code> | Error code from the server, if any. Use `kind` for classification instead of parsing this value. | |
2129
+ | **`kind`** | <code><a href="#updateresponsekind">UpdateResponseKind</a></code> | Classification for this response, provided by the backend. | 8.45.11 |
2130
+ | **`statusCode`** | <code>number</code> | HTTP status code returned by the update server for classified update-check responses. | 8.45.11 |
2131
+ | **`old`** | <code>string</code> | The previous/current version name (provided for reference). | |
2132
+ | **`url`** | <code>string</code> | Download URL for the bundle (when a new version is available). | |
2133
+ | **`manifest`** | <code>ManifestEntry[]</code> | File list for delta updates (when using multi-file downloads). | 6.1 |
2134
+ | **`link`** | <code>string</code> | Optional link associated with this bundle version (e.g., release notes URL, changelog, GitHub release). | 7.35.0 |
2135
+ | **`comment`** | <code>string</code> | Optional comment or description for this bundle version. | 7.35.0 |
2061
2136
 
2062
2137
 
2063
2138
  ##### GetLatestOptions
@@ -2176,6 +2251,18 @@ If you don't use backend, you need to provide the URL and version of the bundle.
2176
2251
  | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Current status of download, between 0 and 100. | 4.0.0 |
2177
2252
 
2178
2253
 
2254
+ ##### UpdateCheckResultEvent
2255
+
2256
+ | Prop | Type | Description | Since |
2257
+ | ---------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------- | ------- |
2258
+ | **`kind`** | <code><a href="#updateresponsekind">UpdateResponseKind</a></code> | Classification for the update check result, provided by the backend. | 8.45.11 |
2259
+ | **`error`** | <code>string</code> | Backend error code, when provided. | 8.45.11 |
2260
+ | **`message`** | <code>string</code> | Backend message, when provided. | 8.45.11 |
2261
+ | **`statusCode`** | <code>number</code> | HTTP status code returned by the update endpoint. | 8.45.11 |
2262
+ | **`version`** | <code>string</code> | Version referenced by the update check result. | 8.45.11 |
2263
+ | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Current bundle on the device. | 8.45.11 |
2264
+
2265
+
2179
2266
  ##### UpdateAvailableEvent
2180
2267
 
2181
2268
  | Prop | Type | Description | Since |
@@ -2204,6 +2291,20 @@ If you don't use backend, you need to provide the URL and version of the bundle.
2204
2291
  | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emit when a update failed to install. | 4.0.0 |
2205
2292
 
2206
2293
 
2294
+ ##### SetEvent
2295
+
2296
+ | Prop | Type | Description | Since |
2297
+ | ------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------- |
2298
+ | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emit when a bundle has been applied successfully. This event uses native `retainUntilConsumed` behavior. | 8.43.12 |
2299
+
2300
+
2301
+ ##### SetNextEvent
2302
+
2303
+ | Prop | Type | Description | Since |
2304
+ | ------------ | ------------------------------------------------- | ----------------------------------------------------------- | ------ |
2305
+ | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emit when a bundle is queued as the next bundle to install. | 6.14.0 |
2306
+
2307
+
2207
2308
  ##### DownloadFailedEvent
2208
2309
 
2209
2310
  | Prop | Type | Description | Since |
@@ -2213,10 +2314,10 @@ If you don't use backend, you need to provide the URL and version of the bundle.
2213
2314
 
2214
2315
  ##### AppReadyEvent
2215
2316
 
2216
- | Prop | Type | Description | Since |
2217
- | ------------ | ------------------------------------------------- | ------------------------------------- | ----- |
2218
- | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emitted when the app is ready to use. | 5.2.0 |
2219
- | **`status`** | <code>string</code> | | |
2317
+ | Prop | Type | Description | Since |
2318
+ | ------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----- |
2319
+ | **`bundle`** | <code><a href="#bundleinfo">BundleInfo</a></code> | Emitted when the app is ready to use. This event uses native `retainUntilConsumed` behavior. | 5.2.0 |
2320
+ | **`status`** | <code>string</code> | | |
2220
2321
 
2221
2322
 
2222
2323
  ##### ChannelPrivateEvent
@@ -2353,6 +2454,15 @@ error: The bundle has failed to download.
2353
2454
  <code>'background' | 'kill' | 'nativeVersion' | 'date'</code>
2354
2455
 
2355
2456
 
2457
+ ##### UpdateResponseKind
2458
+
2459
+ Classification for update-check responses that do not provide a downloadable bundle.
2460
+ The update backend provides this field directly. Missing or unknown values are treated as
2461
+ failed by native clients.
2462
+
2463
+ <code>'up_to_date' | 'blocked' | 'failed'</code>
2464
+
2465
+
2356
2466
  ##### BreakingAvailableEvent
2357
2467
 
2358
2468
  Payload emitted by {@link CapacitorUpdaterPlugin.addListener} with `breakingAvailable`.
@@ -30,7 +30,7 @@ android {
30
30
  buildTypes {
31
31
  release {
32
32
  minifyEnabled false
33
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
33
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
34
34
  }
35
35
  }
36
36
  lintOptions {
@@ -54,7 +54,7 @@ dependencies {
54
54
  implementation "androidx.work:work-runtime:$work_version"
55
55
  implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
56
56
  implementation "com.google.android.gms:play-services-tasks:18.4.1"
57
- implementation "com.google.guava:guava:33.5.0-android"
57
+ implementation "com.google.guava:guava:33.6.0-android"
58
58
  implementation fileTree(dir: 'libs', include: ['*.jar'])
59
59
  implementation project(':capacitor-android')
60
60
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
@@ -63,7 +63,7 @@ dependencies {
63
63
  implementation 'com.google.android.play:app-update:2.1.0'
64
64
  implementation 'com.google.android.play:app-update-ktx:2.1.0'
65
65
  testImplementation "junit:junit:$junitVersion"
66
- testImplementation 'org.mockito:mockito-core:5.21.0'
66
+ testImplementation 'org.mockito:mockito-core:5.23.0'
67
67
  testImplementation 'org.json:json:20250517'
68
68
  testImplementation 'org.robolectric:robolectric:4.16.1'
69
69
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"