native-update 1.3.2 → 1.3.4
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/android/build.gradle +12 -0
- package/cli/package.json +1 -1
- package/docs/FIREBASE_QUERIES_AND_INDEXES_AUDIT.md +221 -0
- package/docs/PROJECT_COMPLETION_TRACKER.md +438 -239
- package/docs/REMAINING_FEATURES.md +130 -125
- package/docs/ROADMAP.md +182 -110
- package/docs/TESTING_REQUIREMENTS.md +312 -0
- package/docs/guides/BACKEND_TEMPLATES_GUIDE.md +183 -0
- package/docs/reports/COMPLETE_VERIFICATION.md +1 -1
- package/docs/reports/PRODUCTION_STATUS.md +1 -1
- package/package.json +5 -5
- package/cli/cap-update.js +0 -45
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# Testing Requirements
|
|
2
|
+
|
|
3
|
+
This document outlines the testing requirements for the native-update plugin.
|
|
4
|
+
|
|
5
|
+
## Current Testing Status
|
|
6
|
+
|
|
7
|
+
- **Plugin testing**: Handled in actual/live applications using the plugin
|
|
8
|
+
- **Example apps**: Demonstrate functionality for manual testing
|
|
9
|
+
- **Unit tests (TypeScript)**: ✅ Implemented in `/src/__tests__/`
|
|
10
|
+
- **iOS Native Tests (XCTest)**: ✅ Implemented in `/ios/Tests/NativeUpdateTests/`
|
|
11
|
+
- **Android Native Tests (JUnit/Kotlin)**: ✅ Implemented in `/android/src/test/`
|
|
12
|
+
- **E2E Tests (Detox)**: ✅ Implemented in `/e2e/`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## iOS Native Tests (XCTest)
|
|
17
|
+
|
|
18
|
+
### Test File Structure
|
|
19
|
+
```
|
|
20
|
+
ios/
|
|
21
|
+
└── Tests/
|
|
22
|
+
└── NativeUpdateTests/
|
|
23
|
+
├── LiveUpdateTests.swift
|
|
24
|
+
├── AppUpdateTests.swift
|
|
25
|
+
├── AppReviewTests.swift
|
|
26
|
+
├── BundleManagerTests.swift
|
|
27
|
+
└── SecurityTests.swift
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Test Categories
|
|
31
|
+
|
|
32
|
+
#### LiveUpdateTests.swift
|
|
33
|
+
- `testCheckForUpdate()` - Verify update check returns correct response
|
|
34
|
+
- `testDownloadBundle()` - Verify bundle download with progress
|
|
35
|
+
- `testApplyUpdate()` - Verify bundle extraction and application
|
|
36
|
+
- `testRollback()` - Verify rollback to previous version
|
|
37
|
+
- `testChecksumVerification()` - Verify SHA-256 checksum validation
|
|
38
|
+
- `testSignatureVerification()` - Verify RSA/ECDSA signature validation
|
|
39
|
+
- `testChannelManagement()` - Verify channel switching (production/staging/dev)
|
|
40
|
+
|
|
41
|
+
#### AppUpdateTests.swift
|
|
42
|
+
- `testCheckAppStoreVersion()` - Verify app store version check
|
|
43
|
+
- `testVersionComparison()` - Verify semantic version comparison
|
|
44
|
+
- `testUpdateAvailability()` - Verify update availability detection
|
|
45
|
+
- `testOpenAppStore()` - Verify App Store navigation
|
|
46
|
+
|
|
47
|
+
#### AppReviewTests.swift
|
|
48
|
+
- `testRequestReview()` - Verify StoreKit review request
|
|
49
|
+
- `testRateLimiting()` - Verify review request rate limiting
|
|
50
|
+
|
|
51
|
+
#### BundleManagerTests.swift
|
|
52
|
+
- `testBundleStorage()` - Verify bundle storage in app sandbox
|
|
53
|
+
- `testBundleCleanup()` - Verify old bundle cleanup
|
|
54
|
+
- `testActiveBundlePath()` - Verify active bundle path resolution
|
|
55
|
+
|
|
56
|
+
#### SecurityTests.swift
|
|
57
|
+
- `testInputValidation()` - Verify URL/input sanitization
|
|
58
|
+
- `testHTTPSEnforcement()` - Verify HTTPS-only connections
|
|
59
|
+
- `testDowngradeProtection()` - Verify version downgrade prevention
|
|
60
|
+
- `testKeychain Storage()` - Verify sensitive data in Keychain
|
|
61
|
+
|
|
62
|
+
### Running iOS Tests
|
|
63
|
+
```bash
|
|
64
|
+
cd ios
|
|
65
|
+
xcodebuild test -scheme NativeUpdate -destination 'platform=iOS Simulator,name=iPhone 15'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Current Test Files (✅ Implemented)
|
|
69
|
+
|
|
70
|
+
| File | Tests | Status |
|
|
71
|
+
|------|-------|--------|
|
|
72
|
+
| `SecurityManagerTests.swift` | 6 tests | ✅ |
|
|
73
|
+
| `LiveUpdateTests.swift` | 10 tests | ✅ |
|
|
74
|
+
| `AppUpdateTests.swift` | 5 tests | ✅ |
|
|
75
|
+
| `AppReviewTests.swift` | 5 tests | ✅ |
|
|
76
|
+
| `BackgroundUpdateTests.swift` | 6 tests | ✅ |
|
|
77
|
+
| **Total** | **32 tests** | ✅ |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Android Native Tests (JUnit)
|
|
82
|
+
|
|
83
|
+
### Test File Structure
|
|
84
|
+
```
|
|
85
|
+
android/
|
|
86
|
+
└── src/
|
|
87
|
+
└── test/
|
|
88
|
+
└── java/
|
|
89
|
+
└── com/
|
|
90
|
+
└── aoneahsan/
|
|
91
|
+
└── nativeupdate/
|
|
92
|
+
├── LiveUpdateTest.kt
|
|
93
|
+
├── AppUpdateTest.kt
|
|
94
|
+
├── AppReviewTest.kt
|
|
95
|
+
├── BundleManagerTest.kt
|
|
96
|
+
└── SecurityTest.kt
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Test Categories
|
|
100
|
+
|
|
101
|
+
#### LiveUpdateTest.kt
|
|
102
|
+
- `testCheckForUpdate()` - Verify update check HTTP request
|
|
103
|
+
- `testDownloadBundle()` - Verify bundle download with OkHttp
|
|
104
|
+
- `testApplyUpdate()` - Verify bundle extraction to internal storage
|
|
105
|
+
- `testRollback()` - Verify rollback mechanism
|
|
106
|
+
- `testChecksumVerification()` - Verify SHA-256 validation
|
|
107
|
+
- `testSignatureVerification()` - Verify signature with Android Keystore
|
|
108
|
+
- `testChannelManagement()` - Verify channel configuration
|
|
109
|
+
|
|
110
|
+
#### AppUpdateTest.kt
|
|
111
|
+
- `testCheckPlayStoreVersion()` - Verify Play Core version check
|
|
112
|
+
- `testImmediateUpdate()` - Verify blocking update flow
|
|
113
|
+
- `testFlexibleUpdate()` - Verify background update flow
|
|
114
|
+
- `testUpdatePriority()` - Verify update priority handling
|
|
115
|
+
|
|
116
|
+
#### AppReviewTest.kt
|
|
117
|
+
- `testRequestReview()` - Verify Play Core review API
|
|
118
|
+
- `testReviewManagerInitialization()` - Verify ReviewManager setup
|
|
119
|
+
- `testRateLimiting()` - Verify request limiting
|
|
120
|
+
|
|
121
|
+
#### BundleManagerTest.kt
|
|
122
|
+
- `testBundleStorage()` - Verify internal storage operations
|
|
123
|
+
- `testBundleCleanup()` - Verify old bundle deletion
|
|
124
|
+
- `testActiveBundlePath()` - Verify bundle path resolution
|
|
125
|
+
- `testStoragePermissions()` - Verify no external storage access
|
|
126
|
+
|
|
127
|
+
#### SecurityTest.kt
|
|
128
|
+
- `testInputValidation()` - Verify input sanitization
|
|
129
|
+
- `testHTTPSEnforcement()` - Verify HTTPS-only policy
|
|
130
|
+
- `testDowngradeProtection()` - Verify version validation
|
|
131
|
+
- `testKeystore()` - Verify Android Keystore usage
|
|
132
|
+
|
|
133
|
+
### Running Android Tests
|
|
134
|
+
```bash
|
|
135
|
+
cd android
|
|
136
|
+
./gradlew test
|
|
137
|
+
./gradlew connectedAndroidTest # For instrumented tests
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Current Test Files (✅ Implemented)
|
|
141
|
+
|
|
142
|
+
| File | Tests | Status |
|
|
143
|
+
|------|-------|--------|
|
|
144
|
+
| `SecurityManagerTest.kt` | 10 tests | ✅ |
|
|
145
|
+
| `LiveUpdatePluginTest.kt` | 10 tests | ✅ |
|
|
146
|
+
| `AppUpdatePluginTest.kt` | 5 tests | ✅ |
|
|
147
|
+
| `AppReviewPluginTest.kt` | 5 tests | ✅ |
|
|
148
|
+
| `BackgroundUpdateWorkerTest.kt` | 5 tests | ✅ |
|
|
149
|
+
| `BackgroundNotificationManagerTest.kt` | 5 tests | ✅ |
|
|
150
|
+
| **Total** | **40 tests** | ✅ |
|
|
151
|
+
|
|
152
|
+
### Test Dependencies (Added to build.gradle)
|
|
153
|
+
|
|
154
|
+
```gradle
|
|
155
|
+
testImplementation 'junit:junit:4.13.2'
|
|
156
|
+
testImplementation 'org.mockito:mockito-core:5.8.0'
|
|
157
|
+
testImplementation 'org.mockito.kotlin:mockito-kotlin:5.2.1'
|
|
158
|
+
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
|
|
159
|
+
testImplementation 'com.google.truth:truth:1.1.5'
|
|
160
|
+
testImplementation 'org.robolectric:robolectric:4.11.1'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## End-to-End Tests (Detox) ✅ IMPLEMENTED
|
|
166
|
+
|
|
167
|
+
The E2E tests are implemented in `/e2e/` using Detox framework.
|
|
168
|
+
|
|
169
|
+
### Framework
|
|
170
|
+
- **Detox** for React Native + Capacitor apps
|
|
171
|
+
|
|
172
|
+
### Test Coverage
|
|
173
|
+
|
|
174
|
+
| Spec File | Tests | Status |
|
|
175
|
+
|-----------|-------|--------|
|
|
176
|
+
| `ota-update.e2e.spec.js` | 5 tests | ✅ |
|
|
177
|
+
| `download-progress.e2e.spec.js` | 5 tests | ✅ |
|
|
178
|
+
| `channel-switching.e2e.spec.js` | 5 tests | ✅ |
|
|
179
|
+
| `error-handling.e2e.spec.js` | 4 tests | ✅ |
|
|
180
|
+
| **Total** | **19 tests** | ✅ |
|
|
181
|
+
|
|
182
|
+
### Running E2E Tests
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
cd e2e
|
|
186
|
+
yarn install
|
|
187
|
+
yarn build:android # or yarn build:ios
|
|
188
|
+
yarn test:android # or yarn test:ios
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Mock Server
|
|
192
|
+
|
|
193
|
+
Start the mock update server for E2E tests:
|
|
194
|
+
```bash
|
|
195
|
+
yarn start-mock-server
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Test Scenarios
|
|
199
|
+
|
|
200
|
+
#### OTA Update Flow
|
|
201
|
+
```
|
|
202
|
+
1. App starts with version 1.0.0
|
|
203
|
+
2. Server has version 1.1.0 available
|
|
204
|
+
3. App checks for update → receives update info
|
|
205
|
+
4. App downloads bundle → shows progress
|
|
206
|
+
5. App applies update → restarts
|
|
207
|
+
6. App shows version 1.1.0
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### Rollback Flow
|
|
211
|
+
```
|
|
212
|
+
1. App has version 1.1.0 applied
|
|
213
|
+
2. New update 1.2.0 has critical bug
|
|
214
|
+
3. App applies 1.2.0 → crashes on start
|
|
215
|
+
4. App automatically rolls back to 1.1.0
|
|
216
|
+
5. App reports rollback to server
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### Native Update Flow
|
|
220
|
+
```
|
|
221
|
+
1. App version 1.0.0 installed from store
|
|
222
|
+
2. Store has version 2.0.0 (native update required)
|
|
223
|
+
3. App detects native update available
|
|
224
|
+
4. User shown update prompt
|
|
225
|
+
5. User redirected to app store
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Channel Switching
|
|
229
|
+
```
|
|
230
|
+
1. App configured for 'production' channel
|
|
231
|
+
2. Developer switches to 'staging' channel
|
|
232
|
+
3. App receives staging bundle
|
|
233
|
+
4. App applies staging updates
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### E2E Test File Structure
|
|
237
|
+
```
|
|
238
|
+
e2e/
|
|
239
|
+
├── specs/
|
|
240
|
+
│ ├── ota-update.spec.js
|
|
241
|
+
│ ├── rollback.spec.js
|
|
242
|
+
│ ├── native-update.spec.js
|
|
243
|
+
│ └── channel-switching.spec.js
|
|
244
|
+
├── helpers/
|
|
245
|
+
│ └── server-mock.js
|
|
246
|
+
└── setup.js
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Test Server for E2E
|
|
252
|
+
|
|
253
|
+
A mock update server should provide:
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
// Mock endpoints
|
|
257
|
+
GET /api/updates/check?appId=xxx&version=1.0.0&channel=production
|
|
258
|
+
POST /api/updates/download/:bundleId
|
|
259
|
+
POST /api/updates/report
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The CLI already provides `npx native-update server start` for local testing.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Security Testing Checklist
|
|
267
|
+
|
|
268
|
+
- [ ] Test with malformed bundle files (corrupted ZIP)
|
|
269
|
+
- [ ] Test with invalid checksums
|
|
270
|
+
- [ ] Test with expired/invalid signatures
|
|
271
|
+
- [ ] Test with HTTP URLs (should be rejected)
|
|
272
|
+
- [ ] Test downgrade attempts (should be blocked)
|
|
273
|
+
- [ ] Test oversized bundles (should respect limits)
|
|
274
|
+
- [ ] Test with network interruptions
|
|
275
|
+
- [ ] Test permission denial scenarios
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## Test Implementation Status
|
|
280
|
+
|
|
281
|
+
All test categories have been implemented as of 2026-01-16:
|
|
282
|
+
|
|
283
|
+
| Category | Location | Tests | Status |
|
|
284
|
+
|----------|----------|-------|--------|
|
|
285
|
+
| TypeScript Unit Tests | `/src/__tests__/` | 9 test files | ✅ Complete |
|
|
286
|
+
| iOS Native Tests | `/ios/Tests/NativeUpdateTests/` | 5 test files, 32 tests | ✅ Complete |
|
|
287
|
+
| Android Native Tests | `/android/src/test/.../nativeupdate/` | 6 test files, 40 tests | ✅ Complete |
|
|
288
|
+
| E2E Tests | `/e2e/specs/` | 4 spec files, 19 tests | ✅ Complete |
|
|
289
|
+
| **Total** | | **~100 tests** | ✅ Complete |
|
|
290
|
+
|
|
291
|
+
## Running All Tests
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
# TypeScript Unit Tests
|
|
295
|
+
yarn test
|
|
296
|
+
|
|
297
|
+
# iOS Native Tests
|
|
298
|
+
cd ios && xcodebuild test -scheme NativeUpdate -destination 'platform=iOS Simulator,name=iPhone 15'
|
|
299
|
+
|
|
300
|
+
# Android Native Tests
|
|
301
|
+
cd android && ./gradlew test
|
|
302
|
+
|
|
303
|
+
# E2E Tests
|
|
304
|
+
cd e2e && yarn install && yarn test:android # or yarn test:ios
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Additional Testing
|
|
308
|
+
|
|
309
|
+
Manual testing is also supported through:
|
|
310
|
+
- Example apps for end-user testing
|
|
311
|
+
- CLI command verification
|
|
312
|
+
- Integration testing in production apps
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Backend Templates Guide
|
|
2
|
+
|
|
3
|
+
This guide explains the backend templates provided by the native-update CLI and how to customize them for your production environment.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `npx native-update backend create <type>` command generates backend templates for managing OTA updates. These templates are **starting points** that require customization for your specific infrastructure.
|
|
8
|
+
|
|
9
|
+
## Available Templates
|
|
10
|
+
|
|
11
|
+
| Template | Command | Use Case |
|
|
12
|
+
|----------|---------|----------|
|
|
13
|
+
| Express.js | `npx native-update backend create express` | Self-hosted Node.js server |
|
|
14
|
+
| Firebase | `npx native-update backend create firebase` | Serverless with Firebase Functions |
|
|
15
|
+
| Vercel | `npx native-update backend create vercel` | Serverless with Vercel Edge Functions |
|
|
16
|
+
|
|
17
|
+
## Template Structure
|
|
18
|
+
|
|
19
|
+
Each template includes:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
native-update-backend/
|
|
23
|
+
├── src/
|
|
24
|
+
│ ├── routes/
|
|
25
|
+
│ │ ├── updates.js # Update check/download endpoints
|
|
26
|
+
│ │ └── admin.js # Admin dashboard routes (if --with-admin)
|
|
27
|
+
│ ├── services/
|
|
28
|
+
│ │ ├── storage.js # Bundle storage service (CUSTOMIZE THIS)
|
|
29
|
+
│ │ └── database.js # Metadata storage (CUSTOMIZE THIS)
|
|
30
|
+
│ └── index.js # Entry point
|
|
31
|
+
├── package.json
|
|
32
|
+
└── README.md
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Understanding Placeholder Code
|
|
36
|
+
|
|
37
|
+
The generated templates contain placeholder implementations marked with comments explaining what you need to implement. These are **intentional customization points**, not incomplete code.
|
|
38
|
+
|
|
39
|
+
### Example: Storage Service
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// storage.js - CUSTOMIZE FOR YOUR INFRASTRUCTURE
|
|
43
|
+
export async function storeBundle(bundleId, file) {
|
|
44
|
+
// Implement your storage logic here
|
|
45
|
+
// Options:
|
|
46
|
+
// - AWS S3: Use @aws-sdk/client-s3
|
|
47
|
+
// - Google Cloud Storage: Use @google-cloud/storage
|
|
48
|
+
// - Azure Blob: Use @azure/storage-blob
|
|
49
|
+
// - Local filesystem: Use fs/promises
|
|
50
|
+
throw new Error('Storage not configured - implement storeBundle()');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function getBundle(bundleId) {
|
|
54
|
+
// Implement your retrieval logic here
|
|
55
|
+
throw new Error('Storage not configured - implement getBundle()');
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Example: Database Service
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// database.js - CUSTOMIZE FOR YOUR INFRASTRUCTURE
|
|
63
|
+
export async function saveBundleMetadata(metadata) {
|
|
64
|
+
// Implement your database logic here
|
|
65
|
+
// Options:
|
|
66
|
+
// - PostgreSQL: Use pg or prisma
|
|
67
|
+
// - MongoDB: Use mongoose
|
|
68
|
+
// - Firebase Firestore: Use firebase-admin
|
|
69
|
+
// - MySQL: Use mysql2
|
|
70
|
+
throw new Error('Database not configured - implement saveBundleMetadata()');
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Customization Guide
|
|
75
|
+
|
|
76
|
+
### Step 1: Choose Your Storage
|
|
77
|
+
|
|
78
|
+
| Storage Option | Package | Best For |
|
|
79
|
+
|----------------|---------|----------|
|
|
80
|
+
| AWS S3 | `@aws-sdk/client-s3` | Production, scalable |
|
|
81
|
+
| Google Cloud Storage | `@google-cloud/storage` | GCP infrastructure |
|
|
82
|
+
| Azure Blob | `@azure/storage-blob` | Azure infrastructure |
|
|
83
|
+
| Local Filesystem | `fs/promises` | Development only |
|
|
84
|
+
| Cloudflare R2 | `@aws-sdk/client-s3` | Cost-effective |
|
|
85
|
+
|
|
86
|
+
### Step 2: Choose Your Database
|
|
87
|
+
|
|
88
|
+
| Database Option | Package | Best For |
|
|
89
|
+
|----------------|---------|----------|
|
|
90
|
+
| PostgreSQL | `pg`, `prisma` | Production, relational |
|
|
91
|
+
| MongoDB | `mongoose` | Document-based |
|
|
92
|
+
| Firebase Firestore | `firebase-admin` | Serverless |
|
|
93
|
+
| SQLite | `better-sqlite3` | Small deployments |
|
|
94
|
+
| Redis | `ioredis` | Caching, fast reads |
|
|
95
|
+
|
|
96
|
+
### Step 3: Implement the Services
|
|
97
|
+
|
|
98
|
+
Replace the placeholder functions with your actual implementations:
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
// Example: AWS S3 implementation
|
|
102
|
+
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
103
|
+
|
|
104
|
+
const s3 = new S3Client({ region: process.env.AWS_REGION });
|
|
105
|
+
|
|
106
|
+
export async function storeBundle(bundleId, file) {
|
|
107
|
+
await s3.send(new PutObjectCommand({
|
|
108
|
+
Bucket: process.env.S3_BUCKET,
|
|
109
|
+
Key: `bundles/${bundleId}.zip`,
|
|
110
|
+
Body: file,
|
|
111
|
+
}));
|
|
112
|
+
return `bundles/${bundleId}.zip`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export async function getBundle(bundleId) {
|
|
116
|
+
const response = await s3.send(new GetObjectCommand({
|
|
117
|
+
Bucket: process.env.S3_BUCKET,
|
|
118
|
+
Key: `bundles/${bundleId}.zip`,
|
|
119
|
+
}));
|
|
120
|
+
return response.Body;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Template Options
|
|
125
|
+
|
|
126
|
+
### --with-admin
|
|
127
|
+
|
|
128
|
+
Adds an admin dashboard for:
|
|
129
|
+
- Viewing deployed bundles
|
|
130
|
+
- Monitoring update adoption
|
|
131
|
+
- Managing channels
|
|
132
|
+
- Viewing device statistics
|
|
133
|
+
|
|
134
|
+
### --with-monitoring
|
|
135
|
+
|
|
136
|
+
Adds monitoring endpoints for:
|
|
137
|
+
- Health checks
|
|
138
|
+
- Prometheus metrics
|
|
139
|
+
- Update success/failure rates
|
|
140
|
+
- Download statistics
|
|
141
|
+
|
|
142
|
+
## Production Checklist
|
|
143
|
+
|
|
144
|
+
Before deploying to production:
|
|
145
|
+
|
|
146
|
+
- [ ] Implement storage service for your cloud provider
|
|
147
|
+
- [ ] Implement database service for metadata
|
|
148
|
+
- [ ] Configure environment variables
|
|
149
|
+
- [ ] Set up authentication for admin endpoints
|
|
150
|
+
- [ ] Configure HTTPS/TLS
|
|
151
|
+
- [ ] Set up rate limiting
|
|
152
|
+
- [ ] Configure logging (Winston, Pino, etc.)
|
|
153
|
+
- [ ] Set up error tracking (Sentry, etc.)
|
|
154
|
+
- [ ] Configure backup strategy for bundles
|
|
155
|
+
|
|
156
|
+
## Environment Variables
|
|
157
|
+
|
|
158
|
+
Templates expect these environment variables:
|
|
159
|
+
|
|
160
|
+
```env
|
|
161
|
+
# Server
|
|
162
|
+
PORT=3000
|
|
163
|
+
NODE_ENV=production
|
|
164
|
+
|
|
165
|
+
# Storage (example for S3)
|
|
166
|
+
AWS_REGION=us-east-1
|
|
167
|
+
S3_BUCKET=my-update-bundles
|
|
168
|
+
AWS_ACCESS_KEY_ID=xxx
|
|
169
|
+
AWS_SECRET_ACCESS_KEY=xxx
|
|
170
|
+
|
|
171
|
+
# Database (example for PostgreSQL)
|
|
172
|
+
DATABASE_URL=postgres://user:pass@host:5432/dbname
|
|
173
|
+
|
|
174
|
+
# Security
|
|
175
|
+
API_KEY=your-admin-api-key
|
|
176
|
+
SIGNING_PUBLIC_KEY_PATH=./keys/public.pem
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Related Documentation
|
|
180
|
+
|
|
181
|
+
- [Deployment Guide](./deployment-guide.md) - Full deployment instructions
|
|
182
|
+
- [Security Best Practices](./security-best-practices.md) - Security recommendations
|
|
183
|
+
- [Key Management](./key-management.md) - Managing signing keys
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
2. **Development Tools** ✅
|
|
18
18
|
- Bundle creation utility (`tools/bundle-creator.js`)
|
|
19
19
|
- Bundle signing tool (`tools/bundle-signer.js`)
|
|
20
|
-
- CLI tool (`cli/
|
|
20
|
+
- CLI tool (`cli/index.js`)
|
|
21
21
|
- Testing framework with Vitest
|
|
22
22
|
- Unit and integration tests
|
|
23
23
|
|
|
@@ -20,7 +20,7 @@ This document summarizes the current production readiness status of the capacito
|
|
|
20
20
|
- Bundle creation utility (`tools/bundle-creator.js`)
|
|
21
21
|
- Bundle signing tool (`tools/bundle-signer.js`)
|
|
22
22
|
- Minimal backend server template (`backend-template/`)
|
|
23
|
-
- CLI tool for easier usage (`cli/
|
|
23
|
+
- CLI tool for easier usage (`cli/index.js`)
|
|
24
24
|
|
|
25
25
|
### Core Features ✅
|
|
26
26
|
- Client-side signature verification using Web Crypto API
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "native-update",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Foundation package for building a comprehensive update system for Capacitor apps. Provides architecture and interfaces but requires backend implementation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/plugin.cjs.js",
|
|
@@ -89,20 +89,20 @@
|
|
|
89
89
|
"@rollup/plugin-json": "^6.1.0",
|
|
90
90
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
91
91
|
"@rollup/plugin-terser": "^0.4.4",
|
|
92
|
-
"@types/node": "^25.0.
|
|
92
|
+
"@types/node": "^25.0.9",
|
|
93
93
|
"@typescript-eslint/eslint-plugin": "^8.53.0",
|
|
94
94
|
"@typescript-eslint/parser": "^8.53.0",
|
|
95
95
|
"@vitest/ui": "^4.0.17",
|
|
96
96
|
"eslint": "^9.39.2",
|
|
97
|
-
"happy-dom": "^20.1
|
|
98
|
-
"prettier": "^3.
|
|
97
|
+
"happy-dom": "^20.3.1",
|
|
98
|
+
"prettier": "^3.8.0",
|
|
99
99
|
"rimraf": "^6.1.2",
|
|
100
100
|
"rollup": "^4.55.1",
|
|
101
101
|
"typescript": "^5.9.3",
|
|
102
102
|
"vitest": "^4.0.17"
|
|
103
103
|
},
|
|
104
104
|
"peerDependencies": {
|
|
105
|
-
"@capacitor/core": "^8.0.
|
|
105
|
+
"@capacitor/core": "^8.0.1"
|
|
106
106
|
},
|
|
107
107
|
"capacitor": {
|
|
108
108
|
"ios": {
|
package/cli/cap-update.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { readFileSync } from 'fs';
|
|
5
|
-
import { resolve } from 'path';
|
|
6
|
-
|
|
7
|
-
const program = new Command();
|
|
8
|
-
const packageJson = JSON.parse(
|
|
9
|
-
readFileSync(resolve(process.cwd(), 'package.json'), 'utf8')
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
program
|
|
13
|
-
.name('cap-update')
|
|
14
|
-
.description('CLI for Capacitor Native Update')
|
|
15
|
-
.version('1.0.0');
|
|
16
|
-
|
|
17
|
-
program
|
|
18
|
-
.command('init')
|
|
19
|
-
.description('Initialize update configuration')
|
|
20
|
-
.option('-s, --server <url>', 'Update server URL')
|
|
21
|
-
.action((options) => {
|
|
22
|
-
console.log('Initializing Capacitor Native Update...');
|
|
23
|
-
console.log('Server:', options.server || 'Not specified');
|
|
24
|
-
// TODO: Create config file
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
program
|
|
28
|
-
.command('bundle')
|
|
29
|
-
.description('Create update bundle')
|
|
30
|
-
.argument('<path>', 'Path to dist directory')
|
|
31
|
-
.action((path) => {
|
|
32
|
-
console.log(`Creating bundle from: ${path}`);
|
|
33
|
-
// TODO: Call bundle creator
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
program
|
|
37
|
-
.command('sign')
|
|
38
|
-
.description('Sign update bundle')
|
|
39
|
-
.argument('<bundle>', 'Bundle file path')
|
|
40
|
-
.action((bundle) => {
|
|
41
|
-
console.log(`Signing bundle: ${bundle}`);
|
|
42
|
-
// TODO: Call bundle signer
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
program.parse();
|