native-update 1.1.1 → 1.1.3

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.
@@ -252,18 +252,18 @@ class AppUpdatePlugin(
252
252
  }
253
253
 
254
254
  // Async method for background update checks
255
- suspend fun getAppUpdateInfoAsync(): AppUpdateInfo? {
255
+ suspend fun getAppUpdateInfoAsync(): AppUpdateStatus? {
256
256
  return try {
257
257
  val appUpdateInfo = appUpdateManager.appUpdateInfo.await()
258
258
 
259
259
  if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
260
- AppUpdateInfo(
260
+ AppUpdateStatus(
261
261
  updateAvailable = true,
262
262
  currentVersion = getCurrentAppVersion(),
263
263
  availableVersion = appUpdateInfo.availableVersionCode().toString()
264
264
  )
265
265
  } else {
266
- AppUpdateInfo(
266
+ AppUpdateStatus(
267
267
  updateAvailable = false,
268
268
  currentVersion = getCurrentAppVersion(),
269
269
  availableVersion = null
@@ -106,7 +106,7 @@ class BackgroundNotificationManager(
106
106
  }
107
107
 
108
108
  fun sendUpdateNotification(
109
- appUpdate: AppUpdateInfo?,
109
+ appUpdate: AppUpdateStatus?,
110
110
  liveUpdate: LatestVersion?
111
111
  ): Boolean {
112
112
  val permissionStatus = getPermissionStatus()
@@ -127,7 +127,7 @@ class BackgroundNotificationManager(
127
127
  eventData.put("version", appUpdate?.availableVersion ?: liveUpdate?.version ?: "unknown")
128
128
  eventData.put("action", "shown")
129
129
 
130
- plugin.notifyListeners("backgroundUpdateNotification", eventData)
130
+ plugin.notifyBackgroundUpdateListeners("backgroundUpdateNotification", eventData)
131
131
 
132
132
  return true
133
133
  } catch (e: Exception) {
@@ -146,7 +146,7 @@ class BackgroundNotificationManager(
146
146
  }
147
147
 
148
148
  private fun createNotificationBuilder(
149
- appUpdate: AppUpdateInfo?,
149
+ appUpdate: AppUpdateStatus?,
150
150
  liveUpdate: LatestVersion?
151
151
  ): NotificationCompat.Builder {
152
152
  val title = determineTitle(appUpdate, liveUpdate)
@@ -183,7 +183,7 @@ class BackgroundNotificationManager(
183
183
  return builder
184
184
  }
185
185
 
186
- private fun determineTitle(appUpdate: AppUpdateInfo?, liveUpdate: LatestVersion?): String {
186
+ private fun determineTitle(appUpdate: AppUpdateStatus?, liveUpdate: LatestVersion?): String {
187
187
  return when {
188
188
  appUpdate?.updateAvailable == true && liveUpdate?.available == true -> "App Updates Available"
189
189
  appUpdate?.updateAvailable == true -> "App Update Available"
@@ -192,7 +192,7 @@ class BackgroundNotificationManager(
192
192
  }
193
193
  }
194
194
 
195
- private fun determineContent(appUpdate: AppUpdateInfo?, liveUpdate: LatestVersion?): String {
195
+ private fun determineContent(appUpdate: AppUpdateStatus?, liveUpdate: LatestVersion?): String {
196
196
  return when {
197
197
  appUpdate?.updateAvailable == true && liveUpdate?.available == true ->
198
198
  "App version ${appUpdate.availableVersion} and content updates are available"
@@ -237,7 +237,7 @@ class BackgroundNotificationManager(
237
237
  }
238
238
  }
239
239
 
240
- private fun createContentIntent(appUpdate: AppUpdateInfo?, liveUpdate: LatestVersion?): PendingIntent {
240
+ private fun createContentIntent(appUpdate: AppUpdateStatus?, liveUpdate: LatestVersion?): PendingIntent {
241
241
  val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
242
242
  ?: Intent()
243
243
 
@@ -254,7 +254,7 @@ class BackgroundNotificationManager(
254
254
 
255
255
  private fun addActionButtons(
256
256
  builder: NotificationCompat.Builder,
257
- appUpdate: AppUpdateInfo?,
257
+ appUpdate: AppUpdateStatus?,
258
258
  liveUpdate: LatestVersion?
259
259
  ) {
260
260
  val actionLabels = preferences.actionLabels ?: ActionLabels.default()
@@ -337,13 +337,13 @@ data class NotificationPreferences(
337
337
  title = obj.getString("title"),
338
338
  description = obj.getString("description"),
339
339
  iconName = obj.getString("iconName"),
340
- soundEnabled = obj.getBoolean("soundEnabled", true),
341
- vibrationEnabled = obj.getBoolean("vibrationEnabled", true),
342
- showActions = obj.getBoolean("showActions", true),
340
+ soundEnabled = obj.getBoolean("soundEnabled", true) ?: true,
341
+ vibrationEnabled = obj.getBoolean("vibrationEnabled", true) ?: true,
342
+ showActions = obj.getBoolean("showActions", true) ?: true,
343
343
  actionLabels = actionLabelsObj?.let { ActionLabels.fromJSObject(it) } ?: ActionLabels.default(),
344
344
  channelId = obj.getString("channelId"),
345
345
  channelName = obj.getString("channelName"),
346
- priority = NotificationPriority.fromString(priorityString)
346
+ priority = NotificationPriority.fromString(priorityString ?: "default")
347
347
  )
348
348
  }
349
349
  }
@@ -33,6 +33,10 @@ class BackgroundUpdatePlugin : Plugin() {
33
33
  BackgroundUpdateManager.registerBackgroundUpdatePlugin(this)
34
34
  }
35
35
 
36
+ fun notifyBackgroundUpdateListeners(event: String, data: JSObject) {
37
+ notifyListeners(event, data)
38
+ }
39
+
36
40
  @PluginMethod
37
41
  fun enableBackgroundUpdates(call: PluginCall) {
38
42
  try {
@@ -67,7 +71,7 @@ class BackgroundUpdatePlugin : Plugin() {
67
71
 
68
72
  @PluginMethod
69
73
  fun scheduleBackgroundCheck(call: PluginCall) {
70
- val interval = call.getLong("interval", 24 * 60 * 60 * 1000L) // Default 24 hours
74
+ val interval = call.getLong("interval") ?: (24 * 60 * 60 * 1000L) // Default 24 hours
71
75
  scheduleBackgroundWork(interval)
72
76
  call.resolve()
73
77
  }
@@ -185,8 +189,8 @@ data class BackgroundUpdateConfig(
185
189
  ) {
186
190
  companion object {
187
191
  fun fromJSObject(obj: JSObject): BackgroundUpdateConfig {
188
- val enabled = obj.getBoolean("enabled", false)
189
- val checkInterval = obj.getInt("checkInterval", 24 * 60 * 60 * 1000)
192
+ val enabled = obj.getBoolean("enabled") ?: false
193
+ val checkInterval = obj.getInt("checkInterval") ?: (24 * 60 * 60 * 1000)
190
194
  val updateTypesArray = obj.getJSONArray("updateTypes")
191
195
  val updateTypes = mutableListOf<BackgroundUpdateType>()
192
196
 
@@ -201,14 +205,14 @@ data class BackgroundUpdateConfig(
201
205
  enabled = enabled,
202
206
  checkInterval = checkInterval,
203
207
  updateTypes = updateTypes,
204
- autoInstall = obj.getBoolean("autoInstall", false),
208
+ autoInstall = obj.getBoolean("autoInstall") ?: false,
205
209
  notificationPreferences = notificationPrefs?.let { NotificationPreferences.fromJSObject(it) },
206
- respectBatteryOptimization = obj.getBoolean("respectBatteryOptimization", true),
207
- allowMeteredConnection = obj.getBoolean("allowMeteredConnection", false),
208
- minimumBatteryLevel = obj.getInt("minimumBatteryLevel", 20),
209
- requireWifi = obj.getBoolean("requireWifi", false),
210
- maxRetries = obj.getInt("maxRetries", 3),
211
- retryDelay = obj.getInt("retryDelay", 5000),
210
+ respectBatteryOptimization = obj.getBoolean("respectBatteryOptimization") ?: true,
211
+ allowMeteredConnection = obj.getBoolean("allowMeteredConnection") ?: false,
212
+ minimumBatteryLevel = obj.getInt("minimumBatteryLevel") ?: 20,
213
+ requireWifi = obj.getBoolean("requireWifi") ?: false,
214
+ maxRetries = obj.getInt("maxRetries") ?: 3,
215
+ retryDelay = obj.getInt("retryDelay") ?: 5000,
212
216
  taskIdentifier = obj.getString("taskIdentifier")
213
217
  )
214
218
  }
@@ -274,7 +278,7 @@ data class BackgroundUpdateStatus(
274
278
  data class BackgroundCheckResult(
275
279
  val success: Boolean,
276
280
  val updatesFound: Boolean,
277
- val appUpdate: AppUpdateInfo? = null,
281
+ val appUpdate: AppUpdateStatus? = null,
278
282
  val liveUpdate: LatestVersion? = null,
279
283
  val notificationSent: Boolean = false,
280
284
  val error: UpdateError? = null
@@ -306,7 +310,7 @@ data class UpdateError(
306
310
  }
307
311
 
308
312
  // Placeholder data classes - would be defined in other plugins
309
- data class AppUpdateInfo(
313
+ data class AppUpdateStatus(
310
314
  val updateAvailable: Boolean,
311
315
  val currentVersion: String,
312
316
  val availableVersion: String? = null
@@ -65,7 +65,7 @@ class BackgroundUpdateWorker(
65
65
 
66
66
  private suspend fun performBackgroundCheck(config: BackgroundUpdateConfig): BackgroundCheckResult {
67
67
  try {
68
- var appUpdate: AppUpdateInfo? = null
68
+ var appUpdate: AppUpdateStatus? = null
69
69
  var liveUpdate: LatestVersion? = null
70
70
 
71
71
  // Check for app updates
@@ -99,7 +99,7 @@ class BackgroundUpdateWorker(
99
99
  }
100
100
  }
101
101
 
102
- private suspend fun checkForAppUpdate(): AppUpdateInfo? {
102
+ private suspend fun checkForAppUpdate(): AppUpdateStatus? {
103
103
  return withContext(Dispatchers.IO) {
104
104
  try {
105
105
  val appUpdatePlugin = BackgroundUpdateManager.getAppUpdatePlugin()
@@ -111,7 +111,7 @@ class BackgroundUpdateWorker(
111
111
  val currentVersion = getCurrentAppVersion()
112
112
  val availableVersion = getAvailableAppVersion()
113
113
 
114
- AppUpdateInfo(
114
+ AppUpdateStatus(
115
115
  updateAvailable = availableVersion != currentVersion,
116
116
  currentVersion = currentVersion,
117
117
  availableVersion = if (availableVersion != currentVersion) availableVersion else null
@@ -224,7 +224,7 @@ class BackgroundUpdateWorker(
224
224
  progressData.put("status", if (result.success) "completed" else "failed")
225
225
  progressData.put("percent", 100)
226
226
 
227
- plugin?.notifyListeners("backgroundUpdateProgress", progressData)
227
+ plugin?.notifyBackgroundUpdateListeners("backgroundUpdateProgress", progressData)
228
228
 
229
229
  // Notify about notification if sent
230
230
  if (result.notificationSent) {
@@ -233,7 +233,7 @@ class BackgroundUpdateWorker(
233
233
  notificationData.put("updateAvailable", result.updatesFound)
234
234
  notificationData.put("action", "shown")
235
235
 
236
- plugin?.notifyListeners("backgroundUpdateNotification", notificationData)
236
+ plugin?.notifyBackgroundUpdateListeners("backgroundUpdateNotification", notificationData)
237
237
  }
238
238
  } catch (e: Exception) {
239
239
  android.util.Log.e(TAG, "Failed to notify listeners", e)
@@ -77,9 +77,7 @@ class NativeUpdatePlugin : Plugin() {
77
77
  appReviewPlugin.configure(it)
78
78
  }
79
79
 
80
- config.getJSObject("backgroundUpdate")?.let {
81
- backgroundUpdatePlugin.configure(it)
82
- }
80
+ // Background update configuration is handled separately via enableBackgroundUpdates
83
81
 
84
82
  call.resolve()
85
83
  } catch (e: Exception) {
@@ -259,7 +257,7 @@ class NativeUpdatePlugin : Plugin() {
259
257
  }
260
258
  }
261
259
 
262
- private fun hasRequiredPermissions(): Boolean {
260
+ override fun hasRequiredPermissions(): Boolean {
263
261
  return hasPermission("storage")
264
262
  }
265
263
  }
package/cli/index.js CHANGED
File without changes
@@ -617,7 +617,7 @@ export interface PluginInitConfig {
617
617
  /**
618
618
  * Main plugin interface with initialization
619
619
  */
620
- export interface NativeUpdatePlugin extends NativeUpdateCombinedPlugin {
620
+ export interface NativeUpdatePlugin extends NativeUpdateCombinedPlugin, NativeUpdateListeners {
621
621
  /**
622
622
  * Initialize the plugin with configuration
623
623
  */
@@ -289,6 +289,19 @@ class NativeUpdatePluginWeb {
289
289
  async requestNotificationPermissions() {
290
290
  return false;
291
291
  }
292
+ // Event listener methods
293
+ async addListener(_eventName, _listenerFunc) {
294
+ // Web implementation doesn't support native events
295
+ // Return a dummy handle
296
+ return {
297
+ remove: async () => {
298
+ // No-op for web
299
+ },
300
+ };
301
+ }
302
+ async removeAllListeners() {
303
+ // No-op for web implementation
304
+ }
292
305
  }
293
306
  /**
294
307
  * Register the plugin
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var e,t,r,a,i,n,s,o,l,c,d,u,h=require("@capacitor/core"),g=require("@capacitor/filesystem"),p=require("@capacitor/preferences");!function(e){e.APP_UPDATE="app_update",e.LIVE_UPDATE="live_update",e.BOTH="both"}(e||(e={})),function(e){e.MIN="min",e.LOW="low",e.DEFAULT="default",e.HIGH="high",e.MAX="max"}(t||(t={})),function(e){e.IMMEDIATE="immediate",e.BACKGROUND="background",e.MANUAL="manual"}(r||(r={})),function(e){e.IMMEDIATE="immediate",e.ON_NEXT_RESTART="on_next_restart",e.ON_NEXT_RESUME="on_next_resume"}(a||(a={})),function(e){e.IMMEDIATE="immediate",e.ON_NEXT_RESTART="on_next_restart",e.ON_NEXT_RESUME="on_next_resume"}(i||(i={})),function(e){e.SHA256="SHA-256",e.SHA512="SHA-512"}(n||(n={})),function(e){e.UP_TO_DATE="UP_TO_DATE",e.UPDATE_AVAILABLE="UPDATE_AVAILABLE",e.UPDATE_INSTALLED="UPDATE_INSTALLED",e.ERROR="ERROR"}(s||(s={})),function(e){e.PENDING="PENDING",e.DOWNLOADING="DOWNLOADING",e.READY="READY",e.ACTIVE="ACTIVE",e.FAILED="FAILED"}(o||(o={})),function(e){e.UNKNOWN="UNKNOWN",e.PENDING="PENDING",e.DOWNLOADING="DOWNLOADING",e.DOWNLOADED="DOWNLOADED",e.INSTALLING="INSTALLING",e.INSTALLED="INSTALLED",e.FAILED="FAILED",e.CANCELED="CANCELED"}(l||(l={})),function(e){e.NETWORK_ERROR="NETWORK_ERROR",e.SERVER_ERROR="SERVER_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.DOWNLOAD_ERROR="DOWNLOAD_ERROR",e.STORAGE_ERROR="STORAGE_ERROR",e.SIZE_LIMIT_EXCEEDED="SIZE_LIMIT_EXCEEDED",e.VERIFICATION_ERROR="VERIFICATION_ERROR",e.CHECKSUM_ERROR="CHECKSUM_ERROR",e.SIGNATURE_ERROR="SIGNATURE_ERROR",e.INSECURE_URL="INSECURE_URL",e.INVALID_CERTIFICATE="INVALID_CERTIFICATE",e.PATH_TRAVERSAL="PATH_TRAVERSAL",e.INSTALL_ERROR="INSTALL_ERROR",e.ROLLBACK_ERROR="ROLLBACK_ERROR",e.VERSION_MISMATCH="VERSION_MISMATCH",e.PERMISSION_DENIED="PERMISSION_DENIED",e.UPDATE_NOT_AVAILABLE="UPDATE_NOT_AVAILABLE",e.UPDATE_IN_PROGRESS="UPDATE_IN_PROGRESS",e.UPDATE_CANCELLED="UPDATE_CANCELLED",e.PLATFORM_NOT_SUPPORTED="PLATFORM_NOT_SUPPORTED",e.REVIEW_NOT_SUPPORTED="REVIEW_NOT_SUPPORTED",e.QUOTA_EXCEEDED="QUOTA_EXCEEDED",e.CONDITIONS_NOT_MET="CONDITIONS_NOT_MET",e.INVALID_CONFIG="INVALID_CONFIG",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(c||(c={}));class f{constructor(){this.config=this.getDefaultConfig()}static getInstance(){return f.instance||(f.instance=new f),f.instance}getDefaultConfig(){return{filesystem:null,preferences:null,baseUrl:"",allowedHosts:[],maxBundleSize:104857600,downloadTimeout:3e4,retryAttempts:3,retryDelay:1e3,enableSignatureValidation:!0,publicKey:"",cacheExpiration:864e5,enableLogging:!1,serverUrl:"",channel:"production",autoCheck:!0,autoUpdate:!1,updateStrategy:"background",requireSignature:!0,checksumAlgorithm:"SHA-256",checkInterval:864e5,security:{enforceHttps:!0,validateInputs:!0,secureStorage:!0,logSecurityEvents:!1},promptAfterPositiveEvents:!1,maxPromptsPerVersion:1,minimumDaysSinceLastPrompt:7,isPremiumUser:!1,appStoreId:"",iosAppId:"",packageName:"",webReviewUrl:"",minimumVersion:"1.0.0"}}configure(e){this.config=Object.assign(Object.assign({},this.config),e),this.validateConfig()}validateConfig(){if(this.config.maxBundleSize<=0)throw new Error("maxBundleSize must be greater than 0");if(this.config.downloadTimeout<=0)throw new Error("downloadTimeout must be greater than 0");if(this.config.retryAttempts<0)throw new Error("retryAttempts must be non-negative");if(this.config.retryDelay<0)throw new Error("retryDelay must be non-negative")}get(e){return this.config[e]}set(e,t){this.config[e]=t}getAll(){return Object.assign({},this.config)}isConfigured(){return!(!this.config.filesystem||!this.config.preferences)}}exports.LogLevel=void 0,(d=exports.LogLevel||(exports.LogLevel={}))[d.DEBUG=0]="DEBUG",d[d.INFO=1]="INFO",d[d.WARN=2]="WARN",d[d.ERROR=3]="ERROR";class E{constructor(e){this.configManager=f.getInstance(),this.context=e||"NativeUpdate"}static getInstance(){return E.instance||(E.instance=new E),E.instance}shouldLog(){return this.configManager.get("enableLogging")}sanitize(e){if("string"==typeof e){let t=e;return t=t.replace(/\/[^\s]+\/([\w.-]+)$/g,"/<path>/$1"),t=t.replace(/https?:\/\/[^:]+:[^@]+@/g,"https://***:***@"),t=t.replace(/[a-zA-Z0-9]{32,}/g,"<redacted>"),t}if("object"==typeof e&&null!==e){if(Array.isArray(e))return e.map(e=>this.sanitize(e));{const t={},r=e;for(const e in r)t[e]=e.toLowerCase().includes("key")||e.toLowerCase().includes("secret")||e.toLowerCase().includes("password")||e.toLowerCase().includes("token")?"<redacted>":this.sanitize(r[e]);return t}}return e}log(e,t){this.logWithLevel(exports.LogLevel.INFO,e,t)}logWithLevel(e,t,r){if(!this.shouldLog())return;const a=(new Date).toISOString(),i=r?this.sanitize(r):void 0,n={timestamp:a,level:exports.LogLevel[e],context:this.context,message:t};switch(void 0!==i&&(n.data=i),e){case exports.LogLevel.DEBUG:console.debug(`[${this.context}]`,n);break;case exports.LogLevel.INFO:console.info(`[${this.context}]`,n);break;case exports.LogLevel.WARN:console.warn(`[${this.context}]`,n);break;case exports.LogLevel.ERROR:console.error(`[${this.context}]`,n)}}debug(e,t){this.logWithLevel(exports.LogLevel.DEBUG,e,t)}info(e,t){this.logWithLevel(exports.LogLevel.INFO,e,t)}warn(e,t){this.logWithLevel(exports.LogLevel.WARN,e,t)}error(e,t){const r=t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t;this.logWithLevel(exports.LogLevel.ERROR,e,r)}}exports.ErrorCode=void 0,(u=exports.ErrorCode||(exports.ErrorCode={})).NOT_CONFIGURED="NOT_CONFIGURED",u.INVALID_CONFIG="INVALID_CONFIG",u.MISSING_DEPENDENCY="MISSING_DEPENDENCY",u.DOWNLOAD_FAILED="DOWNLOAD_FAILED",u.DOWNLOAD_TIMEOUT="DOWNLOAD_TIMEOUT",u.INVALID_URL="INVALID_URL",u.UNAUTHORIZED_HOST="UNAUTHORIZED_HOST",u.BUNDLE_TOO_LARGE="BUNDLE_TOO_LARGE",u.CHECKSUM_MISMATCH="CHECKSUM_MISMATCH",u.SIGNATURE_INVALID="SIGNATURE_INVALID",u.VERSION_DOWNGRADE="VERSION_DOWNGRADE",u.INVALID_BUNDLE_FORMAT="INVALID_BUNDLE_FORMAT",u.STORAGE_FULL="STORAGE_FULL",u.FILE_NOT_FOUND="FILE_NOT_FOUND",u.PERMISSION_DENIED="PERMISSION_DENIED",u.UPDATE_FAILED="UPDATE_FAILED",u.ROLLBACK_FAILED="ROLLBACK_FAILED",u.BUNDLE_NOT_READY="BUNDLE_NOT_READY",u.PLATFORM_NOT_SUPPORTED="PLATFORM_NOT_SUPPORTED",u.NATIVE_ERROR="NATIVE_ERROR";class w extends Error{constructor(e,t,r,a){super(t),this.code=e,this.message=t,this.details=r,this.originalError=a,this.name="NativeUpdateError",Object.setPrototypeOf(this,w.prototype)}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,stack:this.stack}}}class I extends w{constructor(e,t,r,a){super(e,t,r,a),this.name="DownloadError"}}class y extends w{constructor(e,t,r){super(e,t,r),this.name="ValidationError"}}class D extends w{constructor(e,t,r,a){super(e,t,r,a),this.name="StorageError"}}class A extends w{constructor(e,t,r,a){super(e,t,r,a),this.name="UpdateError"}}class m{constructor(){this.configManager=f.getInstance(),this.logger=E.getInstance()}static getInstance(){return m.instance||(m.instance=new m),m.instance}static validateUrl(e){try{return"https:"===new URL(e).protocol}catch(e){return!1}}static validateChecksum(e){return/^[a-f0-9]{64}$/i.test(e)}static sanitizeInput(e){return e?e.replace(/<[^>]*>/g,"").replace(/[^\w\s/.-]/g,""):""}static validateBundleSize(e){return e>0&&e<=104857600}async calculateChecksum(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}async verifyChecksum(e,t){if(!t)return this.logger.warn("No checksum provided for verification"),!0;const r=await this.calculateChecksum(e),a=r===t.toLowerCase();return a||this.logger.error("Checksum verification failed",{expected:t,actual:r}),a}async validateChecksum(e,t){return this.verifyChecksum(e,t)}async verifySignature(e,t){if(!this.configManager.get("enableSignatureValidation"))return!0;const r=this.configManager.get("publicKey");if(!r)throw new y(exports.ErrorCode.SIGNATURE_INVALID,"Public key not configured for signature validation");try{const a=await crypto.subtle.importKey("spki",this.pemToArrayBuffer(r),{name:"RSA-PSS",hash:"SHA-256"},!1,["verify"]),i=await crypto.subtle.verify({name:"RSA-PSS",saltLength:32},a,this.base64ToArrayBuffer(t),e);return i||this.logger.error("Signature verification failed"),i}catch(e){return this.logger.error("Signature verification error",e),!1}}pemToArrayBuffer(e){const t=e.replace(/-----BEGIN PUBLIC KEY-----/g,"").replace(/-----END PUBLIC KEY-----/g,"").replace(/\s/g,"");return this.base64ToArrayBuffer(t)}base64ToArrayBuffer(e){const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r.buffer}sanitizePath(e){return e.split("/").filter(e=>".."!==e&&"."!==e).join("/").replace(/^\/+/,"")}validateBundleId(e){if(!e||"string"!=typeof e)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID must be a non-empty string");if(!/^[a-zA-Z0-9\-_.]+$/.test(e))throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID contains invalid characters");if(e.length>100)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is too long (max 100 characters)")}validateVersion(e){if(!e||"string"!=typeof e)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Version must be a non-empty string");if(!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(e))throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Version must follow semantic versioning format (e.g., 1.2.3)")}isVersionDowngrade(e,t){const r=this.parseVersion(e),a=this.parseVersion(t);return a.major<r.major||!(a.major>r.major)&&(a.minor<r.minor||!(a.minor>r.minor)&&a.patch<r.patch)}parseVersion(e){const t=e.split("-")[0].split(".");return{major:parseInt(t[0],10)||0,minor:parseInt(t[1],10)||0,patch:parseInt(t[2],10)||0}}validateUrl(e){if(!e||"string"!=typeof e)throw new y(exports.ErrorCode.INVALID_URL,"URL must be a non-empty string");let t;try{t=new URL(e)}catch(e){throw new y(exports.ErrorCode.INVALID_URL,"Invalid URL format")}if("https:"!==t.protocol)throw new y(exports.ErrorCode.INVALID_URL,"Only HTTPS URLs are allowed");const r=this.configManager.get("allowedHosts");if(r.length>0&&!r.includes(t.hostname))throw new y(exports.ErrorCode.UNAUTHORIZED_HOST,`Host ${t.hostname} is not in the allowed hosts list`);if([/^localhost$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2[0-9]|3[0-1])\./,/^192\.168\./,/^::1$/,/^fc00:/i,/^fe80:/i].some(e=>e.test(t.hostname)))throw new y(exports.ErrorCode.UNAUTHORIZED_HOST,"Private/local addresses are not allowed")}validateFileSize(e){if("number"!=typeof e||e<0)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"File size must be a non-negative number");const t=this.configManager.get("maxBundleSize");if(e>t)throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,`File size ${e} exceeds maximum allowed size of ${t} bytes`)}generateSecureId(){const e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,"0")).join("")}async validateCertificatePin(e,t){const r=this.configManager.certificatePins;if(!r||!Array.isArray(r)||0===r.length)return!0;const a=r.filter(t=>t.hostname===e);if(0===a.length)return!0;const i=await this.calculateCertificateHash(t),n=a.some(e=>e.sha256===i);return n||this.logger.error("Certificate pinning validation failed",{hostname:e,expectedPins:a.map(e=>e.sha256),actualHash:i}),n}async calculateCertificateHash(e){const t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-256",t),a=Array.from(new Uint8Array(r));return"sha256/"+btoa(String.fromCharCode(...a))}validateMetadata(e){if(e&&"object"!=typeof e)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Metadata must be an object");if(JSON.stringify(e||{}).length>10240)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Metadata is too large (max 10KB)")}}class N{constructor(){this.STORAGE_KEY="capacitor_native_update_bundles",this.ACTIVE_BUNDLE_KEY="capacitor_native_update_active",this.preferences=null,this.cache=new Map,this.cacheExpiry=0,this.logger=E.getInstance(),this.configManager=f.getInstance()}async initialize(){if(this.preferences=this.configManager.get("preferences"),!this.preferences)throw new D(exports.ErrorCode.MISSING_DEPENDENCY,"Preferences not configured. Please configure the plugin first.");await this.loadCache()}async loadCache(){if(!(Date.now()<this.cacheExpiry))try{const{value:e}=await this.preferences.get({key:this.STORAGE_KEY});if(e){const t=JSON.parse(e);this.cache.clear(),t.forEach(e=>this.cache.set(e.bundleId,e))}this.cacheExpiry=Date.now()+5e3}catch(e){this.logger.error("Failed to load bundles from storage",e),this.cache.clear()}}async saveCache(){try{const e=Array.from(this.cache.values());await this.preferences.set({key:this.STORAGE_KEY,value:JSON.stringify(e)}),this.logger.debug("Saved bundles to storage",{count:e.length})}catch(e){throw new D(exports.ErrorCode.STORAGE_FULL,"Failed to save bundles to storage",void 0,e)}}async saveBundleInfo(e){this.validateBundleInfo(e),this.cache.set(e.bundleId,e),await this.saveCache(),this.logger.info("Bundle saved",{bundleId:e.bundleId,version:e.version})}validateBundleInfo(e){if(!e.bundleId||"string"!=typeof e.bundleId)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle ID");if(!e.version||"string"!=typeof e.version)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle version");if(!e.path||"string"!=typeof e.path)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle path");if("number"!=typeof e.size||e.size<0)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle size")}async getAllBundles(){return await this.loadCache(),Array.from(this.cache.values())}async getBundle(e){if(!e)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");return await this.loadCache(),this.cache.get(e)||null}async deleteBundle(e){if(!e)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");await this.loadCache(),this.cache.get(e)?(this.cache.delete(e),await this.saveCache(),await this.getActiveBundleId()===e&&await this.clearActiveBundle(),this.logger.info("Bundle deleted",{bundleId:e})):this.logger.warn("Attempted to delete non-existent bundle",{bundleId:e})}async getActiveBundle(){const e=await this.getActiveBundleId();return e?this.getBundle(e):null}async setActiveBundle(e){if(!e)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");const t=await this.getBundle(e);if(!t)throw new D(exports.ErrorCode.FILE_NOT_FOUND,`Bundle ${e} not found`);const r=await this.getActiveBundle();r&&r.bundleId!==e&&(r.status="READY",await this.saveBundleInfo(r)),t.status="ACTIVE",await this.saveBundleInfo(t),await this.preferences.set({key:this.ACTIVE_BUNDLE_KEY,value:e}),this.logger.info("Active bundle set",{bundleId:e,version:t.version})}async getActiveBundleId(){try{const{value:e}=await this.preferences.get({key:this.ACTIVE_BUNDLE_KEY});return e}catch(e){return this.logger.error("Failed to get active bundle ID",e),null}}async clearActiveBundle(){await this.preferences.remove({key:this.ACTIVE_BUNDLE_KEY}),this.logger.info("Active bundle cleared")}async clearAllBundles(){await this.preferences.remove({key:this.STORAGE_KEY}),await this.preferences.remove({key:this.ACTIVE_BUNDLE_KEY}),this.cache.clear(),this.cacheExpiry=0,this.logger.info("All bundles cleared")}async cleanupOldBundles(e){if(e<1)throw new D(exports.ErrorCode.INVALID_CONFIG,"Keep count must be at least 1");const t=await this.getAllBundles(),r=await this.getActiveBundleId(),a=t.sort((e,t)=>t.downloadTime-e.downloadTime),i=new Set;r&&i.add(r);let n=i.size;for(const t of a){if(n>=e)break;i.has(t.bundleId)||(i.add(t.bundleId),n++)}let s=0;for(const e of t)i.has(e.bundleId)||(await this.deleteBundle(e.bundleId),s++);s>0&&this.logger.info("Cleaned up old bundles",{deleted:s,kept:n})}async getBundlesOlderThan(e){if(e<0)throw new D(exports.ErrorCode.INVALID_CONFIG,"Timestamp must be non-negative");return(await this.getAllBundles()).filter(t=>t.downloadTime<e)}async markBundleAsVerified(e){const t=await this.getBundle(e);if(!t)throw new D(exports.ErrorCode.FILE_NOT_FOUND,`Bundle ${e} not found`);t.verified=!0,await this.saveBundleInfo(t),this.logger.info("Bundle marked as verified",{bundleId:e})}async getTotalStorageUsed(){return(await this.getAllBundles()).reduce((e,t)=>e+t.size,0)}async isStorageLimitExceeded(e=0){return await this.getTotalStorageUsed()+e>3*this.configManager.get("maxBundleSize")}createDefaultBundle(){return{bundleId:"default",version:"1.0.0",path:"/",downloadTime:Date.now(),size:0,status:"ACTIVE",checksum:"",verified:!0}}async cleanExpiredBundles(){const e=this.configManager.get("cacheExpiration"),t=Date.now()-e,r=await this.getBundlesOlderThan(t);for(const e of r){const t=await this.getActiveBundleId();e.bundleId!==t&&await this.deleteBundle(e.bundleId)}}}class _{constructor(){this.activeDownloads=new Map,this.filesystem=null,this.logger=E.getInstance(),this.configManager=f.getInstance()}async initialize(){if(this.filesystem=this.configManager.get("filesystem"),!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not configured. Please configure the plugin first.")}validateUrl(e){try{const t=new URL(e);if("https:"!==t.protocol)throw new y(exports.ErrorCode.INVALID_URL,"Only HTTPS URLs are allowed for security reasons");const r=this.configManager.get("allowedHosts");if(r.length>0&&!r.includes(t.hostname))throw new y(exports.ErrorCode.UNAUTHORIZED_HOST,`Host ${t.hostname} is not in the allowed hosts list`)}catch(e){if(e instanceof y)throw e;throw new y(exports.ErrorCode.INVALID_URL,"Invalid URL format")}}async download(e,t,r){if(this.validateUrl(e),!t)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");if(this.activeDownloads.has(t))throw new I(exports.ErrorCode.DOWNLOAD_FAILED,`Download already in progress for bundle ${t}`);const a=new AbortController,i={controller:a,startTime:Date.now()};this.activeDownloads.set(t,i);try{const n=this.configManager.get("downloadTimeout"),s=setTimeout(()=>a.abort(),n),o=await fetch(e,{signal:a.signal,headers:{"Cache-Control":"no-cache",Accept:"application/octet-stream, application/zip"}});if(clearTimeout(s),!o.ok)throw new I(exports.ErrorCode.DOWNLOAD_FAILED,`Download failed: ${o.status} ${o.statusText}`,{status:o.status,statusText:o.statusText});const l=o.headers.get("content-type");if(l&&!this.isValidContentType(l))throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,`Invalid content type: ${l}`);const c=o.headers.get("content-length"),d=c?parseInt(c,10):0;if(d>this.configManager.get("maxBundleSize"))throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,`Bundle size ${d} exceeds maximum allowed size`);if(!d||!o.body){const e=await o.blob();return this.validateBlobSize(e),e}const u=o.body.getReader(),h=[];let g=0;for(;;){const{done:e,value:a}=await u.read();if(e)break;if(h.push(a),g+=a.length,g>this.configManager.get("maxBundleSize"))throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,"Download size exceeds maximum allowed size");r&&r({percent:Math.round(g/d*100),bytesDownloaded:g,totalBytes:d,bundleId:t})}const p=new Blob(h);return this.validateBlobSize(p),this.logger.info("Download completed",{bundleId:t,size:p.size,duration:Date.now()-i.startTime}),p}catch(e){if(e instanceof Error&&"AbortError"===e.name){const t=Date.now()-i.startTime>=this.configManager.get("downloadTimeout");throw new I(t?exports.ErrorCode.DOWNLOAD_TIMEOUT:exports.ErrorCode.DOWNLOAD_FAILED,t?"Download timed out":"Download cancelled",void 0,e)}throw e}finally{this.activeDownloads.delete(t)}}isValidContentType(e){return["application/octet-stream","application/zip","application/x-zip-compressed","application/x-zip"].some(t=>e.includes(t))}validateBlobSize(e){if(0===e.size)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Downloaded file is empty");if(e.size>this.configManager.get("maxBundleSize"))throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,`File size ${e.size} exceeds maximum allowed size`)}cancelDownload(e){const t=this.activeDownloads.get(e);t&&(t.controller.abort(),this.activeDownloads.delete(e),this.logger.info("Download cancelled",{bundleId:e}))}cancelAllDownloads(){for(const e of this.activeDownloads.values())e.controller.abort();const e=this.activeDownloads.size;this.activeDownloads.clear(),e>0&&this.logger.info("All downloads cancelled",{count:e})}isDownloading(e){return this.activeDownloads.has(e)}getActiveDownloadCount(){return this.activeDownloads.size}async downloadWithRetry(e,t,r){const a=this.configManager.get("retryAttempts"),i=this.configManager.get("retryDelay");let n=null;for(let s=0;s<a;s++)try{if(s>0){const e=Math.min(i*Math.pow(2,s-1),3e4);await new Promise(t=>setTimeout(t,e)),this.logger.debug("Retrying download",{bundleId:t,attempt:s,delay:e})}return await this.download(e,t,r)}catch(e){if(n=e,e instanceof y||e instanceof Error&&"AbortError"===e.name)throw e;this.logger.warn(`Download attempt ${s+1} failed`,{bundleId:t,error:e})}throw new I(exports.ErrorCode.DOWNLOAD_FAILED,"Download failed after all retries",{attempts:a},n||void 0)}async blobToArrayBuffer(e){return e.arrayBuffer()}async saveBlob(e,t){if(!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not initialized");const r=await this.blobToArrayBuffer(t),a=btoa(String.fromCharCode(...new Uint8Array(r))),i=`bundles/${e}/bundle.zip`;return await this.filesystem.writeFile({path:i,data:a,directory:g.Directory.Data,recursive:!0}),this.logger.debug("Bundle saved to filesystem",{bundleId:e,path:i,size:t.size}),i}async loadBlob(e){if(!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not initialized");try{const t=`bundles/${e}/bundle.zip`,r=await this.filesystem.readFile({path:t,directory:g.Directory.Data}),a=atob(r.data),i=new Uint8Array(a.length);for(let e=0;e<a.length;e++)i[e]=a.charCodeAt(e);return new Blob([i],{type:"application/zip"})}catch(t){return this.logger.debug("Failed to load bundle from filesystem",{bundleId:e,error:t}),null}}async deleteBlob(e){if(!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not initialized");try{const t=`bundles/${e}`;await this.filesystem.rmdir({path:t,directory:g.Directory.Data,recursive:!0}),this.logger.debug("Bundle deleted from filesystem",{bundleId:e})}catch(t){this.logger.warn("Failed to delete bundle from filesystem",{bundleId:e,error:t})}}}class C{constructor(){this.VERSION_CHECK_CACHE_KEY="capacitor_native_update_version_cache",this.CACHE_DURATION=3e5,this.preferences=null,this.memoryCache=new Map,this.logger=E.getInstance(),this.configManager=f.getInstance(),this.securityValidator=m.getInstance()}static compareVersions(e,t){try{const[r,a]=e.split("-"),[i,n]=t.split("-"),s=r.split(".").map(Number),o=i.split(".").map(Number);for(let e=0;e<3;e++){const t=s[e]||0,r=o[e]||0;if(t>r)return 1;if(t<r)return-1}return a&&!n?-1:!a&&n?1:a&&n?a.localeCompare(n):0}catch(r){return e===t?0:e>t?1:-1}}static isValidVersion(e){return/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/.test(e)}static shouldUpdate(e,t,r){return!(r&&C.compareVersions(e,r)<0)&&C.compareVersions(e,t)<0}async initialize(){if(this.preferences=this.configManager.get("preferences"),!this.preferences)throw new y(exports.ErrorCode.MISSING_DEPENDENCY,"Preferences not configured. Please configure the plugin first.")}async checkForUpdates(e,t,r,a){if(this.securityValidator.validateUrl(e),this.securityValidator.validateVersion(r),!t||!a)throw new y(exports.ErrorCode.INVALID_CONFIG,"Channel and appId are required");const i=`${t}-${a}`,n=await this.getCachedVersionInfo(i);if(n&&n.channel===t&&Date.now()-n.timestamp<this.CACHE_DURATION)return this.logger.debug("Returning cached version info",{channel:t,version:n.data.version}),n.data;try{const n=new URL(`${e}/check`);n.searchParams.append("channel",t),n.searchParams.append("version",r),n.searchParams.append("appId",a),n.searchParams.append("platform","web");const s=await fetch(n.toString(),{method:"GET",headers:{"Content-Type":"application/json","X-App-Version":r,"X-App-Id":a},signal:AbortSignal.timeout(this.configManager.get("downloadTimeout"))});if(!s.ok)throw new Error(`Version check failed: ${s.status}`);const o=await s.json();if(!o.version)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"No version in server response");return this.securityValidator.validateVersion(o.version),o.bundleUrl&&this.securityValidator.validateUrl(o.bundleUrl),o.minAppVersion&&this.securityValidator.validateVersion(o.minAppVersion),await this.cacheVersionInfo(i,t,o),this.logger.info("Version check completed",{channel:t,currentVersion:r,latestVersion:o.version,updateAvailable:this.isNewerVersion(o.version,r)}),o}catch(e){return this.logger.error("Failed to check for updates",e),null}}isNewerVersion(e,t){try{const r=this.parseVersion(e),a=this.parseVersion(t);return r.major!==a.major?r.major>a.major:r.minor!==a.minor?r.minor>a.minor:r.patch!==a.patch?r.patch>a.patch:!(r.prerelease&&!a.prerelease||(r.prerelease||!a.prerelease)&&(!r.prerelease||!a.prerelease||!(r.prerelease>a.prerelease)))}catch(r){return this.logger.error("Failed to compare versions",{version1:e,version2:t,error:r}),!1}}isUpdateMandatory(e,t){if(!t)return!1;try{return this.securityValidator.validateVersion(e),this.securityValidator.validateVersion(t),!this.isNewerVersion(e,t)&&e!==t}catch(e){return this.logger.error("Failed to check mandatory update",e),!1}}parseVersion(e){const t=e.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/);if(!t)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid version format");return{major:parseInt(t[1],10),minor:parseInt(t[2],10),patch:parseInt(t[3],10),prerelease:t[4],build:t[5]}}buildVersionString(e){let t=`${e.major}.${e.minor}.${e.patch}`;return e.prerelease&&(t+=`-${e.prerelease}`),e.build&&(t+=`+${e.build}`),t}isCompatibleWithNativeVersion(e,t,r){if(!r)return!0;try{const a=r[e];return!a||(this.securityValidator.validateVersion(t),this.securityValidator.validateVersion(a),!this.isNewerVersion(a,t))}catch(e){return this.logger.error("Failed to check compatibility",e),!1}}async getCachedVersionInfo(e){const t=this.memoryCache.get(e);if(t&&Date.now()-t.timestamp<this.CACHE_DURATION)return t;try{const{value:t}=await this.preferences.get({key:this.VERSION_CHECK_CACHE_KEY});if(!t)return null;const r=JSON.parse(t)[e];if(r&&Date.now()-r.timestamp<this.CACHE_DURATION)return this.memoryCache.set(e,r),r}catch(e){this.logger.debug("Failed to load cached version info",e)}return null}async cacheVersionInfo(e,t,r){const a={channel:t,data:r,timestamp:Date.now()};this.memoryCache.set(e,a);try{const{value:t}=await this.preferences.get({key:this.VERSION_CHECK_CACHE_KEY}),r=t?JSON.parse(t):{},i=Date.now();for(const e in r)i-r[e].timestamp>2*this.CACHE_DURATION&&delete r[e];r[e]=a,await this.preferences.set({key:this.VERSION_CHECK_CACHE_KEY,value:JSON.stringify(r)})}catch(e){this.logger.warn("Failed to cache version info",e)}}async clearVersionCache(){this.memoryCache.clear();try{await this.preferences.remove({key:this.VERSION_CHECK_CACHE_KEY})}catch(e){this.logger.warn("Failed to clear version cache",e)}}shouldBlockDowngrade(e,t){try{return this.securityValidator.isVersionDowngrade(e,t)}catch(e){return this.logger.error("Failed to check downgrade",e),!0}}}class R{constructor(){this.bundleManager=null,this.downloadManager=null,this.versionManager=null,this.initialized=!1,this.configManager=f.getInstance(),this.logger=E.getInstance(),this.securityValidator=m.getInstance()}static getInstance(){return R.instance||(R.instance=new R),R.instance}async initialize(e){if(this.initialized)this.logger.warn("Plugin already initialized");else try{this.configManager.configure(e),e.filesystem||(e.filesystem=g.Filesystem),e.preferences||(e.preferences=p.Preferences),this.bundleManager=new N,await this.bundleManager.initialize(),this.downloadManager=new _,await this.downloadManager.initialize(),this.versionManager=new C,await this.versionManager.initialize(),this.initialized=!0,this.logger.info("Plugin initialized successfully")}catch(e){throw this.logger.error("Failed to initialize plugin",e),e}}isInitialized(){return this.initialized&&this.configManager.isConfigured()}ensureInitialized(){if(!this.isInitialized())throw new w(exports.ErrorCode.NOT_CONFIGURED,"Plugin not initialized. Please call initialize() first.")}getBundleManager(){return this.ensureInitialized(),this.bundleManager}getDownloadManager(){return this.ensureInitialized(),this.downloadManager}getVersionManager(){return this.ensureInitialized(),this.versionManager}getConfigManager(){return this.configManager}getLogger(){return this.logger}getSecurityValidator(){return this.securityValidator}async reset(){this.logger.info("Resetting plugin state"),this.bundleManager&&await this.bundleManager.clearAllBundles(),this.versionManager&&await this.versionManager.clearVersionCache(),this.downloadManager&&this.downloadManager.cancelAllDownloads(),this.bundleManager=null,this.downloadManager=null,this.versionManager=null,this.initialized=!1,this.logger.info("Plugin reset complete")}async cleanup(){this.logger.info("Cleaning up plugin resources"),this.downloadManager&&this.downloadManager.cancelAllDownloads(),this.bundleManager&&await this.bundleManager.cleanExpiredBundles(),this.logger.info("Cleanup complete")}}class v{constructor(){this.initialized=!1,this.pluginManager=R.getInstance()}async initialize(e){await this.pluginManager.initialize(e),this.initialized=!0}isInitialized(){return this.initialized&&this.pluginManager.isInitialized()}async reset(){await this.pluginManager.reset()}async cleanup(){await this.pluginManager.cleanup()}async configure(e){var t;let r;r="config"in e&&"object"==typeof e.config?e.config:{baseUrl:null===(t=e.liveUpdate)||void 0===t?void 0:t.serverUrl},this.initialized?this.pluginManager.getConfigManager().configure(r):await this.initialize(r)}async getSecurityInfo(){return{enforceHttps:!0,certificatePinning:{enabled:!1,pins:[]},validateInputs:!0,secureStorage:!0}}async sync(e){const t=this.pluginManager.getBundleManager();try{const e=await t.getActiveBundle();return{status:s.UP_TO_DATE,version:(null==e?void 0:e.version)||"1.0.0"}}catch(e){return{status:s.ERROR,error:{code:c.UNKNOWN_ERROR,message:e instanceof Error?e.message:"Sync failed"}}}}async download(e){const t=this.pluginManager.getDownloadManager(),r=this.pluginManager.getBundleManager(),a=await t.downloadWithRetry(e.url,e.version),i=await t.saveBlob(e.version,a),n={bundleId:e.version,version:e.version,path:i,downloadTime:Date.now(),size:a.size,status:o.READY,checksum:e.checksum,signature:e.signature,verified:!1};return await r.saveBundleInfo(n),n}async set(e){const t=this.pluginManager.getBundleManager();await t.setActiveBundle(e.bundleId)}async reload(){"undefined"!=typeof window&&window.location.reload()}async current(){const e=this.pluginManager.getBundleManager(),t=await e.getActiveBundle();if(!t)throw new w(exports.ErrorCode.FILE_NOT_FOUND,"No active bundle found");return t}async list(){return this.pluginManager.getBundleManager().getAllBundles()}async delete(e){const t=this.pluginManager.getBundleManager();if(e.bundleId)await t.deleteBundle(e.bundleId);else if(void 0!==e.keepVersions){const r=(await t.getAllBundles()).sort((e,t)=>t.downloadTime-e.downloadTime);for(let a=e.keepVersions;a<r.length;a++)await t.deleteBundle(r[a].bundleId)}}async notifyAppReady(){const e=this.pluginManager.getBundleManager(),t=await e.getActiveBundle();t&&(t.status=o.ACTIVE,await e.saveBundleInfo(t))}async getLatest(){return{available:!1}}async setChannel(e){const t=this.pluginManager.getConfigManager().get("preferences");t&&await t.set({key:"update_channel",value:e})}async setUpdateUrl(e){this.pluginManager.getConfigManager().configure({baseUrl:e})}async validateUpdate(e){const t=this.pluginManager.getSecurityValidator();try{const r=await t.validateChecksum(new ArrayBuffer(0),e.checksum);return{isValid:r,details:{checksumValid:r,signatureValid:!0,sizeValid:!0,versionValid:!0}}}catch(e){return{isValid:!1,error:e instanceof Error?e.message:"Validation failed"}}}async getAppUpdateInfo(){return{updateAvailable:!1,currentVersion:"1.0.0"}}async performImmediateUpdate(){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Native app updates are not supported on web")}async startFlexibleUpdate(){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Native app updates are not supported on web")}async completeFlexibleUpdate(){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Native app updates are not supported on web")}async openAppStore(e){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"App store is not available on web")}async requestReview(){return{displayed:!1,error:"Reviews are not supported on web"}}async canRequestReview(){return{canRequest:!1,reason:"Reviews are not supported on web"}}async enableBackgroundUpdates(e){const t=this.pluginManager.getConfigManager().get("preferences");t&&await t.set({key:"background_update_config",value:JSON.stringify(e)})}async disableBackgroundUpdates(){const e=this.pluginManager.getConfigManager().get("preferences");e&&await e.remove({key:"background_update_config"})}async getBackgroundUpdateStatus(){return{enabled:!1,isRunning:!1,checkCount:0,failureCount:0}}async scheduleBackgroundCheck(e){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Background updates are not supported on web")}async triggerBackgroundCheck(){return{success:!1,updatesFound:!1,notificationSent:!1,error:{code:c.PLATFORM_NOT_SUPPORTED,message:"Background updates are not supported on web"}}}async setNotificationPreferences(e){const t=this.pluginManager.getConfigManager().get("preferences");t&&await t.set({key:"notification_preferences",value:JSON.stringify(e)})}async getNotificationPermissions(){return{granted:!1,canRequest:!1}}async requestNotificationPermissions(){return!1}}const O=h.registerPlugin("NativeUpdate",{web:()=>new v});exports.BundleManager=N,exports.CacheManager=class{constructor(){this.filesystem=null,this.memoryCache=new Map,this.CACHE_DIR="cache",this.logger=E.getInstance(),this.configManager=f.getInstance()}async initialize(){if(this.filesystem=this.configManager.get("filesystem"),!this.filesystem)throw new Error("Filesystem not configured");try{await this.filesystem.mkdir({path:this.CACHE_DIR,directory:g.Directory.Data,recursive:!0})}catch(e){this.logger.debug("Cache directory may already exist",e)}await this.cleanExpiredCache()}async set(e,t,r){const a=Date.now()+(r||this.configManager.get("cacheExpiration")),i={data:t,timestamp:Date.now(),expiry:a};this.memoryCache.set(e,i),this.shouldPersist(t)&&await this.persistToFile(e,i),this.logger.debug("Cache entry set",{key:e,expiry:new Date(a)})}async get(e){const t=this.memoryCache.get(e);if(t){if(Date.now()<t.expiry)return t.data;this.memoryCache.delete(e)}const r=await this.loadFromFile(e);if(r){if(Date.now()<r.expiry)return this.memoryCache.set(e,r),r.data;await this.removeFile(e)}return null}async has(e){return null!==await this.get(e)}async remove(e){this.memoryCache.delete(e),await this.removeFile(e),this.logger.debug("Cache entry removed",{key:e})}async clear(){this.memoryCache.clear();try{await this.filesystem.rmdir({path:this.CACHE_DIR,directory:g.Directory.Data,recursive:!0}),await this.filesystem.mkdir({path:this.CACHE_DIR,directory:g.Directory.Data,recursive:!0})}catch(e){this.logger.warn("Failed to clear cache directory",e)}this.logger.info("Cache cleared")}async cleanExpiredCache(){const e=Date.now();let t=0;for(const[r,a]of this.memoryCache)e>=a.expiry&&(this.memoryCache.delete(r),t++);try{const r=await this.filesystem.readdir({path:this.CACHE_DIR,directory:g.Directory.Data});for(const a of r.files){const r=a.name.replace(".json",""),i=await this.loadFromFile(r);(!i||e>=i.expiry)&&(await this.removeFile(r),t++)}}catch(e){this.logger.debug("Failed to clean filesystem cache",e)}t>0&&this.logger.info("Cleaned expired cache entries",{count:t})}async getStats(){let e=0,t=0;try{const r=await this.filesystem.readdir({path:this.CACHE_DIR,directory:g.Directory.Data});e=r.files.length;for(const e of r.files)t+=(await this.filesystem.stat({path:`${this.CACHE_DIR}/${e.name}`,directory:g.Directory.Data})).size||0}catch(e){this.logger.debug("Failed to get cache stats",e)}return{memoryEntries:this.memoryCache.size,fileEntries:e,totalSize:t}}async cacheBundleMetadata(e){const t=`bundle_meta_${e.bundleId}`;await this.set(t,e,864e5)}async getCachedBundleMetadata(e){return this.get(`bundle_meta_${e}`)}shouldPersist(e){return"object"==typeof e||"string"==typeof e&&e.length>1024}async persistToFile(e,t){if(this.filesystem)try{const r=`${this.CACHE_DIR}/${e}.json`,a=JSON.stringify(t);await this.filesystem.writeFile({path:r,data:a,directory:g.Directory.Data,encoding:g.Encoding.UTF8})}catch(t){this.logger.warn("Failed to persist cache to file",{key:e,error:t})}}async loadFromFile(e){if(!this.filesystem)return null;try{const t=`${this.CACHE_DIR}/${e}.json`,r=await this.filesystem.readFile({path:t,directory:g.Directory.Data,encoding:g.Encoding.UTF8});return JSON.parse(r.data)}catch(e){return null}}async removeFile(e){if(this.filesystem)try{const t=`${this.CACHE_DIR}/${e}.json`;await this.filesystem.deleteFile({path:t,directory:g.Directory.Data})}catch(t){this.logger.debug("Failed to remove cache file",{key:e,error:t})}}},exports.ConfigManager=f,exports.ConfigurationError=class extends w{constructor(e,t){super(exports.ErrorCode.INVALID_CONFIG,e,t),this.name="ConfigurationError"}},exports.DownloadError=I,exports.DownloadManager=_,exports.Logger=E,exports.NativeUpdate=O,exports.NativeUpdateError=w,exports.PluginManager=R,exports.SecurityValidator=m,exports.StorageError=D,exports.UpdateErrorClass=A,exports.UpdateManager=class{constructor(){this.filesystem=null,this.updateInProgress=!1,this.currentState=null,this.pluginManager=R.getInstance(),this.securityValidator=m.getInstance()}async initialize(){if(this.filesystem=this.pluginManager.getConfigManager().get("filesystem"),!this.filesystem)throw new A(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not configured")}async applyUpdate(e,t){if(this.updateInProgress)throw new A(exports.ErrorCode.UPDATE_FAILED,"Another update is already in progress");const r=this.pluginManager.getLogger(),a=this.pluginManager.getBundleManager();try{this.updateInProgress=!0,r.info("Starting bundle update",{bundleId:e});const i=await a.getBundle(e);if(!i)throw new A(exports.ErrorCode.FILE_NOT_FOUND,`Bundle ${e} not found`);if("READY"!==i.status&&"ACTIVE"!==i.status)throw new A(exports.ErrorCode.BUNDLE_NOT_READY,`Bundle ${e} is not ready for installation`);const n=await a.getActiveBundle();this.currentState={currentBundle:n,newBundle:i,backupPath:null,startTime:Date.now()},await this.validateUpdate(n,i,t),n&&"default"!==n.bundleId&&(this.currentState.backupPath=await this.createBackup(n)),await this.performUpdate(i),await this.verifyUpdate(i),await a.setActiveBundle(e),(null==t?void 0:t.cleanupOldBundles)&&await a.cleanupOldBundles(t.keepBundleCount||3),r.info("Bundle update completed successfully",{bundleId:e,version:i.version,duration:Date.now()-this.currentState.startTime}),this.currentState=null}catch(e){throw r.error("Bundle update failed",e),this.currentState&&await this.rollback(),e}finally{this.updateInProgress=!1}}async validateUpdate(e,t,r){const a=this.pluginManager.getLogger(),i=this.pluginManager.getVersionManager();if(e&&!(null==r?void 0:r.allowDowngrade)&&i.shouldBlockDowngrade(e.version,t.version))throw new y(exports.ErrorCode.VERSION_DOWNGRADE,`Cannot downgrade from ${e.version} to ${t.version}`);if(!t.verified){a.warn("Bundle not verified, verifying now",{bundleId:t.bundleId});const e=this.pluginManager.getDownloadManager(),r=await e.loadBlob(t.bundleId);if(!r)throw new A(exports.ErrorCode.FILE_NOT_FOUND,"Bundle data not found");const i=await r.arrayBuffer();if(!await this.securityValidator.verifyChecksum(i,t.checksum))throw new y(exports.ErrorCode.CHECKSUM_MISMATCH,"Bundle checksum verification failed");if(t.signature&&!await this.securityValidator.verifySignature(i,t.signature))throw new y(exports.ErrorCode.SIGNATURE_INVALID,"Bundle signature verification failed");await this.pluginManager.getBundleManager().markBundleAsVerified(t.bundleId)}a.debug("Bundle validation passed",{bundleId:t.bundleId})}async createBackup(e){const t=`backups/${e.bundleId}_${Date.now()}`,r=this.pluginManager.getLogger();try{return await this.filesystem.mkdir({path:t,directory:g.Directory.Data,recursive:!0}),await this.filesystem.copy({from:e.path,to:t,directory:g.Directory.Data}),r.info("Backup created",{bundleId:e.bundleId,backupPath:t}),t}catch(e){throw r.error("Failed to create backup",e),new A(exports.ErrorCode.UPDATE_FAILED,"Failed to create backup",void 0,e)}}async performUpdate(e){const t=this.pluginManager.getLogger();try{const r=`active/${e.bundleId}`;await this.filesystem.mkdir({path:r,directory:g.Directory.Data,recursive:!0}),await this.filesystem.copy({from:e.path,to:r,directory:g.Directory.Data}),e.path=r,t.debug("Bundle files installed",{bundleId:e.bundleId,targetPath:r})}catch(e){throw new A(exports.ErrorCode.UPDATE_FAILED,"Failed to install bundle files",void 0,e)}}async verifyUpdate(e){try{const t=`${e.path}/index.html`;await this.filesystem.stat({path:t,directory:g.Directory.Data})}catch(e){throw new A(exports.ErrorCode.UPDATE_FAILED,"Bundle verification failed after installation",void 0,e)}}async rollback(){var e;if(!this.currentState)throw new A(exports.ErrorCode.ROLLBACK_FAILED,"No update state to rollback");const t=this.pluginManager.getLogger();t.warn("Starting rollback",{from:this.currentState.newBundle.bundleId,to:(null===(e=this.currentState.currentBundle)||void 0===e?void 0:e.bundleId)||"default"});try{const e=this.pluginManager.getBundleManager();if(this.currentState.backupPath&&this.currentState.currentBundle){const t=`active/${this.currentState.currentBundle.bundleId}`;await this.filesystem.copy({from:this.currentState.backupPath,to:t,directory:g.Directory.Data}),this.currentState.currentBundle.path=t,await e.saveBundleInfo(this.currentState.currentBundle)}this.currentState.currentBundle?await e.setActiveBundle(this.currentState.currentBundle.bundleId):await e.clearActiveBundle(),t.info("Rollback completed successfully")}catch(e){throw t.error("Rollback failed",e),new A(exports.ErrorCode.ROLLBACK_FAILED,"Failed to rollback update",void 0,e)}finally{if(this.currentState.backupPath)try{await this.filesystem.rmdir({path:this.currentState.backupPath,directory:g.Directory.Data,recursive:!0})}catch(e){t.warn("Failed to clean up backup",e)}}}getUpdateProgress(){var e,t;return{inProgress:this.updateInProgress,bundleId:null===(e=this.currentState)||void 0===e?void 0:e.newBundle.bundleId,startTime:null===(t=this.currentState)||void 0===t?void 0:t.startTime}}async cancelUpdate(){this.updateInProgress&&this.currentState&&(this.pluginManager.getLogger().warn("Cancelling update",{bundleId:this.currentState.newBundle.bundleId}),await this.rollback(),this.updateInProgress=!1,this.currentState=null)}},exports.ValidationError=y,exports.VersionManager=C;
1
+ var e,t,r,a,i,n,s,o,l,c,d,u,h=require("@capacitor/core"),g=require("@capacitor/filesystem"),p=require("@capacitor/preferences");!function(e){e.APP_UPDATE="app_update",e.LIVE_UPDATE="live_update",e.BOTH="both"}(e||(e={})),function(e){e.MIN="min",e.LOW="low",e.DEFAULT="default",e.HIGH="high",e.MAX="max"}(t||(t={})),function(e){e.IMMEDIATE="immediate",e.BACKGROUND="background",e.MANUAL="manual"}(r||(r={})),function(e){e.IMMEDIATE="immediate",e.ON_NEXT_RESTART="on_next_restart",e.ON_NEXT_RESUME="on_next_resume"}(a||(a={})),function(e){e.IMMEDIATE="immediate",e.ON_NEXT_RESTART="on_next_restart",e.ON_NEXT_RESUME="on_next_resume"}(i||(i={})),function(e){e.SHA256="SHA-256",e.SHA512="SHA-512"}(n||(n={})),function(e){e.UP_TO_DATE="UP_TO_DATE",e.UPDATE_AVAILABLE="UPDATE_AVAILABLE",e.UPDATE_INSTALLED="UPDATE_INSTALLED",e.ERROR="ERROR"}(s||(s={})),function(e){e.PENDING="PENDING",e.DOWNLOADING="DOWNLOADING",e.READY="READY",e.ACTIVE="ACTIVE",e.FAILED="FAILED"}(o||(o={})),function(e){e.UNKNOWN="UNKNOWN",e.PENDING="PENDING",e.DOWNLOADING="DOWNLOADING",e.DOWNLOADED="DOWNLOADED",e.INSTALLING="INSTALLING",e.INSTALLED="INSTALLED",e.FAILED="FAILED",e.CANCELED="CANCELED"}(l||(l={})),function(e){e.NETWORK_ERROR="NETWORK_ERROR",e.SERVER_ERROR="SERVER_ERROR",e.TIMEOUT_ERROR="TIMEOUT_ERROR",e.DOWNLOAD_ERROR="DOWNLOAD_ERROR",e.STORAGE_ERROR="STORAGE_ERROR",e.SIZE_LIMIT_EXCEEDED="SIZE_LIMIT_EXCEEDED",e.VERIFICATION_ERROR="VERIFICATION_ERROR",e.CHECKSUM_ERROR="CHECKSUM_ERROR",e.SIGNATURE_ERROR="SIGNATURE_ERROR",e.INSECURE_URL="INSECURE_URL",e.INVALID_CERTIFICATE="INVALID_CERTIFICATE",e.PATH_TRAVERSAL="PATH_TRAVERSAL",e.INSTALL_ERROR="INSTALL_ERROR",e.ROLLBACK_ERROR="ROLLBACK_ERROR",e.VERSION_MISMATCH="VERSION_MISMATCH",e.PERMISSION_DENIED="PERMISSION_DENIED",e.UPDATE_NOT_AVAILABLE="UPDATE_NOT_AVAILABLE",e.UPDATE_IN_PROGRESS="UPDATE_IN_PROGRESS",e.UPDATE_CANCELLED="UPDATE_CANCELLED",e.PLATFORM_NOT_SUPPORTED="PLATFORM_NOT_SUPPORTED",e.REVIEW_NOT_SUPPORTED="REVIEW_NOT_SUPPORTED",e.QUOTA_EXCEEDED="QUOTA_EXCEEDED",e.CONDITIONS_NOT_MET="CONDITIONS_NOT_MET",e.INVALID_CONFIG="INVALID_CONFIG",e.UNKNOWN_ERROR="UNKNOWN_ERROR"}(c||(c={}));class f{constructor(){this.config=this.getDefaultConfig()}static getInstance(){return f.instance||(f.instance=new f),f.instance}getDefaultConfig(){return{filesystem:null,preferences:null,baseUrl:"",allowedHosts:[],maxBundleSize:104857600,downloadTimeout:3e4,retryAttempts:3,retryDelay:1e3,enableSignatureValidation:!0,publicKey:"",cacheExpiration:864e5,enableLogging:!1,serverUrl:"",channel:"production",autoCheck:!0,autoUpdate:!1,updateStrategy:"background",requireSignature:!0,checksumAlgorithm:"SHA-256",checkInterval:864e5,security:{enforceHttps:!0,validateInputs:!0,secureStorage:!0,logSecurityEvents:!1},promptAfterPositiveEvents:!1,maxPromptsPerVersion:1,minimumDaysSinceLastPrompt:7,isPremiumUser:!1,appStoreId:"",iosAppId:"",packageName:"",webReviewUrl:"",minimumVersion:"1.0.0"}}configure(e){this.config=Object.assign(Object.assign({},this.config),e),this.validateConfig()}validateConfig(){if(this.config.maxBundleSize<=0)throw new Error("maxBundleSize must be greater than 0");if(this.config.downloadTimeout<=0)throw new Error("downloadTimeout must be greater than 0");if(this.config.retryAttempts<0)throw new Error("retryAttempts must be non-negative");if(this.config.retryDelay<0)throw new Error("retryDelay must be non-negative")}get(e){return this.config[e]}set(e,t){this.config[e]=t}getAll(){return Object.assign({},this.config)}isConfigured(){return!(!this.config.filesystem||!this.config.preferences)}}exports.LogLevel=void 0,(d=exports.LogLevel||(exports.LogLevel={}))[d.DEBUG=0]="DEBUG",d[d.INFO=1]="INFO",d[d.WARN=2]="WARN",d[d.ERROR=3]="ERROR";class E{constructor(e){this.configManager=f.getInstance(),this.context=e||"NativeUpdate"}static getInstance(){return E.instance||(E.instance=new E),E.instance}shouldLog(){return this.configManager.get("enableLogging")}sanitize(e){if("string"==typeof e){let t=e;return t=t.replace(/\/[^\s]+\/([\w.-]+)$/g,"/<path>/$1"),t=t.replace(/https?:\/\/[^:]+:[^@]+@/g,"https://***:***@"),t=t.replace(/[a-zA-Z0-9]{32,}/g,"<redacted>"),t}if("object"==typeof e&&null!==e){if(Array.isArray(e))return e.map(e=>this.sanitize(e));{const t={},r=e;for(const e in r)t[e]=e.toLowerCase().includes("key")||e.toLowerCase().includes("secret")||e.toLowerCase().includes("password")||e.toLowerCase().includes("token")?"<redacted>":this.sanitize(r[e]);return t}}return e}log(e,t){this.logWithLevel(exports.LogLevel.INFO,e,t)}logWithLevel(e,t,r){if(!this.shouldLog())return;const a=(new Date).toISOString(),i=r?this.sanitize(r):void 0,n={timestamp:a,level:exports.LogLevel[e],context:this.context,message:t};switch(void 0!==i&&(n.data=i),e){case exports.LogLevel.DEBUG:console.debug(`[${this.context}]`,n);break;case exports.LogLevel.INFO:console.info(`[${this.context}]`,n);break;case exports.LogLevel.WARN:console.warn(`[${this.context}]`,n);break;case exports.LogLevel.ERROR:console.error(`[${this.context}]`,n)}}debug(e,t){this.logWithLevel(exports.LogLevel.DEBUG,e,t)}info(e,t){this.logWithLevel(exports.LogLevel.INFO,e,t)}warn(e,t){this.logWithLevel(exports.LogLevel.WARN,e,t)}error(e,t){const r=t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t;this.logWithLevel(exports.LogLevel.ERROR,e,r)}}exports.ErrorCode=void 0,(u=exports.ErrorCode||(exports.ErrorCode={})).NOT_CONFIGURED="NOT_CONFIGURED",u.INVALID_CONFIG="INVALID_CONFIG",u.MISSING_DEPENDENCY="MISSING_DEPENDENCY",u.DOWNLOAD_FAILED="DOWNLOAD_FAILED",u.DOWNLOAD_TIMEOUT="DOWNLOAD_TIMEOUT",u.INVALID_URL="INVALID_URL",u.UNAUTHORIZED_HOST="UNAUTHORIZED_HOST",u.BUNDLE_TOO_LARGE="BUNDLE_TOO_LARGE",u.CHECKSUM_MISMATCH="CHECKSUM_MISMATCH",u.SIGNATURE_INVALID="SIGNATURE_INVALID",u.VERSION_DOWNGRADE="VERSION_DOWNGRADE",u.INVALID_BUNDLE_FORMAT="INVALID_BUNDLE_FORMAT",u.STORAGE_FULL="STORAGE_FULL",u.FILE_NOT_FOUND="FILE_NOT_FOUND",u.PERMISSION_DENIED="PERMISSION_DENIED",u.UPDATE_FAILED="UPDATE_FAILED",u.ROLLBACK_FAILED="ROLLBACK_FAILED",u.BUNDLE_NOT_READY="BUNDLE_NOT_READY",u.PLATFORM_NOT_SUPPORTED="PLATFORM_NOT_SUPPORTED",u.NATIVE_ERROR="NATIVE_ERROR";class w extends Error{constructor(e,t,r,a){super(t),this.code=e,this.message=t,this.details=r,this.originalError=a,this.name="NativeUpdateError",Object.setPrototypeOf(this,w.prototype)}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details,stack:this.stack}}}class I extends w{constructor(e,t,r,a){super(e,t,r,a),this.name="DownloadError"}}class y extends w{constructor(e,t,r){super(e,t,r),this.name="ValidationError"}}class D extends w{constructor(e,t,r,a){super(e,t,r,a),this.name="StorageError"}}class A extends w{constructor(e,t,r,a){super(e,t,r,a),this.name="UpdateError"}}class m{constructor(){this.configManager=f.getInstance(),this.logger=E.getInstance()}static getInstance(){return m.instance||(m.instance=new m),m.instance}static validateUrl(e){try{return"https:"===new URL(e).protocol}catch(e){return!1}}static validateChecksum(e){return/^[a-f0-9]{64}$/i.test(e)}static sanitizeInput(e){return e?e.replace(/<[^>]*>/g,"").replace(/[^\w\s/.-]/g,""):""}static validateBundleSize(e){return e>0&&e<=104857600}async calculateChecksum(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}async verifyChecksum(e,t){if(!t)return this.logger.warn("No checksum provided for verification"),!0;const r=await this.calculateChecksum(e),a=r===t.toLowerCase();return a||this.logger.error("Checksum verification failed",{expected:t,actual:r}),a}async validateChecksum(e,t){return this.verifyChecksum(e,t)}async verifySignature(e,t){if(!this.configManager.get("enableSignatureValidation"))return!0;const r=this.configManager.get("publicKey");if(!r)throw new y(exports.ErrorCode.SIGNATURE_INVALID,"Public key not configured for signature validation");try{const a=await crypto.subtle.importKey("spki",this.pemToArrayBuffer(r),{name:"RSA-PSS",hash:"SHA-256"},!1,["verify"]),i=await crypto.subtle.verify({name:"RSA-PSS",saltLength:32},a,this.base64ToArrayBuffer(t),e);return i||this.logger.error("Signature verification failed"),i}catch(e){return this.logger.error("Signature verification error",e),!1}}pemToArrayBuffer(e){const t=e.replace(/-----BEGIN PUBLIC KEY-----/g,"").replace(/-----END PUBLIC KEY-----/g,"").replace(/\s/g,"");return this.base64ToArrayBuffer(t)}base64ToArrayBuffer(e){const t=atob(e),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r.buffer}sanitizePath(e){return e.split("/").filter(e=>".."!==e&&"."!==e).join("/").replace(/^\/+/,"")}validateBundleId(e){if(!e||"string"!=typeof e)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID must be a non-empty string");if(!/^[a-zA-Z0-9\-_.]+$/.test(e))throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID contains invalid characters");if(e.length>100)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is too long (max 100 characters)")}validateVersion(e){if(!e||"string"!=typeof e)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Version must be a non-empty string");if(!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/.test(e))throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Version must follow semantic versioning format (e.g., 1.2.3)")}isVersionDowngrade(e,t){const r=this.parseVersion(e),a=this.parseVersion(t);return a.major<r.major||!(a.major>r.major)&&(a.minor<r.minor||!(a.minor>r.minor)&&a.patch<r.patch)}parseVersion(e){const t=e.split("-")[0].split(".");return{major:parseInt(t[0],10)||0,minor:parseInt(t[1],10)||0,patch:parseInt(t[2],10)||0}}validateUrl(e){if(!e||"string"!=typeof e)throw new y(exports.ErrorCode.INVALID_URL,"URL must be a non-empty string");let t;try{t=new URL(e)}catch(e){throw new y(exports.ErrorCode.INVALID_URL,"Invalid URL format")}if("https:"!==t.protocol)throw new y(exports.ErrorCode.INVALID_URL,"Only HTTPS URLs are allowed");const r=this.configManager.get("allowedHosts");if(r.length>0&&!r.includes(t.hostname))throw new y(exports.ErrorCode.UNAUTHORIZED_HOST,`Host ${t.hostname} is not in the allowed hosts list`);if([/^localhost$/i,/^127\./,/^10\./,/^172\.(1[6-9]|2[0-9]|3[0-1])\./,/^192\.168\./,/^::1$/,/^fc00:/i,/^fe80:/i].some(e=>e.test(t.hostname)))throw new y(exports.ErrorCode.UNAUTHORIZED_HOST,"Private/local addresses are not allowed")}validateFileSize(e){if("number"!=typeof e||e<0)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"File size must be a non-negative number");const t=this.configManager.get("maxBundleSize");if(e>t)throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,`File size ${e} exceeds maximum allowed size of ${t} bytes`)}generateSecureId(){const e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,"0")).join("")}async validateCertificatePin(e,t){const r=this.configManager.certificatePins;if(!r||!Array.isArray(r)||0===r.length)return!0;const a=r.filter(t=>t.hostname===e);if(0===a.length)return!0;const i=await this.calculateCertificateHash(t),n=a.some(e=>e.sha256===i);return n||this.logger.error("Certificate pinning validation failed",{hostname:e,expectedPins:a.map(e=>e.sha256),actualHash:i}),n}async calculateCertificateHash(e){const t=(new TextEncoder).encode(e),r=await crypto.subtle.digest("SHA-256",t),a=Array.from(new Uint8Array(r));return"sha256/"+btoa(String.fromCharCode(...a))}validateMetadata(e){if(e&&"object"!=typeof e)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Metadata must be an object");if(JSON.stringify(e||{}).length>10240)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Metadata is too large (max 10KB)")}}class N{constructor(){this.STORAGE_KEY="capacitor_native_update_bundles",this.ACTIVE_BUNDLE_KEY="capacitor_native_update_active",this.preferences=null,this.cache=new Map,this.cacheExpiry=0,this.logger=E.getInstance(),this.configManager=f.getInstance()}async initialize(){if(this.preferences=this.configManager.get("preferences"),!this.preferences)throw new D(exports.ErrorCode.MISSING_DEPENDENCY,"Preferences not configured. Please configure the plugin first.");await this.loadCache()}async loadCache(){if(!(Date.now()<this.cacheExpiry))try{const{value:e}=await this.preferences.get({key:this.STORAGE_KEY});if(e){const t=JSON.parse(e);this.cache.clear(),t.forEach(e=>this.cache.set(e.bundleId,e))}this.cacheExpiry=Date.now()+5e3}catch(e){this.logger.error("Failed to load bundles from storage",e),this.cache.clear()}}async saveCache(){try{const e=Array.from(this.cache.values());await this.preferences.set({key:this.STORAGE_KEY,value:JSON.stringify(e)}),this.logger.debug("Saved bundles to storage",{count:e.length})}catch(e){throw new D(exports.ErrorCode.STORAGE_FULL,"Failed to save bundles to storage",void 0,e)}}async saveBundleInfo(e){this.validateBundleInfo(e),this.cache.set(e.bundleId,e),await this.saveCache(),this.logger.info("Bundle saved",{bundleId:e.bundleId,version:e.version})}validateBundleInfo(e){if(!e.bundleId||"string"!=typeof e.bundleId)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle ID");if(!e.version||"string"!=typeof e.version)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle version");if(!e.path||"string"!=typeof e.path)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle path");if("number"!=typeof e.size||e.size<0)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid bundle size")}async getAllBundles(){return await this.loadCache(),Array.from(this.cache.values())}async getBundle(e){if(!e)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");return await this.loadCache(),this.cache.get(e)||null}async deleteBundle(e){if(!e)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");await this.loadCache(),this.cache.get(e)?(this.cache.delete(e),await this.saveCache(),await this.getActiveBundleId()===e&&await this.clearActiveBundle(),this.logger.info("Bundle deleted",{bundleId:e})):this.logger.warn("Attempted to delete non-existent bundle",{bundleId:e})}async getActiveBundle(){const e=await this.getActiveBundleId();return e?this.getBundle(e):null}async setActiveBundle(e){if(!e)throw new D(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");const t=await this.getBundle(e);if(!t)throw new D(exports.ErrorCode.FILE_NOT_FOUND,`Bundle ${e} not found`);const r=await this.getActiveBundle();r&&r.bundleId!==e&&(r.status="READY",await this.saveBundleInfo(r)),t.status="ACTIVE",await this.saveBundleInfo(t),await this.preferences.set({key:this.ACTIVE_BUNDLE_KEY,value:e}),this.logger.info("Active bundle set",{bundleId:e,version:t.version})}async getActiveBundleId(){try{const{value:e}=await this.preferences.get({key:this.ACTIVE_BUNDLE_KEY});return e}catch(e){return this.logger.error("Failed to get active bundle ID",e),null}}async clearActiveBundle(){await this.preferences.remove({key:this.ACTIVE_BUNDLE_KEY}),this.logger.info("Active bundle cleared")}async clearAllBundles(){await this.preferences.remove({key:this.STORAGE_KEY}),await this.preferences.remove({key:this.ACTIVE_BUNDLE_KEY}),this.cache.clear(),this.cacheExpiry=0,this.logger.info("All bundles cleared")}async cleanupOldBundles(e){if(e<1)throw new D(exports.ErrorCode.INVALID_CONFIG,"Keep count must be at least 1");const t=await this.getAllBundles(),r=await this.getActiveBundleId(),a=t.sort((e,t)=>t.downloadTime-e.downloadTime),i=new Set;r&&i.add(r);let n=i.size;for(const t of a){if(n>=e)break;i.has(t.bundleId)||(i.add(t.bundleId),n++)}let s=0;for(const e of t)i.has(e.bundleId)||(await this.deleteBundle(e.bundleId),s++);s>0&&this.logger.info("Cleaned up old bundles",{deleted:s,kept:n})}async getBundlesOlderThan(e){if(e<0)throw new D(exports.ErrorCode.INVALID_CONFIG,"Timestamp must be non-negative");return(await this.getAllBundles()).filter(t=>t.downloadTime<e)}async markBundleAsVerified(e){const t=await this.getBundle(e);if(!t)throw new D(exports.ErrorCode.FILE_NOT_FOUND,`Bundle ${e} not found`);t.verified=!0,await this.saveBundleInfo(t),this.logger.info("Bundle marked as verified",{bundleId:e})}async getTotalStorageUsed(){return(await this.getAllBundles()).reduce((e,t)=>e+t.size,0)}async isStorageLimitExceeded(e=0){return await this.getTotalStorageUsed()+e>3*this.configManager.get("maxBundleSize")}createDefaultBundle(){return{bundleId:"default",version:"1.0.0",path:"/",downloadTime:Date.now(),size:0,status:"ACTIVE",checksum:"",verified:!0}}async cleanExpiredBundles(){const e=this.configManager.get("cacheExpiration"),t=Date.now()-e,r=await this.getBundlesOlderThan(t);for(const e of r){const t=await this.getActiveBundleId();e.bundleId!==t&&await this.deleteBundle(e.bundleId)}}}class _{constructor(){this.activeDownloads=new Map,this.filesystem=null,this.logger=E.getInstance(),this.configManager=f.getInstance()}async initialize(){if(this.filesystem=this.configManager.get("filesystem"),!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not configured. Please configure the plugin first.")}validateUrl(e){try{const t=new URL(e);if("https:"!==t.protocol)throw new y(exports.ErrorCode.INVALID_URL,"Only HTTPS URLs are allowed for security reasons");const r=this.configManager.get("allowedHosts");if(r.length>0&&!r.includes(t.hostname))throw new y(exports.ErrorCode.UNAUTHORIZED_HOST,`Host ${t.hostname} is not in the allowed hosts list`)}catch(e){if(e instanceof y)throw e;throw new y(exports.ErrorCode.INVALID_URL,"Invalid URL format")}}async download(e,t,r){if(this.validateUrl(e),!t)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Bundle ID is required");if(this.activeDownloads.has(t))throw new I(exports.ErrorCode.DOWNLOAD_FAILED,`Download already in progress for bundle ${t}`);const a=new AbortController,i={controller:a,startTime:Date.now()};this.activeDownloads.set(t,i);try{const n=this.configManager.get("downloadTimeout"),s=setTimeout(()=>a.abort(),n),o=await fetch(e,{signal:a.signal,headers:{"Cache-Control":"no-cache",Accept:"application/octet-stream, application/zip"}});if(clearTimeout(s),!o.ok)throw new I(exports.ErrorCode.DOWNLOAD_FAILED,`Download failed: ${o.status} ${o.statusText}`,{status:o.status,statusText:o.statusText});const l=o.headers.get("content-type");if(l&&!this.isValidContentType(l))throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,`Invalid content type: ${l}`);const c=o.headers.get("content-length"),d=c?parseInt(c,10):0;if(d>this.configManager.get("maxBundleSize"))throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,`Bundle size ${d} exceeds maximum allowed size`);if(!d||!o.body){const e=await o.blob();return this.validateBlobSize(e),e}const u=o.body.getReader(),h=[];let g=0;for(;;){const{done:e,value:a}=await u.read();if(e)break;if(h.push(a),g+=a.length,g>this.configManager.get("maxBundleSize"))throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,"Download size exceeds maximum allowed size");r&&r({percent:Math.round(g/d*100),bytesDownloaded:g,totalBytes:d,bundleId:t})}const p=new Blob(h);return this.validateBlobSize(p),this.logger.info("Download completed",{bundleId:t,size:p.size,duration:Date.now()-i.startTime}),p}catch(e){if(e instanceof Error&&"AbortError"===e.name){const t=Date.now()-i.startTime>=this.configManager.get("downloadTimeout");throw new I(t?exports.ErrorCode.DOWNLOAD_TIMEOUT:exports.ErrorCode.DOWNLOAD_FAILED,t?"Download timed out":"Download cancelled",void 0,e)}throw e}finally{this.activeDownloads.delete(t)}}isValidContentType(e){return["application/octet-stream","application/zip","application/x-zip-compressed","application/x-zip"].some(t=>e.includes(t))}validateBlobSize(e){if(0===e.size)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Downloaded file is empty");if(e.size>this.configManager.get("maxBundleSize"))throw new y(exports.ErrorCode.BUNDLE_TOO_LARGE,`File size ${e.size} exceeds maximum allowed size`)}cancelDownload(e){const t=this.activeDownloads.get(e);t&&(t.controller.abort(),this.activeDownloads.delete(e),this.logger.info("Download cancelled",{bundleId:e}))}cancelAllDownloads(){for(const e of this.activeDownloads.values())e.controller.abort();const e=this.activeDownloads.size;this.activeDownloads.clear(),e>0&&this.logger.info("All downloads cancelled",{count:e})}isDownloading(e){return this.activeDownloads.has(e)}getActiveDownloadCount(){return this.activeDownloads.size}async downloadWithRetry(e,t,r){const a=this.configManager.get("retryAttempts"),i=this.configManager.get("retryDelay");let n=null;for(let s=0;s<a;s++)try{if(s>0){const e=Math.min(i*Math.pow(2,s-1),3e4);await new Promise(t=>setTimeout(t,e)),this.logger.debug("Retrying download",{bundleId:t,attempt:s,delay:e})}return await this.download(e,t,r)}catch(e){if(n=e,e instanceof y||e instanceof Error&&"AbortError"===e.name)throw e;this.logger.warn(`Download attempt ${s+1} failed`,{bundleId:t,error:e})}throw new I(exports.ErrorCode.DOWNLOAD_FAILED,"Download failed after all retries",{attempts:a},n||void 0)}async blobToArrayBuffer(e){return e.arrayBuffer()}async saveBlob(e,t){if(!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not initialized");const r=await this.blobToArrayBuffer(t),a=btoa(String.fromCharCode(...new Uint8Array(r))),i=`bundles/${e}/bundle.zip`;return await this.filesystem.writeFile({path:i,data:a,directory:g.Directory.Data,recursive:!0}),this.logger.debug("Bundle saved to filesystem",{bundleId:e,path:i,size:t.size}),i}async loadBlob(e){if(!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not initialized");try{const t=`bundles/${e}/bundle.zip`,r=await this.filesystem.readFile({path:t,directory:g.Directory.Data}),a=atob(r.data),i=new Uint8Array(a.length);for(let e=0;e<a.length;e++)i[e]=a.charCodeAt(e);return new Blob([i],{type:"application/zip"})}catch(t){return this.logger.debug("Failed to load bundle from filesystem",{bundleId:e,error:t}),null}}async deleteBlob(e){if(!this.filesystem)throw new I(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not initialized");try{const t=`bundles/${e}`;await this.filesystem.rmdir({path:t,directory:g.Directory.Data,recursive:!0}),this.logger.debug("Bundle deleted from filesystem",{bundleId:e})}catch(t){this.logger.warn("Failed to delete bundle from filesystem",{bundleId:e,error:t})}}}class C{constructor(){this.VERSION_CHECK_CACHE_KEY="capacitor_native_update_version_cache",this.CACHE_DURATION=3e5,this.preferences=null,this.memoryCache=new Map,this.logger=E.getInstance(),this.configManager=f.getInstance(),this.securityValidator=m.getInstance()}static compareVersions(e,t){try{const[r,a]=e.split("-"),[i,n]=t.split("-"),s=r.split(".").map(Number),o=i.split(".").map(Number);for(let e=0;e<3;e++){const t=s[e]||0,r=o[e]||0;if(t>r)return 1;if(t<r)return-1}return a&&!n?-1:!a&&n?1:a&&n?a.localeCompare(n):0}catch(r){return e===t?0:e>t?1:-1}}static isValidVersion(e){return/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/.test(e)}static shouldUpdate(e,t,r){return!(r&&C.compareVersions(e,r)<0)&&C.compareVersions(e,t)<0}async initialize(){if(this.preferences=this.configManager.get("preferences"),!this.preferences)throw new y(exports.ErrorCode.MISSING_DEPENDENCY,"Preferences not configured. Please configure the plugin first.")}async checkForUpdates(e,t,r,a){if(this.securityValidator.validateUrl(e),this.securityValidator.validateVersion(r),!t||!a)throw new y(exports.ErrorCode.INVALID_CONFIG,"Channel and appId are required");const i=`${t}-${a}`,n=await this.getCachedVersionInfo(i);if(n&&n.channel===t&&Date.now()-n.timestamp<this.CACHE_DURATION)return this.logger.debug("Returning cached version info",{channel:t,version:n.data.version}),n.data;try{const n=new URL(`${e}/check`);n.searchParams.append("channel",t),n.searchParams.append("version",r),n.searchParams.append("appId",a),n.searchParams.append("platform","web");const s=await fetch(n.toString(),{method:"GET",headers:{"Content-Type":"application/json","X-App-Version":r,"X-App-Id":a},signal:AbortSignal.timeout(this.configManager.get("downloadTimeout"))});if(!s.ok)throw new Error(`Version check failed: ${s.status}`);const o=await s.json();if(!o.version)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"No version in server response");return this.securityValidator.validateVersion(o.version),o.bundleUrl&&this.securityValidator.validateUrl(o.bundleUrl),o.minAppVersion&&this.securityValidator.validateVersion(o.minAppVersion),await this.cacheVersionInfo(i,t,o),this.logger.info("Version check completed",{channel:t,currentVersion:r,latestVersion:o.version,updateAvailable:this.isNewerVersion(o.version,r)}),o}catch(e){return this.logger.error("Failed to check for updates",e),null}}isNewerVersion(e,t){try{const r=this.parseVersion(e),a=this.parseVersion(t);return r.major!==a.major?r.major>a.major:r.minor!==a.minor?r.minor>a.minor:r.patch!==a.patch?r.patch>a.patch:!(r.prerelease&&!a.prerelease||(r.prerelease||!a.prerelease)&&(!r.prerelease||!a.prerelease||!(r.prerelease>a.prerelease)))}catch(r){return this.logger.error("Failed to compare versions",{version1:e,version2:t,error:r}),!1}}isUpdateMandatory(e,t){if(!t)return!1;try{return this.securityValidator.validateVersion(e),this.securityValidator.validateVersion(t),!this.isNewerVersion(e,t)&&e!==t}catch(e){return this.logger.error("Failed to check mandatory update",e),!1}}parseVersion(e){const t=e.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/);if(!t)throw new y(exports.ErrorCode.INVALID_BUNDLE_FORMAT,"Invalid version format");return{major:parseInt(t[1],10),minor:parseInt(t[2],10),patch:parseInt(t[3],10),prerelease:t[4],build:t[5]}}buildVersionString(e){let t=`${e.major}.${e.minor}.${e.patch}`;return e.prerelease&&(t+=`-${e.prerelease}`),e.build&&(t+=`+${e.build}`),t}isCompatibleWithNativeVersion(e,t,r){if(!r)return!0;try{const a=r[e];return!a||(this.securityValidator.validateVersion(t),this.securityValidator.validateVersion(a),!this.isNewerVersion(a,t))}catch(e){return this.logger.error("Failed to check compatibility",e),!1}}async getCachedVersionInfo(e){const t=this.memoryCache.get(e);if(t&&Date.now()-t.timestamp<this.CACHE_DURATION)return t;try{const{value:t}=await this.preferences.get({key:this.VERSION_CHECK_CACHE_KEY});if(!t)return null;const r=JSON.parse(t)[e];if(r&&Date.now()-r.timestamp<this.CACHE_DURATION)return this.memoryCache.set(e,r),r}catch(e){this.logger.debug("Failed to load cached version info",e)}return null}async cacheVersionInfo(e,t,r){const a={channel:t,data:r,timestamp:Date.now()};this.memoryCache.set(e,a);try{const{value:t}=await this.preferences.get({key:this.VERSION_CHECK_CACHE_KEY}),r=t?JSON.parse(t):{},i=Date.now();for(const e in r)i-r[e].timestamp>2*this.CACHE_DURATION&&delete r[e];r[e]=a,await this.preferences.set({key:this.VERSION_CHECK_CACHE_KEY,value:JSON.stringify(r)})}catch(e){this.logger.warn("Failed to cache version info",e)}}async clearVersionCache(){this.memoryCache.clear();try{await this.preferences.remove({key:this.VERSION_CHECK_CACHE_KEY})}catch(e){this.logger.warn("Failed to clear version cache",e)}}shouldBlockDowngrade(e,t){try{return this.securityValidator.isVersionDowngrade(e,t)}catch(e){return this.logger.error("Failed to check downgrade",e),!0}}}class v{constructor(){this.bundleManager=null,this.downloadManager=null,this.versionManager=null,this.initialized=!1,this.configManager=f.getInstance(),this.logger=E.getInstance(),this.securityValidator=m.getInstance()}static getInstance(){return v.instance||(v.instance=new v),v.instance}async initialize(e){if(this.initialized)this.logger.warn("Plugin already initialized");else try{this.configManager.configure(e),e.filesystem||(e.filesystem=g.Filesystem),e.preferences||(e.preferences=p.Preferences),this.bundleManager=new N,await this.bundleManager.initialize(),this.downloadManager=new _,await this.downloadManager.initialize(),this.versionManager=new C,await this.versionManager.initialize(),this.initialized=!0,this.logger.info("Plugin initialized successfully")}catch(e){throw this.logger.error("Failed to initialize plugin",e),e}}isInitialized(){return this.initialized&&this.configManager.isConfigured()}ensureInitialized(){if(!this.isInitialized())throw new w(exports.ErrorCode.NOT_CONFIGURED,"Plugin not initialized. Please call initialize() first.")}getBundleManager(){return this.ensureInitialized(),this.bundleManager}getDownloadManager(){return this.ensureInitialized(),this.downloadManager}getVersionManager(){return this.ensureInitialized(),this.versionManager}getConfigManager(){return this.configManager}getLogger(){return this.logger}getSecurityValidator(){return this.securityValidator}async reset(){this.logger.info("Resetting plugin state"),this.bundleManager&&await this.bundleManager.clearAllBundles(),this.versionManager&&await this.versionManager.clearVersionCache(),this.downloadManager&&this.downloadManager.cancelAllDownloads(),this.bundleManager=null,this.downloadManager=null,this.versionManager=null,this.initialized=!1,this.logger.info("Plugin reset complete")}async cleanup(){this.logger.info("Cleaning up plugin resources"),this.downloadManager&&this.downloadManager.cancelAllDownloads(),this.bundleManager&&await this.bundleManager.cleanExpiredBundles(),this.logger.info("Cleanup complete")}}class R{constructor(){this.initialized=!1,this.pluginManager=v.getInstance()}async initialize(e){await this.pluginManager.initialize(e),this.initialized=!0}isInitialized(){return this.initialized&&this.pluginManager.isInitialized()}async reset(){await this.pluginManager.reset()}async cleanup(){await this.pluginManager.cleanup()}async configure(e){var t;let r;r="config"in e&&"object"==typeof e.config?e.config:{baseUrl:null===(t=e.liveUpdate)||void 0===t?void 0:t.serverUrl},this.initialized?this.pluginManager.getConfigManager().configure(r):await this.initialize(r)}async getSecurityInfo(){return{enforceHttps:!0,certificatePinning:{enabled:!1,pins:[]},validateInputs:!0,secureStorage:!0}}async sync(e){const t=this.pluginManager.getBundleManager();try{const e=await t.getActiveBundle();return{status:s.UP_TO_DATE,version:(null==e?void 0:e.version)||"1.0.0"}}catch(e){return{status:s.ERROR,error:{code:c.UNKNOWN_ERROR,message:e instanceof Error?e.message:"Sync failed"}}}}async download(e){const t=this.pluginManager.getDownloadManager(),r=this.pluginManager.getBundleManager(),a=await t.downloadWithRetry(e.url,e.version),i=await t.saveBlob(e.version,a),n={bundleId:e.version,version:e.version,path:i,downloadTime:Date.now(),size:a.size,status:o.READY,checksum:e.checksum,signature:e.signature,verified:!1};return await r.saveBundleInfo(n),n}async set(e){const t=this.pluginManager.getBundleManager();await t.setActiveBundle(e.bundleId)}async reload(){"undefined"!=typeof window&&window.location.reload()}async current(){const e=this.pluginManager.getBundleManager(),t=await e.getActiveBundle();if(!t)throw new w(exports.ErrorCode.FILE_NOT_FOUND,"No active bundle found");return t}async list(){return this.pluginManager.getBundleManager().getAllBundles()}async delete(e){const t=this.pluginManager.getBundleManager();if(e.bundleId)await t.deleteBundle(e.bundleId);else if(void 0!==e.keepVersions){const r=(await t.getAllBundles()).sort((e,t)=>t.downloadTime-e.downloadTime);for(let a=e.keepVersions;a<r.length;a++)await t.deleteBundle(r[a].bundleId)}}async notifyAppReady(){const e=this.pluginManager.getBundleManager(),t=await e.getActiveBundle();t&&(t.status=o.ACTIVE,await e.saveBundleInfo(t))}async getLatest(){return{available:!1}}async setChannel(e){const t=this.pluginManager.getConfigManager().get("preferences");t&&await t.set({key:"update_channel",value:e})}async setUpdateUrl(e){this.pluginManager.getConfigManager().configure({baseUrl:e})}async validateUpdate(e){const t=this.pluginManager.getSecurityValidator();try{const r=await t.validateChecksum(new ArrayBuffer(0),e.checksum);return{isValid:r,details:{checksumValid:r,signatureValid:!0,sizeValid:!0,versionValid:!0}}}catch(e){return{isValid:!1,error:e instanceof Error?e.message:"Validation failed"}}}async getAppUpdateInfo(){return{updateAvailable:!1,currentVersion:"1.0.0"}}async performImmediateUpdate(){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Native app updates are not supported on web")}async startFlexibleUpdate(){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Native app updates are not supported on web")}async completeFlexibleUpdate(){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Native app updates are not supported on web")}async openAppStore(e){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"App store is not available on web")}async requestReview(){return{displayed:!1,error:"Reviews are not supported on web"}}async canRequestReview(){return{canRequest:!1,reason:"Reviews are not supported on web"}}async enableBackgroundUpdates(e){const t=this.pluginManager.getConfigManager().get("preferences");t&&await t.set({key:"background_update_config",value:JSON.stringify(e)})}async disableBackgroundUpdates(){const e=this.pluginManager.getConfigManager().get("preferences");e&&await e.remove({key:"background_update_config"})}async getBackgroundUpdateStatus(){return{enabled:!1,isRunning:!1,checkCount:0,failureCount:0}}async scheduleBackgroundCheck(e){throw new w(exports.ErrorCode.PLATFORM_NOT_SUPPORTED,"Background updates are not supported on web")}async triggerBackgroundCheck(){return{success:!1,updatesFound:!1,notificationSent:!1,error:{code:c.PLATFORM_NOT_SUPPORTED,message:"Background updates are not supported on web"}}}async setNotificationPreferences(e){const t=this.pluginManager.getConfigManager().get("preferences");t&&await t.set({key:"notification_preferences",value:JSON.stringify(e)})}async getNotificationPermissions(){return{granted:!1,canRequest:!1}}async requestNotificationPermissions(){return!1}async addListener(e,t){return{remove:async()=>{}}}async removeAllListeners(){}}const O=h.registerPlugin("NativeUpdate",{web:()=>new R});exports.BundleManager=N,exports.CacheManager=class{constructor(){this.filesystem=null,this.memoryCache=new Map,this.CACHE_DIR="cache",this.logger=E.getInstance(),this.configManager=f.getInstance()}async initialize(){if(this.filesystem=this.configManager.get("filesystem"),!this.filesystem)throw new Error("Filesystem not configured");try{await this.filesystem.mkdir({path:this.CACHE_DIR,directory:g.Directory.Data,recursive:!0})}catch(e){this.logger.debug("Cache directory may already exist",e)}await this.cleanExpiredCache()}async set(e,t,r){const a=Date.now()+(r||this.configManager.get("cacheExpiration")),i={data:t,timestamp:Date.now(),expiry:a};this.memoryCache.set(e,i),this.shouldPersist(t)&&await this.persistToFile(e,i),this.logger.debug("Cache entry set",{key:e,expiry:new Date(a)})}async get(e){const t=this.memoryCache.get(e);if(t){if(Date.now()<t.expiry)return t.data;this.memoryCache.delete(e)}const r=await this.loadFromFile(e);if(r){if(Date.now()<r.expiry)return this.memoryCache.set(e,r),r.data;await this.removeFile(e)}return null}async has(e){return null!==await this.get(e)}async remove(e){this.memoryCache.delete(e),await this.removeFile(e),this.logger.debug("Cache entry removed",{key:e})}async clear(){this.memoryCache.clear();try{await this.filesystem.rmdir({path:this.CACHE_DIR,directory:g.Directory.Data,recursive:!0}),await this.filesystem.mkdir({path:this.CACHE_DIR,directory:g.Directory.Data,recursive:!0})}catch(e){this.logger.warn("Failed to clear cache directory",e)}this.logger.info("Cache cleared")}async cleanExpiredCache(){const e=Date.now();let t=0;for(const[r,a]of this.memoryCache)e>=a.expiry&&(this.memoryCache.delete(r),t++);try{const r=await this.filesystem.readdir({path:this.CACHE_DIR,directory:g.Directory.Data});for(const a of r.files){const r=a.name.replace(".json",""),i=await this.loadFromFile(r);(!i||e>=i.expiry)&&(await this.removeFile(r),t++)}}catch(e){this.logger.debug("Failed to clean filesystem cache",e)}t>0&&this.logger.info("Cleaned expired cache entries",{count:t})}async getStats(){let e=0,t=0;try{const r=await this.filesystem.readdir({path:this.CACHE_DIR,directory:g.Directory.Data});e=r.files.length;for(const e of r.files)t+=(await this.filesystem.stat({path:`${this.CACHE_DIR}/${e.name}`,directory:g.Directory.Data})).size||0}catch(e){this.logger.debug("Failed to get cache stats",e)}return{memoryEntries:this.memoryCache.size,fileEntries:e,totalSize:t}}async cacheBundleMetadata(e){const t=`bundle_meta_${e.bundleId}`;await this.set(t,e,864e5)}async getCachedBundleMetadata(e){return this.get(`bundle_meta_${e}`)}shouldPersist(e){return"object"==typeof e||"string"==typeof e&&e.length>1024}async persistToFile(e,t){if(this.filesystem)try{const r=`${this.CACHE_DIR}/${e}.json`,a=JSON.stringify(t);await this.filesystem.writeFile({path:r,data:a,directory:g.Directory.Data,encoding:g.Encoding.UTF8})}catch(t){this.logger.warn("Failed to persist cache to file",{key:e,error:t})}}async loadFromFile(e){if(!this.filesystem)return null;try{const t=`${this.CACHE_DIR}/${e}.json`,r=await this.filesystem.readFile({path:t,directory:g.Directory.Data,encoding:g.Encoding.UTF8});return JSON.parse(r.data)}catch(e){return null}}async removeFile(e){if(this.filesystem)try{const t=`${this.CACHE_DIR}/${e}.json`;await this.filesystem.deleteFile({path:t,directory:g.Directory.Data})}catch(t){this.logger.debug("Failed to remove cache file",{key:e,error:t})}}},exports.ConfigManager=f,exports.ConfigurationError=class extends w{constructor(e,t){super(exports.ErrorCode.INVALID_CONFIG,e,t),this.name="ConfigurationError"}},exports.DownloadError=I,exports.DownloadManager=_,exports.Logger=E,exports.NativeUpdate=O,exports.NativeUpdateError=w,exports.PluginManager=v,exports.SecurityValidator=m,exports.StorageError=D,exports.UpdateErrorClass=A,exports.UpdateManager=class{constructor(){this.filesystem=null,this.updateInProgress=!1,this.currentState=null,this.pluginManager=v.getInstance(),this.securityValidator=m.getInstance()}async initialize(){if(this.filesystem=this.pluginManager.getConfigManager().get("filesystem"),!this.filesystem)throw new A(exports.ErrorCode.MISSING_DEPENDENCY,"Filesystem not configured")}async applyUpdate(e,t){if(this.updateInProgress)throw new A(exports.ErrorCode.UPDATE_FAILED,"Another update is already in progress");const r=this.pluginManager.getLogger(),a=this.pluginManager.getBundleManager();try{this.updateInProgress=!0,r.info("Starting bundle update",{bundleId:e});const i=await a.getBundle(e);if(!i)throw new A(exports.ErrorCode.FILE_NOT_FOUND,`Bundle ${e} not found`);if("READY"!==i.status&&"ACTIVE"!==i.status)throw new A(exports.ErrorCode.BUNDLE_NOT_READY,`Bundle ${e} is not ready for installation`);const n=await a.getActiveBundle();this.currentState={currentBundle:n,newBundle:i,backupPath:null,startTime:Date.now()},await this.validateUpdate(n,i,t),n&&"default"!==n.bundleId&&(this.currentState.backupPath=await this.createBackup(n)),await this.performUpdate(i),await this.verifyUpdate(i),await a.setActiveBundle(e),(null==t?void 0:t.cleanupOldBundles)&&await a.cleanupOldBundles(t.keepBundleCount||3),r.info("Bundle update completed successfully",{bundleId:e,version:i.version,duration:Date.now()-this.currentState.startTime}),this.currentState=null}catch(e){throw r.error("Bundle update failed",e),this.currentState&&await this.rollback(),e}finally{this.updateInProgress=!1}}async validateUpdate(e,t,r){const a=this.pluginManager.getLogger(),i=this.pluginManager.getVersionManager();if(e&&!(null==r?void 0:r.allowDowngrade)&&i.shouldBlockDowngrade(e.version,t.version))throw new y(exports.ErrorCode.VERSION_DOWNGRADE,`Cannot downgrade from ${e.version} to ${t.version}`);if(!t.verified){a.warn("Bundle not verified, verifying now",{bundleId:t.bundleId});const e=this.pluginManager.getDownloadManager(),r=await e.loadBlob(t.bundleId);if(!r)throw new A(exports.ErrorCode.FILE_NOT_FOUND,"Bundle data not found");const i=await r.arrayBuffer();if(!await this.securityValidator.verifyChecksum(i,t.checksum))throw new y(exports.ErrorCode.CHECKSUM_MISMATCH,"Bundle checksum verification failed");if(t.signature&&!await this.securityValidator.verifySignature(i,t.signature))throw new y(exports.ErrorCode.SIGNATURE_INVALID,"Bundle signature verification failed");await this.pluginManager.getBundleManager().markBundleAsVerified(t.bundleId)}a.debug("Bundle validation passed",{bundleId:t.bundleId})}async createBackup(e){const t=`backups/${e.bundleId}_${Date.now()}`,r=this.pluginManager.getLogger();try{return await this.filesystem.mkdir({path:t,directory:g.Directory.Data,recursive:!0}),await this.filesystem.copy({from:e.path,to:t,directory:g.Directory.Data}),r.info("Backup created",{bundleId:e.bundleId,backupPath:t}),t}catch(e){throw r.error("Failed to create backup",e),new A(exports.ErrorCode.UPDATE_FAILED,"Failed to create backup",void 0,e)}}async performUpdate(e){const t=this.pluginManager.getLogger();try{const r=`active/${e.bundleId}`;await this.filesystem.mkdir({path:r,directory:g.Directory.Data,recursive:!0}),await this.filesystem.copy({from:e.path,to:r,directory:g.Directory.Data}),e.path=r,t.debug("Bundle files installed",{bundleId:e.bundleId,targetPath:r})}catch(e){throw new A(exports.ErrorCode.UPDATE_FAILED,"Failed to install bundle files",void 0,e)}}async verifyUpdate(e){try{const t=`${e.path}/index.html`;await this.filesystem.stat({path:t,directory:g.Directory.Data})}catch(e){throw new A(exports.ErrorCode.UPDATE_FAILED,"Bundle verification failed after installation",void 0,e)}}async rollback(){var e;if(!this.currentState)throw new A(exports.ErrorCode.ROLLBACK_FAILED,"No update state to rollback");const t=this.pluginManager.getLogger();t.warn("Starting rollback",{from:this.currentState.newBundle.bundleId,to:(null===(e=this.currentState.currentBundle)||void 0===e?void 0:e.bundleId)||"default"});try{const e=this.pluginManager.getBundleManager();if(this.currentState.backupPath&&this.currentState.currentBundle){const t=`active/${this.currentState.currentBundle.bundleId}`;await this.filesystem.copy({from:this.currentState.backupPath,to:t,directory:g.Directory.Data}),this.currentState.currentBundle.path=t,await e.saveBundleInfo(this.currentState.currentBundle)}this.currentState.currentBundle?await e.setActiveBundle(this.currentState.currentBundle.bundleId):await e.clearActiveBundle(),t.info("Rollback completed successfully")}catch(e){throw t.error("Rollback failed",e),new A(exports.ErrorCode.ROLLBACK_FAILED,"Failed to rollback update",void 0,e)}finally{if(this.currentState.backupPath)try{await this.filesystem.rmdir({path:this.currentState.backupPath,directory:g.Directory.Data,recursive:!0})}catch(e){t.warn("Failed to clean up backup",e)}}}getUpdateProgress(){var e,t;return{inProgress:this.updateInProgress,bundleId:null===(e=this.currentState)||void 0===e?void 0:e.newBundle.bundleId,startTime:null===(t=this.currentState)||void 0===t?void 0:t.startTime}}async cancelUpdate(){this.updateInProgress&&this.currentState&&(this.pluginManager.getLogger().warn("Cancelling update",{bundleId:this.currentState.newBundle.bundleId}),await this.rollback(),this.updateInProgress=!1,this.currentState=null)}},exports.ValidationError=y,exports.VersionManager=C;
2
2
  //# sourceMappingURL=plugin.cjs.js.map