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.
Files changed (184) hide show
  1. package/CapacitorNativeUpdate.podspec +18 -0
  2. package/LICENSE +21 -0
  3. package/Readme.md +451 -0
  4. package/android/build.gradle +92 -0
  5. package/android/gradle/wrapper/gradle-wrapper.properties +8 -0
  6. package/android/gradle.properties +17 -0
  7. package/android/proguard-rules.pro +29 -0
  8. package/android/settings.gradle +2 -0
  9. package/android/src/main/AndroidManifest.xml +34 -0
  10. package/android/src/main/java/com/aoneahsan/nativeupdate/AppReviewPlugin.kt +153 -0
  11. package/android/src/main/java/com/aoneahsan/nativeupdate/AppUpdatePlugin.kt +275 -0
  12. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +390 -0
  13. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateManager.kt +46 -0
  14. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +333 -0
  15. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +251 -0
  16. package/android/src/main/java/com/aoneahsan/nativeupdate/CapacitorNativeUpdatePlugin.kt +265 -0
  17. package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +526 -0
  18. package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +99 -0
  19. package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +249 -0
  20. package/dist/esm/__tests__/bundle-manager.test.d.ts +1 -0
  21. package/dist/esm/__tests__/bundle-manager.test.js +123 -0
  22. package/dist/esm/__tests__/bundle-manager.test.js.map +1 -0
  23. package/dist/esm/__tests__/config.test.d.ts +1 -0
  24. package/dist/esm/__tests__/config.test.js +69 -0
  25. package/dist/esm/__tests__/config.test.js.map +1 -0
  26. package/dist/esm/__tests__/integration.test.d.ts +1 -0
  27. package/dist/esm/__tests__/integration.test.js +78 -0
  28. package/dist/esm/__tests__/integration.test.js.map +1 -0
  29. package/dist/esm/__tests__/security.test.d.ts +1 -0
  30. package/dist/esm/__tests__/security.test.js +54 -0
  31. package/dist/esm/__tests__/security.test.js.map +1 -0
  32. package/dist/esm/__tests__/version-manager.test.d.ts +1 -0
  33. package/dist/esm/__tests__/version-manager.test.js +45 -0
  34. package/dist/esm/__tests__/version-manager.test.js.map +1 -0
  35. package/dist/esm/app-review/app-review-manager.d.ts +24 -0
  36. package/dist/esm/app-review/app-review-manager.js +195 -0
  37. package/dist/esm/app-review/app-review-manager.js.map +1 -0
  38. package/dist/esm/app-review/index.d.ts +5 -0
  39. package/dist/esm/app-review/index.js +6 -0
  40. package/dist/esm/app-review/index.js.map +1 -0
  41. package/dist/esm/app-review/platform-review-handler.d.ts +20 -0
  42. package/dist/esm/app-review/platform-review-handler.js +138 -0
  43. package/dist/esm/app-review/platform-review-handler.js.map +1 -0
  44. package/dist/esm/app-review/review-conditions-checker.d.ts +22 -0
  45. package/dist/esm/app-review/review-conditions-checker.js +155 -0
  46. package/dist/esm/app-review/review-conditions-checker.js.map +1 -0
  47. package/dist/esm/app-review/review-rate-limiter.d.ts +23 -0
  48. package/dist/esm/app-review/review-rate-limiter.js +164 -0
  49. package/dist/esm/app-review/review-rate-limiter.js.map +1 -0
  50. package/dist/esm/app-review/types.d.ts +41 -0
  51. package/dist/esm/app-review/types.js +2 -0
  52. package/dist/esm/app-review/types.js.map +1 -0
  53. package/dist/esm/app-update/app-update-checker.d.ts +13 -0
  54. package/dist/esm/app-update/app-update-checker.js +104 -0
  55. package/dist/esm/app-update/app-update-checker.js.map +1 -0
  56. package/dist/esm/app-update/app-update-installer.d.ts +19 -0
  57. package/dist/esm/app-update/app-update-installer.js +123 -0
  58. package/dist/esm/app-update/app-update-installer.js.map +1 -0
  59. package/dist/esm/app-update/app-update-manager.d.ts +28 -0
  60. package/dist/esm/app-update/app-update-manager.js +199 -0
  61. package/dist/esm/app-update/app-update-manager.js.map +1 -0
  62. package/dist/esm/app-update/app-update-notifier.d.ts +14 -0
  63. package/dist/esm/app-update/app-update-notifier.js +100 -0
  64. package/dist/esm/app-update/app-update-notifier.js.map +1 -0
  65. package/dist/esm/app-update/index.d.ts +6 -0
  66. package/dist/esm/app-update/index.js +7 -0
  67. package/dist/esm/app-update/index.js.map +1 -0
  68. package/dist/esm/app-update/platform-app-update.d.ts +19 -0
  69. package/dist/esm/app-update/platform-app-update.js +129 -0
  70. package/dist/esm/app-update/platform-app-update.js.map +1 -0
  71. package/dist/esm/app-update/types.d.ts +58 -0
  72. package/dist/esm/app-update/types.js +12 -0
  73. package/dist/esm/app-update/types.js.map +1 -0
  74. package/dist/esm/background-update/background-scheduler.d.ts +17 -0
  75. package/dist/esm/background-update/background-scheduler.js +195 -0
  76. package/dist/esm/background-update/background-scheduler.js.map +1 -0
  77. package/dist/esm/background-update/index.d.ts +3 -0
  78. package/dist/esm/background-update/index.js +3 -0
  79. package/dist/esm/background-update/index.js.map +1 -0
  80. package/dist/esm/background-update/notification-manager.d.ts +29 -0
  81. package/dist/esm/background-update/notification-manager.js +89 -0
  82. package/dist/esm/background-update/notification-manager.js.map +1 -0
  83. package/dist/esm/core/analytics.d.ts +70 -0
  84. package/dist/esm/core/analytics.js +137 -0
  85. package/dist/esm/core/analytics.js.map +1 -0
  86. package/dist/esm/core/cache-manager.d.ts +72 -0
  87. package/dist/esm/core/cache-manager.js +275 -0
  88. package/dist/esm/core/cache-manager.js.map +1 -0
  89. package/dist/esm/core/config.d.ts +48 -0
  90. package/dist/esm/core/config.js +83 -0
  91. package/dist/esm/core/config.js.map +1 -0
  92. package/dist/esm/core/errors.d.ts +51 -0
  93. package/dist/esm/core/errors.js +80 -0
  94. package/dist/esm/core/errors.js.map +1 -0
  95. package/dist/esm/core/logger.d.ts +21 -0
  96. package/dist/esm/core/logger.js +109 -0
  97. package/dist/esm/core/logger.js.map +1 -0
  98. package/dist/esm/core/performance.d.ts +53 -0
  99. package/dist/esm/core/performance.js +140 -0
  100. package/dist/esm/core/performance.js.map +1 -0
  101. package/dist/esm/core/plugin-manager.d.ts +66 -0
  102. package/dist/esm/core/plugin-manager.js +148 -0
  103. package/dist/esm/core/plugin-manager.js.map +1 -0
  104. package/dist/esm/core/security.d.ts +93 -0
  105. package/dist/esm/core/security.js +315 -0
  106. package/dist/esm/core/security.js.map +1 -0
  107. package/dist/esm/definitions.d.ts +639 -0
  108. package/dist/esm/definitions.js +103 -0
  109. package/dist/esm/definitions.js.map +1 -0
  110. package/dist/esm/index.d.ts +12 -0
  111. package/dist/esm/index.js +16 -0
  112. package/dist/esm/index.js.map +1 -0
  113. package/dist/esm/live-update/bundle-manager.d.ts +94 -0
  114. package/dist/esm/live-update/bundle-manager.js +310 -0
  115. package/dist/esm/live-update/bundle-manager.js.map +1 -0
  116. package/dist/esm/live-update/certificate-pinning.d.ts +38 -0
  117. package/dist/esm/live-update/certificate-pinning.js +78 -0
  118. package/dist/esm/live-update/certificate-pinning.js.map +1 -0
  119. package/dist/esm/live-update/download-manager.d.ts +67 -0
  120. package/dist/esm/live-update/download-manager.js +319 -0
  121. package/dist/esm/live-update/download-manager.js.map +1 -0
  122. package/dist/esm/live-update/update-manager.d.ts +52 -0
  123. package/dist/esm/live-update/update-manager.js +294 -0
  124. package/dist/esm/live-update/update-manager.js.map +1 -0
  125. package/dist/esm/live-update/version-manager.d.ts +84 -0
  126. package/dist/esm/live-update/version-manager.js +335 -0
  127. package/dist/esm/live-update/version-manager.js.map +1 -0
  128. package/dist/esm/plugin.d.ts +6 -0
  129. package/dist/esm/plugin.js +283 -0
  130. package/dist/esm/plugin.js.map +1 -0
  131. package/dist/esm/security/crypto.d.ts +25 -0
  132. package/dist/esm/security/crypto.js +70 -0
  133. package/dist/esm/security/crypto.js.map +1 -0
  134. package/dist/esm/security/validator.d.ts +60 -0
  135. package/dist/esm/security/validator.js +143 -0
  136. package/dist/esm/security/validator.js.map +1 -0
  137. package/dist/esm/web.d.ts +74 -0
  138. package/dist/esm/web.js +595 -0
  139. package/dist/esm/web.js.map +1 -0
  140. package/dist/plugin.cjs.js +2 -0
  141. package/dist/plugin.cjs.js.map +1 -0
  142. package/dist/plugin.esm.js +2 -0
  143. package/dist/plugin.esm.js.map +1 -0
  144. package/dist/plugin.js +3 -0
  145. package/dist/plugin.js.map +1 -0
  146. package/docs/APP_REVIEW_GUIDE.md +768 -0
  147. package/docs/BUNDLE_SIGNING.md +264 -0
  148. package/docs/LIVE_UPDATES_GUIDE.md +650 -0
  149. package/docs/MIGRATION.md +192 -0
  150. package/docs/NATIVE_UPDATES_GUIDE.md +694 -0
  151. package/docs/QUICK_START.md +606 -0
  152. package/docs/README.md +111 -0
  153. package/docs/REMAINING_FEATURES.md +139 -0
  154. package/docs/api/app-review-api.md +259 -0
  155. package/docs/api/app-update-api.md +238 -0
  156. package/docs/api/events-api.md +451 -0
  157. package/docs/api/live-update-api.md +265 -0
  158. package/docs/background-updates.md +392 -0
  159. package/docs/examples/advanced-scenarios.md +410 -0
  160. package/docs/examples/basic-usage.md +185 -0
  161. package/docs/features/app-reviews.md +975 -0
  162. package/docs/features/app-updates.md +785 -0
  163. package/docs/features/live-updates.md +633 -0
  164. package/docs/getting-started/configuration.md +468 -0
  165. package/docs/getting-started/installation.md +209 -0
  166. package/docs/getting-started/quick-start.md +379 -0
  167. package/docs/guides/deployment-guide.md +333 -0
  168. package/docs/guides/migration-from-codepush.md +142 -0
  169. package/docs/guides/security-best-practices.md +1057 -0
  170. package/docs/guides/testing-guide.md +373 -0
  171. package/docs/production-readiness.md +478 -0
  172. package/docs/security/certificate-pinning.md +122 -0
  173. package/docs/server-requirements.md +147 -0
  174. package/ios/Plugin/AppReview/AppReviewPlugin.swift +158 -0
  175. package/ios/Plugin/AppUpdate/AppUpdatePlugin.swift +234 -0
  176. package/ios/Plugin/BackgroundUpdate/BackgroundNotificationManager.swift +329 -0
  177. package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +396 -0
  178. package/ios/Plugin/CapacitorNativeUpdatePlugin.m +45 -0
  179. package/ios/Plugin/CapacitorNativeUpdatePlugin.swift +190 -0
  180. package/ios/Plugin/Info.plist +43 -0
  181. package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +689 -0
  182. package/ios/Plugin/LiveUpdate/WebViewConfiguration.swift +45 -0
  183. package/ios/Plugin/Security/SecurityManager.swift +289 -0
  184. package/package.json +90 -0
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Certificate pinning utilities
3
+ */
4
+ export class CertificatePinning {
5
+ /**
6
+ * Generate SHA-256 fingerprint from certificate
7
+ * Note: This is a utility for generating pins, not for runtime validation
8
+ */
9
+ static async generateFingerprint(certificatePem) {
10
+ // Remove PEM headers and convert to binary
11
+ const base64 = certificatePem
12
+ .replace(/-----BEGIN CERTIFICATE-----/g, '')
13
+ .replace(/-----END CERTIFICATE-----/g, '')
14
+ .replace(/\s/g, '');
15
+ const binaryString = atob(base64);
16
+ const bytes = new Uint8Array(binaryString.length);
17
+ for (let i = 0; i < binaryString.length; i++) {
18
+ bytes[i] = binaryString.charCodeAt(i);
19
+ }
20
+ // Calculate SHA-256
21
+ const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
22
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
23
+ const hashBase64 = btoa(String.fromCharCode(...hashArray));
24
+ return `sha256/${hashBase64}`;
25
+ }
26
+ /**
27
+ * Validate certificate pinning configuration
28
+ */
29
+ static validateConfig(config) {
30
+ if (!config || typeof config !== 'object') {
31
+ throw new Error('Certificate pinning config must be an object');
32
+ }
33
+ if (typeof config.enabled !== 'boolean') {
34
+ throw new Error('Certificate pinning enabled must be a boolean');
35
+ }
36
+ if (!config.enabled) {
37
+ return; // No need to validate pins if disabled
38
+ }
39
+ if (!Array.isArray(config.pins)) {
40
+ throw new Error('Certificate pins must be an array');
41
+ }
42
+ for (const pin of config.pins) {
43
+ if (!pin.hostname || typeof pin.hostname !== 'string') {
44
+ throw new Error('Certificate pin hostname must be a non-empty string');
45
+ }
46
+ if (!Array.isArray(pin.sha256) || pin.sha256.length === 0) {
47
+ throw new Error('Certificate pin sha256 must be a non-empty array');
48
+ }
49
+ for (const hash of pin.sha256) {
50
+ if (!hash || typeof hash !== 'string' || !hash.startsWith('sha256/')) {
51
+ throw new Error('Certificate pin hash must be in format "sha256/base64hash"');
52
+ }
53
+ }
54
+ }
55
+ }
56
+ /**
57
+ * Example configuration
58
+ */
59
+ static example() {
60
+ return {
61
+ enabled: true,
62
+ pins: [
63
+ {
64
+ hostname: 'api.example.com',
65
+ sha256: [
66
+ 'sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=',
67
+ 'sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=', // Backup pin
68
+ ],
69
+ },
70
+ {
71
+ hostname: 'cdn.example.com',
72
+ sha256: ['sha256/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC='],
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ }
78
+ //# sourceMappingURL=certificate-pinning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"certificate-pinning.js","sourceRoot":"","sources":["../../../src/live-update/certificate-pinning.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { DownloadProgressEvent } from '../definitions';
2
+ /**
3
+ * Manages file downloads with progress tracking and resume capability
4
+ */
5
+ export declare class DownloadManager {
6
+ private activeDownloads;
7
+ private readonly logger;
8
+ private readonly configManager;
9
+ private filesystem;
10
+ constructor();
11
+ /**
12
+ * Initialize the download manager
13
+ */
14
+ initialize(): Promise<void>;
15
+ /**
16
+ * Validate URL against allowed hosts
17
+ */
18
+ private validateUrl;
19
+ /**
20
+ * Download a file with progress tracking
21
+ */
22
+ download(url: string, bundleId: string, onProgress?: (event: DownloadProgressEvent) => void): Promise<Blob>;
23
+ /**
24
+ * Validate content type
25
+ */
26
+ private isValidContentType;
27
+ /**
28
+ * Validate blob size
29
+ */
30
+ private validateBlobSize;
31
+ /**
32
+ * Cancel a download
33
+ */
34
+ cancelDownload(bundleId: string): void;
35
+ /**
36
+ * Cancel all active downloads
37
+ */
38
+ cancelAllDownloads(): void;
39
+ /**
40
+ * Check if a download is active
41
+ */
42
+ isDownloading(bundleId: string): boolean;
43
+ /**
44
+ * Get active download count
45
+ */
46
+ getActiveDownloadCount(): number;
47
+ /**
48
+ * Download with retry logic
49
+ */
50
+ downloadWithRetry(url: string, bundleId: string, onProgress?: (event: DownloadProgressEvent) => void): Promise<Blob>;
51
+ /**
52
+ * Convert blob to ArrayBuffer
53
+ */
54
+ blobToArrayBuffer(blob: Blob): Promise<ArrayBuffer>;
55
+ /**
56
+ * Save blob to filesystem
57
+ */
58
+ saveBlob(bundleId: string, blob: Blob): Promise<string>;
59
+ /**
60
+ * Load blob from filesystem
61
+ */
62
+ loadBlob(bundleId: string): Promise<Blob | null>;
63
+ /**
64
+ * Delete blob from filesystem
65
+ */
66
+ deleteBlob(bundleId: string): Promise<void>;
67
+ }
@@ -0,0 +1,319 @@
1
+ import { ConfigManager } from '../core/config';
2
+ import { Logger } from '../core/logger';
3
+ import { DownloadError, ErrorCode, ValidationError } from '../core/errors';
4
+ import { Directory } from '@capacitor/filesystem';
5
+ /**
6
+ * Manages file downloads with progress tracking and resume capability
7
+ */
8
+ export class DownloadManager {
9
+ constructor() {
10
+ this.activeDownloads = new Map();
11
+ this.filesystem = null;
12
+ this.logger = Logger.getInstance();
13
+ this.configManager = ConfigManager.getInstance();
14
+ }
15
+ /**
16
+ * Initialize the download manager
17
+ */
18
+ async initialize() {
19
+ this.filesystem = this.configManager.get('filesystem');
20
+ if (!this.filesystem) {
21
+ throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not configured. Please configure the plugin first.');
22
+ }
23
+ }
24
+ /**
25
+ * Validate URL against allowed hosts
26
+ */
27
+ validateUrl(url) {
28
+ try {
29
+ const parsedUrl = new URL(url);
30
+ // Ensure HTTPS
31
+ if (parsedUrl.protocol !== 'https:') {
32
+ throw new ValidationError(ErrorCode.INVALID_URL, 'Only HTTPS URLs are allowed for security reasons');
33
+ }
34
+ // Check against allowed hosts if configured
35
+ const allowedHosts = this.configManager.get('allowedHosts');
36
+ if (allowedHosts.length > 0 &&
37
+ !allowedHosts.includes(parsedUrl.hostname)) {
38
+ throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, `Host ${parsedUrl.hostname} is not in the allowed hosts list`);
39
+ }
40
+ }
41
+ catch (error) {
42
+ if (error instanceof ValidationError)
43
+ throw error;
44
+ throw new ValidationError(ErrorCode.INVALID_URL, 'Invalid URL format');
45
+ }
46
+ }
47
+ /**
48
+ * Download a file with progress tracking
49
+ */
50
+ async download(url, bundleId, onProgress) {
51
+ // Validate inputs
52
+ this.validateUrl(url);
53
+ if (!bundleId) {
54
+ throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');
55
+ }
56
+ // Check if already downloading
57
+ if (this.activeDownloads.has(bundleId)) {
58
+ throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, `Download already in progress for bundle ${bundleId}`);
59
+ }
60
+ // Create abort controller for this download
61
+ const abortController = new AbortController();
62
+ const downloadState = {
63
+ controller: abortController,
64
+ startTime: Date.now(),
65
+ };
66
+ this.activeDownloads.set(bundleId, downloadState);
67
+ try {
68
+ const timeout = this.configManager.get('downloadTimeout');
69
+ const timeoutId = setTimeout(() => abortController.abort(), timeout);
70
+ const response = await fetch(url, {
71
+ signal: abortController.signal,
72
+ headers: {
73
+ 'Cache-Control': 'no-cache',
74
+ Accept: 'application/octet-stream, application/zip',
75
+ },
76
+ });
77
+ clearTimeout(timeoutId);
78
+ if (!response.ok) {
79
+ throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, `Download failed: ${response.status} ${response.statusText}`, { status: response.status, statusText: response.statusText });
80
+ }
81
+ // Validate content type
82
+ const contentType = response.headers.get('content-type');
83
+ if (contentType && !this.isValidContentType(contentType)) {
84
+ throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, `Invalid content type: ${contentType}`);
85
+ }
86
+ // Get total size from headers
87
+ const contentLength = response.headers.get('content-length');
88
+ const totalBytes = contentLength ? parseInt(contentLength, 10) : 0;
89
+ // Check size limit
90
+ if (totalBytes > this.configManager.get('maxBundleSize')) {
91
+ throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `Bundle size ${totalBytes} exceeds maximum allowed size`);
92
+ }
93
+ // If no content length, fall back to simple download
94
+ if (!totalBytes || !response.body) {
95
+ const blob = await response.blob();
96
+ this.validateBlobSize(blob);
97
+ return blob;
98
+ }
99
+ // Stream the response with progress tracking
100
+ const reader = response.body.getReader();
101
+ const chunks = [];
102
+ let receivedBytes = 0;
103
+ while (true) {
104
+ const { done, value } = await reader.read();
105
+ if (done)
106
+ break;
107
+ chunks.push(value);
108
+ receivedBytes += value.length;
109
+ // Check if size exceeds limit during download
110
+ if (receivedBytes > this.configManager.get('maxBundleSize')) {
111
+ throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `Download size exceeds maximum allowed size`);
112
+ }
113
+ // Report progress
114
+ if (onProgress) {
115
+ const percent = Math.round((receivedBytes / totalBytes) * 100);
116
+ onProgress({
117
+ percent,
118
+ bytesDownloaded: receivedBytes,
119
+ totalBytes,
120
+ bundleId,
121
+ });
122
+ }
123
+ }
124
+ // Combine chunks into a single blob
125
+ const blob = new Blob(chunks);
126
+ this.validateBlobSize(blob);
127
+ this.logger.info('Download completed', {
128
+ bundleId,
129
+ size: blob.size,
130
+ duration: Date.now() - downloadState.startTime,
131
+ });
132
+ return blob;
133
+ }
134
+ catch (error) {
135
+ if (error instanceof Error && error.name === 'AbortError') {
136
+ const isTimeout = Date.now() - downloadState.startTime >=
137
+ this.configManager.get('downloadTimeout');
138
+ throw new DownloadError(isTimeout ? ErrorCode.DOWNLOAD_TIMEOUT : ErrorCode.DOWNLOAD_FAILED, isTimeout ? 'Download timed out' : 'Download cancelled', undefined, error);
139
+ }
140
+ throw error;
141
+ }
142
+ finally {
143
+ // Clean up
144
+ this.activeDownloads.delete(bundleId);
145
+ }
146
+ }
147
+ /**
148
+ * Validate content type
149
+ */
150
+ isValidContentType(contentType) {
151
+ const validTypes = [
152
+ 'application/octet-stream',
153
+ 'application/zip',
154
+ 'application/x-zip-compressed',
155
+ 'application/x-zip',
156
+ ];
157
+ return validTypes.some((type) => contentType.includes(type));
158
+ }
159
+ /**
160
+ * Validate blob size
161
+ */
162
+ validateBlobSize(blob) {
163
+ if (blob.size === 0) {
164
+ throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Downloaded file is empty');
165
+ }
166
+ if (blob.size > this.configManager.get('maxBundleSize')) {
167
+ throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `File size ${blob.size} exceeds maximum allowed size`);
168
+ }
169
+ }
170
+ /**
171
+ * Cancel a download
172
+ */
173
+ cancelDownload(bundleId) {
174
+ const state = this.activeDownloads.get(bundleId);
175
+ if (state) {
176
+ state.controller.abort();
177
+ this.activeDownloads.delete(bundleId);
178
+ this.logger.info('Download cancelled', { bundleId });
179
+ }
180
+ }
181
+ /**
182
+ * Cancel all active downloads
183
+ */
184
+ cancelAllDownloads() {
185
+ for (const state of this.activeDownloads.values()) {
186
+ state.controller.abort();
187
+ }
188
+ const count = this.activeDownloads.size;
189
+ this.activeDownloads.clear();
190
+ if (count > 0) {
191
+ this.logger.info('All downloads cancelled', { count });
192
+ }
193
+ }
194
+ /**
195
+ * Check if a download is active
196
+ */
197
+ isDownloading(bundleId) {
198
+ return this.activeDownloads.has(bundleId);
199
+ }
200
+ /**
201
+ * Get active download count
202
+ */
203
+ getActiveDownloadCount() {
204
+ return this.activeDownloads.size;
205
+ }
206
+ /**
207
+ * Download with retry logic
208
+ */
209
+ async downloadWithRetry(url, bundleId, onProgress) {
210
+ const maxRetries = this.configManager.get('retryAttempts');
211
+ const retryDelay = this.configManager.get('retryDelay');
212
+ let lastError = null;
213
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
214
+ try {
215
+ // Add delay between retries (exponential backoff)
216
+ if (attempt > 0) {
217
+ const delay = Math.min(retryDelay * Math.pow(2, attempt - 1), 30000);
218
+ await new Promise((resolve) => setTimeout(resolve, delay));
219
+ this.logger.debug('Retrying download', { bundleId, attempt, delay });
220
+ }
221
+ return await this.download(url, bundleId, onProgress);
222
+ }
223
+ catch (error) {
224
+ lastError = error;
225
+ // Don't retry if cancelled or validation error
226
+ if (error instanceof ValidationError ||
227
+ (error instanceof Error && error.name === 'AbortError')) {
228
+ throw error;
229
+ }
230
+ this.logger.warn(`Download attempt ${attempt + 1} failed`, {
231
+ bundleId,
232
+ error,
233
+ });
234
+ }
235
+ }
236
+ throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, 'Download failed after all retries', { attempts: maxRetries }, lastError || undefined);
237
+ }
238
+ /**
239
+ * Convert blob to ArrayBuffer
240
+ */
241
+ async blobToArrayBuffer(blob) {
242
+ return blob.arrayBuffer();
243
+ }
244
+ /**
245
+ * Save blob to filesystem
246
+ */
247
+ async saveBlob(bundleId, blob) {
248
+ if (!this.filesystem) {
249
+ throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');
250
+ }
251
+ const arrayBuffer = await this.blobToArrayBuffer(blob);
252
+ const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
253
+ const path = `bundles/${bundleId}/bundle.zip`;
254
+ await this.filesystem.writeFile({
255
+ path,
256
+ data: base64,
257
+ directory: Directory.Data,
258
+ recursive: true,
259
+ });
260
+ this.logger.debug('Bundle saved to filesystem', {
261
+ bundleId,
262
+ path,
263
+ size: blob.size,
264
+ });
265
+ return path;
266
+ }
267
+ /**
268
+ * Load blob from filesystem
269
+ */
270
+ async loadBlob(bundleId) {
271
+ if (!this.filesystem) {
272
+ throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');
273
+ }
274
+ try {
275
+ const path = `bundles/${bundleId}/bundle.zip`;
276
+ const result = await this.filesystem.readFile({
277
+ path,
278
+ directory: Directory.Data,
279
+ });
280
+ const binaryString = atob(result.data);
281
+ const bytes = new Uint8Array(binaryString.length);
282
+ for (let i = 0; i < binaryString.length; i++) {
283
+ bytes[i] = binaryString.charCodeAt(i);
284
+ }
285
+ return new Blob([bytes], { type: 'application/zip' });
286
+ }
287
+ catch (error) {
288
+ this.logger.debug('Failed to load bundle from filesystem', {
289
+ bundleId,
290
+ error,
291
+ });
292
+ return null;
293
+ }
294
+ }
295
+ /**
296
+ * Delete blob from filesystem
297
+ */
298
+ async deleteBlob(bundleId) {
299
+ if (!this.filesystem) {
300
+ throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');
301
+ }
302
+ try {
303
+ const path = `bundles/${bundleId}`;
304
+ await this.filesystem.rmdir({
305
+ path,
306
+ directory: Directory.Data,
307
+ recursive: true,
308
+ });
309
+ this.logger.debug('Bundle deleted from filesystem', { bundleId });
310
+ }
311
+ catch (error) {
312
+ this.logger.warn('Failed to delete bundle from filesystem', {
313
+ bundleId,
314
+ error,
315
+ });
316
+ }
317
+ }
318
+ }
319
+ //# sourceMappingURL=download-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download-manager.js","sourceRoot":"","sources":["../../../src/live-update/download-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { UpdateOptions } from '../definitions';
2
+ /**
3
+ * Manages atomic bundle installation with rollback capability
4
+ */
5
+ export declare class UpdateManager {
6
+ private readonly pluginManager;
7
+ private readonly securityValidator;
8
+ private filesystem;
9
+ private updateInProgress;
10
+ private currentState;
11
+ constructor();
12
+ /**
13
+ * Initialize update manager
14
+ */
15
+ initialize(): Promise<void>;
16
+ /**
17
+ * Apply bundle update atomically
18
+ */
19
+ applyUpdate(bundleId: string, options?: UpdateOptions): Promise<void>;
20
+ /**
21
+ * Validate update before applying
22
+ */
23
+ private validateUpdate;
24
+ /**
25
+ * Create backup of current bundle
26
+ */
27
+ private createBackup;
28
+ /**
29
+ * Perform the actual update
30
+ */
31
+ private performUpdate;
32
+ /**
33
+ * Verify update was successful
34
+ */
35
+ private verifyUpdate;
36
+ /**
37
+ * Rollback to previous state
38
+ */
39
+ rollback(): Promise<void>;
40
+ /**
41
+ * Get current update progress
42
+ */
43
+ getUpdateProgress(): {
44
+ inProgress: boolean;
45
+ bundleId?: string;
46
+ startTime?: number;
47
+ };
48
+ /**
49
+ * Cancel current update (if possible)
50
+ */
51
+ cancelUpdate(): Promise<void>;
52
+ }