@capgo/capacitor-updater 6.14.26 → 6.14.29
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/CapgoCapacitorUpdater.podspec +3 -2
- package/Package.swift +2 -2
- package/README.md +341 -74
- package/android/build.gradle +20 -8
- package/android/proguard-rules.pro +22 -5
- package/android/src/main/java/ee/forgr/capacitor_updater/BundleInfo.java +52 -16
- package/android/src/main/java/ee/forgr/capacitor_updater/Callback.java +2 -2
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1196 -508
- package/android/src/main/java/ee/forgr/capacitor_updater/{CapacitorUpdater.java → CapgoUpdater.java} +522 -154
- package/android/src/main/java/ee/forgr/capacitor_updater/{CryptoCipher.java → CryptoCipherV1.java} +17 -9
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipherV2.java +15 -26
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayCondition.java +0 -3
- package/android/src/main/java/ee/forgr/capacitor_updater/DelayUpdateUtils.java +260 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +300 -119
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadWorkerManager.java +63 -25
- package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +338 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeDetector.java +72 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/ShakeMenu.java +169 -0
- package/dist/docs.json +652 -63
- package/dist/esm/definitions.d.ts +265 -15
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/history.d.ts +1 -0
- package/dist/esm/history.js +283 -0
- package/dist/esm/history.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +12 -1
- package/dist/esm/web.js +29 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +311 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +311 -2
- package/dist/plugin.js.map +1 -1
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/AES.swift +6 -3
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +1575 -0
- package/ios/{Plugin/CapacitorUpdater.swift → Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift} +365 -139
- package/ios/{Plugin/CryptoCipher.swift → Sources/CapacitorUpdaterPlugin/CryptoCipherV1.swift} +13 -6
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/CryptoCipherV2.swift +33 -27
- package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +220 -0
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/InternalUtils.swift +47 -0
- package/ios/Sources/CapacitorUpdaterPlugin/Logger.swift +310 -0
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/RSA.swift +1 -0
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +112 -0
- package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/UserDefaultsExtension.swift +0 -2
- package/package.json +20 -16
- package/ios/Plugin/CapacitorUpdaterPlugin.swift +0 -1030
- /package/{LICENCE → LICENSE} +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BigInt.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleInfo.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/BundleStatus.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayCondition.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/DelayUntilNext.swift +0 -0
- /package/ios/{Plugin → Sources/CapacitorUpdaterPlugin}/Info.plist +0 -0
package/README.md
CHANGED
|
@@ -16,30 +16,55 @@
|
|
|
16
16
|
[](https://console.algora.io/org/Capgo/bounties?status=completed)
|
|
17
17
|
|
|
18
18
|
<div align="center">
|
|
19
|
-
<h2><a href="https://capgo.app/?ref=
|
|
20
|
-
<h2><a href="https://capgo.app/consulting/?ref=
|
|
19
|
+
<h2><a href="https://capgo.app/?ref=plugin_updater_v6"> ➡️ Get Instant updates for your App with Capgo</a></h2>
|
|
20
|
+
<h2><a href="https://capgo.app/consulting/?ref=plugin_updater_v6"> Missing a feature? We’ll build the plugin for you 💪</a></h2>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Capacitor plugin to update your app remotely in real-time.
|
|
24
|
+
|
|
25
|
+
Open-source Alternative to Appflow, Codepush or Capawesome
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- ☁️ Cloud / Self hosted Support: Use our [Cloud](https://capgo.app/) to manage your app updates or yours.
|
|
30
|
+
- 📦 Bundle Management: Download, assign to channel, rollback.
|
|
31
|
+
- 📺 Channel Support: Use channels to manage different environements.
|
|
32
|
+
- 🎯 Set Channel to specific device to do QA or debug one user.
|
|
33
|
+
- 🔄 Auto Update: Automatically download and set the latest bundle for the app.
|
|
34
|
+
- 🛟 Rollback: Reset the app to last working bundle if an incompatible bundle has been set.
|
|
35
|
+
- 🔁 **Delta Updates**: Make instant updates by only downloading changed files.
|
|
36
|
+
- 🔒 **Security**: Encrypt and sign each updates with best in class security standards.
|
|
37
|
+
- ⚔️ **Battle-Tested**: Used in more than 3000 projects.
|
|
38
|
+
- 📊 View your deployment statistics
|
|
39
|
+
- 🔋 Supports Android and iOS
|
|
40
|
+
- ⚡️ Capacitor 6/7 support
|
|
41
|
+
- 🌐 **Open Source**: Licensed under the Mozilla Public License 2.0
|
|
42
|
+
- 🌐 **Open Source Backend**: Self install [our backend](https://github.com/Cap-go/capgo) in your infra
|
|
43
|
+
|
|
24
44
|
|
|
25
45
|
You have 3 ways possible :
|
|
26
46
|
- Use [capgo.app](https://capgo.app) a full featured auto-update system in 5 min Setup, to manage version, update, revert and see stats.
|
|
27
47
|
- Use your own server update with auto-update system
|
|
28
48
|
- Use manual methods to zip, upload, download, from JS to do it when you want.
|
|
29
49
|
|
|
50
|
+
## Documentation
|
|
51
|
+
The most complete [documentation here](https://capgo.app/docs/).
|
|
30
52
|
|
|
31
53
|
## Community
|
|
32
54
|
Join the [discord](https://discord.gg/VnYRvBfgA6) to get help.
|
|
33
55
|
|
|
34
|
-
##
|
|
35
|
-
|
|
56
|
+
## Migration to v7
|
|
57
|
+
|
|
58
|
+
- `privateKey` is not available anymore, it was used for the old encryption method. to migrate follow this guide : [https://capgo.app/docs/plugin/cloud-mode/getting-started/](https://capgo.app/docs/cli/migrations/encryption/)
|
|
59
|
+
- To capacitor v7 : [https://capacitorjs.com/docs/updating/7-0](https://capacitorjs.com/docs/updating/7-0)
|
|
36
60
|
|
|
37
61
|
## Compatibility
|
|
38
62
|
|
|
39
63
|
| Plugin version | Capacitor compatibility | Maintained |
|
|
40
64
|
| -------------- | ----------------------- | ----------------- |
|
|
41
|
-
|
|
|
42
|
-
|
|
|
65
|
+
| v7.\*.\* | v7.\*.\* | ✅ |
|
|
66
|
+
| v6.\*.\* | v6.\*.\* | ✅ |
|
|
67
|
+
| v5.\*.\* | v5.\*.\* | ⚠️ Deprecated |
|
|
43
68
|
| v4.\*.\* | v4.\*.\* | ⚠️ Deprecated |
|
|
44
69
|
| v3.\*.\* | v3.\*.\* | ⚠️ Deprecated |
|
|
45
70
|
| > 7 | v4.\*.\* | ⚠️ Deprecated, our CI got crazy and bumped too much version |
|
|
@@ -75,6 +100,10 @@ We recommend to declare [`CA92.1`](https://developer.apple.com/documentation/bun
|
|
|
75
100
|
|
|
76
101
|
## Installation
|
|
77
102
|
|
|
103
|
+
Step by step here: [Getting started](https://capgo.app/docs/getting-started/add-an-app/)
|
|
104
|
+
|
|
105
|
+
Or
|
|
106
|
+
|
|
78
107
|
```bash
|
|
79
108
|
npm install @capgo/capacitor-updater
|
|
80
109
|
npx cap sync
|
|
@@ -89,7 +118,7 @@ And follow the steps by step to setup your app.
|
|
|
89
118
|
For detailed instructions on the auto-update setup, refer to the [Auto update documentation](https://capgo.app/docs/plugin/cloud-mode/getting-started/).
|
|
90
119
|
|
|
91
120
|
|
|
92
|
-
##
|
|
121
|
+
## No Cloud setup
|
|
93
122
|
|
|
94
123
|
Download update distribution zipfiles from a custom URL. Manually control the entire update process.
|
|
95
124
|
|
|
@@ -115,6 +144,7 @@ This informs Capacitor Updater that the current update bundle has loaded succesf
|
|
|
115
144
|
- Add this to your application.
|
|
116
145
|
```javascript
|
|
117
146
|
const version = await CapacitorUpdater.download({
|
|
147
|
+
version: '0.0.4',
|
|
118
148
|
url: 'https://github.com/Cap-go/demo-app/releases/download/0.0.4/dist.zip',
|
|
119
149
|
})
|
|
120
150
|
await CapacitorUpdater.set(version); // sets the new version, and reloads the app
|
|
@@ -132,6 +162,7 @@ You might also consider performing auto-update when application state changes, a
|
|
|
132
162
|
if (state.isActive) {
|
|
133
163
|
// Ensure download occurs while the app is active, or download may fail
|
|
134
164
|
version = await CapacitorUpdater.download({
|
|
165
|
+
version: '0.0.4',
|
|
135
166
|
url: 'https://github.com/Cap-go/demo-app/releases/download/0.0.4/dist.zip',
|
|
136
167
|
})
|
|
137
168
|
}
|
|
@@ -197,33 +228,42 @@ Capacitor Updater works by unzipping a compiled app bundle to the native device
|
|
|
197
228
|
|
|
198
229
|
CapacitorUpdater can be configured with these options:
|
|
199
230
|
|
|
200
|
-
| Prop
|
|
201
|
-
|
|
|
202
|
-
| **`appReadyTimeout`**
|
|
203
|
-
| **`responseTimeout`**
|
|
204
|
-
| **`autoDeleteFailed`**
|
|
205
|
-
| **`autoDeletePrevious`**
|
|
206
|
-
| **`autoUpdate`**
|
|
207
|
-
| **`resetWhenUpdate`**
|
|
208
|
-
| **`updateUrl`**
|
|
209
|
-
| **`channelUrl`**
|
|
210
|
-
| **`statsUrl`**
|
|
211
|
-
| **`privateKey`**
|
|
212
|
-
| **`publicKey`**
|
|
213
|
-
| **`version`**
|
|
214
|
-
| **`directUpdate`**
|
|
215
|
-
| **`
|
|
216
|
-
| **`
|
|
217
|
-
| **`
|
|
218
|
-
| **`
|
|
219
|
-
| **`
|
|
220
|
-
| **`
|
|
221
|
-
| **`
|
|
222
|
-
| **`
|
|
223
|
-
| **`
|
|
224
|
-
| **`
|
|
225
|
-
| **`
|
|
226
|
-
| **`
|
|
231
|
+
| Prop | Type | Description | Default | Since |
|
|
232
|
+
| ----------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------- |
|
|
233
|
+
| **`appReadyTimeout`** | <code>number</code> | Configure the number of milliseconds the native plugin should wait before considering an update 'failed'. Only available for Android and iOS. | <code>10000 // (10 seconds)</code> | |
|
|
234
|
+
| **`responseTimeout`** | <code>number</code> | Configure the number of seconds the native plugin should wait before considering API timeout. Only available for Android and iOS. | <code>20 // (20 second)</code> | |
|
|
235
|
+
| **`autoDeleteFailed`** | <code>boolean</code> | Configure whether the plugin should use automatically delete failed bundles. Only available for Android and iOS. | <code>true</code> | |
|
|
236
|
+
| **`autoDeletePrevious`** | <code>boolean</code> | Configure whether the plugin should use automatically delete previous bundles after a successful update. Only available for Android and iOS. | <code>true</code> | |
|
|
237
|
+
| **`autoUpdate`** | <code>boolean</code> | Configure whether the plugin should use Auto Update via an update server. Only available for Android and iOS. | <code>true</code> | |
|
|
238
|
+
| **`resetWhenUpdate`** | <code>boolean</code> | Automatically delete previous downloaded bundles when a newer native app bundle is installed to the device. Only available for Android and iOS. | <code>true</code> | |
|
|
239
|
+
| **`updateUrl`** | <code>string</code> | Configure the URL / endpoint to which update checks are sent. Only available for Android and iOS. | <code>https://plugin.capgo.app/updates</code> | |
|
|
240
|
+
| **`channelUrl`** | <code>string</code> | Configure the URL / endpoint for channel operations. Only available for Android and iOS. | <code>https://plugin.capgo.app/channel_self</code> | |
|
|
241
|
+
| **`statsUrl`** | <code>string</code> | Configure the URL / endpoint to which update statistics are sent. Only available for Android and iOS. Set to "" to disable stats reporting. | <code>https://plugin.capgo.app/stats</code> | |
|
|
242
|
+
| **`privateKey`** | <code>string</code> | Configure the private key for end to end live update encryption. Only available for Android and iOS. Deprecated in version 6.2.0 in favor of publicKey. Still supported for backwards compatibility. | <code>undefined</code> | |
|
|
243
|
+
| **`publicKey`** | <code>string</code> | Configure the public key for end to end live update encryption Version 2 Only available for Android and iOS. | <code>undefined</code> | 6.2.0 |
|
|
244
|
+
| **`version`** | <code>string</code> | Configure the current version of the app. This will be used for the first update request. If not set, the plugin will get the version from the native code. Only available for Android and iOS. | <code>undefined</code> | 4.17.48 |
|
|
245
|
+
| **`directUpdate`** | <code>boolean \| 'always' \| 'atInstall'</code> | Configure when the plugin should direct install updates. Only for autoUpdate mode. Works well for apps less than 10MB and with uploads done using --partial flag. Zip or apps more than 10MB will be relatively slow for users to update. - false: Never do direct updates (default behavior) - atInstall: Direct update only when app is installed/updated from store, otherwise use normal background update - always: Always do direct updates immediately when available - true: (deprecated) Same as "always" for backward compatibility Only available for Android and iOS. | <code>false</code> | 5.1.0 |
|
|
246
|
+
| **`autoSplashscreen`** | <code>boolean</code> | Automatically handle splashscreen hiding when using directUpdate. When enabled, the plugin will automatically hide the splashscreen after updates are applied or when no update is needed. This removes the need to manually listen for appReady events and call SplashScreen.hide(). Only works when directUpdate is set to "atInstall", "always", or true. Requires the @capacitor/splash-screen plugin to be installed and configured with launchAutoHide: false. Requires autoUpdate and directUpdate to be enabled. Only available for Android and iOS. | <code>false</code> | 7.6.0 |
|
|
247
|
+
| **`autoSplashscreenLoader`** | <code>boolean</code> | Display a native loading indicator on top of the splashscreen while automatic direct updates are running. Only takes effect when {@link autoSplashscreen} is enabled. Requires the @capacitor/splash-screen plugin to be installed and configured with launchAutoHide: false. Only available for Android and iOS. | <code>false</code> | 7.19.0 |
|
|
248
|
+
| **`autoSplashscreenTimeout`** | <code>number</code> | Automatically hide the splashscreen after the specified number of milliseconds when using automatic direct updates. If the timeout elapses, the update continues to download in the background while the splashscreen is dismissed. Set to `0` (zero) to disable the timeout. When the timeout fires, the direct update flow is skipped and the downloaded bundle is installed on the next background/launch. Requires {@link autoSplashscreen} to be enabled. Only available for Android and iOS. | <code>10000 // (10 seconds)</code> | 7.19.0 |
|
|
249
|
+
| **`periodCheckDelay`** | <code>number</code> | Configure the delay period for period update check. the unit is in seconds. Only available for Android and iOS. Cannot be less than 600 seconds (10 minutes). | <code>0 (disabled)</code> | |
|
|
250
|
+
| **`localS3`** | <code>boolean</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
|
|
251
|
+
| **`localHost`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
|
|
252
|
+
| **`localWebHost`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
|
|
253
|
+
| **`localSupa`** | <code>string</code> | Configure the CLI to use a local server for testing or self-hosted update server. | <code>undefined</code> | 4.17.48 |
|
|
254
|
+
| **`localSupaAnon`** | <code>string</code> | Configure the CLI to use a local server for testing. | <code>undefined</code> | 4.17.48 |
|
|
255
|
+
| **`localApi`** | <code>string</code> | Configure the CLI to use a local api for testing. | <code>undefined</code> | 6.3.3 |
|
|
256
|
+
| **`localApiFiles`** | <code>string</code> | Configure the CLI to use a local file api for testing. | <code>undefined</code> | 6.3.3 |
|
|
257
|
+
| **`allowModifyUrl`** | <code>boolean</code> | Allow the plugin to modify the updateUrl, statsUrl and channelUrl dynamically from the JavaScript side. | <code>false</code> | 5.4.0 |
|
|
258
|
+
| **`allowModifyAppId`** | <code>boolean</code> | Allow the plugin to modify the appId dynamically from the JavaScript side. | <code>false</code> | 7.14.0 |
|
|
259
|
+
| **`allowManualBundleError`** | <code>boolean</code> | Allow marking bundles as errored from JavaScript while using manual update flows. When enabled, {@link CapacitorUpdaterPlugin.setBundleError} can change a bundle status to `error`. | <code>false</code> | 7.20.0 |
|
|
260
|
+
| **`persistCustomId`** | <code>boolean</code> | Persist the customId set through {@link CapacitorUpdaterPlugin.setCustomId} across app restarts. Only available for Android and iOS. | <code>false (will be true by default in a future major release v8.x.x)</code> | 7.17.3 |
|
|
261
|
+
| **`persistModifyUrl`** | <code>boolean</code> | Persist the updateUrl, statsUrl and channelUrl set through {@link CapacitorUpdaterPlugin.setUpdateUrl}, {@link CapacitorUpdaterPlugin.setStatsUrl} and {@link CapacitorUpdaterPlugin.setChannelUrl} across app restarts. Only available for Android and iOS. | <code>false</code> | 7.20.0 |
|
|
262
|
+
| **`defaultChannel`** | <code>string</code> | Set the default channel for the app in the config. Case sensitive. This will setting will override the default channel set in the cloud, but will still respect overrides made in the cloud. This requires the channel to allow devices to self dissociate/associate in the channel settings. https://capgo.app/docs/public-api/channels/#channel-configuration-options | <code>undefined</code> | 5.5.0 |
|
|
263
|
+
| **`appId`** | <code>string</code> | Configure the app id for the app in the config. | <code>undefined</code> | 6.0.0 |
|
|
264
|
+
| **`keepUrlPathAfterReload`** | <code>boolean</code> | Configure the plugin to keep the URL path after a reload. WARNING: When a reload is triggered, 'window.history' will be cleared. | <code>false</code> | 6.8.0 |
|
|
265
|
+
| **`disableJSLogging`** | <code>boolean</code> | Disable the JavaScript logging of the plugin. if true, the plugin will not log to the JavaScript console. only the native log will be done | <code>false</code> | 7.3.0 |
|
|
266
|
+
| **`shakeMenu`** | <code>boolean</code> | Enable shake gesture to show update menu for debugging/testing purposes | <code>false</code> | 7.5.0 |
|
|
227
267
|
|
|
228
268
|
### Examples
|
|
229
269
|
|
|
@@ -246,7 +286,10 @@ In `capacitor.config.json`:
|
|
|
246
286
|
"publicKey": undefined,
|
|
247
287
|
"version": undefined,
|
|
248
288
|
"directUpdate": undefined,
|
|
249
|
-
"
|
|
289
|
+
"autoSplashscreen": undefined,
|
|
290
|
+
"autoSplashscreenLoader": undefined,
|
|
291
|
+
"autoSplashscreenTimeout": undefined,
|
|
292
|
+
"periodCheckDelay": 3600 (1 hour),
|
|
250
293
|
"localS3": undefined,
|
|
251
294
|
"localHost": undefined,
|
|
252
295
|
"localWebHost": undefined,
|
|
@@ -255,9 +298,15 @@ In `capacitor.config.json`:
|
|
|
255
298
|
"localApi": undefined,
|
|
256
299
|
"localApiFiles": undefined,
|
|
257
300
|
"allowModifyUrl": undefined,
|
|
301
|
+
"allowModifyAppId": undefined,
|
|
302
|
+
"allowManualBundleError": undefined,
|
|
303
|
+
"persistCustomId": undefined,
|
|
304
|
+
"persistModifyUrl": undefined,
|
|
258
305
|
"defaultChannel": undefined,
|
|
259
306
|
"appId": undefined,
|
|
260
|
-
"keepUrlPathAfterReload": undefined
|
|
307
|
+
"keepUrlPathAfterReload": undefined,
|
|
308
|
+
"disableJSLogging": undefined,
|
|
309
|
+
"shakeMenu": undefined
|
|
261
310
|
}
|
|
262
311
|
}
|
|
263
312
|
}
|
|
@@ -286,7 +335,10 @@ const config: CapacitorConfig = {
|
|
|
286
335
|
publicKey: undefined,
|
|
287
336
|
version: undefined,
|
|
288
337
|
directUpdate: undefined,
|
|
289
|
-
|
|
338
|
+
autoSplashscreen: undefined,
|
|
339
|
+
autoSplashscreenLoader: undefined,
|
|
340
|
+
autoSplashscreenTimeout: undefined,
|
|
341
|
+
periodCheckDelay: 3600 (1 hour),
|
|
290
342
|
localS3: undefined,
|
|
291
343
|
localHost: undefined,
|
|
292
344
|
localWebHost: undefined,
|
|
@@ -295,9 +347,15 @@ const config: CapacitorConfig = {
|
|
|
295
347
|
localApi: undefined,
|
|
296
348
|
localApiFiles: undefined,
|
|
297
349
|
allowModifyUrl: undefined,
|
|
350
|
+
allowModifyAppId: undefined,
|
|
351
|
+
allowManualBundleError: undefined,
|
|
352
|
+
persistCustomId: undefined,
|
|
353
|
+
persistModifyUrl: undefined,
|
|
298
354
|
defaultChannel: undefined,
|
|
299
355
|
appId: undefined,
|
|
300
356
|
keepUrlPathAfterReload: undefined,
|
|
357
|
+
disableJSLogging: undefined,
|
|
358
|
+
shakeMenu: undefined,
|
|
301
359
|
},
|
|
302
360
|
},
|
|
303
361
|
};
|
|
@@ -319,6 +377,7 @@ export default config;
|
|
|
319
377
|
* [`next(...)`](#next)
|
|
320
378
|
* [`set(...)`](#set)
|
|
321
379
|
* [`delete(...)`](#delete)
|
|
380
|
+
* [`setBundleError(...)`](#setbundleerror)
|
|
322
381
|
* [`list(...)`](#list)
|
|
323
382
|
* [`reset(...)`](#reset)
|
|
324
383
|
* [`current()`](#current)
|
|
@@ -329,6 +388,7 @@ export default config;
|
|
|
329
388
|
* [`setChannel(...)`](#setchannel)
|
|
330
389
|
* [`unsetChannel(...)`](#unsetchannel)
|
|
331
390
|
* [`getChannel()`](#getchannel)
|
|
391
|
+
* [`listChannels()`](#listchannels)
|
|
332
392
|
* [`setCustomId(...)`](#setcustomid)
|
|
333
393
|
* [`getBuiltinVersion()`](#getbuiltinversion)
|
|
334
394
|
* [`getDeviceId()`](#getdeviceid)
|
|
@@ -339,6 +399,7 @@ export default config;
|
|
|
339
399
|
* [`addListener('noNeedUpdate', ...)`](#addlistenernoneedupdate-)
|
|
340
400
|
* [`addListener('updateAvailable', ...)`](#addlistenerupdateavailable-)
|
|
341
401
|
* [`addListener('downloadComplete', ...)`](#addlistenerdownloadcomplete-)
|
|
402
|
+
* [`addListener('breakingAvailable', ...)`](#addlistenerbreakingavailable-)
|
|
342
403
|
* [`addListener('majorAvailable', ...)`](#addlistenermajoravailable-)
|
|
343
404
|
* [`addListener('updateFailed', ...)`](#addlistenerupdatefailed-)
|
|
344
405
|
* [`addListener('downloadFailed', ...)`](#addlistenerdownloadfailed-)
|
|
@@ -346,6 +407,11 @@ export default config;
|
|
|
346
407
|
* [`addListener('appReady', ...)`](#addlistenerappready-)
|
|
347
408
|
* [`isAutoUpdateAvailable()`](#isautoupdateavailable)
|
|
348
409
|
* [`getNextBundle()`](#getnextbundle)
|
|
410
|
+
* [`getFailedUpdate()`](#getfailedupdate)
|
|
411
|
+
* [`setShakeMenu(...)`](#setshakemenu)
|
|
412
|
+
* [`isShakeMenuEnabled()`](#isshakemenuenabled)
|
|
413
|
+
* [`getAppId()`](#getappid)
|
|
414
|
+
* [`setAppId(...)`](#setappid)
|
|
349
415
|
* [Interfaces](#interfaces)
|
|
350
416
|
* [Type Aliases](#type-aliases)
|
|
351
417
|
|
|
@@ -484,6 +550,25 @@ Deletes the specified bundle from the native app storage. Use with {@link list}
|
|
|
484
550
|
--------------------
|
|
485
551
|
|
|
486
552
|
|
|
553
|
+
### setBundleError(...)
|
|
554
|
+
|
|
555
|
+
```typescript
|
|
556
|
+
setBundleError(options: BundleId) => Promise<BundleInfo>
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
Mark an installed bundle as errored. Only available when {@link PluginsConfig.CapacitorUpdater.allowManualBundleError} is true.
|
|
560
|
+
|
|
561
|
+
| Param | Type | Description |
|
|
562
|
+
| ------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
563
|
+
| **`options`** | <code><a href="#bundleid">BundleId</a></code> | A {@link <a href="#bundleid">BundleId</a>} object containing the bundle id to mark as errored. |
|
|
564
|
+
|
|
565
|
+
**Returns:** <code>Promise<<a href="#bundleinfo">BundleInfo</a>></code>
|
|
566
|
+
|
|
567
|
+
**Since:** 7.20.0
|
|
568
|
+
|
|
569
|
+
--------------------
|
|
570
|
+
|
|
571
|
+
|
|
487
572
|
### list(...)
|
|
488
573
|
|
|
489
574
|
```typescript
|
|
@@ -602,8 +687,9 @@ setChannel(options: SetChannelOptions) => Promise<ChannelRes>
|
|
|
602
687
|
```
|
|
603
688
|
|
|
604
689
|
Sets the channel for this device. The channel has to allow for self assignment for this to work.
|
|
605
|
-
Do not use this method to set the channel at boot
|
|
606
|
-
This method is to set the channel after the app is ready.
|
|
690
|
+
Do not use this method to set the channel at boot.
|
|
691
|
+
This method is to set the channel after the app is ready, and user interacted.
|
|
692
|
+
If you want to set the channel at boot, use the {@link PluginsConfig} to set the default channel.
|
|
607
693
|
This methods send to Capgo backend a request to link the device ID to the channel. Capgo can accept or refuse depending of the setting of your channel.
|
|
608
694
|
|
|
609
695
|
| Param | Type | Description |
|
|
@@ -649,6 +735,21 @@ Get the channel for this device
|
|
|
649
735
|
--------------------
|
|
650
736
|
|
|
651
737
|
|
|
738
|
+
### listChannels()
|
|
739
|
+
|
|
740
|
+
```typescript
|
|
741
|
+
listChannels() => Promise<ListChannelsResult>
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
List all channels available for this device that allow self-assignment
|
|
745
|
+
|
|
746
|
+
**Returns:** <code>Promise<<a href="#listchannelsresult">ListChannelsResult</a>></code>
|
|
747
|
+
|
|
748
|
+
**Since:** 7.5.0
|
|
749
|
+
|
|
750
|
+
--------------------
|
|
751
|
+
|
|
752
|
+
|
|
652
753
|
### setCustomId(...)
|
|
653
754
|
|
|
654
755
|
```typescript
|
|
@@ -657,6 +758,9 @@ setCustomId(options: SetCustomIdOptions) => Promise<void>
|
|
|
657
758
|
|
|
658
759
|
Set a custom ID for this device
|
|
659
760
|
|
|
761
|
+
When {@link PluginsConfig.CapacitorUpdater.persistCustomId} is true, the value will be stored natively and restored on the next app launch.
|
|
762
|
+
Pass an empty string to remove any previously stored customId.
|
|
763
|
+
|
|
660
764
|
| Param | Type | Description |
|
|
661
765
|
| ------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
662
766
|
| **`options`** | <code><a href="#setcustomidoptions">SetCustomIdOptions</a></code> | is the {@link <a href="#setcustomidoptions">SetCustomIdOptions</a>} customId to set |
|
|
@@ -687,7 +791,7 @@ Get the native app version or the builtin version if set in config
|
|
|
687
791
|
getDeviceId() => Promise<DeviceId>
|
|
688
792
|
```
|
|
689
793
|
|
|
690
|
-
Get unique ID used to identify device (sent to auto update server)
|
|
794
|
+
Get unique ID used to identify device (sent to auto update server), this ID is made following Apple and Google privacy best practices, and not persisted between installs
|
|
691
795
|
|
|
692
796
|
**Returns:** <code>Promise<<a href="#deviceid">DeviceId</a>></code>
|
|
693
797
|
|
|
@@ -740,6 +844,7 @@ addListener(eventName: 'download', listenerFunc: (state: DownloadEvent) => void)
|
|
|
740
844
|
```
|
|
741
845
|
|
|
742
846
|
Listen for bundle download event in the App. Fires once a download has started, during downloading and when finished.
|
|
847
|
+
This will return you all download percent during the download
|
|
743
848
|
|
|
744
849
|
| Param | Type |
|
|
745
850
|
| ------------------ | --------------------------------------------------------------------------- |
|
|
@@ -813,6 +918,27 @@ Listen for downloadComplete events.
|
|
|
813
918
|
--------------------
|
|
814
919
|
|
|
815
920
|
|
|
921
|
+
### addListener('breakingAvailable', ...)
|
|
922
|
+
|
|
923
|
+
```typescript
|
|
924
|
+
addListener(eventName: 'breakingAvailable', listenerFunc: (state: BreakingAvailableEvent) => void) => Promise<PluginListenerHandle>
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
Listen for breaking update events when the backend flags an update as incompatible with the current app.
|
|
928
|
+
Emits the same payload as the legacy `majorAvailable` listener.
|
|
929
|
+
|
|
930
|
+
| Param | Type |
|
|
931
|
+
| ------------------ | --------------------------------------------------------------------------------------- |
|
|
932
|
+
| **`eventName`** | <code>'breakingAvailable'</code> |
|
|
933
|
+
| **`listenerFunc`** | <code>(state: <a href="#majoravailableevent">MajorAvailableEvent</a>) => void</code> |
|
|
934
|
+
|
|
935
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
936
|
+
|
|
937
|
+
**Since:** 7.22.0
|
|
938
|
+
|
|
939
|
+
--------------------
|
|
940
|
+
|
|
941
|
+
|
|
816
942
|
### addListener('majorAvailable', ...)
|
|
817
943
|
|
|
818
944
|
```typescript
|
|
@@ -899,7 +1025,7 @@ Listen for reload event in the App, let you know when reload has happened
|
|
|
899
1025
|
addListener(eventName: 'appReady', listenerFunc: (state: AppReadyEvent) => void) => Promise<PluginListenerHandle>
|
|
900
1026
|
```
|
|
901
1027
|
|
|
902
|
-
Listen for app ready event in the App, let you know when app is ready to use
|
|
1028
|
+
Listen for app ready event in the App, let you know when app is ready to use, this event is retain till consumed.
|
|
903
1029
|
|
|
904
1030
|
| Param | Type |
|
|
905
1031
|
| ------------------ | --------------------------------------------------------------------------- |
|
|
@@ -942,6 +1068,85 @@ Returns null if no next bundle is set.
|
|
|
942
1068
|
--------------------
|
|
943
1069
|
|
|
944
1070
|
|
|
1071
|
+
### getFailedUpdate()
|
|
1072
|
+
|
|
1073
|
+
```typescript
|
|
1074
|
+
getFailedUpdate() => Promise<UpdateFailedEvent | null>
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
Get the most recent update that failed to install, if any. The stored value is cleared after it is retrieved once.
|
|
1078
|
+
|
|
1079
|
+
**Returns:** <code>Promise<<a href="#updatefailedevent">UpdateFailedEvent</a> | null></code>
|
|
1080
|
+
|
|
1081
|
+
**Since:** 7.22.0
|
|
1082
|
+
|
|
1083
|
+
--------------------
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
### setShakeMenu(...)
|
|
1087
|
+
|
|
1088
|
+
```typescript
|
|
1089
|
+
setShakeMenu(options: SetShakeMenuOptions) => Promise<void>
|
|
1090
|
+
```
|
|
1091
|
+
|
|
1092
|
+
Enable or disable the shake menu for debugging/testing purposes
|
|
1093
|
+
|
|
1094
|
+
| Param | Type | Description |
|
|
1095
|
+
| ------------- | ------------------------------------------------------------------- | -------------------------------------------------------- |
|
|
1096
|
+
| **`options`** | <code><a href="#setshakemenuoptions">SetShakeMenuOptions</a></code> | Contains enabled boolean to enable or disable shake menu |
|
|
1097
|
+
|
|
1098
|
+
**Since:** 7.5.0
|
|
1099
|
+
|
|
1100
|
+
--------------------
|
|
1101
|
+
|
|
1102
|
+
|
|
1103
|
+
### isShakeMenuEnabled()
|
|
1104
|
+
|
|
1105
|
+
```typescript
|
|
1106
|
+
isShakeMenuEnabled() => Promise<ShakeMenuEnabled>
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
Get the current state of the shake menu
|
|
1110
|
+
|
|
1111
|
+
**Returns:** <code>Promise<<a href="#shakemenuenabled">ShakeMenuEnabled</a>></code>
|
|
1112
|
+
|
|
1113
|
+
**Since:** 7.5.0
|
|
1114
|
+
|
|
1115
|
+
--------------------
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
### getAppId()
|
|
1119
|
+
|
|
1120
|
+
```typescript
|
|
1121
|
+
getAppId() => Promise<GetAppIdRes>
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
Get the configured App ID
|
|
1125
|
+
|
|
1126
|
+
**Returns:** <code>Promise<<a href="#getappidres">GetAppIdRes</a>></code>
|
|
1127
|
+
|
|
1128
|
+
**Since:** 7.14.0
|
|
1129
|
+
|
|
1130
|
+
--------------------
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
### setAppId(...)
|
|
1134
|
+
|
|
1135
|
+
```typescript
|
|
1136
|
+
setAppId(options: SetAppIdOptions) => Promise<void>
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
Set the App ID for the app (requires allowModifyAppId to be true in config)
|
|
1140
|
+
|
|
1141
|
+
| Param | Type | Description |
|
|
1142
|
+
| ------------- | ----------------------------------------------------------- | --------------------- |
|
|
1143
|
+
| **`options`** | <code><a href="#setappidoptions">SetAppIdOptions</a></code> | The new App ID to set |
|
|
1144
|
+
|
|
1145
|
+
**Since:** 7.14.0
|
|
1146
|
+
|
|
1147
|
+
--------------------
|
|
1148
|
+
|
|
1149
|
+
|
|
945
1150
|
### Interfaces
|
|
946
1151
|
|
|
947
1152
|
|
|
@@ -986,12 +1191,25 @@ Returns null if no next bundle is set.
|
|
|
986
1191
|
|
|
987
1192
|
#### DownloadOptions
|
|
988
1193
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
|
993
|
-
|
|
|
994
|
-
| **`
|
|
1194
|
+
This URL and versions are used to download the bundle from the server, If you use backend all information will be gived by the method getLatest.
|
|
1195
|
+
If you don't use backend, you need to provide the URL and version of the bundle. Checksum and sessionKey are required if you encrypted the bundle with the CLI command encrypt, you should receive them as result of the command.
|
|
1196
|
+
|
|
1197
|
+
| Prop | Type | Description | Default | Since |
|
|
1198
|
+
| ---------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ----- |
|
|
1199
|
+
| **`url`** | <code>string</code> | The URL of the bundle zip file (e.g: dist.zip) to be downloaded. (This can be any URL. E.g: Amazon S3, a GitHub tag, any other place you've hosted your bundle.) | | |
|
|
1200
|
+
| **`version`** | <code>string</code> | The version code/name of this bundle/version | | |
|
|
1201
|
+
| **`sessionKey`** | <code>string</code> | The session key for the update, when the bundle is encrypted with a session key | <code>undefined</code> | 4.0.0 |
|
|
1202
|
+
| **`checksum`** | <code>string</code> | The checksum for the update, it should be in sha256 and encrypted with private key if the bundle is encrypted | <code>undefined</code> | 4.0.0 |
|
|
1203
|
+
| **`manifest`** | <code>ManifestEntry[]</code> | The manifest for multi-file downloads | <code>undefined</code> | 6.1.0 |
|
|
1204
|
+
|
|
1205
|
+
|
|
1206
|
+
#### ManifestEntry
|
|
1207
|
+
|
|
1208
|
+
| Prop | Type |
|
|
1209
|
+
| ------------------ | --------------------------- |
|
|
1210
|
+
| **`file_name`** | <code>string \| null</code> |
|
|
1211
|
+
| **`file_hash`** | <code>string \| null</code> |
|
|
1212
|
+
| **`download_url`** | <code>string \| null</code> |
|
|
995
1213
|
|
|
996
1214
|
|
|
997
1215
|
#### BundleId
|
|
@@ -1047,26 +1265,18 @@ Returns null if no next bundle is set.
|
|
|
1047
1265
|
|
|
1048
1266
|
#### LatestVersion
|
|
1049
1267
|
|
|
1050
|
-
| Prop | Type | Description
|
|
1051
|
-
| ---------------- | ---------------------------- |
|
|
1052
|
-
| **`version`** | <code>string</code> | Result of getLatest method
|
|
1053
|
-
| **`checksum`** | <code>string</code> |
|
|
1054
|
-
| **`
|
|
1055
|
-
| **`
|
|
1056
|
-
| **`
|
|
1057
|
-
| **`
|
|
1058
|
-
| **`
|
|
1059
|
-
| **`
|
|
1060
|
-
| **`
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
#### ManifestEntry
|
|
1064
|
-
|
|
1065
|
-
| Prop | Type |
|
|
1066
|
-
| ------------------ | --------------------------- |
|
|
1067
|
-
| **`file_name`** | <code>string \| null</code> |
|
|
1068
|
-
| **`file_hash`** | <code>string \| null</code> |
|
|
1069
|
-
| **`download_url`** | <code>string \| null</code> |
|
|
1268
|
+
| Prop | Type | Description | Since |
|
|
1269
|
+
| ---------------- | ---------------------------- | -------------------------------------------------------------------- | ------ |
|
|
1270
|
+
| **`version`** | <code>string</code> | Result of getLatest method | 4.0.0 |
|
|
1271
|
+
| **`checksum`** | <code>string</code> | | 6 |
|
|
1272
|
+
| **`breaking`** | <code>boolean</code> | Indicates whether the update was flagged as breaking by the backend. | 7.22.0 |
|
|
1273
|
+
| **`major`** | <code>boolean</code> | | |
|
|
1274
|
+
| **`message`** | <code>string</code> | | |
|
|
1275
|
+
| **`sessionKey`** | <code>string</code> | | |
|
|
1276
|
+
| **`error`** | <code>string</code> | | |
|
|
1277
|
+
| **`old`** | <code>string</code> | | |
|
|
1278
|
+
| **`url`** | <code>string</code> | | |
|
|
1279
|
+
| **`manifest`** | <code>ManifestEntry[]</code> | | 6.1 |
|
|
1070
1280
|
|
|
1071
1281
|
|
|
1072
1282
|
#### GetLatestOptions
|
|
@@ -1111,11 +1321,28 @@ Returns null if no next bundle is set.
|
|
|
1111
1321
|
| **`allowSet`** | <code>boolean</code> | | |
|
|
1112
1322
|
|
|
1113
1323
|
|
|
1324
|
+
#### ListChannelsResult
|
|
1325
|
+
|
|
1326
|
+
| Prop | Type | Description | Since |
|
|
1327
|
+
| -------------- | -------------------------- | -------------------------- | ----- |
|
|
1328
|
+
| **`channels`** | <code>ChannelInfo[]</code> | List of available channels | 7.5.0 |
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
#### ChannelInfo
|
|
1332
|
+
|
|
1333
|
+
| Prop | Type | Description | Since |
|
|
1334
|
+
| -------------------- | -------------------- | ----------------------------------------------- | ----- |
|
|
1335
|
+
| **`id`** | <code>string</code> | The channel ID | 7.5.0 |
|
|
1336
|
+
| **`name`** | <code>string</code> | The channel name | 7.5.0 |
|
|
1337
|
+
| **`public`** | <code>boolean</code> | Whether this is a public channel | 7.5.0 |
|
|
1338
|
+
| **`allow_self_set`** | <code>boolean</code> | Whether devices can self-assign to this channel | 7.5.0 |
|
|
1339
|
+
|
|
1340
|
+
|
|
1114
1341
|
#### SetCustomIdOptions
|
|
1115
1342
|
|
|
1116
|
-
| Prop | Type |
|
|
1117
|
-
| -------------- | ------------------- |
|
|
1118
|
-
| **`customId`** | <code>string</code> |
|
|
1343
|
+
| Prop | Type | Description |
|
|
1344
|
+
| -------------- | ------------------- | --------------------------------------------------------------------------------------------- |
|
|
1345
|
+
| **`customId`** | <code>string</code> | Custom identifier to associate with the device. Use an empty string to clear any saved value. |
|
|
1119
1346
|
|
|
1120
1347
|
|
|
1121
1348
|
#### BuiltinVersion
|
|
@@ -1184,9 +1411,9 @@ Returns null if no next bundle is set.
|
|
|
1184
1411
|
|
|
1185
1412
|
#### MajorAvailableEvent
|
|
1186
1413
|
|
|
1187
|
-
| Prop | Type | Description
|
|
1188
|
-
| ------------- | ------------------- |
|
|
1189
|
-
| **`version`** | <code>string</code> | Emit when a
|
|
1414
|
+
| Prop | Type | Description | Since |
|
|
1415
|
+
| ------------- | ------------------- | ----------------------------------------- | ----- |
|
|
1416
|
+
| **`version`** | <code>string</code> | Emit when a breaking update is available. | 4.0.0 |
|
|
1190
1417
|
|
|
1191
1418
|
|
|
1192
1419
|
#### UpdateFailedEvent
|
|
@@ -1218,11 +1445,44 @@ Returns null if no next bundle is set.
|
|
|
1218
1445
|
| **`available`** | <code>boolean</code> |
|
|
1219
1446
|
|
|
1220
1447
|
|
|
1448
|
+
#### SetShakeMenuOptions
|
|
1449
|
+
|
|
1450
|
+
| Prop | Type |
|
|
1451
|
+
| ------------- | -------------------- |
|
|
1452
|
+
| **`enabled`** | <code>boolean</code> |
|
|
1453
|
+
|
|
1454
|
+
|
|
1455
|
+
#### ShakeMenuEnabled
|
|
1456
|
+
|
|
1457
|
+
| Prop | Type |
|
|
1458
|
+
| ------------- | -------------------- |
|
|
1459
|
+
| **`enabled`** | <code>boolean</code> |
|
|
1460
|
+
|
|
1461
|
+
|
|
1462
|
+
#### GetAppIdRes
|
|
1463
|
+
|
|
1464
|
+
| Prop | Type |
|
|
1465
|
+
| ----------- | ------------------- |
|
|
1466
|
+
| **`appId`** | <code>string</code> |
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
#### SetAppIdOptions
|
|
1470
|
+
|
|
1471
|
+
| Prop | Type |
|
|
1472
|
+
| ----------- | ------------------- |
|
|
1473
|
+
| **`appId`** | <code>string</code> |
|
|
1474
|
+
|
|
1475
|
+
|
|
1221
1476
|
### Type Aliases
|
|
1222
1477
|
|
|
1223
1478
|
|
|
1224
1479
|
#### BundleStatus
|
|
1225
1480
|
|
|
1481
|
+
pending: The bundle is pending to be **SET** as the next bundle.
|
|
1482
|
+
downloading: The bundle is being downloaded.
|
|
1483
|
+
success: The bundle has been downloaded and is ready to be **SET** as the next bundle.
|
|
1484
|
+
error: The bundle has failed to download.
|
|
1485
|
+
|
|
1226
1486
|
<code>'success' | 'error' | 'pending' | 'downloading'</code>
|
|
1227
1487
|
|
|
1228
1488
|
|
|
@@ -1230,6 +1490,13 @@ Returns null if no next bundle is set.
|
|
|
1230
1490
|
|
|
1231
1491
|
<code>'background' | 'kill' | 'nativeVersion' | 'date'</code>
|
|
1232
1492
|
|
|
1493
|
+
|
|
1494
|
+
#### BreakingAvailableEvent
|
|
1495
|
+
|
|
1496
|
+
Payload emitted by {@link CapacitorUpdaterPlugin.addListener} with `breakingAvailable`.
|
|
1497
|
+
|
|
1498
|
+
<code><a href="#majoravailableevent">MajorAvailableEvent</a></code>
|
|
1499
|
+
|
|
1233
1500
|
</docgen-api>
|
|
1234
1501
|
|
|
1235
1502
|
### Listen to download events
|