native-update 1.0.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/CapacitorNativeUpdate.podspec +18 -0
- package/LICENSE +21 -0
- package/Readme.md +451 -0
- package/android/build.gradle +92 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/android/gradle.properties +17 -0
- package/android/proguard-rules.pro +29 -0
- package/android/settings.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +34 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/AppReviewPlugin.kt +153 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/AppUpdatePlugin.kt +275 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +390 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateManager.kt +46 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +333 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +251 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/CapacitorNativeUpdatePlugin.kt +265 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +526 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +99 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +249 -0
- package/dist/esm/__tests__/bundle-manager.test.d.ts +1 -0
- package/dist/esm/__tests__/bundle-manager.test.js +123 -0
- package/dist/esm/__tests__/bundle-manager.test.js.map +1 -0
- package/dist/esm/__tests__/config.test.d.ts +1 -0
- package/dist/esm/__tests__/config.test.js +69 -0
- package/dist/esm/__tests__/config.test.js.map +1 -0
- package/dist/esm/__tests__/integration.test.d.ts +1 -0
- package/dist/esm/__tests__/integration.test.js +78 -0
- package/dist/esm/__tests__/integration.test.js.map +1 -0
- package/dist/esm/__tests__/security.test.d.ts +1 -0
- package/dist/esm/__tests__/security.test.js +54 -0
- package/dist/esm/__tests__/security.test.js.map +1 -0
- package/dist/esm/__tests__/version-manager.test.d.ts +1 -0
- package/dist/esm/__tests__/version-manager.test.js +45 -0
- package/dist/esm/__tests__/version-manager.test.js.map +1 -0
- package/dist/esm/app-review/app-review-manager.d.ts +24 -0
- package/dist/esm/app-review/app-review-manager.js +195 -0
- package/dist/esm/app-review/app-review-manager.js.map +1 -0
- package/dist/esm/app-review/index.d.ts +5 -0
- package/dist/esm/app-review/index.js +6 -0
- package/dist/esm/app-review/index.js.map +1 -0
- package/dist/esm/app-review/platform-review-handler.d.ts +20 -0
- package/dist/esm/app-review/platform-review-handler.js +138 -0
- package/dist/esm/app-review/platform-review-handler.js.map +1 -0
- package/dist/esm/app-review/review-conditions-checker.d.ts +22 -0
- package/dist/esm/app-review/review-conditions-checker.js +155 -0
- package/dist/esm/app-review/review-conditions-checker.js.map +1 -0
- package/dist/esm/app-review/review-rate-limiter.d.ts +23 -0
- package/dist/esm/app-review/review-rate-limiter.js +164 -0
- package/dist/esm/app-review/review-rate-limiter.js.map +1 -0
- package/dist/esm/app-review/types.d.ts +41 -0
- package/dist/esm/app-review/types.js +2 -0
- package/dist/esm/app-review/types.js.map +1 -0
- package/dist/esm/app-update/app-update-checker.d.ts +13 -0
- package/dist/esm/app-update/app-update-checker.js +104 -0
- package/dist/esm/app-update/app-update-checker.js.map +1 -0
- package/dist/esm/app-update/app-update-installer.d.ts +19 -0
- package/dist/esm/app-update/app-update-installer.js +123 -0
- package/dist/esm/app-update/app-update-installer.js.map +1 -0
- package/dist/esm/app-update/app-update-manager.d.ts +28 -0
- package/dist/esm/app-update/app-update-manager.js +199 -0
- package/dist/esm/app-update/app-update-manager.js.map +1 -0
- package/dist/esm/app-update/app-update-notifier.d.ts +14 -0
- package/dist/esm/app-update/app-update-notifier.js +100 -0
- package/dist/esm/app-update/app-update-notifier.js.map +1 -0
- package/dist/esm/app-update/index.d.ts +6 -0
- package/dist/esm/app-update/index.js +7 -0
- package/dist/esm/app-update/index.js.map +1 -0
- package/dist/esm/app-update/platform-app-update.d.ts +19 -0
- package/dist/esm/app-update/platform-app-update.js +129 -0
- package/dist/esm/app-update/platform-app-update.js.map +1 -0
- package/dist/esm/app-update/types.d.ts +58 -0
- package/dist/esm/app-update/types.js +12 -0
- package/dist/esm/app-update/types.js.map +1 -0
- package/dist/esm/background-update/background-scheduler.d.ts +17 -0
- package/dist/esm/background-update/background-scheduler.js +195 -0
- package/dist/esm/background-update/background-scheduler.js.map +1 -0
- package/dist/esm/background-update/index.d.ts +3 -0
- package/dist/esm/background-update/index.js +3 -0
- package/dist/esm/background-update/index.js.map +1 -0
- package/dist/esm/background-update/notification-manager.d.ts +29 -0
- package/dist/esm/background-update/notification-manager.js +89 -0
- package/dist/esm/background-update/notification-manager.js.map +1 -0
- package/dist/esm/core/analytics.d.ts +70 -0
- package/dist/esm/core/analytics.js +137 -0
- package/dist/esm/core/analytics.js.map +1 -0
- package/dist/esm/core/cache-manager.d.ts +72 -0
- package/dist/esm/core/cache-manager.js +275 -0
- package/dist/esm/core/cache-manager.js.map +1 -0
- package/dist/esm/core/config.d.ts +48 -0
- package/dist/esm/core/config.js +83 -0
- package/dist/esm/core/config.js.map +1 -0
- package/dist/esm/core/errors.d.ts +51 -0
- package/dist/esm/core/errors.js +80 -0
- package/dist/esm/core/errors.js.map +1 -0
- package/dist/esm/core/logger.d.ts +21 -0
- package/dist/esm/core/logger.js +109 -0
- package/dist/esm/core/logger.js.map +1 -0
- package/dist/esm/core/performance.d.ts +53 -0
- package/dist/esm/core/performance.js +140 -0
- package/dist/esm/core/performance.js.map +1 -0
- package/dist/esm/core/plugin-manager.d.ts +66 -0
- package/dist/esm/core/plugin-manager.js +148 -0
- package/dist/esm/core/plugin-manager.js.map +1 -0
- package/dist/esm/core/security.d.ts +93 -0
- package/dist/esm/core/security.js +315 -0
- package/dist/esm/core/security.js.map +1 -0
- package/dist/esm/definitions.d.ts +639 -0
- package/dist/esm/definitions.js +103 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/live-update/bundle-manager.d.ts +94 -0
- package/dist/esm/live-update/bundle-manager.js +310 -0
- package/dist/esm/live-update/bundle-manager.js.map +1 -0
- package/dist/esm/live-update/certificate-pinning.d.ts +38 -0
- package/dist/esm/live-update/certificate-pinning.js +78 -0
- package/dist/esm/live-update/certificate-pinning.js.map +1 -0
- package/dist/esm/live-update/download-manager.d.ts +67 -0
- package/dist/esm/live-update/download-manager.js +319 -0
- package/dist/esm/live-update/download-manager.js.map +1 -0
- package/dist/esm/live-update/update-manager.d.ts +52 -0
- package/dist/esm/live-update/update-manager.js +294 -0
- package/dist/esm/live-update/update-manager.js.map +1 -0
- package/dist/esm/live-update/version-manager.d.ts +84 -0
- package/dist/esm/live-update/version-manager.js +335 -0
- package/dist/esm/live-update/version-manager.js.map +1 -0
- package/dist/esm/plugin.d.ts +6 -0
- package/dist/esm/plugin.js +283 -0
- package/dist/esm/plugin.js.map +1 -0
- package/dist/esm/security/crypto.d.ts +25 -0
- package/dist/esm/security/crypto.js +70 -0
- package/dist/esm/security/crypto.js.map +1 -0
- package/dist/esm/security/validator.d.ts +60 -0
- package/dist/esm/security/validator.js +143 -0
- package/dist/esm/security/validator.js.map +1 -0
- package/dist/esm/web.d.ts +74 -0
- package/dist/esm/web.js +595 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +2 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.esm.js +2 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -0
- package/docs/APP_REVIEW_GUIDE.md +768 -0
- package/docs/BUNDLE_SIGNING.md +264 -0
- package/docs/LIVE_UPDATES_GUIDE.md +650 -0
- package/docs/MIGRATION.md +192 -0
- package/docs/NATIVE_UPDATES_GUIDE.md +694 -0
- package/docs/QUICK_START.md +606 -0
- package/docs/README.md +111 -0
- package/docs/REMAINING_FEATURES.md +139 -0
- package/docs/api/app-review-api.md +259 -0
- package/docs/api/app-update-api.md +238 -0
- package/docs/api/events-api.md +451 -0
- package/docs/api/live-update-api.md +265 -0
- package/docs/background-updates.md +392 -0
- package/docs/examples/advanced-scenarios.md +410 -0
- package/docs/examples/basic-usage.md +185 -0
- package/docs/features/app-reviews.md +975 -0
- package/docs/features/app-updates.md +785 -0
- package/docs/features/live-updates.md +633 -0
- package/docs/getting-started/configuration.md +468 -0
- package/docs/getting-started/installation.md +209 -0
- package/docs/getting-started/quick-start.md +379 -0
- package/docs/guides/deployment-guide.md +333 -0
- package/docs/guides/migration-from-codepush.md +142 -0
- package/docs/guides/security-best-practices.md +1057 -0
- package/docs/guides/testing-guide.md +373 -0
- package/docs/production-readiness.md +478 -0
- package/docs/security/certificate-pinning.md +122 -0
- package/docs/server-requirements.md +147 -0
- package/ios/Plugin/AppReview/AppReviewPlugin.swift +158 -0
- package/ios/Plugin/AppUpdate/AppUpdatePlugin.swift +234 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundNotificationManager.swift +329 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +396 -0
- package/ios/Plugin/CapacitorNativeUpdatePlugin.m +45 -0
- package/ios/Plugin/CapacitorNativeUpdatePlugin.swift +190 -0
- package/ios/Plugin/Info.plist +43 -0
- package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +689 -0
- package/ios/Plugin/LiveUpdate/WebViewConfiguration.swift +45 -0
- package/ios/Plugin/Security/SecurityManager.swift +289 -0
- package/package.json +90 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
> **⚠️ IMPORTANT: Backend Infrastructure Required**
|
|
4
|
+
>
|
|
5
|
+
> This plugin is a **client-side SDK only** and requires significant backend infrastructure to function:
|
|
6
|
+
>
|
|
7
|
+
> - **Update Server**: You must build and host your own server to manage and serve update bundles
|
|
8
|
+
> - **Bundle Generation**: You need a CI/CD pipeline to create, sign, and deploy update bundles
|
|
9
|
+
> - **Security Infrastructure**: Implement bundle signing, verification, and secure distribution
|
|
10
|
+
> - **Version Management**: Handle versioning, channels, and rollback mechanisms
|
|
11
|
+
> - **Analytics & Monitoring**: Track update success rates and handle failures
|
|
12
|
+
>
|
|
13
|
+
> **This is NOT a complete solution** - it's a foundation that requires substantial additional development. See our [Server Requirements](../server-requirements.md) guide for detailed backend implementation requirements.
|
|
14
|
+
|
|
15
|
+
Get up and running with Capacitor Native Update in just a few minutes! This guide covers the most common use cases.
|
|
16
|
+
|
|
17
|
+
## Basic Setup
|
|
18
|
+
|
|
19
|
+
### 1. Import and Configure
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { CapacitorNativeUpdate } from 'native-update';
|
|
23
|
+
|
|
24
|
+
// Initialize the plugin with your configuration
|
|
25
|
+
async function initializeUpdates() {
|
|
26
|
+
await CapacitorNativeUpdate.configure({
|
|
27
|
+
liveUpdate: {
|
|
28
|
+
appId: 'com.yourcompany.app',
|
|
29
|
+
serverUrl: 'https://updates.yourserver.com',
|
|
30
|
+
channel: 'production',
|
|
31
|
+
autoUpdate: true,
|
|
32
|
+
updateStrategy: 'IMMEDIATE',
|
|
33
|
+
},
|
|
34
|
+
appUpdate: {
|
|
35
|
+
checkOnAppStart: true,
|
|
36
|
+
minimumVersion: '1.0.0',
|
|
37
|
+
},
|
|
38
|
+
appReview: {
|
|
39
|
+
minimumDaysSinceInstall: 7,
|
|
40
|
+
minimumLaunchCount: 3,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Call this when your app starts
|
|
46
|
+
initializeUpdates();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Live Updates (OTA)
|
|
50
|
+
|
|
51
|
+
### Check and Apply Updates Automatically
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Sync with server and apply updates if available
|
|
55
|
+
async function syncUpdates() {
|
|
56
|
+
try {
|
|
57
|
+
const result = await CapacitorNativeUpdate.LiveUpdate.sync();
|
|
58
|
+
|
|
59
|
+
if (result.status === 'UPDATE_INSTALLED') {
|
|
60
|
+
console.log('Update installed:', result.bundle.version);
|
|
61
|
+
// Update will be applied based on your updateStrategy
|
|
62
|
+
} else if (result.status === 'UP_TO_DATE') {
|
|
63
|
+
console.log('App is up to date');
|
|
64
|
+
}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('Sync failed:', error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Manual Update Control
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
// Check for updates without downloading
|
|
75
|
+
async function checkForUpdates() {
|
|
76
|
+
const latest = await CapacitorNativeUpdate.LiveUpdate.getLatest();
|
|
77
|
+
const current = await CapacitorNativeUpdate.LiveUpdate.current();
|
|
78
|
+
|
|
79
|
+
if (latest.version !== current.version) {
|
|
80
|
+
console.log(`Update available: ${latest.version}`);
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Download and install update manually
|
|
87
|
+
async function downloadAndInstallUpdate() {
|
|
88
|
+
try {
|
|
89
|
+
// Download the latest version
|
|
90
|
+
const bundle = await CapacitorNativeUpdate.LiveUpdate.download({
|
|
91
|
+
version: 'latest',
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Set it as active
|
|
95
|
+
await CapacitorNativeUpdate.LiveUpdate.set(bundle);
|
|
96
|
+
|
|
97
|
+
// Reload the app to apply
|
|
98
|
+
await CapacitorNativeUpdate.LiveUpdate.reload();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('Update failed:', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Listen for Download Progress
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// Add download progress listener
|
|
109
|
+
const progressListener = await CapacitorNativeUpdate.LiveUpdate.addListener(
|
|
110
|
+
'downloadProgress',
|
|
111
|
+
(progress) => {
|
|
112
|
+
console.log(`Download: ${progress.percent}% complete`);
|
|
113
|
+
console.log(`${progress.bytesDownloaded} / ${progress.totalBytes} bytes`);
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
// Remember to remove listener when done
|
|
118
|
+
// progressListener.remove();
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Native App Updates
|
|
122
|
+
|
|
123
|
+
### Check for App Store Updates
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
async function checkAppStoreUpdate() {
|
|
127
|
+
try {
|
|
128
|
+
const updateInfo = await CapacitorNativeUpdate.AppUpdate.getAppUpdateInfo();
|
|
129
|
+
|
|
130
|
+
if (updateInfo.updateAvailable) {
|
|
131
|
+
console.log(`New version available: ${updateInfo.availableVersion}`);
|
|
132
|
+
|
|
133
|
+
if (updateInfo.updatePriority >= 4) {
|
|
134
|
+
// High priority - immediate update
|
|
135
|
+
await CapacitorNativeUpdate.AppUpdate.performImmediateUpdate();
|
|
136
|
+
} else {
|
|
137
|
+
// Optional update
|
|
138
|
+
showUpdateDialog(updateInfo);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error('App update check failed:', error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function showUpdateDialog(updateInfo) {
|
|
147
|
+
// Show your custom update UI
|
|
148
|
+
if (userAcceptsUpdate) {
|
|
149
|
+
CapacitorNativeUpdate.AppUpdate.openAppStore();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Flexible Updates (Android)
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
// Start downloading in background
|
|
158
|
+
async function startFlexibleUpdate() {
|
|
159
|
+
await CapacitorNativeUpdate.AppUpdate.startFlexibleUpdate();
|
|
160
|
+
|
|
161
|
+
// Listen for download completion
|
|
162
|
+
const listener = await CapacitorNativeUpdate.AppUpdate.addListener(
|
|
163
|
+
'flexibleUpdateStateChanged',
|
|
164
|
+
(state) => {
|
|
165
|
+
if (state.status === 'DOWNLOADED') {
|
|
166
|
+
// Prompt user to restart
|
|
167
|
+
showRestartPrompt();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Complete the update
|
|
174
|
+
async function completeUpdate() {
|
|
175
|
+
await CapacitorNativeUpdate.AppUpdate.completeFlexibleUpdate();
|
|
176
|
+
// App will restart with new version
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## App Reviews
|
|
181
|
+
|
|
182
|
+
### Request Review at the Right Time
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
async function requestReviewIfAppropriate() {
|
|
186
|
+
try {
|
|
187
|
+
// Check if we can request a review
|
|
188
|
+
const canRequest = await CapacitorNativeUpdate.AppReview.canRequestReview();
|
|
189
|
+
|
|
190
|
+
if (canRequest.allowed) {
|
|
191
|
+
// Request the review
|
|
192
|
+
const result = await CapacitorNativeUpdate.AppReview.requestReview();
|
|
193
|
+
|
|
194
|
+
if (result.shown) {
|
|
195
|
+
console.log('Review dialog was shown');
|
|
196
|
+
}
|
|
197
|
+
} else {
|
|
198
|
+
console.log('Cannot request review:', canRequest.reason);
|
|
199
|
+
}
|
|
200
|
+
} catch (error) {
|
|
201
|
+
console.error('Review request failed:', error);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Call after positive user actions
|
|
206
|
+
// e.g., after completing a task, making a purchase, etc.
|
|
207
|
+
requestReviewIfAppropriate();
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Common Patterns
|
|
211
|
+
|
|
212
|
+
### Initialize on App Start
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
// In your main app component
|
|
216
|
+
import { App } from '@capacitor/app';
|
|
217
|
+
import { CapacitorNativeUpdate } from 'native-update';
|
|
218
|
+
|
|
219
|
+
App.addListener('appStateChange', async ({ isActive }) => {
|
|
220
|
+
if (isActive) {
|
|
221
|
+
// Check for updates when app becomes active
|
|
222
|
+
await CapacitorNativeUpdate.LiveUpdate.sync({
|
|
223
|
+
installMode: 'ON_NEXT_RESUME',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Handle Update Lifecycle
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
class UpdateManager {
|
|
233
|
+
async initialize() {
|
|
234
|
+
// Configure plugin
|
|
235
|
+
await CapacitorNativeUpdate.configure({
|
|
236
|
+
liveUpdate: {
|
|
237
|
+
appId: 'your-app-id',
|
|
238
|
+
serverUrl: 'https://your-server.com',
|
|
239
|
+
autoUpdate: true,
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// Set up listeners
|
|
244
|
+
this.setupListeners();
|
|
245
|
+
|
|
246
|
+
// Initial sync
|
|
247
|
+
await this.checkForUpdates();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
setupListeners() {
|
|
251
|
+
// Listen for update state changes
|
|
252
|
+
CapacitorNativeUpdate.LiveUpdate.addListener(
|
|
253
|
+
'updateStateChanged',
|
|
254
|
+
(event) => {
|
|
255
|
+
console.log('Update state:', event.status);
|
|
256
|
+
this.handleUpdateState(event);
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async checkForUpdates() {
|
|
262
|
+
try {
|
|
263
|
+
const result = await CapacitorNativeUpdate.LiveUpdate.sync();
|
|
264
|
+
|
|
265
|
+
if (result.status === 'UPDATE_INSTALLED') {
|
|
266
|
+
// Notify user about update
|
|
267
|
+
this.notifyUpdateInstalled(result.bundle.version);
|
|
268
|
+
}
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error('Update check failed:', error);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
handleUpdateState(event) {
|
|
275
|
+
switch (event.status) {
|
|
276
|
+
case 'DOWNLOADING':
|
|
277
|
+
// Show progress indicator
|
|
278
|
+
break;
|
|
279
|
+
case 'READY':
|
|
280
|
+
// Update downloaded, ready to install
|
|
281
|
+
break;
|
|
282
|
+
case 'FAILED':
|
|
283
|
+
// Handle failure
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Error Handling Best Practices
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
import { CapacitorNativeUpdateError } from 'capacitor-native-update';
|
|
294
|
+
|
|
295
|
+
async function safeUpdateCheck() {
|
|
296
|
+
try {
|
|
297
|
+
await CapacitorNativeUpdate.LiveUpdate.sync();
|
|
298
|
+
} catch (error) {
|
|
299
|
+
if (error instanceof CapacitorNativeUpdateError) {
|
|
300
|
+
switch (error.code) {
|
|
301
|
+
case 'NETWORK_ERROR':
|
|
302
|
+
// Handle network issues
|
|
303
|
+
console.log('No internet connection');
|
|
304
|
+
break;
|
|
305
|
+
case 'SERVER_ERROR':
|
|
306
|
+
// Server issues
|
|
307
|
+
console.log('Update server unavailable');
|
|
308
|
+
break;
|
|
309
|
+
case 'VERIFICATION_ERROR':
|
|
310
|
+
// Security validation failed
|
|
311
|
+
console.log('Update verification failed');
|
|
312
|
+
break;
|
|
313
|
+
default:
|
|
314
|
+
console.error('Update error:', error.message);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Testing Your Implementation
|
|
322
|
+
|
|
323
|
+
### Development Tips
|
|
324
|
+
|
|
325
|
+
1. **Use staging channel for testing**:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
await CapacitorNativeUpdate.LiveUpdate.setChannel('staging');
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
2. **Enable debug mode for app reviews**:
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
await CapacitorNativeUpdate.configure({
|
|
335
|
+
appReview: {
|
|
336
|
+
debugMode: true, // Bypass time restrictions
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
3. **Force update check**:
|
|
342
|
+
```typescript
|
|
343
|
+
// Clear cache and check
|
|
344
|
+
await CapacitorNativeUpdate.LiveUpdate.sync({
|
|
345
|
+
forceCheck: true,
|
|
346
|
+
});
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Next Steps
|
|
350
|
+
|
|
351
|
+
Now that you have the basics working:
|
|
352
|
+
|
|
353
|
+
1. Set up your [Update Server](../examples/server-setup.md)
|
|
354
|
+
2. Implement [Security Best Practices](../guides/security-best-practices.md)
|
|
355
|
+
3. Configure [Advanced Options](./configuration.md)
|
|
356
|
+
4. Explore [API Reference](../api/live-update-api.md) for all available methods
|
|
357
|
+
|
|
358
|
+
## Quick Reference
|
|
359
|
+
|
|
360
|
+
### Essential Methods
|
|
361
|
+
|
|
362
|
+
| Method | Purpose |
|
|
363
|
+
| ------------------------------ | ------------------------------- |
|
|
364
|
+
| `configure()` | Initialize plugin with settings |
|
|
365
|
+
| `LiveUpdate.sync()` | Check and apply updates |
|
|
366
|
+
| `LiveUpdate.current()` | Get current bundle info |
|
|
367
|
+
| `AppUpdate.getAppUpdateInfo()` | Check app store updates |
|
|
368
|
+
| `AppReview.requestReview()` | Request user review |
|
|
369
|
+
|
|
370
|
+
### Key Events
|
|
371
|
+
|
|
372
|
+
| Event | Description |
|
|
373
|
+
| -------------------- | ------------------------ |
|
|
374
|
+
| `downloadProgress` | Update download progress |
|
|
375
|
+
| `updateStateChanged` | Bundle state changes |
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
Made with ❤️ by Ahsan Mahmood
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# Deployment Guide
|
|
2
|
+
|
|
3
|
+
This guide covers deploying the Capacitor Native Update plugin to production.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Capacitor Native Update plugin configured
|
|
8
|
+
- Update server deployed
|
|
9
|
+
- SSL certificates configured
|
|
10
|
+
- CDN setup (optional but recommended)
|
|
11
|
+
|
|
12
|
+
## Server Deployment
|
|
13
|
+
|
|
14
|
+
### 1. Environment Setup
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Clone production backend
|
|
18
|
+
cd production-backend
|
|
19
|
+
|
|
20
|
+
# Install dependencies
|
|
21
|
+
npm install
|
|
22
|
+
|
|
23
|
+
# Set environment variables
|
|
24
|
+
cp .env.example .env
|
|
25
|
+
# Edit .env with production values
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### 2. Database Setup
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Initialize production database
|
|
32
|
+
npm run db:init
|
|
33
|
+
|
|
34
|
+
# For PostgreSQL (recommended for production)
|
|
35
|
+
# Update DB_PATH in .env to PostgreSQL connection string
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 3. Security Configuration
|
|
39
|
+
|
|
40
|
+
```env
|
|
41
|
+
# .env production settings
|
|
42
|
+
NODE_ENV=production
|
|
43
|
+
JWT_SECRET=<generate-strong-secret>
|
|
44
|
+
ADMIN_PASSWORD=<strong-password>
|
|
45
|
+
|
|
46
|
+
# Enable HTTPS only
|
|
47
|
+
ALLOWED_ORIGINS=https://your-app.com,capacitor://localhost
|
|
48
|
+
|
|
49
|
+
# Rate limiting
|
|
50
|
+
RATE_LIMIT_WINDOW=15
|
|
51
|
+
RATE_LIMIT_MAX=100
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 4. Deploy to Cloud
|
|
55
|
+
|
|
56
|
+
#### Option A: Docker Deployment
|
|
57
|
+
|
|
58
|
+
```dockerfile
|
|
59
|
+
# Dockerfile
|
|
60
|
+
FROM node:20-alpine
|
|
61
|
+
WORKDIR /app
|
|
62
|
+
COPY package*.json ./
|
|
63
|
+
RUN npm ci --only=production
|
|
64
|
+
COPY . .
|
|
65
|
+
EXPOSE 3000
|
|
66
|
+
CMD ["npm", "start"]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Build and run
|
|
71
|
+
docker build -t update-server .
|
|
72
|
+
docker run -p 3000:3000 update-server
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Option B: PM2 Deployment
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Install PM2
|
|
79
|
+
npm install -g pm2
|
|
80
|
+
|
|
81
|
+
# Start server
|
|
82
|
+
pm2 start src/index.js --name update-server
|
|
83
|
+
|
|
84
|
+
# Save PM2 config
|
|
85
|
+
pm2 save
|
|
86
|
+
pm2 startup
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## App Configuration
|
|
90
|
+
|
|
91
|
+
### 1. Production Keys
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// Generate RSA keys for production
|
|
95
|
+
const keys = await generateKeyPair();
|
|
96
|
+
// Store private key securely on server
|
|
97
|
+
// Embed public key in app
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 2. Configure Plugin
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
await CapacitorNativeUpdate.configure({
|
|
104
|
+
serverUrl: 'https://updates.your-domain.com',
|
|
105
|
+
publicKey: PRODUCTION_PUBLIC_KEY,
|
|
106
|
+
channel: 'production',
|
|
107
|
+
autoCheck: true,
|
|
108
|
+
checkInterval: 3600000, // 1 hour
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## CDN Setup
|
|
113
|
+
|
|
114
|
+
### 1. CloudFront Configuration
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"Origins": [{
|
|
119
|
+
"DomainName": "update-server.your-domain.com",
|
|
120
|
+
"OriginPath": "/api/bundles"
|
|
121
|
+
}],
|
|
122
|
+
"DefaultCacheBehavior": {
|
|
123
|
+
"TargetOriginId": "update-bundles",
|
|
124
|
+
"ViewerProtocolPolicy": "https-only",
|
|
125
|
+
"CachePolicyId": "658327ea-f89e-4fab-a63d-7e88639e58f6"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 2. Update Server Config
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
// Return CDN URLs for bundles
|
|
134
|
+
const cdnUrl = process.env.CDN_URL;
|
|
135
|
+
bundle.downloadUrl = `${cdnUrl}/${bundle.id}`;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Monitoring Setup
|
|
139
|
+
|
|
140
|
+
### 1. Application Monitoring
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Install monitoring dependencies
|
|
144
|
+
npm install @opentelemetry/api @opentelemetry/sdk-node
|
|
145
|
+
|
|
146
|
+
# Configure in server
|
|
147
|
+
const { NodeSDK } = require('@opentelemetry/sdk-node');
|
|
148
|
+
const sdk = new NodeSDK();
|
|
149
|
+
sdk.start();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 2. Health Checks
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Monitor endpoints
|
|
156
|
+
curl https://updates.your-domain.com/api/health
|
|
157
|
+
curl https://updates.your-domain.com/api/health/detailed
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### 3. Alerts Configuration
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
# CloudWatch alarms example
|
|
164
|
+
HighErrorRate:
|
|
165
|
+
MetricName: 4XXError
|
|
166
|
+
Threshold: 10
|
|
167
|
+
Period: 300
|
|
168
|
+
|
|
169
|
+
ServerDown:
|
|
170
|
+
MetricName: HealthCheck
|
|
171
|
+
Threshold: 1
|
|
172
|
+
Period: 60
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Release Process
|
|
176
|
+
|
|
177
|
+
### 1. Create Update Bundle
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Build your app
|
|
181
|
+
npm run build
|
|
182
|
+
|
|
183
|
+
# Create bundle
|
|
184
|
+
node tools/bundle-creator.js create ./www
|
|
185
|
+
|
|
186
|
+
# Sign bundle
|
|
187
|
+
node tools/bundle-signer.js sign bundle.zip private-key.pem
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 2. Upload to Server
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Create update record
|
|
194
|
+
curl -X POST https://updates.your-domain.com/api/updates/create \
|
|
195
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
196
|
+
-H "Content-Type: application/json" \
|
|
197
|
+
-d '{
|
|
198
|
+
"appId": "com.your.app",
|
|
199
|
+
"platform": "web",
|
|
200
|
+
"version": "1.1.0",
|
|
201
|
+
"channel": "production",
|
|
202
|
+
"description": "Bug fixes and improvements"
|
|
203
|
+
}'
|
|
204
|
+
|
|
205
|
+
# Upload bundle
|
|
206
|
+
curl -X POST https://updates.your-domain.com/api/bundles/upload/$UPDATE_ID \
|
|
207
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
208
|
+
-F "bundle=@bundle.zip" \
|
|
209
|
+
-F "signature=@bundle.sig"
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### 3. Gradual Rollout
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Start with 10% rollout
|
|
216
|
+
curl -X PUT https://updates.your-domain.com/api/updates/$UPDATE_ID \
|
|
217
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
218
|
+
-H "Content-Type: application/json" \
|
|
219
|
+
-d '{"rolloutPercentage": 10}'
|
|
220
|
+
|
|
221
|
+
# Monitor metrics, then increase
|
|
222
|
+
# 10% -> 25% -> 50% -> 100%
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Security Checklist
|
|
226
|
+
|
|
227
|
+
- [ ] HTTPS enforced on all endpoints
|
|
228
|
+
- [ ] API authentication configured
|
|
229
|
+
- [ ] Rate limiting enabled
|
|
230
|
+
- [ ] CORS properly configured
|
|
231
|
+
- [ ] Bundle signatures verified
|
|
232
|
+
- [ ] SSL certificates valid
|
|
233
|
+
- [ ] Secrets stored securely
|
|
234
|
+
- [ ] Database backups configured
|
|
235
|
+
- [ ] Access logs enabled
|
|
236
|
+
- [ ] Security headers configured
|
|
237
|
+
|
|
238
|
+
## Performance Optimization
|
|
239
|
+
|
|
240
|
+
### 1. Enable Compression
|
|
241
|
+
|
|
242
|
+
```javascript
|
|
243
|
+
// Already included in production server
|
|
244
|
+
app.use(compression());
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 2. Database Indexing
|
|
248
|
+
|
|
249
|
+
```sql
|
|
250
|
+
-- Ensure indexes exist
|
|
251
|
+
CREATE INDEX idx_updates_lookup
|
|
252
|
+
ON updates(app_id, platform, channel, enabled);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### 3. Bundle Optimization
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Compress bundles before upload
|
|
259
|
+
zip -r -9 bundle.zip www/
|
|
260
|
+
|
|
261
|
+
# Consider differential updates
|
|
262
|
+
# Only include changed files
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Backup Strategy
|
|
266
|
+
|
|
267
|
+
### 1. Database Backups
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
# Daily backups
|
|
271
|
+
0 2 * * * pg_dump update_db > backup_$(date +\%Y\%m\%d).sql
|
|
272
|
+
|
|
273
|
+
# Keep 30 days of backups
|
|
274
|
+
find ./backups -name "*.sql" -mtime +30 -delete
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 2. Bundle Storage
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
# Sync bundles to S3
|
|
281
|
+
aws s3 sync ./storage/bundles s3://your-backup-bucket/bundles
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Troubleshooting
|
|
285
|
+
|
|
286
|
+
### Common Issues
|
|
287
|
+
|
|
288
|
+
1. **SSL Certificate Errors**
|
|
289
|
+
- Verify certificate chain
|
|
290
|
+
- Check certificate expiration
|
|
291
|
+
- Ensure proper domain configuration
|
|
292
|
+
|
|
293
|
+
2. **CORS Issues**
|
|
294
|
+
- Add app origin to ALLOWED_ORIGINS
|
|
295
|
+
- Check preflight requests
|
|
296
|
+
|
|
297
|
+
3. **Download Failures**
|
|
298
|
+
- Check CDN configuration
|
|
299
|
+
- Verify bundle permissions
|
|
300
|
+
- Monitor server logs
|
|
301
|
+
|
|
302
|
+
### Debug Mode
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
// Enable debug logging in production
|
|
306
|
+
CapacitorNativeUpdate.configure({
|
|
307
|
+
debug: process.env.NODE_ENV !== 'production',
|
|
308
|
+
serverUrl: 'https://updates.your-domain.com',
|
|
309
|
+
});
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Maintenance
|
|
313
|
+
|
|
314
|
+
### Regular Tasks
|
|
315
|
+
|
|
316
|
+
- [ ] Weekly: Check server health
|
|
317
|
+
- [ ] Monthly: Review analytics
|
|
318
|
+
- [ ] Monthly: Clean old bundles
|
|
319
|
+
- [ ] Quarterly: Update dependencies
|
|
320
|
+
- [ ] Yearly: Rotate certificates
|
|
321
|
+
|
|
322
|
+
### Update Server
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# Update dependencies
|
|
326
|
+
npm update
|
|
327
|
+
|
|
328
|
+
# Restart server
|
|
329
|
+
pm2 restart update-server
|
|
330
|
+
|
|
331
|
+
# Check logs
|
|
332
|
+
pm2 logs update-server
|
|
333
|
+
```
|