native-update 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/core/logger.js","esm/core/errors.js","esm/core/config.js","esm/core/security.js","esm/live-update/bundle-manager.js","esm/live-update/download-manager.js","esm/live-update/version-manager.js","esm/core/plugin-manager.js","esm/plugin.js","esm/core/cache-manager.js","esm/live-update/update-manager.js"],"sourcesContent":["// Core plugin interface will be defined later after other interfaces\n/**\n * Enums\n */\nexport var BackgroundUpdateType;\n(function (BackgroundUpdateType) {\n BackgroundUpdateType[\"APP_UPDATE\"] = \"app_update\";\n BackgroundUpdateType[\"LIVE_UPDATE\"] = \"live_update\";\n BackgroundUpdateType[\"BOTH\"] = \"both\";\n})(BackgroundUpdateType || (BackgroundUpdateType = {}));\nexport var NotificationPriority;\n(function (NotificationPriority) {\n NotificationPriority[\"MIN\"] = \"min\";\n NotificationPriority[\"LOW\"] = \"low\";\n NotificationPriority[\"DEFAULT\"] = \"default\";\n NotificationPriority[\"HIGH\"] = \"high\";\n NotificationPriority[\"MAX\"] = \"max\";\n})(NotificationPriority || (NotificationPriority = {}));\nexport var UpdateStrategy;\n(function (UpdateStrategy) {\n UpdateStrategy[\"IMMEDIATE\"] = \"immediate\";\n UpdateStrategy[\"BACKGROUND\"] = \"background\";\n UpdateStrategy[\"MANUAL\"] = \"manual\";\n})(UpdateStrategy || (UpdateStrategy = {}));\nexport var UpdateMode;\n(function (UpdateMode) {\n UpdateMode[\"IMMEDIATE\"] = \"immediate\";\n UpdateMode[\"ON_NEXT_RESTART\"] = \"on_next_restart\";\n UpdateMode[\"ON_NEXT_RESUME\"] = \"on_next_resume\";\n})(UpdateMode || (UpdateMode = {}));\nexport var InstallMode;\n(function (InstallMode) {\n InstallMode[\"IMMEDIATE\"] = \"immediate\";\n InstallMode[\"ON_NEXT_RESTART\"] = \"on_next_restart\";\n InstallMode[\"ON_NEXT_RESUME\"] = \"on_next_resume\";\n})(InstallMode || (InstallMode = {}));\nexport var ChecksumAlgorithm;\n(function (ChecksumAlgorithm) {\n ChecksumAlgorithm[\"SHA256\"] = \"SHA-256\";\n ChecksumAlgorithm[\"SHA512\"] = \"SHA-512\";\n})(ChecksumAlgorithm || (ChecksumAlgorithm = {}));\nexport var SyncStatus;\n(function (SyncStatus) {\n SyncStatus[\"UP_TO_DATE\"] = \"UP_TO_DATE\";\n SyncStatus[\"UPDATE_AVAILABLE\"] = \"UPDATE_AVAILABLE\";\n SyncStatus[\"UPDATE_INSTALLED\"] = \"UPDATE_INSTALLED\";\n SyncStatus[\"ERROR\"] = \"ERROR\";\n})(SyncStatus || (SyncStatus = {}));\nexport var BundleStatus;\n(function (BundleStatus) {\n BundleStatus[\"PENDING\"] = \"PENDING\";\n BundleStatus[\"DOWNLOADING\"] = \"DOWNLOADING\";\n BundleStatus[\"READY\"] = \"READY\";\n BundleStatus[\"ACTIVE\"] = \"ACTIVE\";\n BundleStatus[\"FAILED\"] = \"FAILED\";\n})(BundleStatus || (BundleStatus = {}));\nexport var InstallStatus;\n(function (InstallStatus) {\n InstallStatus[\"UNKNOWN\"] = \"UNKNOWN\";\n InstallStatus[\"PENDING\"] = \"PENDING\";\n InstallStatus[\"DOWNLOADING\"] = \"DOWNLOADING\";\n InstallStatus[\"DOWNLOADED\"] = \"DOWNLOADED\";\n InstallStatus[\"INSTALLING\"] = \"INSTALLING\";\n InstallStatus[\"INSTALLED\"] = \"INSTALLED\";\n InstallStatus[\"FAILED\"] = \"FAILED\";\n InstallStatus[\"CANCELED\"] = \"CANCELED\";\n})(InstallStatus || (InstallStatus = {}));\nexport var UpdateErrorCode;\n(function (UpdateErrorCode) {\n // Network errors\n UpdateErrorCode[\"NETWORK_ERROR\"] = \"NETWORK_ERROR\";\n UpdateErrorCode[\"SERVER_ERROR\"] = \"SERVER_ERROR\";\n UpdateErrorCode[\"TIMEOUT_ERROR\"] = \"TIMEOUT_ERROR\";\n // Download errors\n UpdateErrorCode[\"DOWNLOAD_ERROR\"] = \"DOWNLOAD_ERROR\";\n UpdateErrorCode[\"STORAGE_ERROR\"] = \"STORAGE_ERROR\";\n UpdateErrorCode[\"SIZE_LIMIT_EXCEEDED\"] = \"SIZE_LIMIT_EXCEEDED\";\n // Security errors\n UpdateErrorCode[\"VERIFICATION_ERROR\"] = \"VERIFICATION_ERROR\";\n UpdateErrorCode[\"CHECKSUM_ERROR\"] = \"CHECKSUM_ERROR\";\n UpdateErrorCode[\"SIGNATURE_ERROR\"] = \"SIGNATURE_ERROR\";\n UpdateErrorCode[\"INSECURE_URL\"] = \"INSECURE_URL\";\n UpdateErrorCode[\"INVALID_CERTIFICATE\"] = \"INVALID_CERTIFICATE\";\n UpdateErrorCode[\"PATH_TRAVERSAL\"] = \"PATH_TRAVERSAL\";\n // Installation errors\n UpdateErrorCode[\"INSTALL_ERROR\"] = \"INSTALL_ERROR\";\n UpdateErrorCode[\"ROLLBACK_ERROR\"] = \"ROLLBACK_ERROR\";\n UpdateErrorCode[\"VERSION_MISMATCH\"] = \"VERSION_MISMATCH\";\n // Permission errors\n UpdateErrorCode[\"PERMISSION_DENIED\"] = \"PERMISSION_DENIED\";\n // App update errors\n UpdateErrorCode[\"UPDATE_NOT_AVAILABLE\"] = \"UPDATE_NOT_AVAILABLE\";\n UpdateErrorCode[\"UPDATE_IN_PROGRESS\"] = \"UPDATE_IN_PROGRESS\";\n UpdateErrorCode[\"UPDATE_CANCELLED\"] = \"UPDATE_CANCELLED\";\n UpdateErrorCode[\"PLATFORM_NOT_SUPPORTED\"] = \"PLATFORM_NOT_SUPPORTED\";\n // Review errors\n UpdateErrorCode[\"REVIEW_NOT_SUPPORTED\"] = \"REVIEW_NOT_SUPPORTED\";\n UpdateErrorCode[\"QUOTA_EXCEEDED\"] = \"QUOTA_EXCEEDED\";\n UpdateErrorCode[\"CONDITIONS_NOT_MET\"] = \"CONDITIONS_NOT_MET\";\n // General errors\n UpdateErrorCode[\"INVALID_CONFIG\"] = \"INVALID_CONFIG\";\n UpdateErrorCode[\"UNKNOWN_ERROR\"] = \"UNKNOWN_ERROR\";\n})(UpdateErrorCode || (UpdateErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { ConfigManager } from './config';\nexport var LogLevel;\n(function (LogLevel) {\n LogLevel[LogLevel[\"DEBUG\"] = 0] = \"DEBUG\";\n LogLevel[LogLevel[\"INFO\"] = 1] = \"INFO\";\n LogLevel[LogLevel[\"WARN\"] = 2] = \"WARN\";\n LogLevel[LogLevel[\"ERROR\"] = 3] = \"ERROR\";\n})(LogLevel || (LogLevel = {}));\nexport class Logger {\n constructor(context) {\n this.configManager = ConfigManager.getInstance();\n this.context = context || 'NativeUpdate';\n }\n static getInstance() {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n shouldLog() {\n return this.configManager.get('enableLogging');\n }\n sanitize(data) {\n if (typeof data === 'string') {\n let sanitized = data;\n // Remove potential file paths\n sanitized = sanitized.replace(/\\/[^\\s]+\\/([\\w.-]+)$/g, '/<path>/$1');\n // Remove potential URLs with credentials\n sanitized = sanitized.replace(/https?:\\/\\/[^:]+:[^@]+@/g, 'https://***:***@');\n // Remove potential API keys\n sanitized = sanitized.replace(/[a-zA-Z0-9]{32,}/g, '<redacted>');\n return sanitized;\n }\n else if (typeof data === 'object' && data !== null) {\n if (Array.isArray(data)) {\n return data.map((item) => this.sanitize(item));\n }\n else {\n const sanitized = {};\n const dataObj = data;\n for (const key in dataObj) {\n if (key.toLowerCase().includes('key') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('password') ||\n key.toLowerCase().includes('token')) {\n sanitized[key] = '<redacted>';\n }\n else {\n sanitized[key] = this.sanitize(dataObj[key]);\n }\n }\n return sanitized;\n }\n }\n return data;\n }\n log(message, data) {\n this.logWithLevel(LogLevel.INFO, message, data);\n }\n logWithLevel(level, message, data) {\n if (!this.shouldLog())\n return;\n const timestamp = new Date().toISOString();\n const sanitizedData = data ? this.sanitize(data) : undefined;\n const logEntry = {\n timestamp,\n level: LogLevel[level],\n context: this.context,\n message,\n };\n if (sanitizedData !== undefined) {\n logEntry.data = sanitizedData;\n }\n switch (level) {\n case LogLevel.DEBUG:\n console.debug(`[${this.context}]`, logEntry);\n break;\n case LogLevel.INFO:\n console.info(`[${this.context}]`, logEntry);\n break;\n case LogLevel.WARN:\n console.warn(`[${this.context}]`, logEntry);\n break;\n case LogLevel.ERROR:\n console.error(`[${this.context}]`, logEntry);\n break;\n }\n }\n debug(message, data) {\n this.logWithLevel(LogLevel.DEBUG, message, data);\n }\n info(message, data) {\n this.logWithLevel(LogLevel.INFO, message, data);\n }\n warn(message, data) {\n this.logWithLevel(LogLevel.WARN, message, data);\n }\n error(message, error) {\n const errorData = error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error;\n this.logWithLevel(LogLevel.ERROR, message, errorData);\n }\n}\n//# sourceMappingURL=logger.js.map","export var ErrorCode;\n(function (ErrorCode) {\n // Configuration errors\n ErrorCode[\"NOT_CONFIGURED\"] = \"NOT_CONFIGURED\";\n ErrorCode[\"INVALID_CONFIG\"] = \"INVALID_CONFIG\";\n ErrorCode[\"MISSING_DEPENDENCY\"] = \"MISSING_DEPENDENCY\";\n // Download errors\n ErrorCode[\"DOWNLOAD_FAILED\"] = \"DOWNLOAD_FAILED\";\n ErrorCode[\"DOWNLOAD_TIMEOUT\"] = \"DOWNLOAD_TIMEOUT\";\n ErrorCode[\"INVALID_URL\"] = \"INVALID_URL\";\n ErrorCode[\"UNAUTHORIZED_HOST\"] = \"UNAUTHORIZED_HOST\";\n ErrorCode[\"BUNDLE_TOO_LARGE\"] = \"BUNDLE_TOO_LARGE\";\n // Validation errors\n ErrorCode[\"CHECKSUM_MISMATCH\"] = \"CHECKSUM_MISMATCH\";\n ErrorCode[\"SIGNATURE_INVALID\"] = \"SIGNATURE_INVALID\";\n ErrorCode[\"VERSION_DOWNGRADE\"] = \"VERSION_DOWNGRADE\";\n ErrorCode[\"INVALID_BUNDLE_FORMAT\"] = \"INVALID_BUNDLE_FORMAT\";\n // Storage errors\n ErrorCode[\"STORAGE_FULL\"] = \"STORAGE_FULL\";\n ErrorCode[\"FILE_NOT_FOUND\"] = \"FILE_NOT_FOUND\";\n ErrorCode[\"PERMISSION_DENIED\"] = \"PERMISSION_DENIED\";\n // Update errors\n ErrorCode[\"UPDATE_FAILED\"] = \"UPDATE_FAILED\";\n ErrorCode[\"ROLLBACK_FAILED\"] = \"ROLLBACK_FAILED\";\n ErrorCode[\"BUNDLE_NOT_READY\"] = \"BUNDLE_NOT_READY\";\n // Platform errors\n ErrorCode[\"PLATFORM_NOT_SUPPORTED\"] = \"PLATFORM_NOT_SUPPORTED\";\n ErrorCode[\"NATIVE_ERROR\"] = \"NATIVE_ERROR\";\n})(ErrorCode || (ErrorCode = {}));\nexport class NativeUpdateError extends Error {\n constructor(code, message, details, originalError) {\n super(message);\n this.code = code;\n this.message = message;\n this.details = details;\n this.originalError = originalError;\n this.name = 'NativeUpdateError';\n Object.setPrototypeOf(this, NativeUpdateError.prototype);\n }\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n stack: this.stack,\n };\n }\n}\nexport class ConfigurationError extends NativeUpdateError {\n constructor(message, details) {\n super(ErrorCode.INVALID_CONFIG, message, details);\n this.name = 'ConfigurationError';\n }\n}\nexport class DownloadError extends NativeUpdateError {\n constructor(code, message, details, originalError) {\n super(code, message, details, originalError);\n this.name = 'DownloadError';\n }\n}\nexport class ValidationError extends NativeUpdateError {\n constructor(code, message, details) {\n super(code, message, details);\n this.name = 'ValidationError';\n }\n}\nexport class StorageError extends NativeUpdateError {\n constructor(code, message, details, originalError) {\n super(code, message, details, originalError);\n this.name = 'StorageError';\n }\n}\nexport class UpdateError extends NativeUpdateError {\n constructor(code, message, details, originalError) {\n super(code, message, details, originalError);\n this.name = 'UpdateError';\n }\n}\n//# sourceMappingURL=errors.js.map","export class ConfigManager {\n constructor() {\n this.config = this.getDefaultConfig();\n }\n static getInstance() {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n getDefaultConfig() {\n return {\n filesystem: null,\n preferences: null,\n baseUrl: '',\n allowedHosts: [],\n maxBundleSize: 100 * 1024 * 1024, // 100MB\n downloadTimeout: 30000, // 30 seconds\n retryAttempts: 3,\n retryDelay: 1000, // 1 second\n enableSignatureValidation: true,\n publicKey: '',\n cacheExpiration: 24 * 60 * 60 * 1000, // 24 hours\n enableLogging: false,\n serverUrl: '',\n channel: 'production',\n autoCheck: true,\n autoUpdate: false,\n updateStrategy: 'background',\n requireSignature: true,\n checksumAlgorithm: 'SHA-256',\n checkInterval: 24 * 60 * 60 * 1000, // 24 hours\n security: {\n enforceHttps: true,\n validateInputs: true,\n secureStorage: true,\n logSecurityEvents: false,\n },\n // App review config\n promptAfterPositiveEvents: false,\n maxPromptsPerVersion: 1,\n minimumDaysSinceLastPrompt: 7,\n isPremiumUser: false,\n // Platform-specific config\n appStoreId: '',\n iosAppId: '',\n packageName: '',\n webReviewUrl: '',\n minimumVersion: '1.0.0',\n };\n }\n configure(config) {\n this.config = Object.assign(Object.assign({}, this.config), config);\n this.validateConfig();\n }\n validateConfig() {\n if (this.config.maxBundleSize <= 0) {\n throw new Error('maxBundleSize must be greater than 0');\n }\n if (this.config.downloadTimeout <= 0) {\n throw new Error('downloadTimeout must be greater than 0');\n }\n if (this.config.retryAttempts < 0) {\n throw new Error('retryAttempts must be non-negative');\n }\n if (this.config.retryDelay < 0) {\n throw new Error('retryDelay must be non-negative');\n }\n }\n get(key) {\n return this.config[key];\n }\n set(key, value) {\n this.config[key] = value;\n }\n getAll() {\n return Object.assign({}, this.config);\n }\n isConfigured() {\n return !!(this.config.filesystem && this.config.preferences);\n }\n}\n//# sourceMappingURL=config.js.map","import { ConfigManager } from './config';\nimport { ValidationError, ErrorCode } from './errors';\nimport { Logger } from './logger';\nexport class SecurityValidator {\n constructor() {\n this.configManager = ConfigManager.getInstance();\n this.logger = Logger.getInstance();\n }\n static getInstance() {\n if (!SecurityValidator.instance) {\n SecurityValidator.instance = new SecurityValidator();\n }\n return SecurityValidator.instance;\n }\n /**\n * Validate URL is HTTPS\n */\n static validateUrl(url) {\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'https:';\n }\n catch (_a) {\n return false;\n }\n }\n /**\n * Validate checksum format\n */\n static validateChecksum(checksum) {\n return /^[a-f0-9]{64}$/i.test(checksum);\n }\n /**\n * Sanitize input string\n */\n static sanitizeInput(input) {\n if (!input)\n return '';\n return input.replace(/<[^>]*>/g, '').replace(/[^\\w\\s/.-]/g, '');\n }\n /**\n * Validate bundle size\n */\n static validateBundleSize(size) {\n const MAX_SIZE = 100 * 1024 * 1024; // 100MB\n return size > 0 && size <= MAX_SIZE;\n }\n /**\n * Calculate SHA-256 checksum of data\n */\n async calculateChecksum(data) {\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n }\n /**\n * Verify checksum matches expected value\n */\n async verifyChecksum(data, expectedChecksum) {\n if (!expectedChecksum) {\n this.logger.warn('No checksum provided for verification');\n return true; // Allow if no checksum provided\n }\n const actualChecksum = await this.calculateChecksum(data);\n const isValid = actualChecksum === expectedChecksum.toLowerCase();\n if (!isValid) {\n this.logger.error('Checksum verification failed', {\n expected: expectedChecksum,\n actual: actualChecksum,\n });\n }\n return isValid;\n }\n /**\n * Alias for verifyChecksum for backward compatibility\n */\n async validateChecksum(data, expectedChecksum) {\n return this.verifyChecksum(data, expectedChecksum);\n }\n /**\n * Verify digital signature using Web Crypto API\n */\n async verifySignature(data, signature) {\n if (!this.configManager.get('enableSignatureValidation')) {\n return true;\n }\n const publicKey = this.configManager.get('publicKey');\n if (!publicKey) {\n throw new ValidationError(ErrorCode.SIGNATURE_INVALID, 'Public key not configured for signature validation');\n }\n try {\n // Import public key\n const cryptoKey = await crypto.subtle.importKey('spki', this.pemToArrayBuffer(publicKey), {\n name: 'RSA-PSS',\n hash: 'SHA-256',\n }, false, ['verify']);\n // Verify signature\n const isValid = await crypto.subtle.verify({\n name: 'RSA-PSS',\n saltLength: 32,\n }, cryptoKey, this.base64ToArrayBuffer(signature), data);\n if (!isValid) {\n this.logger.error('Signature verification failed');\n }\n return isValid;\n }\n catch (error) {\n this.logger.error('Signature verification error', error);\n return false;\n }\n }\n /**\n * Convert PEM to ArrayBuffer\n */\n pemToArrayBuffer(pem) {\n const base64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/g, '')\n .replace(/-----END PUBLIC KEY-----/g, '')\n .replace(/\\s/g, '');\n return this.base64ToArrayBuffer(base64);\n }\n /**\n * Convert base64 to ArrayBuffer\n */\n base64ToArrayBuffer(base64) {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n }\n /**\n * Sanitize file path to prevent directory traversal\n */\n sanitizePath(path) {\n // Remove any parent directory references\n const sanitized = path\n .split('/')\n .filter((part) => part !== '..' && part !== '.')\n .join('/');\n // Ensure path doesn't start with /\n return sanitized.replace(/^\\/+/, '');\n }\n /**\n * Validate bundle ID format\n */\n validateBundleId(bundleId) {\n if (!bundleId || typeof bundleId !== 'string') {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID must be a non-empty string');\n }\n // Allow alphanumeric, hyphens, underscores, and dots\n const validPattern = /^[a-zA-Z0-9\\-_.]+$/;\n if (!validPattern.test(bundleId)) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID contains invalid characters');\n }\n if (bundleId.length > 100) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is too long (max 100 characters)');\n }\n }\n /**\n * Validate semantic version format\n */\n validateVersion(version) {\n if (!version || typeof version !== 'string') {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Version must be a non-empty string');\n }\n // Basic semantic versioning pattern\n const semverPattern = /^(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-]+)*))?$/;\n if (!semverPattern.test(version)) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Version must follow semantic versioning format (e.g., 1.2.3)');\n }\n }\n /**\n * Check if version is a downgrade\n */\n isVersionDowngrade(currentVersion, newVersion) {\n const current = this.parseVersion(currentVersion);\n const next = this.parseVersion(newVersion);\n if (next.major < current.major)\n return true;\n if (next.major > current.major)\n return false;\n if (next.minor < current.minor)\n return true;\n if (next.minor > current.minor)\n return false;\n return next.patch < current.patch;\n }\n /**\n * Parse semantic version\n */\n parseVersion(version) {\n const parts = version.split('-')[0].split('.'); // Ignore pre-release\n return {\n major: parseInt(parts[0], 10) || 0,\n minor: parseInt(parts[1], 10) || 0,\n patch: parseInt(parts[2], 10) || 0,\n };\n }\n /**\n * Validate URL format and security\n */\n validateUrl(url) {\n if (!url || typeof url !== 'string') {\n throw new ValidationError(ErrorCode.INVALID_URL, 'URL must be a non-empty string');\n }\n let parsedUrl;\n try {\n parsedUrl = new URL(url);\n }\n catch (_a) {\n throw new ValidationError(ErrorCode.INVALID_URL, 'Invalid URL format');\n }\n // Enforce HTTPS\n if (parsedUrl.protocol !== 'https:') {\n throw new ValidationError(ErrorCode.INVALID_URL, 'Only HTTPS URLs are allowed');\n }\n // Check against allowed hosts\n const allowedHosts = this.configManager.get('allowedHosts');\n if (allowedHosts.length > 0 && !allowedHosts.includes(parsedUrl.hostname)) {\n throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, `Host ${parsedUrl.hostname} is not in the allowed hosts list`);\n }\n // Prevent localhost/private IPs in production\n const privatePatterns = [\n /^localhost$/i,\n /^127\\./,\n /^10\\./,\n /^172\\.(1[6-9]|2[0-9]|3[0-1])\\./,\n /^192\\.168\\./,\n /^::1$/,\n /^fc00:/i,\n /^fe80:/i,\n ];\n if (privatePatterns.some((pattern) => pattern.test(parsedUrl.hostname))) {\n throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, 'Private/local addresses are not allowed');\n }\n }\n /**\n * Validate file size\n */\n validateFileSize(size) {\n if (typeof size !== 'number' || size < 0) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'File size must be a non-negative number');\n }\n const maxSize = this.configManager.get('maxBundleSize');\n if (size > maxSize) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `File size ${size} exceeds maximum allowed size of ${maxSize} bytes`);\n }\n }\n /**\n * Generate a secure random ID\n */\n generateSecureId() {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');\n }\n /**\n * Validate certificate pinning for HTTPS connections\n * Note: This is a placeholder for web implementation as certificate pinning\n * is primarily implemented at the native layer\n */\n async validateCertificatePin(hostname, certificate) {\n // Certificate pinning is not available in PluginConfig type\n const certificatePins = this.configManager.certificatePins;\n if (!certificatePins ||\n !Array.isArray(certificatePins) ||\n certificatePins.length === 0) {\n // No pins configured, allow connection\n return true;\n }\n const hostPins = certificatePins.filter((pin) => pin.hostname === hostname);\n if (hostPins.length === 0) {\n // No pins for this host, allow connection\n return true;\n }\n // Check if certificate matches any of the pins\n const certificateHash = await this.calculateCertificateHash(certificate);\n const isValid = hostPins.some((pin) => pin.sha256 === certificateHash);\n if (!isValid) {\n this.logger.error('Certificate pinning validation failed', {\n hostname,\n expectedPins: hostPins.map((p) => p.sha256),\n actualHash: certificateHash,\n });\n }\n return isValid;\n }\n /**\n * Calculate SHA-256 hash of certificate\n */\n async calculateCertificateHash(certificate) {\n const encoder = new TextEncoder();\n const data = encoder.encode(certificate);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return 'sha256/' + btoa(String.fromCharCode(...hashArray));\n }\n /**\n * Validate metadata object\n */\n validateMetadata(metadata) {\n if (metadata && typeof metadata !== 'object') {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Metadata must be an object');\n }\n // Limit metadata size to prevent abuse\n const metadataStr = JSON.stringify(metadata || {});\n if (metadataStr.length > 10240) {\n // 10KB limit\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Metadata is too large (max 10KB)');\n }\n }\n}\n//# sourceMappingURL=security.js.map","import { ConfigManager } from '../core/config';\nimport { Logger } from '../core/logger';\nimport { StorageError, ErrorCode } from '../core/errors';\n/**\n * Manages bundle storage and lifecycle\n */\nexport class BundleManager {\n constructor() {\n this.STORAGE_KEY = 'capacitor_native_update_bundles';\n this.ACTIVE_BUNDLE_KEY = 'capacitor_native_update_active';\n this.preferences = null;\n this.cache = new Map();\n this.cacheExpiry = 0;\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n }\n /**\n * Initialize the bundle manager with preferences\n */\n async initialize() {\n this.preferences = this.configManager.get('preferences');\n if (!this.preferences) {\n throw new StorageError(ErrorCode.MISSING_DEPENDENCY, 'Preferences not configured. Please configure the plugin first.');\n }\n await this.loadCache();\n }\n /**\n * Load cache from preferences\n */\n async loadCache() {\n if (Date.now() < this.cacheExpiry) {\n return; // Cache still valid\n }\n try {\n const { value } = await this.preferences.get({ key: this.STORAGE_KEY });\n if (value) {\n const bundles = JSON.parse(value);\n this.cache.clear();\n bundles.forEach((bundle) => this.cache.set(bundle.bundleId, bundle));\n }\n this.cacheExpiry = Date.now() + 5000; // 5 second cache\n }\n catch (error) {\n this.logger.error('Failed to load bundles from storage', error);\n this.cache.clear();\n }\n }\n /**\n * Save cache to preferences\n */\n async saveCache() {\n try {\n const bundles = Array.from(this.cache.values());\n await this.preferences.set({\n key: this.STORAGE_KEY,\n value: JSON.stringify(bundles),\n });\n this.logger.debug('Saved bundles to storage', { count: bundles.length });\n }\n catch (error) {\n throw new StorageError(ErrorCode.STORAGE_FULL, 'Failed to save bundles to storage', undefined, error);\n }\n }\n /**\n * Save bundle information\n */\n async saveBundleInfo(bundle) {\n this.validateBundleInfo(bundle);\n this.cache.set(bundle.bundleId, bundle);\n await this.saveCache();\n this.logger.info('Bundle saved', {\n bundleId: bundle.bundleId,\n version: bundle.version,\n });\n }\n /**\n * Validate bundle information\n */\n validateBundleInfo(bundle) {\n if (!bundle.bundleId || typeof bundle.bundleId !== 'string') {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle ID');\n }\n if (!bundle.version || typeof bundle.version !== 'string') {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle version');\n }\n if (!bundle.path || typeof bundle.path !== 'string') {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle path');\n }\n if (typeof bundle.size !== 'number' || bundle.size < 0) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle size');\n }\n }\n /**\n * Get all bundles\n */\n async getAllBundles() {\n await this.loadCache();\n return Array.from(this.cache.values());\n }\n /**\n * Get bundle by ID\n */\n async getBundle(bundleId) {\n if (!bundleId) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n await this.loadCache();\n return this.cache.get(bundleId) || null;\n }\n /**\n * Delete bundle\n */\n async deleteBundle(bundleId) {\n if (!bundleId) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n await this.loadCache();\n const bundle = this.cache.get(bundleId);\n if (!bundle) {\n this.logger.warn('Attempted to delete non-existent bundle', { bundleId });\n return;\n }\n this.cache.delete(bundleId);\n await this.saveCache();\n // If this was the active bundle, clear it\n const activeBundleId = await this.getActiveBundleId();\n if (activeBundleId === bundleId) {\n await this.clearActiveBundle();\n }\n this.logger.info('Bundle deleted', { bundleId });\n }\n /**\n * Get active bundle\n */\n async getActiveBundle() {\n const activeBundleId = await this.getActiveBundleId();\n if (!activeBundleId)\n return null;\n return this.getBundle(activeBundleId);\n }\n /**\n * Set active bundle\n */\n async setActiveBundle(bundleId) {\n if (!bundleId) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n const bundle = await this.getBundle(bundleId);\n if (!bundle) {\n throw new StorageError(ErrorCode.FILE_NOT_FOUND, `Bundle ${bundleId} not found`);\n }\n // Update previous active bundle status\n const previousActive = await this.getActiveBundle();\n if (previousActive && previousActive.bundleId !== bundleId) {\n previousActive.status = 'READY';\n await this.saveBundleInfo(previousActive);\n }\n // Set new active bundle\n bundle.status = 'ACTIVE';\n await this.saveBundleInfo(bundle);\n await this.preferences.set({\n key: this.ACTIVE_BUNDLE_KEY,\n value: bundleId,\n });\n this.logger.info('Active bundle set', {\n bundleId,\n version: bundle.version,\n });\n }\n /**\n * Get active bundle ID\n */\n async getActiveBundleId() {\n try {\n const { value } = await this.preferences.get({\n key: this.ACTIVE_BUNDLE_KEY,\n });\n return value;\n }\n catch (error) {\n this.logger.error('Failed to get active bundle ID', error);\n return null;\n }\n }\n /**\n * Clear active bundle\n */\n async clearActiveBundle() {\n await this.preferences.remove({ key: this.ACTIVE_BUNDLE_KEY });\n this.logger.info('Active bundle cleared');\n }\n /**\n * Clear all bundles\n */\n async clearAllBundles() {\n await this.preferences.remove({ key: this.STORAGE_KEY });\n await this.preferences.remove({ key: this.ACTIVE_BUNDLE_KEY });\n this.cache.clear();\n this.cacheExpiry = 0;\n this.logger.info('All bundles cleared');\n }\n /**\n * Clean up old bundles\n */\n async cleanupOldBundles(keepCount) {\n if (keepCount < 1) {\n throw new StorageError(ErrorCode.INVALID_CONFIG, 'Keep count must be at least 1');\n }\n const bundles = await this.getAllBundles();\n const activeBundleId = await this.getActiveBundleId();\n // Sort by download time (newest first)\n const sorted = bundles.sort((a, b) => b.downloadTime - a.downloadTime);\n // Keep the active bundle and the most recent ones\n const toKeep = new Set();\n if (activeBundleId) {\n toKeep.add(activeBundleId);\n }\n let kept = toKeep.size;\n for (const bundle of sorted) {\n if (kept >= keepCount)\n break;\n if (!toKeep.has(bundle.bundleId)) {\n toKeep.add(bundle.bundleId);\n kept++;\n }\n }\n // Delete bundles not in the keep set\n let deletedCount = 0;\n for (const bundle of bundles) {\n if (!toKeep.has(bundle.bundleId)) {\n await this.deleteBundle(bundle.bundleId);\n deletedCount++;\n }\n }\n if (deletedCount > 0) {\n this.logger.info('Cleaned up old bundles', {\n deleted: deletedCount,\n kept,\n });\n }\n }\n /**\n * Get bundles older than specified time\n */\n async getBundlesOlderThan(timestamp) {\n if (timestamp < 0) {\n throw new StorageError(ErrorCode.INVALID_CONFIG, 'Timestamp must be non-negative');\n }\n const bundles = await this.getAllBundles();\n return bundles.filter((b) => b.downloadTime < timestamp);\n }\n /**\n * Mark bundle as verified\n */\n async markBundleAsVerified(bundleId) {\n const bundle = await this.getBundle(bundleId);\n if (!bundle) {\n throw new StorageError(ErrorCode.FILE_NOT_FOUND, `Bundle ${bundleId} not found`);\n }\n bundle.verified = true;\n await this.saveBundleInfo(bundle);\n this.logger.info('Bundle marked as verified', { bundleId });\n }\n /**\n * Get total storage used by bundles\n */\n async getTotalStorageUsed() {\n const bundles = await this.getAllBundles();\n return bundles.reduce((total, bundle) => total + bundle.size, 0);\n }\n /**\n * Check if storage limit is exceeded\n */\n async isStorageLimitExceeded(additionalSize = 0) {\n const totalUsed = await this.getTotalStorageUsed();\n const maxStorage = this.configManager.get('maxBundleSize') * 3; // Allow 3x max bundle size\n return totalUsed + additionalSize > maxStorage;\n }\n /**\n * Create default bundle\n */\n createDefaultBundle() {\n return {\n bundleId: 'default',\n version: '1.0.0',\n path: '/',\n downloadTime: Date.now(),\n size: 0,\n status: 'ACTIVE',\n checksum: '',\n verified: true,\n };\n }\n /**\n * Clean expired cache entries\n */\n async cleanExpiredBundles() {\n const expirationTime = this.configManager.get('cacheExpiration');\n const cutoffTime = Date.now() - expirationTime;\n const expiredBundles = await this.getBundlesOlderThan(cutoffTime);\n for (const bundle of expiredBundles) {\n // Don't delete active bundle\n const activeBundleId = await this.getActiveBundleId();\n if (bundle.bundleId !== activeBundleId) {\n await this.deleteBundle(bundle.bundleId);\n }\n }\n }\n}\n//# sourceMappingURL=bundle-manager.js.map","import { ConfigManager } from '../core/config';\nimport { Logger } from '../core/logger';\nimport { DownloadError, ErrorCode, ValidationError } from '../core/errors';\nimport { Directory } from '@capacitor/filesystem';\n/**\n * Manages file downloads with progress tracking and resume capability\n */\nexport class DownloadManager {\n constructor() {\n this.activeDownloads = new Map();\n this.filesystem = null;\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n }\n /**\n * Initialize the download manager\n */\n async initialize() {\n this.filesystem = this.configManager.get('filesystem');\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not configured. Please configure the plugin first.');\n }\n }\n /**\n * Validate URL against allowed hosts\n */\n validateUrl(url) {\n try {\n const parsedUrl = new URL(url);\n // Ensure HTTPS\n if (parsedUrl.protocol !== 'https:') {\n throw new ValidationError(ErrorCode.INVALID_URL, 'Only HTTPS URLs are allowed for security reasons');\n }\n // Check against allowed hosts if configured\n const allowedHosts = this.configManager.get('allowedHosts');\n if (allowedHosts.length > 0 &&\n !allowedHosts.includes(parsedUrl.hostname)) {\n throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, `Host ${parsedUrl.hostname} is not in the allowed hosts list`);\n }\n }\n catch (error) {\n if (error instanceof ValidationError)\n throw error;\n throw new ValidationError(ErrorCode.INVALID_URL, 'Invalid URL format');\n }\n }\n /**\n * Download a file with progress tracking\n */\n async download(url, bundleId, onProgress) {\n // Validate inputs\n this.validateUrl(url);\n if (!bundleId) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n // Check if already downloading\n if (this.activeDownloads.has(bundleId)) {\n throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, `Download already in progress for bundle ${bundleId}`);\n }\n // Create abort controller for this download\n const abortController = new AbortController();\n const downloadState = {\n controller: abortController,\n startTime: Date.now(),\n };\n this.activeDownloads.set(bundleId, downloadState);\n try {\n const timeout = this.configManager.get('downloadTimeout');\n const timeoutId = setTimeout(() => abortController.abort(), timeout);\n const response = await fetch(url, {\n signal: abortController.signal,\n headers: {\n 'Cache-Control': 'no-cache',\n Accept: 'application/octet-stream, application/zip',\n },\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, `Download failed: ${response.status} ${response.statusText}`, { status: response.status, statusText: response.statusText });\n }\n // Validate content type\n const contentType = response.headers.get('content-type');\n if (contentType && !this.isValidContentType(contentType)) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, `Invalid content type: ${contentType}`);\n }\n // Get total size from headers\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : 0;\n // Check size limit\n if (totalBytes > this.configManager.get('maxBundleSize')) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `Bundle size ${totalBytes} exceeds maximum allowed size`);\n }\n // If no content length, fall back to simple download\n if (!totalBytes || !response.body) {\n const blob = await response.blob();\n this.validateBlobSize(blob);\n return blob;\n }\n // Stream the response with progress tracking\n const reader = response.body.getReader();\n const chunks = [];\n let receivedBytes = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done)\n break;\n chunks.push(value);\n receivedBytes += value.length;\n // Check if size exceeds limit during download\n if (receivedBytes > this.configManager.get('maxBundleSize')) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `Download size exceeds maximum allowed size`);\n }\n // Report progress\n if (onProgress) {\n const percent = Math.round((receivedBytes / totalBytes) * 100);\n onProgress({\n percent,\n bytesDownloaded: receivedBytes,\n totalBytes,\n bundleId,\n });\n }\n }\n // Combine chunks into a single blob\n const blob = new Blob(chunks);\n this.validateBlobSize(blob);\n this.logger.info('Download completed', {\n bundleId,\n size: blob.size,\n duration: Date.now() - downloadState.startTime,\n });\n return blob;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n const isTimeout = Date.now() - downloadState.startTime >=\n this.configManager.get('downloadTimeout');\n throw new DownloadError(isTimeout ? ErrorCode.DOWNLOAD_TIMEOUT : ErrorCode.DOWNLOAD_FAILED, isTimeout ? 'Download timed out' : 'Download cancelled', undefined, error);\n }\n throw error;\n }\n finally {\n // Clean up\n this.activeDownloads.delete(bundleId);\n }\n }\n /**\n * Validate content type\n */\n isValidContentType(contentType) {\n const validTypes = [\n 'application/octet-stream',\n 'application/zip',\n 'application/x-zip-compressed',\n 'application/x-zip',\n ];\n return validTypes.some((type) => contentType.includes(type));\n }\n /**\n * Validate blob size\n */\n validateBlobSize(blob) {\n if (blob.size === 0) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Downloaded file is empty');\n }\n if (blob.size > this.configManager.get('maxBundleSize')) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `File size ${blob.size} exceeds maximum allowed size`);\n }\n }\n /**\n * Cancel a download\n */\n cancelDownload(bundleId) {\n const state = this.activeDownloads.get(bundleId);\n if (state) {\n state.controller.abort();\n this.activeDownloads.delete(bundleId);\n this.logger.info('Download cancelled', { bundleId });\n }\n }\n /**\n * Cancel all active downloads\n */\n cancelAllDownloads() {\n for (const state of this.activeDownloads.values()) {\n state.controller.abort();\n }\n const count = this.activeDownloads.size;\n this.activeDownloads.clear();\n if (count > 0) {\n this.logger.info('All downloads cancelled', { count });\n }\n }\n /**\n * Check if a download is active\n */\n isDownloading(bundleId) {\n return this.activeDownloads.has(bundleId);\n }\n /**\n * Get active download count\n */\n getActiveDownloadCount() {\n return this.activeDownloads.size;\n }\n /**\n * Download with retry logic\n */\n async downloadWithRetry(url, bundleId, onProgress) {\n const maxRetries = this.configManager.get('retryAttempts');\n const retryDelay = this.configManager.get('retryDelay');\n let lastError = null;\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n // Add delay between retries (exponential backoff)\n if (attempt > 0) {\n const delay = Math.min(retryDelay * Math.pow(2, attempt - 1), 30000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n this.logger.debug('Retrying download', { bundleId, attempt, delay });\n }\n return await this.download(url, bundleId, onProgress);\n }\n catch (error) {\n lastError = error;\n // Don't retry if cancelled or validation error\n if (error instanceof ValidationError ||\n (error instanceof Error && error.name === 'AbortError')) {\n throw error;\n }\n this.logger.warn(`Download attempt ${attempt + 1} failed`, {\n bundleId,\n error,\n });\n }\n }\n throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, 'Download failed after all retries', { attempts: maxRetries }, lastError || undefined);\n }\n /**\n * Convert blob to ArrayBuffer\n */\n async blobToArrayBuffer(blob) {\n return blob.arrayBuffer();\n }\n /**\n * Save blob to filesystem\n */\n async saveBlob(bundleId, blob) {\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');\n }\n const arrayBuffer = await this.blobToArrayBuffer(blob);\n const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));\n const path = `bundles/${bundleId}/bundle.zip`;\n await this.filesystem.writeFile({\n path,\n data: base64,\n directory: Directory.Data,\n recursive: true,\n });\n this.logger.debug('Bundle saved to filesystem', {\n bundleId,\n path,\n size: blob.size,\n });\n return path;\n }\n /**\n * Load blob from filesystem\n */\n async loadBlob(bundleId) {\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');\n }\n try {\n const path = `bundles/${bundleId}/bundle.zip`;\n const result = await this.filesystem.readFile({\n path,\n directory: Directory.Data,\n });\n const binaryString = atob(result.data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return new Blob([bytes], { type: 'application/zip' });\n }\n catch (error) {\n this.logger.debug('Failed to load bundle from filesystem', {\n bundleId,\n error,\n });\n return null;\n }\n }\n /**\n * Delete blob from filesystem\n */\n async deleteBlob(bundleId) {\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');\n }\n try {\n const path = `bundles/${bundleId}`;\n await this.filesystem.rmdir({\n path,\n directory: Directory.Data,\n recursive: true,\n });\n this.logger.debug('Bundle deleted from filesystem', { bundleId });\n }\n catch (error) {\n this.logger.warn('Failed to delete bundle from filesystem', {\n bundleId,\n error,\n });\n }\n }\n}\n//# sourceMappingURL=download-manager.js.map","import { ConfigManager } from '../core/config';\nimport { Logger } from '../core/logger';\nimport { SecurityValidator } from '../core/security';\nimport { ValidationError, ErrorCode } from '../core/errors';\n/**\n * Manages version checking and comparison\n */\nexport class VersionManager {\n constructor() {\n this.VERSION_CHECK_CACHE_KEY = 'capacitor_native_update_version_cache';\n this.CACHE_DURATION = 5 * 60 * 1000; // 5 minutes\n this.preferences = null;\n this.memoryCache = new Map();\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n this.securityValidator = SecurityValidator.getInstance();\n }\n /**\n * Compare two semantic versions\n */\n static compareVersions(version1, version2) {\n try {\n // Split version and pre-release\n const [v1Base, v1Pre] = version1.split('-');\n const [v2Base, v2Pre] = version2.split('-');\n const v1Parts = v1Base.split('.').map(Number);\n const v2Parts = v2Base.split('.').map(Number);\n // Compare major.minor.patch\n for (let i = 0; i < 3; i++) {\n const v1Part = v1Parts[i] || 0;\n const v2Part = v2Parts[i] || 0;\n if (v1Part > v2Part)\n return 1;\n if (v1Part < v2Part)\n return -1;\n }\n // If base versions are equal, compare pre-release\n if (v1Pre && !v2Pre)\n return -1; // 1.0.0-alpha < 1.0.0\n if (!v1Pre && v2Pre)\n return 1; // 1.0.0 > 1.0.0-alpha\n if (v1Pre && v2Pre) {\n return v1Pre.localeCompare(v2Pre);\n }\n return 0;\n }\n catch (_a) {\n if (version1 === version2)\n return 0;\n return version1 > version2 ? 1 : -1;\n }\n }\n /**\n * Validate semantic version format\n */\n static isValidVersion(version) {\n return /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$/.test(version);\n }\n /**\n * Check if update should be performed\n */\n static shouldUpdate(currentVersion, newVersion, minAppVersion) {\n if (minAppVersion &&\n VersionManager.compareVersions(currentVersion, minAppVersion) < 0) {\n return false;\n }\n return VersionManager.compareVersions(currentVersion, newVersion) < 0;\n }\n /**\n * Initialize the version manager\n */\n async initialize() {\n this.preferences = this.configManager.get('preferences');\n if (!this.preferences) {\n throw new ValidationError(ErrorCode.MISSING_DEPENDENCY, 'Preferences not configured. Please configure the plugin first.');\n }\n }\n /**\n * Check for latest version from server\n */\n async checkForUpdates(serverUrl, channel, currentVersion, appId) {\n // Validate inputs\n this.securityValidator.validateUrl(serverUrl);\n this.securityValidator.validateVersion(currentVersion);\n if (!channel || !appId) {\n throw new ValidationError(ErrorCode.INVALID_CONFIG, 'Channel and appId are required');\n }\n // Check cache first\n const cacheKey = `${channel}-${appId}`;\n const cached = await this.getCachedVersionInfo(cacheKey);\n if (cached &&\n cached.channel === channel &&\n Date.now() - cached.timestamp < this.CACHE_DURATION) {\n this.logger.debug('Returning cached version info', {\n channel,\n version: cached.data.version,\n });\n return cached.data;\n }\n try {\n const url = new URL(`${serverUrl}/check`);\n url.searchParams.append('channel', channel);\n url.searchParams.append('version', currentVersion);\n url.searchParams.append('appId', appId);\n url.searchParams.append('platform', 'web'); // Will be overridden by native platforms\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-App-Version': currentVersion,\n 'X-App-Id': appId,\n },\n signal: AbortSignal.timeout(this.configManager.get('downloadTimeout')),\n });\n if (!response.ok) {\n throw new Error(`Version check failed: ${response.status}`);\n }\n const data = await response.json();\n // Validate response\n if (!data.version) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'No version in server response');\n }\n this.securityValidator.validateVersion(data.version);\n // Additional validation\n if (data.bundleUrl) {\n this.securityValidator.validateUrl(data.bundleUrl);\n }\n if (data.minAppVersion) {\n this.securityValidator.validateVersion(data.minAppVersion);\n }\n // Cache the result\n await this.cacheVersionInfo(cacheKey, channel, data);\n this.logger.info('Version check completed', {\n channel,\n currentVersion,\n latestVersion: data.version,\n updateAvailable: this.isNewerVersion(data.version, currentVersion),\n });\n return data;\n }\n catch (error) {\n this.logger.error('Failed to check for updates', error);\n return null;\n }\n }\n /**\n * Compare two versions\n */\n isNewerVersion(version1, version2) {\n try {\n const v1 = this.parseVersion(version1);\n const v2 = this.parseVersion(version2);\n if (v1.major !== v2.major)\n return v1.major > v2.major;\n if (v1.minor !== v2.minor)\n return v1.minor > v2.minor;\n if (v1.patch !== v2.patch)\n return v1.patch > v2.patch;\n // If main versions are equal, check pre-release\n if (v1.prerelease && !v2.prerelease)\n return false; // v1 is pre-release, v2 is not\n if (!v1.prerelease && v2.prerelease)\n return true; // v1 is not pre-release, v2 is\n if (v1.prerelease && v2.prerelease) {\n return v1.prerelease > v2.prerelease;\n }\n return false; // Versions are equal\n }\n catch (error) {\n this.logger.error('Failed to compare versions', {\n version1,\n version2,\n error,\n });\n return false;\n }\n }\n /**\n * Check if update is mandatory based on minimum version\n */\n isUpdateMandatory(currentVersion, minimumVersion) {\n if (!minimumVersion)\n return false;\n try {\n this.securityValidator.validateVersion(currentVersion);\n this.securityValidator.validateVersion(minimumVersion);\n return (!this.isNewerVersion(currentVersion, minimumVersion) &&\n currentVersion !== minimumVersion);\n }\n catch (error) {\n this.logger.error('Failed to check mandatory update', error);\n return false;\n }\n }\n /**\n * Parse version metadata\n */\n parseVersion(version) {\n const match = version.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$/);\n if (!match) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid version format');\n }\n return {\n major: parseInt(match[1], 10),\n minor: parseInt(match[2], 10),\n patch: parseInt(match[3], 10),\n prerelease: match[4],\n build: match[5],\n };\n }\n /**\n * Generate version string from components\n */\n buildVersionString(components) {\n let version = `${components.major}.${components.minor}.${components.patch}`;\n if (components.prerelease) {\n version += `-${components.prerelease}`;\n }\n if (components.build) {\n version += `+${components.build}`;\n }\n return version;\n }\n /**\n * Check if version is compatible with native version requirements\n */\n isCompatibleWithNativeVersion(bundleVersion, nativeVersion, compatibility) {\n if (!compatibility)\n return true;\n try {\n // Check if there's a specific native version requirement for this bundle version\n const requiredNativeVersion = compatibility[bundleVersion];\n if (!requiredNativeVersion)\n return true;\n this.securityValidator.validateVersion(nativeVersion);\n this.securityValidator.validateVersion(requiredNativeVersion);\n return !this.isNewerVersion(requiredNativeVersion, nativeVersion);\n }\n catch (error) {\n this.logger.error('Failed to check compatibility', error);\n return false;\n }\n }\n /**\n * Get version from cache\n */\n async getCachedVersionInfo(cacheKey) {\n // Check memory cache first\n const memCached = this.memoryCache.get(cacheKey);\n if (memCached && Date.now() - memCached.timestamp < this.CACHE_DURATION) {\n return memCached;\n }\n // Check persistent cache\n try {\n const { value } = await this.preferences.get({\n key: this.VERSION_CHECK_CACHE_KEY,\n });\n if (!value)\n return null;\n const allCached = JSON.parse(value);\n const cached = allCached[cacheKey];\n if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {\n // Update memory cache\n this.memoryCache.set(cacheKey, cached);\n return cached;\n }\n }\n catch (error) {\n this.logger.debug('Failed to load cached version info', error);\n }\n return null;\n }\n /**\n * Cache version info\n */\n async cacheVersionInfo(cacheKey, channel, data) {\n const cacheEntry = {\n channel,\n data,\n timestamp: Date.now(),\n };\n // Update memory cache\n this.memoryCache.set(cacheKey, cacheEntry);\n // Update persistent cache\n try {\n const { value } = await this.preferences.get({\n key: this.VERSION_CHECK_CACHE_KEY,\n });\n const allCached = value\n ? JSON.parse(value)\n : {};\n // Clean old entries\n const now = Date.now();\n for (const key in allCached) {\n if (now - allCached[key].timestamp > this.CACHE_DURATION * 2) {\n delete allCached[key];\n }\n }\n allCached[cacheKey] = cacheEntry;\n await this.preferences.set({\n key: this.VERSION_CHECK_CACHE_KEY,\n value: JSON.stringify(allCached),\n });\n }\n catch (error) {\n this.logger.warn('Failed to cache version info', error);\n }\n }\n /**\n * Clear version cache\n */\n async clearVersionCache() {\n this.memoryCache.clear();\n try {\n await this.preferences.remove({ key: this.VERSION_CHECK_CACHE_KEY });\n }\n catch (error) {\n this.logger.warn('Failed to clear version cache', error);\n }\n }\n /**\n * Check if downgrade protection should block update\n */\n shouldBlockDowngrade(currentVersion, newVersion) {\n try {\n return this.securityValidator.isVersionDowngrade(currentVersion, newVersion);\n }\n catch (error) {\n this.logger.error('Failed to check downgrade', error);\n // Default to safe behavior - block if we can't determine\n return true;\n }\n }\n}\n//# sourceMappingURL=version-manager.js.map","import { ConfigManager } from './config';\nimport { Logger } from './logger';\nimport { SecurityValidator } from './security';\nimport { BundleManager } from '../live-update/bundle-manager';\nimport { DownloadManager } from '../live-update/download-manager';\nimport { VersionManager } from '../live-update/version-manager';\nimport { NativeUpdateError, ErrorCode } from './errors';\n/**\n * Central manager for all plugin components\n */\nexport class PluginManager {\n constructor() {\n this.bundleManager = null;\n this.downloadManager = null;\n this.versionManager = null;\n this.initialized = false;\n this.configManager = ConfigManager.getInstance();\n this.logger = Logger.getInstance();\n this.securityValidator = SecurityValidator.getInstance();\n }\n static getInstance() {\n if (!PluginManager.instance) {\n PluginManager.instance = new PluginManager();\n }\n return PluginManager.instance;\n }\n /**\n * Initialize the plugin with configuration\n */\n async initialize(config) {\n if (this.initialized) {\n this.logger.warn('Plugin already initialized');\n return;\n }\n try {\n // Configure the plugin\n this.configManager.configure(config);\n // Validate required dependencies\n if (!config.filesystem || !config.preferences) {\n throw new NativeUpdateError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem and Preferences are required for plugin initialization');\n }\n // Initialize managers\n this.bundleManager = new BundleManager();\n await this.bundleManager.initialize();\n this.downloadManager = new DownloadManager();\n await this.downloadManager.initialize();\n this.versionManager = new VersionManager();\n await this.versionManager.initialize();\n this.initialized = true;\n this.logger.info('Plugin initialized successfully');\n }\n catch (error) {\n this.logger.error('Failed to initialize plugin', error);\n throw error;\n }\n }\n /**\n * Check if plugin is initialized\n */\n isInitialized() {\n return this.initialized && this.configManager.isConfigured();\n }\n /**\n * Ensure plugin is initialized\n */\n ensureInitialized() {\n if (!this.isInitialized()) {\n throw new NativeUpdateError(ErrorCode.NOT_CONFIGURED, 'Plugin not initialized. Please call initialize() first.');\n }\n }\n /**\n * Get bundle manager\n */\n getBundleManager() {\n this.ensureInitialized();\n return this.bundleManager;\n }\n /**\n * Get download manager\n */\n getDownloadManager() {\n this.ensureInitialized();\n return this.downloadManager;\n }\n /**\n * Get version manager\n */\n getVersionManager() {\n this.ensureInitialized();\n return this.versionManager;\n }\n /**\n * Get configuration manager\n */\n getConfigManager() {\n return this.configManager;\n }\n /**\n * Get logger\n */\n getLogger() {\n return this.logger;\n }\n /**\n * Get security validator\n */\n getSecurityValidator() {\n return this.securityValidator;\n }\n /**\n * Reset plugin state\n */\n async reset() {\n this.logger.info('Resetting plugin state');\n // Clear all data\n if (this.bundleManager) {\n await this.bundleManager.clearAllBundles();\n }\n if (this.versionManager) {\n await this.versionManager.clearVersionCache();\n }\n if (this.downloadManager) {\n this.downloadManager.cancelAllDownloads();\n }\n // Reset initialization state\n this.bundleManager = null;\n this.downloadManager = null;\n this.versionManager = null;\n this.initialized = false;\n this.logger.info('Plugin reset complete');\n }\n /**\n * Clean up resources\n */\n async cleanup() {\n this.logger.info('Cleaning up plugin resources');\n // Cancel any active downloads\n if (this.downloadManager) {\n this.downloadManager.cancelAllDownloads();\n }\n // Clean expired bundles\n if (this.bundleManager) {\n await this.bundleManager.cleanExpiredBundles();\n }\n this.logger.info('Cleanup complete');\n }\n}\n//# sourceMappingURL=plugin-manager.js.map","import { registerPlugin } from '@capacitor/core';\nimport { SyncStatus, BundleStatus, UpdateErrorCode } from './definitions';\nimport { PluginManager } from './core/plugin-manager';\nimport { NativeUpdateError, ErrorCode } from './core/errors';\n/**\n * Web implementation of the Native Update Plugin\n */\nclass NativeUpdatePluginWeb {\n constructor() {\n this.initialized = false;\n this.pluginManager = PluginManager.getInstance();\n }\n // Main plugin methods\n async initialize(config) {\n await this.pluginManager.initialize(config);\n this.initialized = true;\n }\n isInitialized() {\n return this.initialized && this.pluginManager.isInitialized();\n }\n async reset() {\n await this.pluginManager.reset();\n }\n async cleanup() {\n await this.pluginManager.cleanup();\n }\n // NativeUpdatePlugin methods\n async configure(options) {\n if (!this.initialized) {\n // Auto-initialize with the provided config\n await this.initialize(options.config);\n }\n else {\n // Apply plugin configuration\n const configManager = this.pluginManager.getConfigManager();\n configManager.configure(options.config);\n }\n }\n async getSecurityInfo() {\n return {\n enforceHttps: true,\n certificatePinning: {\n enabled: false,\n pins: [],\n },\n validateInputs: true,\n secureStorage: true,\n };\n }\n // LiveUpdatePlugin methods\n async sync(_options) {\n const bundleManager = this.pluginManager.getBundleManager();\n try {\n // Check for updates\n const currentBundle = await bundleManager.getActiveBundle();\n const currentVersion = (currentBundle === null || currentBundle === void 0 ? void 0 : currentBundle.version) || '1.0.0';\n // For now, return up-to-date status\n return {\n status: SyncStatus.UP_TO_DATE,\n version: currentVersion,\n };\n }\n catch (error) {\n return {\n status: SyncStatus.ERROR,\n error: {\n code: UpdateErrorCode.UNKNOWN_ERROR,\n message: error instanceof Error ? error.message : 'Sync failed',\n },\n };\n }\n }\n async download(options) {\n const downloadManager = this.pluginManager.getDownloadManager();\n const bundleManager = this.pluginManager.getBundleManager();\n const blob = await downloadManager.downloadWithRetry(options.url, options.version);\n const path = await downloadManager.saveBlob(options.version, blob);\n const bundleInfo = {\n bundleId: options.version,\n version: options.version,\n path,\n downloadTime: Date.now(),\n size: blob.size,\n status: BundleStatus.READY,\n checksum: options.checksum,\n signature: options.signature,\n verified: false,\n };\n await bundleManager.saveBundleInfo(bundleInfo);\n return bundleInfo;\n }\n async set(bundle) {\n const bundleManager = this.pluginManager.getBundleManager();\n await bundleManager.setActiveBundle(bundle.bundleId);\n }\n async reload() {\n // In web implementation, we can reload the page\n if (typeof window !== 'undefined') {\n window.location.reload();\n }\n }\n async current() {\n const bundleManager = this.pluginManager.getBundleManager();\n const bundle = await bundleManager.getActiveBundle();\n if (!bundle) {\n throw new NativeUpdateError(ErrorCode.FILE_NOT_FOUND, 'No active bundle found');\n }\n return bundle;\n }\n async list() {\n const bundleManager = this.pluginManager.getBundleManager();\n return bundleManager.getAllBundles();\n }\n async delete(options) {\n const bundleManager = this.pluginManager.getBundleManager();\n if (options.bundleId) {\n await bundleManager.deleteBundle(options.bundleId);\n }\n else if (options.keepVersions !== undefined) {\n // Delete old versions keeping the specified number\n const bundles = await bundleManager.getAllBundles();\n const sortedBundles = bundles.sort((a, b) => b.downloadTime - a.downloadTime);\n for (let i = options.keepVersions; i < sortedBundles.length; i++) {\n await bundleManager.deleteBundle(sortedBundles[i].bundleId);\n }\n }\n }\n async notifyAppReady() {\n // Mark the current bundle as stable\n const bundleManager = this.pluginManager.getBundleManager();\n const activeBundle = await bundleManager.getActiveBundle();\n if (activeBundle) {\n activeBundle.status = BundleStatus.ACTIVE;\n await bundleManager.saveBundleInfo(activeBundle);\n }\n }\n async getLatest() {\n // For web, we'll return no update available\n return {\n available: false,\n };\n }\n async setChannel(channel) {\n // Store the channel preference\n const preferences = this.pluginManager\n .getConfigManager()\n .get('preferences');\n if (preferences) {\n await preferences.set({\n key: 'update_channel',\n value: channel,\n });\n }\n }\n async setUpdateUrl(url) {\n const configManager = this.pluginManager.getConfigManager();\n configManager.configure({ baseUrl: url });\n }\n async validateUpdate(options) {\n const securityValidator = this.pluginManager.getSecurityValidator();\n try {\n // Validate checksum\n const isValid = await securityValidator.validateChecksum(new ArrayBuffer(0), // Placeholder for bundle data\n options.checksum);\n return {\n isValid,\n details: {\n checksumValid: isValid,\n signatureValid: true,\n sizeValid: true,\n versionValid: true,\n },\n };\n }\n catch (error) {\n return {\n isValid: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n }\n // AppUpdatePlugin methods\n async getAppUpdateInfo() {\n // Web doesn't have native app updates\n return {\n updateAvailable: false,\n currentVersion: '1.0.0',\n };\n }\n async performImmediateUpdate() {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');\n }\n async startFlexibleUpdate() {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');\n }\n async completeFlexibleUpdate() {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');\n }\n async openAppStore(_options) {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'App store is not available on web');\n }\n // AppReviewPlugin methods\n async requestReview() {\n return {\n displayed: false,\n error: 'Reviews are not supported on web',\n };\n }\n async canRequestReview() {\n return {\n canRequest: false,\n reason: 'Reviews are not supported on web',\n };\n }\n // BackgroundUpdatePlugin methods\n async enableBackgroundUpdates(config) {\n // Store the configuration\n const preferences = this.pluginManager\n .getConfigManager()\n .get('preferences');\n if (preferences) {\n await preferences.set({\n key: 'background_update_config',\n value: JSON.stringify(config),\n });\n }\n }\n async disableBackgroundUpdates() {\n const preferences = this.pluginManager\n .getConfigManager()\n .get('preferences');\n if (preferences) {\n await preferences.remove({ key: 'background_update_config' });\n }\n }\n async getBackgroundUpdateStatus() {\n return {\n enabled: false,\n isRunning: false,\n checkCount: 0,\n failureCount: 0,\n };\n }\n async scheduleBackgroundCheck(_interval) {\n // Not supported on web\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Background updates are not supported on web');\n }\n async triggerBackgroundCheck() {\n return {\n success: false,\n updatesFound: false,\n notificationSent: false,\n error: {\n code: UpdateErrorCode.PLATFORM_NOT_SUPPORTED,\n message: 'Background updates are not supported on web',\n },\n };\n }\n async setNotificationPreferences(preferences) {\n // Store preferences but notifications aren't supported on web\n const prefs = this.pluginManager.getConfigManager().get('preferences');\n if (prefs) {\n await prefs.set({\n key: 'notification_preferences',\n value: JSON.stringify(preferences),\n });\n }\n }\n async getNotificationPermissions() {\n return {\n granted: false,\n canRequest: false,\n };\n }\n async requestNotificationPermissions() {\n return false;\n }\n}\n/**\n * Register the plugin\n */\nconst NativeUpdate = registerPlugin('NativeUpdate', {\n web: () => new NativeUpdatePluginWeb(),\n});\nexport { NativeUpdate };\n//# sourceMappingURL=plugin.js.map","import { ConfigManager } from './config';\nimport { Logger } from './logger';\nimport { Directory, Encoding } from '@capacitor/filesystem';\n/**\n * Manages caching with expiration for various data types\n */\nexport class CacheManager {\n constructor() {\n this.filesystem = null;\n this.memoryCache = new Map();\n this.CACHE_DIR = 'cache';\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n }\n /**\n * Initialize cache manager\n */\n async initialize() {\n this.filesystem = this.configManager.get('filesystem');\n if (!this.filesystem) {\n throw new Error('Filesystem not configured');\n }\n // Create cache directory if it doesn't exist\n try {\n await this.filesystem.mkdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n recursive: true,\n });\n }\n catch (error) {\n this.logger.debug('Cache directory may already exist', error);\n }\n // Clean expired cache on initialization\n await this.cleanExpiredCache();\n }\n /**\n * Set cache entry with expiration\n */\n async set(key, data, ttlMs) {\n const expiry = Date.now() + (ttlMs || this.configManager.get('cacheExpiration'));\n const entry = {\n data,\n timestamp: Date.now(),\n expiry,\n };\n // Update memory cache\n this.memoryCache.set(key, entry);\n // Persist to filesystem for larger data\n if (this.shouldPersist(data)) {\n await this.persistToFile(key, entry);\n }\n this.logger.debug('Cache entry set', { key, expiry: new Date(expiry) });\n }\n /**\n * Get cache entry\n */\n async get(key) {\n // Check memory cache first\n const memEntry = this.memoryCache.get(key);\n if (memEntry) {\n if (Date.now() < memEntry.expiry) {\n return memEntry.data;\n }\n else {\n // Expired - remove from memory\n this.memoryCache.delete(key);\n }\n }\n // Check filesystem cache\n const fileEntry = await this.loadFromFile(key);\n if (fileEntry) {\n if (Date.now() < fileEntry.expiry) {\n // Update memory cache\n this.memoryCache.set(key, fileEntry);\n return fileEntry.data;\n }\n else {\n // Expired - remove file\n await this.removeFile(key);\n }\n }\n return null;\n }\n /**\n * Check if cache entry exists and is valid\n */\n async has(key) {\n const value = await this.get(key);\n return value !== null;\n }\n /**\n * Remove cache entry\n */\n async remove(key) {\n this.memoryCache.delete(key);\n await this.removeFile(key);\n this.logger.debug('Cache entry removed', { key });\n }\n /**\n * Clear all cache\n */\n async clear() {\n this.memoryCache.clear();\n // Remove cache directory\n try {\n await this.filesystem.rmdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n recursive: true,\n });\n // Recreate empty cache directory\n await this.filesystem.mkdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n recursive: true,\n });\n }\n catch (error) {\n this.logger.warn('Failed to clear cache directory', error);\n }\n this.logger.info('Cache cleared');\n }\n /**\n * Clean expired cache entries\n */\n async cleanExpiredCache() {\n const now = Date.now();\n let cleanedCount = 0;\n // Clean memory cache\n for (const [key, entry] of this.memoryCache) {\n if (now >= entry.expiry) {\n this.memoryCache.delete(key);\n cleanedCount++;\n }\n }\n // Clean filesystem cache\n try {\n const files = await this.filesystem.readdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n });\n for (const file of files.files) {\n const key = file.name.replace('.json', '');\n const entry = await this.loadFromFile(key);\n if (!entry || now >= entry.expiry) {\n await this.removeFile(key);\n cleanedCount++;\n }\n }\n }\n catch (error) {\n this.logger.debug('Failed to clean filesystem cache', error);\n }\n if (cleanedCount > 0) {\n this.logger.info('Cleaned expired cache entries', {\n count: cleanedCount,\n });\n }\n }\n /**\n * Get cache statistics\n */\n async getStats() {\n let fileEntries = 0;\n let totalSize = 0;\n try {\n const files = await this.filesystem.readdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n });\n fileEntries = files.files.length;\n // Estimate size (this is approximate)\n for (const file of files.files) {\n const stat = await this.filesystem.stat({\n path: `${this.CACHE_DIR}/${file.name}`,\n directory: Directory.Data,\n });\n totalSize += stat.size || 0;\n }\n }\n catch (error) {\n this.logger.debug('Failed to get cache stats', error);\n }\n return {\n memoryEntries: this.memoryCache.size,\n fileEntries,\n totalSize,\n };\n }\n /**\n * Cache bundle metadata\n */\n async cacheBundleMetadata(bundle) {\n const key = `bundle_meta_${bundle.bundleId}`;\n await this.set(key, bundle, 24 * 60 * 60 * 1000); // 24 hours\n }\n /**\n * Get cached bundle metadata\n */\n async getCachedBundleMetadata(bundleId) {\n const key = `bundle_meta_${bundleId}`;\n return this.get(key);\n }\n /**\n * Check if data should be persisted to filesystem\n */\n shouldPersist(data) {\n // Persist objects and large strings\n if (typeof data === 'object')\n return true;\n if (typeof data === 'string' && data.length > 1024)\n return true;\n return false;\n }\n /**\n * Persist cache entry to file\n */\n async persistToFile(key, entry) {\n if (!this.filesystem)\n return;\n try {\n const path = `${this.CACHE_DIR}/${key}.json`;\n const data = JSON.stringify(entry);\n await this.filesystem.writeFile({\n path,\n data,\n directory: Directory.Data,\n encoding: Encoding.UTF8,\n });\n }\n catch (error) {\n this.logger.warn('Failed to persist cache to file', { key, error });\n }\n }\n /**\n * Load cache entry from file\n */\n async loadFromFile(key) {\n if (!this.filesystem)\n return null;\n try {\n const path = `${this.CACHE_DIR}/${key}.json`;\n const result = await this.filesystem.readFile({\n path,\n directory: Directory.Data,\n encoding: Encoding.UTF8,\n });\n return JSON.parse(result.data);\n }\n catch (_a) {\n // File doesn't exist or is corrupted\n return null;\n }\n }\n /**\n * Remove cache file\n */\n async removeFile(key) {\n if (!this.filesystem)\n return;\n try {\n const path = `${this.CACHE_DIR}/${key}.json`;\n await this.filesystem.deleteFile({\n path,\n directory: Directory.Data,\n });\n }\n catch (error) {\n // File may not exist\n this.logger.debug('Failed to remove cache file', { key, error });\n }\n }\n}\n//# sourceMappingURL=cache-manager.js.map","import { PluginManager } from '../core/plugin-manager';\nimport { UpdateError, ValidationError, ErrorCode } from '../core/errors';\nimport { SecurityValidator } from '../core/security';\nimport { Directory } from '@capacitor/filesystem';\n/**\n * Manages atomic bundle installation with rollback capability\n */\nexport class UpdateManager {\n constructor() {\n this.filesystem = null;\n this.updateInProgress = false;\n this.currentState = null;\n this.pluginManager = PluginManager.getInstance();\n this.securityValidator = SecurityValidator.getInstance();\n }\n /**\n * Initialize update manager\n */\n async initialize() {\n this.filesystem = this.pluginManager.getConfigManager().get('filesystem');\n if (!this.filesystem) {\n throw new UpdateError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not configured');\n }\n }\n /**\n * Apply bundle update atomically\n */\n async applyUpdate(bundleId, options) {\n if (this.updateInProgress) {\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Another update is already in progress');\n }\n const logger = this.pluginManager.getLogger();\n const bundleManager = this.pluginManager.getBundleManager();\n try {\n this.updateInProgress = true;\n logger.info('Starting bundle update', { bundleId });\n // Get the new bundle\n const newBundle = await bundleManager.getBundle(bundleId);\n if (!newBundle) {\n throw new UpdateError(ErrorCode.FILE_NOT_FOUND, `Bundle ${bundleId} not found`);\n }\n // Verify bundle is ready\n if (newBundle.status !== 'READY' && newBundle.status !== 'ACTIVE') {\n throw new UpdateError(ErrorCode.BUNDLE_NOT_READY, `Bundle ${bundleId} is not ready for installation`);\n }\n // Get current active bundle\n const currentBundle = await bundleManager.getActiveBundle();\n // Initialize update state\n this.currentState = {\n currentBundle,\n newBundle,\n backupPath: null,\n startTime: Date.now(),\n };\n // Validate update\n await this.validateUpdate(currentBundle, newBundle, options);\n // Create backup of current state\n if (currentBundle && currentBundle.bundleId !== 'default') {\n this.currentState.backupPath = await this.createBackup(currentBundle);\n }\n // Apply the update\n await this.performUpdate(newBundle);\n // Verify the update\n await this.verifyUpdate(newBundle);\n // Mark as active\n await bundleManager.setActiveBundle(bundleId);\n // Clean up old bundles if configured\n if (options === null || options === void 0 ? void 0 : options.cleanupOldBundles) {\n await bundleManager.cleanupOldBundles(options.keepBundleCount || 3);\n }\n logger.info('Bundle update completed successfully', {\n bundleId,\n version: newBundle.version,\n duration: Date.now() - this.currentState.startTime,\n });\n // Clear state\n this.currentState = null;\n }\n catch (error) {\n logger.error('Bundle update failed', error);\n // Attempt rollback\n if (this.currentState) {\n await this.rollback();\n }\n throw error;\n }\n finally {\n this.updateInProgress = false;\n }\n }\n /**\n * Validate update before applying\n */\n async validateUpdate(currentBundle, newBundle, options) {\n const logger = this.pluginManager.getLogger();\n const versionManager = this.pluginManager.getVersionManager();\n // Check if downgrade\n if (currentBundle && !(options === null || options === void 0 ? void 0 : options.allowDowngrade)) {\n if (versionManager.shouldBlockDowngrade(currentBundle.version, newBundle.version)) {\n throw new ValidationError(ErrorCode.VERSION_DOWNGRADE, `Cannot downgrade from ${currentBundle.version} to ${newBundle.version}`);\n }\n }\n // Verify bundle integrity\n if (!newBundle.verified) {\n logger.warn('Bundle not verified, verifying now', {\n bundleId: newBundle.bundleId,\n });\n // Load bundle data\n const downloadManager = this.pluginManager.getDownloadManager();\n const blob = await downloadManager.loadBlob(newBundle.bundleId);\n if (!blob) {\n throw new UpdateError(ErrorCode.FILE_NOT_FOUND, 'Bundle data not found');\n }\n // Verify checksum\n const arrayBuffer = await blob.arrayBuffer();\n const isValid = await this.securityValidator.verifyChecksum(arrayBuffer, newBundle.checksum);\n if (!isValid) {\n throw new ValidationError(ErrorCode.CHECKSUM_MISMATCH, 'Bundle checksum verification failed');\n }\n // Verify signature if enabled\n if (newBundle.signature) {\n const signatureValid = await this.securityValidator.verifySignature(arrayBuffer, newBundle.signature);\n if (!signatureValid) {\n throw new ValidationError(ErrorCode.SIGNATURE_INVALID, 'Bundle signature verification failed');\n }\n }\n // Mark as verified\n await this.pluginManager\n .getBundleManager()\n .markBundleAsVerified(newBundle.bundleId);\n }\n logger.debug('Bundle validation passed', { bundleId: newBundle.bundleId });\n }\n /**\n * Create backup of current bundle\n */\n async createBackup(bundle) {\n const backupPath = `backups/${bundle.bundleId}_${Date.now()}`;\n const logger = this.pluginManager.getLogger();\n try {\n // Create backup directory\n await this.filesystem.mkdir({\n path: backupPath,\n directory: Directory.Data,\n recursive: true,\n });\n // Copy bundle files\n await this.filesystem.copy({\n from: bundle.path,\n to: backupPath,\n directory: Directory.Data,\n });\n logger.info('Backup created', { bundleId: bundle.bundleId, backupPath });\n return backupPath;\n }\n catch (error) {\n logger.error('Failed to create backup', error);\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Failed to create backup', undefined, error);\n }\n }\n /**\n * Perform the actual update\n */\n async performUpdate(bundle) {\n const logger = this.pluginManager.getLogger();\n try {\n // Extract bundle to target location\n const targetPath = `active/${bundle.bundleId}`;\n // Create target directory\n await this.filesystem.mkdir({\n path: targetPath,\n directory: Directory.Data,\n recursive: true,\n });\n // Copy bundle files\n await this.filesystem.copy({\n from: bundle.path,\n to: targetPath,\n directory: Directory.Data,\n });\n // Update bundle path\n bundle.path = targetPath;\n logger.debug('Bundle files installed', {\n bundleId: bundle.bundleId,\n targetPath,\n });\n }\n catch (error) {\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Failed to install bundle files', undefined, error);\n }\n }\n /**\n * Verify update was successful\n */\n async verifyUpdate(bundle) {\n try {\n // Check if main bundle files exist\n const indexPath = `${bundle.path}/index.html`;\n await this.filesystem.stat({\n path: indexPath,\n directory: Directory.Data,\n });\n // Additional verification can be added here\n }\n catch (error) {\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Bundle verification failed after installation', undefined, error);\n }\n }\n /**\n * Rollback to previous state\n */\n async rollback() {\n var _a;\n if (!this.currentState) {\n throw new UpdateError(ErrorCode.ROLLBACK_FAILED, 'No update state to rollback');\n }\n const logger = this.pluginManager.getLogger();\n logger.warn('Starting rollback', {\n from: this.currentState.newBundle.bundleId,\n to: ((_a = this.currentState.currentBundle) === null || _a === void 0 ? void 0 : _a.bundleId) || 'default',\n });\n try {\n const bundleManager = this.pluginManager.getBundleManager();\n // Restore from backup if available\n if (this.currentState.backupPath && this.currentState.currentBundle) {\n const restoredPath = `active/${this.currentState.currentBundle.bundleId}`;\n await this.filesystem.copy({\n from: this.currentState.backupPath,\n to: restoredPath,\n directory: Directory.Data,\n });\n // Update bundle path\n this.currentState.currentBundle.path = restoredPath;\n await bundleManager.saveBundleInfo(this.currentState.currentBundle);\n }\n // Restore active bundle\n if (this.currentState.currentBundle) {\n await bundleManager.setActiveBundle(this.currentState.currentBundle.bundleId);\n }\n else {\n // No previous bundle, clear active\n await bundleManager.clearActiveBundle();\n }\n logger.info('Rollback completed successfully');\n }\n catch (error) {\n logger.error('Rollback failed', error);\n throw new UpdateError(ErrorCode.ROLLBACK_FAILED, 'Failed to rollback update', undefined, error);\n }\n finally {\n // Clean up backup\n if (this.currentState.backupPath) {\n try {\n await this.filesystem.rmdir({\n path: this.currentState.backupPath,\n directory: Directory.Data,\n recursive: true,\n });\n }\n catch (error) {\n logger.warn('Failed to clean up backup', error);\n }\n }\n }\n }\n /**\n * Get current update progress\n */\n getUpdateProgress() {\n var _a, _b;\n return {\n inProgress: this.updateInProgress,\n bundleId: (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.newBundle.bundleId,\n startTime: (_b = this.currentState) === null || _b === void 0 ? void 0 : _b.startTime,\n };\n }\n /**\n * Cancel current update (if possible)\n */\n async cancelUpdate() {\n if (!this.updateInProgress || !this.currentState) {\n return;\n }\n const logger = this.pluginManager.getLogger();\n logger.warn('Cancelling update', {\n bundleId: this.currentState.newBundle.bundleId,\n });\n // Attempt rollback\n await this.rollback();\n this.updateInProgress = false;\n this.currentState = null;\n }\n}\n//# sourceMappingURL=update-manager.js.map"],"names":["BackgroundUpdateType","NotificationPriority","UpdateStrategy","UpdateMode","InstallMode","ChecksumAlgorithm","SyncStatus","BundleStatus","InstallStatus","UpdateErrorCode","LogLevel","ErrorCode","ConfigManager","constructor","this","config","getDefaultConfig","getInstance","instance","filesystem","preferences","baseUrl","allowedHosts","maxBundleSize","downloadTimeout","retryAttempts","retryDelay","enableSignatureValidation","publicKey","cacheExpiration","enableLogging","serverUrl","channel","autoCheck","autoUpdate","updateStrategy","requireSignature","checksumAlgorithm","checkInterval","security","enforceHttps","validateInputs","secureStorage","logSecurityEvents","promptAfterPositiveEvents","maxPromptsPerVersion","minimumDaysSinceLastPrompt","isPremiumUser","appStoreId","iosAppId","packageName","webReviewUrl","minimumVersion","configure","Object","assign","validateConfig","Error","get","key","set","value","getAll","isConfigured","Logger","context","configManager","shouldLog","sanitize","data","sanitized","replace","Array","isArray","map","item","dataObj","toLowerCase","includes","log","message","logWithLevel","INFO","level","timestamp","Date","toISOString","sanitizedData","undefined","logEntry","DEBUG","console","debug","info","WARN","warn","ERROR","error","errorData","name","stack","NativeUpdateError","code","details","originalError","super","setPrototypeOf","prototype","toJSON","DownloadError","ValidationError","StorageError","UpdateError","SecurityValidator","logger","validateUrl","url","URL","protocol","_a","validateChecksum","checksum","test","sanitizeInput","input","validateBundleSize","size","calculateChecksum","hashBuffer","crypto","subtle","digest","from","Uint8Array","b","toString","padStart","join","verifyChecksum","expectedChecksum","actualChecksum","isValid","expected","actual","verifySignature","signature","SIGNATURE_INVALID","cryptoKey","importKey","pemToArrayBuffer","hash","verify","saltLength","base64ToArrayBuffer","pem","base64","binaryString","atob","bytes","length","i","charCodeAt","buffer","sanitizePath","path","split","filter","part","validateBundleId","bundleId","INVALID_BUNDLE_FORMAT","validateVersion","version","isVersionDowngrade","currentVersion","newVersion","current","parseVersion","next","major","minor","patch","parts","parseInt","INVALID_URL","parsedUrl","hostname","UNAUTHORIZED_HOST","some","pattern","validateFileSize","maxSize","BUNDLE_TOO_LARGE","generateSecureId","array","getRandomValues","byte","validateCertificatePin","certificate","certificatePins","hostPins","pin","certificateHash","calculateCertificateHash","sha256","expectedPins","p","actualHash","TextEncoder","encode","hashArray","btoa","String","fromCharCode","validateMetadata","metadata","JSON","stringify","BundleManager","STORAGE_KEY","ACTIVE_BUNDLE_KEY","cache","Map","cacheExpiry","initialize","MISSING_DEPENDENCY","loadCache","now","bundles","parse","clear","forEach","bundle","saveCache","values","count","STORAGE_FULL","saveBundleInfo","validateBundleInfo","getAllBundles","getBundle","deleteBundle","delete","getActiveBundleId","clearActiveBundle","getActiveBundle","activeBundleId","setActiveBundle","FILE_NOT_FOUND","previousActive","status","remove","clearAllBundles","cleanupOldBundles","keepCount","INVALID_CONFIG","sorted","sort","a","downloadTime","toKeep","Set","add","kept","has","deletedCount","deleted","getBundlesOlderThan","markBundleAsVerified","verified","getTotalStorageUsed","reduce","total","isStorageLimitExceeded","additionalSize","createDefaultBundle","cleanExpiredBundles","expirationTime","cutoffTime","expiredBundles","DownloadManager","activeDownloads","download","onProgress","DOWNLOAD_FAILED","abortController","AbortController","downloadState","controller","startTime","timeout","timeoutId","setTimeout","abort","response","fetch","signal","headers","Accept","clearTimeout","ok","statusText","contentType","isValidContentType","contentLength","totalBytes","body","blob","validateBlobSize","reader","getReader","chunks","receivedBytes","done","read","push","percent","Math","round","bytesDownloaded","Blob","duration","isTimeout","DOWNLOAD_TIMEOUT","type","cancelDownload","state","cancelAllDownloads","isDownloading","getActiveDownloadCount","downloadWithRetry","maxRetries","lastError","attempt","delay","min","pow","Promise","resolve","attempts","blobToArrayBuffer","arrayBuffer","saveBlob","writeFile","directory","Directory","Data","recursive","loadBlob","result","readFile","deleteBlob","rmdir","VersionManager","VERSION_CHECK_CACHE_KEY","CACHE_DURATION","memoryCache","securityValidator","compareVersions","version1","version2","v1Base","v1Pre","v2Base","v2Pre","v1Parts","Number","v2Parts","v1Part","v2Part","localeCompare","isValidVersion","shouldUpdate","minAppVersion","checkForUpdates","appId","cacheKey","cached","getCachedVersionInfo","searchParams","append","method","AbortSignal","json","bundleUrl","cacheVersionInfo","latestVersion","updateAvailable","isNewerVersion","v1","v2","prerelease","isUpdateMandatory","match","build","buildVersionString","components","isCompatibleWithNativeVersion","bundleVersion","nativeVersion","compatibility","requiredNativeVersion","memCached","cacheEntry","allCached","clearVersionCache","shouldBlockDowngrade","PluginManager","bundleManager","downloadManager","versionManager","initialized","isInitialized","ensureInitialized","NOT_CONFIGURED","getBundleManager","getDownloadManager","getVersionManager","getConfigManager","getLogger","getSecurityValidator","reset","cleanup","NativeUpdatePluginWeb","pluginManager","options","getSecurityInfo","certificatePinning","enabled","pins","sync","_options","currentBundle","UP_TO_DATE","UNKNOWN_ERROR","bundleInfo","READY","reload","window","location","list","keepVersions","sortedBundles","notifyAppReady","activeBundle","ACTIVE","getLatest","available","setChannel","setUpdateUrl","validateUpdate","ArrayBuffer","checksumValid","signatureValid","sizeValid","versionValid","getAppUpdateInfo","performImmediateUpdate","PLATFORM_NOT_SUPPORTED","startFlexibleUpdate","completeFlexibleUpdate","openAppStore","requestReview","displayed","canRequestReview","canRequest","reason","enableBackgroundUpdates","disableBackgroundUpdates","getBackgroundUpdateStatus","isRunning","checkCount","failureCount","scheduleBackgroundCheck","_interval","triggerBackgroundCheck","success","updatesFound","notificationSent","setNotificationPreferences","prefs","getNotificationPermissions","granted","requestNotificationPermissions","NativeUpdate","registerPlugin","web","CACHE_DIR","mkdir","cleanExpiredCache","ttlMs","expiry","entry","shouldPersist","persistToFile","memEntry","fileEntry","loadFromFile","removeFile","cleanedCount","files","readdir","file","getStats","fileEntries","totalSize","stat","memoryEntries","cacheBundleMetadata","getCachedBundleMetadata","encoding","Encoding","UTF8","deleteFile","updateInProgress","currentState","applyUpdate","UPDATE_FAILED","newBundle","BUNDLE_NOT_READY","backupPath","createBackup","performUpdate","verifyUpdate","keepBundleCount","rollback","allowDowngrade","VERSION_DOWNGRADE","CHECKSUM_MISMATCH","copy","to","targetPath","indexPath","ROLLBACK_FAILED","restoredPath","getUpdateProgress","_b","inProgress","cancelUpdate"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/core/logger.js","esm/core/errors.js","esm/core/config.js","esm/core/security.js","esm/live-update/bundle-manager.js","esm/live-update/download-manager.js","esm/live-update/version-manager.js","esm/core/plugin-manager.js","esm/plugin.js","esm/core/cache-manager.js","esm/live-update/update-manager.js"],"sourcesContent":["// Core plugin interface will be defined later after other interfaces\n/**\n * Enums\n */\nexport var BackgroundUpdateType;\n(function (BackgroundUpdateType) {\n BackgroundUpdateType[\"APP_UPDATE\"] = \"app_update\";\n BackgroundUpdateType[\"LIVE_UPDATE\"] = \"live_update\";\n BackgroundUpdateType[\"BOTH\"] = \"both\";\n})(BackgroundUpdateType || (BackgroundUpdateType = {}));\nexport var NotificationPriority;\n(function (NotificationPriority) {\n NotificationPriority[\"MIN\"] = \"min\";\n NotificationPriority[\"LOW\"] = \"low\";\n NotificationPriority[\"DEFAULT\"] = \"default\";\n NotificationPriority[\"HIGH\"] = \"high\";\n NotificationPriority[\"MAX\"] = \"max\";\n})(NotificationPriority || (NotificationPriority = {}));\nexport var UpdateStrategy;\n(function (UpdateStrategy) {\n UpdateStrategy[\"IMMEDIATE\"] = \"immediate\";\n UpdateStrategy[\"BACKGROUND\"] = \"background\";\n UpdateStrategy[\"MANUAL\"] = \"manual\";\n})(UpdateStrategy || (UpdateStrategy = {}));\nexport var UpdateMode;\n(function (UpdateMode) {\n UpdateMode[\"IMMEDIATE\"] = \"immediate\";\n UpdateMode[\"ON_NEXT_RESTART\"] = \"on_next_restart\";\n UpdateMode[\"ON_NEXT_RESUME\"] = \"on_next_resume\";\n})(UpdateMode || (UpdateMode = {}));\nexport var InstallMode;\n(function (InstallMode) {\n InstallMode[\"IMMEDIATE\"] = \"immediate\";\n InstallMode[\"ON_NEXT_RESTART\"] = \"on_next_restart\";\n InstallMode[\"ON_NEXT_RESUME\"] = \"on_next_resume\";\n})(InstallMode || (InstallMode = {}));\nexport var ChecksumAlgorithm;\n(function (ChecksumAlgorithm) {\n ChecksumAlgorithm[\"SHA256\"] = \"SHA-256\";\n ChecksumAlgorithm[\"SHA512\"] = \"SHA-512\";\n})(ChecksumAlgorithm || (ChecksumAlgorithm = {}));\nexport var SyncStatus;\n(function (SyncStatus) {\n SyncStatus[\"UP_TO_DATE\"] = \"UP_TO_DATE\";\n SyncStatus[\"UPDATE_AVAILABLE\"] = \"UPDATE_AVAILABLE\";\n SyncStatus[\"UPDATE_INSTALLED\"] = \"UPDATE_INSTALLED\";\n SyncStatus[\"ERROR\"] = \"ERROR\";\n})(SyncStatus || (SyncStatus = {}));\nexport var BundleStatus;\n(function (BundleStatus) {\n BundleStatus[\"PENDING\"] = \"PENDING\";\n BundleStatus[\"DOWNLOADING\"] = \"DOWNLOADING\";\n BundleStatus[\"READY\"] = \"READY\";\n BundleStatus[\"ACTIVE\"] = \"ACTIVE\";\n BundleStatus[\"FAILED\"] = \"FAILED\";\n})(BundleStatus || (BundleStatus = {}));\nexport var InstallStatus;\n(function (InstallStatus) {\n InstallStatus[\"UNKNOWN\"] = \"UNKNOWN\";\n InstallStatus[\"PENDING\"] = \"PENDING\";\n InstallStatus[\"DOWNLOADING\"] = \"DOWNLOADING\";\n InstallStatus[\"DOWNLOADED\"] = \"DOWNLOADED\";\n InstallStatus[\"INSTALLING\"] = \"INSTALLING\";\n InstallStatus[\"INSTALLED\"] = \"INSTALLED\";\n InstallStatus[\"FAILED\"] = \"FAILED\";\n InstallStatus[\"CANCELED\"] = \"CANCELED\";\n})(InstallStatus || (InstallStatus = {}));\nexport var UpdateErrorCode;\n(function (UpdateErrorCode) {\n // Network errors\n UpdateErrorCode[\"NETWORK_ERROR\"] = \"NETWORK_ERROR\";\n UpdateErrorCode[\"SERVER_ERROR\"] = \"SERVER_ERROR\";\n UpdateErrorCode[\"TIMEOUT_ERROR\"] = \"TIMEOUT_ERROR\";\n // Download errors\n UpdateErrorCode[\"DOWNLOAD_ERROR\"] = \"DOWNLOAD_ERROR\";\n UpdateErrorCode[\"STORAGE_ERROR\"] = \"STORAGE_ERROR\";\n UpdateErrorCode[\"SIZE_LIMIT_EXCEEDED\"] = \"SIZE_LIMIT_EXCEEDED\";\n // Security errors\n UpdateErrorCode[\"VERIFICATION_ERROR\"] = \"VERIFICATION_ERROR\";\n UpdateErrorCode[\"CHECKSUM_ERROR\"] = \"CHECKSUM_ERROR\";\n UpdateErrorCode[\"SIGNATURE_ERROR\"] = \"SIGNATURE_ERROR\";\n UpdateErrorCode[\"INSECURE_URL\"] = \"INSECURE_URL\";\n UpdateErrorCode[\"INVALID_CERTIFICATE\"] = \"INVALID_CERTIFICATE\";\n UpdateErrorCode[\"PATH_TRAVERSAL\"] = \"PATH_TRAVERSAL\";\n // Installation errors\n UpdateErrorCode[\"INSTALL_ERROR\"] = \"INSTALL_ERROR\";\n UpdateErrorCode[\"ROLLBACK_ERROR\"] = \"ROLLBACK_ERROR\";\n UpdateErrorCode[\"VERSION_MISMATCH\"] = \"VERSION_MISMATCH\";\n // Permission errors\n UpdateErrorCode[\"PERMISSION_DENIED\"] = \"PERMISSION_DENIED\";\n // App update errors\n UpdateErrorCode[\"UPDATE_NOT_AVAILABLE\"] = \"UPDATE_NOT_AVAILABLE\";\n UpdateErrorCode[\"UPDATE_IN_PROGRESS\"] = \"UPDATE_IN_PROGRESS\";\n UpdateErrorCode[\"UPDATE_CANCELLED\"] = \"UPDATE_CANCELLED\";\n UpdateErrorCode[\"PLATFORM_NOT_SUPPORTED\"] = \"PLATFORM_NOT_SUPPORTED\";\n // Review errors\n UpdateErrorCode[\"REVIEW_NOT_SUPPORTED\"] = \"REVIEW_NOT_SUPPORTED\";\n UpdateErrorCode[\"QUOTA_EXCEEDED\"] = \"QUOTA_EXCEEDED\";\n UpdateErrorCode[\"CONDITIONS_NOT_MET\"] = \"CONDITIONS_NOT_MET\";\n // General errors\n UpdateErrorCode[\"INVALID_CONFIG\"] = \"INVALID_CONFIG\";\n UpdateErrorCode[\"UNKNOWN_ERROR\"] = \"UNKNOWN_ERROR\";\n})(UpdateErrorCode || (UpdateErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { ConfigManager } from './config';\nexport var LogLevel;\n(function (LogLevel) {\n LogLevel[LogLevel[\"DEBUG\"] = 0] = \"DEBUG\";\n LogLevel[LogLevel[\"INFO\"] = 1] = \"INFO\";\n LogLevel[LogLevel[\"WARN\"] = 2] = \"WARN\";\n LogLevel[LogLevel[\"ERROR\"] = 3] = \"ERROR\";\n})(LogLevel || (LogLevel = {}));\nexport class Logger {\n constructor(context) {\n this.configManager = ConfigManager.getInstance();\n this.context = context || 'NativeUpdate';\n }\n static getInstance() {\n if (!Logger.instance) {\n Logger.instance = new Logger();\n }\n return Logger.instance;\n }\n shouldLog() {\n return this.configManager.get('enableLogging');\n }\n sanitize(data) {\n if (typeof data === 'string') {\n let sanitized = data;\n // Remove potential file paths\n sanitized = sanitized.replace(/\\/[^\\s]+\\/([\\w.-]+)$/g, '/<path>/$1');\n // Remove potential URLs with credentials\n sanitized = sanitized.replace(/https?:\\/\\/[^:]+:[^@]+@/g, 'https://***:***@');\n // Remove potential API keys\n sanitized = sanitized.replace(/[a-zA-Z0-9]{32,}/g, '<redacted>');\n return sanitized;\n }\n else if (typeof data === 'object' && data !== null) {\n if (Array.isArray(data)) {\n return data.map((item) => this.sanitize(item));\n }\n else {\n const sanitized = {};\n const dataObj = data;\n for (const key in dataObj) {\n if (key.toLowerCase().includes('key') ||\n key.toLowerCase().includes('secret') ||\n key.toLowerCase().includes('password') ||\n key.toLowerCase().includes('token')) {\n sanitized[key] = '<redacted>';\n }\n else {\n sanitized[key] = this.sanitize(dataObj[key]);\n }\n }\n return sanitized;\n }\n }\n return data;\n }\n log(message, data) {\n this.logWithLevel(LogLevel.INFO, message, data);\n }\n logWithLevel(level, message, data) {\n if (!this.shouldLog())\n return;\n const timestamp = new Date().toISOString();\n const sanitizedData = data ? this.sanitize(data) : undefined;\n const logEntry = {\n timestamp,\n level: LogLevel[level],\n context: this.context,\n message,\n };\n if (sanitizedData !== undefined) {\n logEntry.data = sanitizedData;\n }\n switch (level) {\n case LogLevel.DEBUG:\n console.debug(`[${this.context}]`, logEntry);\n break;\n case LogLevel.INFO:\n console.info(`[${this.context}]`, logEntry);\n break;\n case LogLevel.WARN:\n console.warn(`[${this.context}]`, logEntry);\n break;\n case LogLevel.ERROR:\n console.error(`[${this.context}]`, logEntry);\n break;\n }\n }\n debug(message, data) {\n this.logWithLevel(LogLevel.DEBUG, message, data);\n }\n info(message, data) {\n this.logWithLevel(LogLevel.INFO, message, data);\n }\n warn(message, data) {\n this.logWithLevel(LogLevel.WARN, message, data);\n }\n error(message, error) {\n const errorData = error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error;\n this.logWithLevel(LogLevel.ERROR, message, errorData);\n }\n}\n//# sourceMappingURL=logger.js.map","export var ErrorCode;\n(function (ErrorCode) {\n // Configuration errors\n ErrorCode[\"NOT_CONFIGURED\"] = \"NOT_CONFIGURED\";\n ErrorCode[\"INVALID_CONFIG\"] = \"INVALID_CONFIG\";\n ErrorCode[\"MISSING_DEPENDENCY\"] = \"MISSING_DEPENDENCY\";\n // Download errors\n ErrorCode[\"DOWNLOAD_FAILED\"] = \"DOWNLOAD_FAILED\";\n ErrorCode[\"DOWNLOAD_TIMEOUT\"] = \"DOWNLOAD_TIMEOUT\";\n ErrorCode[\"INVALID_URL\"] = \"INVALID_URL\";\n ErrorCode[\"UNAUTHORIZED_HOST\"] = \"UNAUTHORIZED_HOST\";\n ErrorCode[\"BUNDLE_TOO_LARGE\"] = \"BUNDLE_TOO_LARGE\";\n // Validation errors\n ErrorCode[\"CHECKSUM_MISMATCH\"] = \"CHECKSUM_MISMATCH\";\n ErrorCode[\"SIGNATURE_INVALID\"] = \"SIGNATURE_INVALID\";\n ErrorCode[\"VERSION_DOWNGRADE\"] = \"VERSION_DOWNGRADE\";\n ErrorCode[\"INVALID_BUNDLE_FORMAT\"] = \"INVALID_BUNDLE_FORMAT\";\n // Storage errors\n ErrorCode[\"STORAGE_FULL\"] = \"STORAGE_FULL\";\n ErrorCode[\"FILE_NOT_FOUND\"] = \"FILE_NOT_FOUND\";\n ErrorCode[\"PERMISSION_DENIED\"] = \"PERMISSION_DENIED\";\n // Update errors\n ErrorCode[\"UPDATE_FAILED\"] = \"UPDATE_FAILED\";\n ErrorCode[\"ROLLBACK_FAILED\"] = \"ROLLBACK_FAILED\";\n ErrorCode[\"BUNDLE_NOT_READY\"] = \"BUNDLE_NOT_READY\";\n // Platform errors\n ErrorCode[\"PLATFORM_NOT_SUPPORTED\"] = \"PLATFORM_NOT_SUPPORTED\";\n ErrorCode[\"NATIVE_ERROR\"] = \"NATIVE_ERROR\";\n})(ErrorCode || (ErrorCode = {}));\nexport class NativeUpdateError extends Error {\n constructor(code, message, details, originalError) {\n super(message);\n this.code = code;\n this.message = message;\n this.details = details;\n this.originalError = originalError;\n this.name = 'NativeUpdateError';\n Object.setPrototypeOf(this, NativeUpdateError.prototype);\n }\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n details: this.details,\n stack: this.stack,\n };\n }\n}\nexport class ConfigurationError extends NativeUpdateError {\n constructor(message, details) {\n super(ErrorCode.INVALID_CONFIG, message, details);\n this.name = 'ConfigurationError';\n }\n}\nexport class DownloadError extends NativeUpdateError {\n constructor(code, message, details, originalError) {\n super(code, message, details, originalError);\n this.name = 'DownloadError';\n }\n}\nexport class ValidationError extends NativeUpdateError {\n constructor(code, message, details) {\n super(code, message, details);\n this.name = 'ValidationError';\n }\n}\nexport class StorageError extends NativeUpdateError {\n constructor(code, message, details, originalError) {\n super(code, message, details, originalError);\n this.name = 'StorageError';\n }\n}\nexport class UpdateError extends NativeUpdateError {\n constructor(code, message, details, originalError) {\n super(code, message, details, originalError);\n this.name = 'UpdateError';\n }\n}\n//# sourceMappingURL=errors.js.map","export class ConfigManager {\n constructor() {\n this.config = this.getDefaultConfig();\n }\n static getInstance() {\n if (!ConfigManager.instance) {\n ConfigManager.instance = new ConfigManager();\n }\n return ConfigManager.instance;\n }\n getDefaultConfig() {\n return {\n filesystem: null,\n preferences: null,\n baseUrl: '',\n allowedHosts: [],\n maxBundleSize: 100 * 1024 * 1024, // 100MB\n downloadTimeout: 30000, // 30 seconds\n retryAttempts: 3,\n retryDelay: 1000, // 1 second\n enableSignatureValidation: true,\n publicKey: '',\n cacheExpiration: 24 * 60 * 60 * 1000, // 24 hours\n enableLogging: false,\n serverUrl: '',\n channel: 'production',\n autoCheck: true,\n autoUpdate: false,\n updateStrategy: 'background',\n requireSignature: true,\n checksumAlgorithm: 'SHA-256',\n checkInterval: 24 * 60 * 60 * 1000, // 24 hours\n security: {\n enforceHttps: true,\n validateInputs: true,\n secureStorage: true,\n logSecurityEvents: false,\n },\n // App review config\n promptAfterPositiveEvents: false,\n maxPromptsPerVersion: 1,\n minimumDaysSinceLastPrompt: 7,\n isPremiumUser: false,\n // Platform-specific config\n appStoreId: '',\n iosAppId: '',\n packageName: '',\n webReviewUrl: '',\n minimumVersion: '1.0.0',\n };\n }\n configure(config) {\n this.config = Object.assign(Object.assign({}, this.config), config);\n this.validateConfig();\n }\n validateConfig() {\n if (this.config.maxBundleSize <= 0) {\n throw new Error('maxBundleSize must be greater than 0');\n }\n if (this.config.downloadTimeout <= 0) {\n throw new Error('downloadTimeout must be greater than 0');\n }\n if (this.config.retryAttempts < 0) {\n throw new Error('retryAttempts must be non-negative');\n }\n if (this.config.retryDelay < 0) {\n throw new Error('retryDelay must be non-negative');\n }\n }\n get(key) {\n return this.config[key];\n }\n set(key, value) {\n this.config[key] = value;\n }\n getAll() {\n return Object.assign({}, this.config);\n }\n isConfigured() {\n return !!(this.config.filesystem && this.config.preferences);\n }\n}\n//# sourceMappingURL=config.js.map","import { ConfigManager } from './config';\nimport { ValidationError, ErrorCode } from './errors';\nimport { Logger } from './logger';\nexport class SecurityValidator {\n constructor() {\n this.configManager = ConfigManager.getInstance();\n this.logger = Logger.getInstance();\n }\n static getInstance() {\n if (!SecurityValidator.instance) {\n SecurityValidator.instance = new SecurityValidator();\n }\n return SecurityValidator.instance;\n }\n /**\n * Validate URL is HTTPS\n */\n static validateUrl(url) {\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'https:';\n }\n catch (_a) {\n return false;\n }\n }\n /**\n * Validate checksum format\n */\n static validateChecksum(checksum) {\n return /^[a-f0-9]{64}$/i.test(checksum);\n }\n /**\n * Sanitize input string\n */\n static sanitizeInput(input) {\n if (!input)\n return '';\n return input.replace(/<[^>]*>/g, '').replace(/[^\\w\\s/.-]/g, '');\n }\n /**\n * Validate bundle size\n */\n static validateBundleSize(size) {\n const MAX_SIZE = 100 * 1024 * 1024; // 100MB\n return size > 0 && size <= MAX_SIZE;\n }\n /**\n * Calculate SHA-256 checksum of data\n */\n async calculateChecksum(data) {\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n }\n /**\n * Verify checksum matches expected value\n */\n async verifyChecksum(data, expectedChecksum) {\n if (!expectedChecksum) {\n this.logger.warn('No checksum provided for verification');\n return true; // Allow if no checksum provided\n }\n const actualChecksum = await this.calculateChecksum(data);\n const isValid = actualChecksum === expectedChecksum.toLowerCase();\n if (!isValid) {\n this.logger.error('Checksum verification failed', {\n expected: expectedChecksum,\n actual: actualChecksum,\n });\n }\n return isValid;\n }\n /**\n * Alias for verifyChecksum for backward compatibility\n */\n async validateChecksum(data, expectedChecksum) {\n return this.verifyChecksum(data, expectedChecksum);\n }\n /**\n * Verify digital signature using Web Crypto API\n */\n async verifySignature(data, signature) {\n if (!this.configManager.get('enableSignatureValidation')) {\n return true;\n }\n const publicKey = this.configManager.get('publicKey');\n if (!publicKey) {\n throw new ValidationError(ErrorCode.SIGNATURE_INVALID, 'Public key not configured for signature validation');\n }\n try {\n // Import public key\n const cryptoKey = await crypto.subtle.importKey('spki', this.pemToArrayBuffer(publicKey), {\n name: 'RSA-PSS',\n hash: 'SHA-256',\n }, false, ['verify']);\n // Verify signature\n const isValid = await crypto.subtle.verify({\n name: 'RSA-PSS',\n saltLength: 32,\n }, cryptoKey, this.base64ToArrayBuffer(signature), data);\n if (!isValid) {\n this.logger.error('Signature verification failed');\n }\n return isValid;\n }\n catch (error) {\n this.logger.error('Signature verification error', error);\n return false;\n }\n }\n /**\n * Convert PEM to ArrayBuffer\n */\n pemToArrayBuffer(pem) {\n const base64 = pem\n .replace(/-----BEGIN PUBLIC KEY-----/g, '')\n .replace(/-----END PUBLIC KEY-----/g, '')\n .replace(/\\s/g, '');\n return this.base64ToArrayBuffer(base64);\n }\n /**\n * Convert base64 to ArrayBuffer\n */\n base64ToArrayBuffer(base64) {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n }\n /**\n * Sanitize file path to prevent directory traversal\n */\n sanitizePath(path) {\n // Remove any parent directory references\n const sanitized = path\n .split('/')\n .filter((part) => part !== '..' && part !== '.')\n .join('/');\n // Ensure path doesn't start with /\n return sanitized.replace(/^\\/+/, '');\n }\n /**\n * Validate bundle ID format\n */\n validateBundleId(bundleId) {\n if (!bundleId || typeof bundleId !== 'string') {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID must be a non-empty string');\n }\n // Allow alphanumeric, hyphens, underscores, and dots\n const validPattern = /^[a-zA-Z0-9\\-_.]+$/;\n if (!validPattern.test(bundleId)) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID contains invalid characters');\n }\n if (bundleId.length > 100) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is too long (max 100 characters)');\n }\n }\n /**\n * Validate semantic version format\n */\n validateVersion(version) {\n if (!version || typeof version !== 'string') {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Version must be a non-empty string');\n }\n // Basic semantic versioning pattern\n const semverPattern = /^(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-]+)*))?$/;\n if (!semverPattern.test(version)) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Version must follow semantic versioning format (e.g., 1.2.3)');\n }\n }\n /**\n * Check if version is a downgrade\n */\n isVersionDowngrade(currentVersion, newVersion) {\n const current = this.parseVersion(currentVersion);\n const next = this.parseVersion(newVersion);\n if (next.major < current.major)\n return true;\n if (next.major > current.major)\n return false;\n if (next.minor < current.minor)\n return true;\n if (next.minor > current.minor)\n return false;\n return next.patch < current.patch;\n }\n /**\n * Parse semantic version\n */\n parseVersion(version) {\n const parts = version.split('-')[0].split('.'); // Ignore pre-release\n return {\n major: parseInt(parts[0], 10) || 0,\n minor: parseInt(parts[1], 10) || 0,\n patch: parseInt(parts[2], 10) || 0,\n };\n }\n /**\n * Validate URL format and security\n */\n validateUrl(url) {\n if (!url || typeof url !== 'string') {\n throw new ValidationError(ErrorCode.INVALID_URL, 'URL must be a non-empty string');\n }\n let parsedUrl;\n try {\n parsedUrl = new URL(url);\n }\n catch (_a) {\n throw new ValidationError(ErrorCode.INVALID_URL, 'Invalid URL format');\n }\n // Enforce HTTPS\n if (parsedUrl.protocol !== 'https:') {\n throw new ValidationError(ErrorCode.INVALID_URL, 'Only HTTPS URLs are allowed');\n }\n // Check against allowed hosts\n const allowedHosts = this.configManager.get('allowedHosts');\n if (allowedHosts.length > 0 && !allowedHosts.includes(parsedUrl.hostname)) {\n throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, `Host ${parsedUrl.hostname} is not in the allowed hosts list`);\n }\n // Prevent localhost/private IPs in production\n const privatePatterns = [\n /^localhost$/i,\n /^127\\./,\n /^10\\./,\n /^172\\.(1[6-9]|2[0-9]|3[0-1])\\./,\n /^192\\.168\\./,\n /^::1$/,\n /^fc00:/i,\n /^fe80:/i,\n ];\n if (privatePatterns.some((pattern) => pattern.test(parsedUrl.hostname))) {\n throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, 'Private/local addresses are not allowed');\n }\n }\n /**\n * Validate file size\n */\n validateFileSize(size) {\n if (typeof size !== 'number' || size < 0) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'File size must be a non-negative number');\n }\n const maxSize = this.configManager.get('maxBundleSize');\n if (size > maxSize) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `File size ${size} exceeds maximum allowed size of ${maxSize} bytes`);\n }\n }\n /**\n * Generate a secure random ID\n */\n generateSecureId() {\n const array = new Uint8Array(16);\n crypto.getRandomValues(array);\n return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');\n }\n /**\n * Validate certificate pinning for HTTPS connections\n * Note: This is a placeholder for web implementation as certificate pinning\n * is primarily implemented at the native layer\n */\n async validateCertificatePin(hostname, certificate) {\n // Certificate pinning is not available in PluginConfig type\n const certificatePins = this.configManager.certificatePins;\n if (!certificatePins ||\n !Array.isArray(certificatePins) ||\n certificatePins.length === 0) {\n // No pins configured, allow connection\n return true;\n }\n const hostPins = certificatePins.filter((pin) => pin.hostname === hostname);\n if (hostPins.length === 0) {\n // No pins for this host, allow connection\n return true;\n }\n // Check if certificate matches any of the pins\n const certificateHash = await this.calculateCertificateHash(certificate);\n const isValid = hostPins.some((pin) => pin.sha256 === certificateHash);\n if (!isValid) {\n this.logger.error('Certificate pinning validation failed', {\n hostname,\n expectedPins: hostPins.map((p) => p.sha256),\n actualHash: certificateHash,\n });\n }\n return isValid;\n }\n /**\n * Calculate SHA-256 hash of certificate\n */\n async calculateCertificateHash(certificate) {\n const encoder = new TextEncoder();\n const data = encoder.encode(certificate);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return 'sha256/' + btoa(String.fromCharCode(...hashArray));\n }\n /**\n * Validate metadata object\n */\n validateMetadata(metadata) {\n if (metadata && typeof metadata !== 'object') {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Metadata must be an object');\n }\n // Limit metadata size to prevent abuse\n const metadataStr = JSON.stringify(metadata || {});\n if (metadataStr.length > 10240) {\n // 10KB limit\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Metadata is too large (max 10KB)');\n }\n }\n}\n//# sourceMappingURL=security.js.map","import { ConfigManager } from '../core/config';\nimport { Logger } from '../core/logger';\nimport { StorageError, ErrorCode } from '../core/errors';\n/**\n * Manages bundle storage and lifecycle\n */\nexport class BundleManager {\n constructor() {\n this.STORAGE_KEY = 'capacitor_native_update_bundles';\n this.ACTIVE_BUNDLE_KEY = 'capacitor_native_update_active';\n this.preferences = null;\n this.cache = new Map();\n this.cacheExpiry = 0;\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n }\n /**\n * Initialize the bundle manager with preferences\n */\n async initialize() {\n this.preferences = this.configManager.get('preferences');\n if (!this.preferences) {\n throw new StorageError(ErrorCode.MISSING_DEPENDENCY, 'Preferences not configured. Please configure the plugin first.');\n }\n await this.loadCache();\n }\n /**\n * Load cache from preferences\n */\n async loadCache() {\n if (Date.now() < this.cacheExpiry) {\n return; // Cache still valid\n }\n try {\n const { value } = await this.preferences.get({ key: this.STORAGE_KEY });\n if (value) {\n const bundles = JSON.parse(value);\n this.cache.clear();\n bundles.forEach((bundle) => this.cache.set(bundle.bundleId, bundle));\n }\n this.cacheExpiry = Date.now() + 5000; // 5 second cache\n }\n catch (error) {\n this.logger.error('Failed to load bundles from storage', error);\n this.cache.clear();\n }\n }\n /**\n * Save cache to preferences\n */\n async saveCache() {\n try {\n const bundles = Array.from(this.cache.values());\n await this.preferences.set({\n key: this.STORAGE_KEY,\n value: JSON.stringify(bundles),\n });\n this.logger.debug('Saved bundles to storage', { count: bundles.length });\n }\n catch (error) {\n throw new StorageError(ErrorCode.STORAGE_FULL, 'Failed to save bundles to storage', undefined, error);\n }\n }\n /**\n * Save bundle information\n */\n async saveBundleInfo(bundle) {\n this.validateBundleInfo(bundle);\n this.cache.set(bundle.bundleId, bundle);\n await this.saveCache();\n this.logger.info('Bundle saved', {\n bundleId: bundle.bundleId,\n version: bundle.version,\n });\n }\n /**\n * Validate bundle information\n */\n validateBundleInfo(bundle) {\n if (!bundle.bundleId || typeof bundle.bundleId !== 'string') {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle ID');\n }\n if (!bundle.version || typeof bundle.version !== 'string') {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle version');\n }\n if (!bundle.path || typeof bundle.path !== 'string') {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle path');\n }\n if (typeof bundle.size !== 'number' || bundle.size < 0) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid bundle size');\n }\n }\n /**\n * Get all bundles\n */\n async getAllBundles() {\n await this.loadCache();\n return Array.from(this.cache.values());\n }\n /**\n * Get bundle by ID\n */\n async getBundle(bundleId) {\n if (!bundleId) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n await this.loadCache();\n return this.cache.get(bundleId) || null;\n }\n /**\n * Delete bundle\n */\n async deleteBundle(bundleId) {\n if (!bundleId) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n await this.loadCache();\n const bundle = this.cache.get(bundleId);\n if (!bundle) {\n this.logger.warn('Attempted to delete non-existent bundle', { bundleId });\n return;\n }\n this.cache.delete(bundleId);\n await this.saveCache();\n // If this was the active bundle, clear it\n const activeBundleId = await this.getActiveBundleId();\n if (activeBundleId === bundleId) {\n await this.clearActiveBundle();\n }\n this.logger.info('Bundle deleted', { bundleId });\n }\n /**\n * Get active bundle\n */\n async getActiveBundle() {\n const activeBundleId = await this.getActiveBundleId();\n if (!activeBundleId)\n return null;\n return this.getBundle(activeBundleId);\n }\n /**\n * Set active bundle\n */\n async setActiveBundle(bundleId) {\n if (!bundleId) {\n throw new StorageError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n const bundle = await this.getBundle(bundleId);\n if (!bundle) {\n throw new StorageError(ErrorCode.FILE_NOT_FOUND, `Bundle ${bundleId} not found`);\n }\n // Update previous active bundle status\n const previousActive = await this.getActiveBundle();\n if (previousActive && previousActive.bundleId !== bundleId) {\n previousActive.status = 'READY';\n await this.saveBundleInfo(previousActive);\n }\n // Set new active bundle\n bundle.status = 'ACTIVE';\n await this.saveBundleInfo(bundle);\n await this.preferences.set({\n key: this.ACTIVE_BUNDLE_KEY,\n value: bundleId,\n });\n this.logger.info('Active bundle set', {\n bundleId,\n version: bundle.version,\n });\n }\n /**\n * Get active bundle ID\n */\n async getActiveBundleId() {\n try {\n const { value } = await this.preferences.get({\n key: this.ACTIVE_BUNDLE_KEY,\n });\n return value;\n }\n catch (error) {\n this.logger.error('Failed to get active bundle ID', error);\n return null;\n }\n }\n /**\n * Clear active bundle\n */\n async clearActiveBundle() {\n await this.preferences.remove({ key: this.ACTIVE_BUNDLE_KEY });\n this.logger.info('Active bundle cleared');\n }\n /**\n * Clear all bundles\n */\n async clearAllBundles() {\n await this.preferences.remove({ key: this.STORAGE_KEY });\n await this.preferences.remove({ key: this.ACTIVE_BUNDLE_KEY });\n this.cache.clear();\n this.cacheExpiry = 0;\n this.logger.info('All bundles cleared');\n }\n /**\n * Clean up old bundles\n */\n async cleanupOldBundles(keepCount) {\n if (keepCount < 1) {\n throw new StorageError(ErrorCode.INVALID_CONFIG, 'Keep count must be at least 1');\n }\n const bundles = await this.getAllBundles();\n const activeBundleId = await this.getActiveBundleId();\n // Sort by download time (newest first)\n const sorted = bundles.sort((a, b) => b.downloadTime - a.downloadTime);\n // Keep the active bundle and the most recent ones\n const toKeep = new Set();\n if (activeBundleId) {\n toKeep.add(activeBundleId);\n }\n let kept = toKeep.size;\n for (const bundle of sorted) {\n if (kept >= keepCount)\n break;\n if (!toKeep.has(bundle.bundleId)) {\n toKeep.add(bundle.bundleId);\n kept++;\n }\n }\n // Delete bundles not in the keep set\n let deletedCount = 0;\n for (const bundle of bundles) {\n if (!toKeep.has(bundle.bundleId)) {\n await this.deleteBundle(bundle.bundleId);\n deletedCount++;\n }\n }\n if (deletedCount > 0) {\n this.logger.info('Cleaned up old bundles', {\n deleted: deletedCount,\n kept,\n });\n }\n }\n /**\n * Get bundles older than specified time\n */\n async getBundlesOlderThan(timestamp) {\n if (timestamp < 0) {\n throw new StorageError(ErrorCode.INVALID_CONFIG, 'Timestamp must be non-negative');\n }\n const bundles = await this.getAllBundles();\n return bundles.filter((b) => b.downloadTime < timestamp);\n }\n /**\n * Mark bundle as verified\n */\n async markBundleAsVerified(bundleId) {\n const bundle = await this.getBundle(bundleId);\n if (!bundle) {\n throw new StorageError(ErrorCode.FILE_NOT_FOUND, `Bundle ${bundleId} not found`);\n }\n bundle.verified = true;\n await this.saveBundleInfo(bundle);\n this.logger.info('Bundle marked as verified', { bundleId });\n }\n /**\n * Get total storage used by bundles\n */\n async getTotalStorageUsed() {\n const bundles = await this.getAllBundles();\n return bundles.reduce((total, bundle) => total + bundle.size, 0);\n }\n /**\n * Check if storage limit is exceeded\n */\n async isStorageLimitExceeded(additionalSize = 0) {\n const totalUsed = await this.getTotalStorageUsed();\n const maxStorage = this.configManager.get('maxBundleSize') * 3; // Allow 3x max bundle size\n return totalUsed + additionalSize > maxStorage;\n }\n /**\n * Create default bundle\n */\n createDefaultBundle() {\n return {\n bundleId: 'default',\n version: '1.0.0',\n path: '/',\n downloadTime: Date.now(),\n size: 0,\n status: 'ACTIVE',\n checksum: '',\n verified: true,\n };\n }\n /**\n * Clean expired cache entries\n */\n async cleanExpiredBundles() {\n const expirationTime = this.configManager.get('cacheExpiration');\n const cutoffTime = Date.now() - expirationTime;\n const expiredBundles = await this.getBundlesOlderThan(cutoffTime);\n for (const bundle of expiredBundles) {\n // Don't delete active bundle\n const activeBundleId = await this.getActiveBundleId();\n if (bundle.bundleId !== activeBundleId) {\n await this.deleteBundle(bundle.bundleId);\n }\n }\n }\n}\n//# sourceMappingURL=bundle-manager.js.map","import { ConfigManager } from '../core/config';\nimport { Logger } from '../core/logger';\nimport { DownloadError, ErrorCode, ValidationError } from '../core/errors';\nimport { Directory } from '@capacitor/filesystem';\n/**\n * Manages file downloads with progress tracking and resume capability\n */\nexport class DownloadManager {\n constructor() {\n this.activeDownloads = new Map();\n this.filesystem = null;\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n }\n /**\n * Initialize the download manager\n */\n async initialize() {\n this.filesystem = this.configManager.get('filesystem');\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not configured. Please configure the plugin first.');\n }\n }\n /**\n * Validate URL against allowed hosts\n */\n validateUrl(url) {\n try {\n const parsedUrl = new URL(url);\n // Ensure HTTPS\n if (parsedUrl.protocol !== 'https:') {\n throw new ValidationError(ErrorCode.INVALID_URL, 'Only HTTPS URLs are allowed for security reasons');\n }\n // Check against allowed hosts if configured\n const allowedHosts = this.configManager.get('allowedHosts');\n if (allowedHosts.length > 0 &&\n !allowedHosts.includes(parsedUrl.hostname)) {\n throw new ValidationError(ErrorCode.UNAUTHORIZED_HOST, `Host ${parsedUrl.hostname} is not in the allowed hosts list`);\n }\n }\n catch (error) {\n if (error instanceof ValidationError)\n throw error;\n throw new ValidationError(ErrorCode.INVALID_URL, 'Invalid URL format');\n }\n }\n /**\n * Download a file with progress tracking\n */\n async download(url, bundleId, onProgress) {\n // Validate inputs\n this.validateUrl(url);\n if (!bundleId) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Bundle ID is required');\n }\n // Check if already downloading\n if (this.activeDownloads.has(bundleId)) {\n throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, `Download already in progress for bundle ${bundleId}`);\n }\n // Create abort controller for this download\n const abortController = new AbortController();\n const downloadState = {\n controller: abortController,\n startTime: Date.now(),\n };\n this.activeDownloads.set(bundleId, downloadState);\n try {\n const timeout = this.configManager.get('downloadTimeout');\n const timeoutId = setTimeout(() => abortController.abort(), timeout);\n const response = await fetch(url, {\n signal: abortController.signal,\n headers: {\n 'Cache-Control': 'no-cache',\n Accept: 'application/octet-stream, application/zip',\n },\n });\n clearTimeout(timeoutId);\n if (!response.ok) {\n throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, `Download failed: ${response.status} ${response.statusText}`, { status: response.status, statusText: response.statusText });\n }\n // Validate content type\n const contentType = response.headers.get('content-type');\n if (contentType && !this.isValidContentType(contentType)) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, `Invalid content type: ${contentType}`);\n }\n // Get total size from headers\n const contentLength = response.headers.get('content-length');\n const totalBytes = contentLength ? parseInt(contentLength, 10) : 0;\n // Check size limit\n if (totalBytes > this.configManager.get('maxBundleSize')) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `Bundle size ${totalBytes} exceeds maximum allowed size`);\n }\n // If no content length, fall back to simple download\n if (!totalBytes || !response.body) {\n const blob = await response.blob();\n this.validateBlobSize(blob);\n return blob;\n }\n // Stream the response with progress tracking\n const reader = response.body.getReader();\n const chunks = [];\n let receivedBytes = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done)\n break;\n chunks.push(value);\n receivedBytes += value.length;\n // Check if size exceeds limit during download\n if (receivedBytes > this.configManager.get('maxBundleSize')) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `Download size exceeds maximum allowed size`);\n }\n // Report progress\n if (onProgress) {\n const percent = Math.round((receivedBytes / totalBytes) * 100);\n onProgress({\n percent,\n bytesDownloaded: receivedBytes,\n totalBytes,\n bundleId,\n });\n }\n }\n // Combine chunks into a single blob\n const blob = new Blob(chunks);\n this.validateBlobSize(blob);\n this.logger.info('Download completed', {\n bundleId,\n size: blob.size,\n duration: Date.now() - downloadState.startTime,\n });\n return blob;\n }\n catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n const isTimeout = Date.now() - downloadState.startTime >=\n this.configManager.get('downloadTimeout');\n throw new DownloadError(isTimeout ? ErrorCode.DOWNLOAD_TIMEOUT : ErrorCode.DOWNLOAD_FAILED, isTimeout ? 'Download timed out' : 'Download cancelled', undefined, error);\n }\n throw error;\n }\n finally {\n // Clean up\n this.activeDownloads.delete(bundleId);\n }\n }\n /**\n * Validate content type\n */\n isValidContentType(contentType) {\n const validTypes = [\n 'application/octet-stream',\n 'application/zip',\n 'application/x-zip-compressed',\n 'application/x-zip',\n ];\n return validTypes.some((type) => contentType.includes(type));\n }\n /**\n * Validate blob size\n */\n validateBlobSize(blob) {\n if (blob.size === 0) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Downloaded file is empty');\n }\n if (blob.size > this.configManager.get('maxBundleSize')) {\n throw new ValidationError(ErrorCode.BUNDLE_TOO_LARGE, `File size ${blob.size} exceeds maximum allowed size`);\n }\n }\n /**\n * Cancel a download\n */\n cancelDownload(bundleId) {\n const state = this.activeDownloads.get(bundleId);\n if (state) {\n state.controller.abort();\n this.activeDownloads.delete(bundleId);\n this.logger.info('Download cancelled', { bundleId });\n }\n }\n /**\n * Cancel all active downloads\n */\n cancelAllDownloads() {\n for (const state of this.activeDownloads.values()) {\n state.controller.abort();\n }\n const count = this.activeDownloads.size;\n this.activeDownloads.clear();\n if (count > 0) {\n this.logger.info('All downloads cancelled', { count });\n }\n }\n /**\n * Check if a download is active\n */\n isDownloading(bundleId) {\n return this.activeDownloads.has(bundleId);\n }\n /**\n * Get active download count\n */\n getActiveDownloadCount() {\n return this.activeDownloads.size;\n }\n /**\n * Download with retry logic\n */\n async downloadWithRetry(url, bundleId, onProgress) {\n const maxRetries = this.configManager.get('retryAttempts');\n const retryDelay = this.configManager.get('retryDelay');\n let lastError = null;\n for (let attempt = 0; attempt < maxRetries; attempt++) {\n try {\n // Add delay between retries (exponential backoff)\n if (attempt > 0) {\n const delay = Math.min(retryDelay * Math.pow(2, attempt - 1), 30000);\n await new Promise((resolve) => setTimeout(resolve, delay));\n this.logger.debug('Retrying download', { bundleId, attempt, delay });\n }\n return await this.download(url, bundleId, onProgress);\n }\n catch (error) {\n lastError = error;\n // Don't retry if cancelled or validation error\n if (error instanceof ValidationError ||\n (error instanceof Error && error.name === 'AbortError')) {\n throw error;\n }\n this.logger.warn(`Download attempt ${attempt + 1} failed`, {\n bundleId,\n error,\n });\n }\n }\n throw new DownloadError(ErrorCode.DOWNLOAD_FAILED, 'Download failed after all retries', { attempts: maxRetries }, lastError || undefined);\n }\n /**\n * Convert blob to ArrayBuffer\n */\n async blobToArrayBuffer(blob) {\n return blob.arrayBuffer();\n }\n /**\n * Save blob to filesystem\n */\n async saveBlob(bundleId, blob) {\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');\n }\n const arrayBuffer = await this.blobToArrayBuffer(blob);\n const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));\n const path = `bundles/${bundleId}/bundle.zip`;\n await this.filesystem.writeFile({\n path,\n data: base64,\n directory: Directory.Data,\n recursive: true,\n });\n this.logger.debug('Bundle saved to filesystem', {\n bundleId,\n path,\n size: blob.size,\n });\n return path;\n }\n /**\n * Load blob from filesystem\n */\n async loadBlob(bundleId) {\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');\n }\n try {\n const path = `bundles/${bundleId}/bundle.zip`;\n const result = await this.filesystem.readFile({\n path,\n directory: Directory.Data,\n });\n const binaryString = atob(result.data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return new Blob([bytes], { type: 'application/zip' });\n }\n catch (error) {\n this.logger.debug('Failed to load bundle from filesystem', {\n bundleId,\n error,\n });\n return null;\n }\n }\n /**\n * Delete blob from filesystem\n */\n async deleteBlob(bundleId) {\n if (!this.filesystem) {\n throw new DownloadError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not initialized');\n }\n try {\n const path = `bundles/${bundleId}`;\n await this.filesystem.rmdir({\n path,\n directory: Directory.Data,\n recursive: true,\n });\n this.logger.debug('Bundle deleted from filesystem', { bundleId });\n }\n catch (error) {\n this.logger.warn('Failed to delete bundle from filesystem', {\n bundleId,\n error,\n });\n }\n }\n}\n//# sourceMappingURL=download-manager.js.map","import { ConfigManager } from '../core/config';\nimport { Logger } from '../core/logger';\nimport { SecurityValidator } from '../core/security';\nimport { ValidationError, ErrorCode } from '../core/errors';\n/**\n * Manages version checking and comparison\n */\nexport class VersionManager {\n constructor() {\n this.VERSION_CHECK_CACHE_KEY = 'capacitor_native_update_version_cache';\n this.CACHE_DURATION = 5 * 60 * 1000; // 5 minutes\n this.preferences = null;\n this.memoryCache = new Map();\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n this.securityValidator = SecurityValidator.getInstance();\n }\n /**\n * Compare two semantic versions\n */\n static compareVersions(version1, version2) {\n try {\n // Split version and pre-release\n const [v1Base, v1Pre] = version1.split('-');\n const [v2Base, v2Pre] = version2.split('-');\n const v1Parts = v1Base.split('.').map(Number);\n const v2Parts = v2Base.split('.').map(Number);\n // Compare major.minor.patch\n for (let i = 0; i < 3; i++) {\n const v1Part = v1Parts[i] || 0;\n const v2Part = v2Parts[i] || 0;\n if (v1Part > v2Part)\n return 1;\n if (v1Part < v2Part)\n return -1;\n }\n // If base versions are equal, compare pre-release\n if (v1Pre && !v2Pre)\n return -1; // 1.0.0-alpha < 1.0.0\n if (!v1Pre && v2Pre)\n return 1; // 1.0.0 > 1.0.0-alpha\n if (v1Pre && v2Pre) {\n return v1Pre.localeCompare(v2Pre);\n }\n return 0;\n }\n catch (_a) {\n if (version1 === version2)\n return 0;\n return version1 > version2 ? 1 : -1;\n }\n }\n /**\n * Validate semantic version format\n */\n static isValidVersion(version) {\n return /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$/.test(version);\n }\n /**\n * Check if update should be performed\n */\n static shouldUpdate(currentVersion, newVersion, minAppVersion) {\n if (minAppVersion &&\n VersionManager.compareVersions(currentVersion, minAppVersion) < 0) {\n return false;\n }\n return VersionManager.compareVersions(currentVersion, newVersion) < 0;\n }\n /**\n * Initialize the version manager\n */\n async initialize() {\n this.preferences = this.configManager.get('preferences');\n if (!this.preferences) {\n throw new ValidationError(ErrorCode.MISSING_DEPENDENCY, 'Preferences not configured. Please configure the plugin first.');\n }\n }\n /**\n * Check for latest version from server\n */\n async checkForUpdates(serverUrl, channel, currentVersion, appId) {\n // Validate inputs\n this.securityValidator.validateUrl(serverUrl);\n this.securityValidator.validateVersion(currentVersion);\n if (!channel || !appId) {\n throw new ValidationError(ErrorCode.INVALID_CONFIG, 'Channel and appId are required');\n }\n // Check cache first\n const cacheKey = `${channel}-${appId}`;\n const cached = await this.getCachedVersionInfo(cacheKey);\n if (cached &&\n cached.channel === channel &&\n Date.now() - cached.timestamp < this.CACHE_DURATION) {\n this.logger.debug('Returning cached version info', {\n channel,\n version: cached.data.version,\n });\n return cached.data;\n }\n try {\n const url = new URL(`${serverUrl}/check`);\n url.searchParams.append('channel', channel);\n url.searchParams.append('version', currentVersion);\n url.searchParams.append('appId', appId);\n url.searchParams.append('platform', 'web'); // Will be overridden by native platforms\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-App-Version': currentVersion,\n 'X-App-Id': appId,\n },\n signal: AbortSignal.timeout(this.configManager.get('downloadTimeout')),\n });\n if (!response.ok) {\n throw new Error(`Version check failed: ${response.status}`);\n }\n const data = await response.json();\n // Validate response\n if (!data.version) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'No version in server response');\n }\n this.securityValidator.validateVersion(data.version);\n // Additional validation\n if (data.bundleUrl) {\n this.securityValidator.validateUrl(data.bundleUrl);\n }\n if (data.minAppVersion) {\n this.securityValidator.validateVersion(data.minAppVersion);\n }\n // Cache the result\n await this.cacheVersionInfo(cacheKey, channel, data);\n this.logger.info('Version check completed', {\n channel,\n currentVersion,\n latestVersion: data.version,\n updateAvailable: this.isNewerVersion(data.version, currentVersion),\n });\n return data;\n }\n catch (error) {\n this.logger.error('Failed to check for updates', error);\n return null;\n }\n }\n /**\n * Compare two versions\n */\n isNewerVersion(version1, version2) {\n try {\n const v1 = this.parseVersion(version1);\n const v2 = this.parseVersion(version2);\n if (v1.major !== v2.major)\n return v1.major > v2.major;\n if (v1.minor !== v2.minor)\n return v1.minor > v2.minor;\n if (v1.patch !== v2.patch)\n return v1.patch > v2.patch;\n // If main versions are equal, check pre-release\n if (v1.prerelease && !v2.prerelease)\n return false; // v1 is pre-release, v2 is not\n if (!v1.prerelease && v2.prerelease)\n return true; // v1 is not pre-release, v2 is\n if (v1.prerelease && v2.prerelease) {\n return v1.prerelease > v2.prerelease;\n }\n return false; // Versions are equal\n }\n catch (error) {\n this.logger.error('Failed to compare versions', {\n version1,\n version2,\n error,\n });\n return false;\n }\n }\n /**\n * Check if update is mandatory based on minimum version\n */\n isUpdateMandatory(currentVersion, minimumVersion) {\n if (!minimumVersion)\n return false;\n try {\n this.securityValidator.validateVersion(currentVersion);\n this.securityValidator.validateVersion(minimumVersion);\n return (!this.isNewerVersion(currentVersion, minimumVersion) &&\n currentVersion !== minimumVersion);\n }\n catch (error) {\n this.logger.error('Failed to check mandatory update', error);\n return false;\n }\n }\n /**\n * Parse version metadata\n */\n parseVersion(version) {\n const match = version.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$/);\n if (!match) {\n throw new ValidationError(ErrorCode.INVALID_BUNDLE_FORMAT, 'Invalid version format');\n }\n return {\n major: parseInt(match[1], 10),\n minor: parseInt(match[2], 10),\n patch: parseInt(match[3], 10),\n prerelease: match[4],\n build: match[5],\n };\n }\n /**\n * Generate version string from components\n */\n buildVersionString(components) {\n let version = `${components.major}.${components.minor}.${components.patch}`;\n if (components.prerelease) {\n version += `-${components.prerelease}`;\n }\n if (components.build) {\n version += `+${components.build}`;\n }\n return version;\n }\n /**\n * Check if version is compatible with native version requirements\n */\n isCompatibleWithNativeVersion(bundleVersion, nativeVersion, compatibility) {\n if (!compatibility)\n return true;\n try {\n // Check if there's a specific native version requirement for this bundle version\n const requiredNativeVersion = compatibility[bundleVersion];\n if (!requiredNativeVersion)\n return true;\n this.securityValidator.validateVersion(nativeVersion);\n this.securityValidator.validateVersion(requiredNativeVersion);\n return !this.isNewerVersion(requiredNativeVersion, nativeVersion);\n }\n catch (error) {\n this.logger.error('Failed to check compatibility', error);\n return false;\n }\n }\n /**\n * Get version from cache\n */\n async getCachedVersionInfo(cacheKey) {\n // Check memory cache first\n const memCached = this.memoryCache.get(cacheKey);\n if (memCached && Date.now() - memCached.timestamp < this.CACHE_DURATION) {\n return memCached;\n }\n // Check persistent cache\n try {\n const { value } = await this.preferences.get({\n key: this.VERSION_CHECK_CACHE_KEY,\n });\n if (!value)\n return null;\n const allCached = JSON.parse(value);\n const cached = allCached[cacheKey];\n if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {\n // Update memory cache\n this.memoryCache.set(cacheKey, cached);\n return cached;\n }\n }\n catch (error) {\n this.logger.debug('Failed to load cached version info', error);\n }\n return null;\n }\n /**\n * Cache version info\n */\n async cacheVersionInfo(cacheKey, channel, data) {\n const cacheEntry = {\n channel,\n data,\n timestamp: Date.now(),\n };\n // Update memory cache\n this.memoryCache.set(cacheKey, cacheEntry);\n // Update persistent cache\n try {\n const { value } = await this.preferences.get({\n key: this.VERSION_CHECK_CACHE_KEY,\n });\n const allCached = value\n ? JSON.parse(value)\n : {};\n // Clean old entries\n const now = Date.now();\n for (const key in allCached) {\n if (now - allCached[key].timestamp > this.CACHE_DURATION * 2) {\n delete allCached[key];\n }\n }\n allCached[cacheKey] = cacheEntry;\n await this.preferences.set({\n key: this.VERSION_CHECK_CACHE_KEY,\n value: JSON.stringify(allCached),\n });\n }\n catch (error) {\n this.logger.warn('Failed to cache version info', error);\n }\n }\n /**\n * Clear version cache\n */\n async clearVersionCache() {\n this.memoryCache.clear();\n try {\n await this.preferences.remove({ key: this.VERSION_CHECK_CACHE_KEY });\n }\n catch (error) {\n this.logger.warn('Failed to clear version cache', error);\n }\n }\n /**\n * Check if downgrade protection should block update\n */\n shouldBlockDowngrade(currentVersion, newVersion) {\n try {\n return this.securityValidator.isVersionDowngrade(currentVersion, newVersion);\n }\n catch (error) {\n this.logger.error('Failed to check downgrade', error);\n // Default to safe behavior - block if we can't determine\n return true;\n }\n }\n}\n//# sourceMappingURL=version-manager.js.map","import { Filesystem } from '@capacitor/filesystem';\nimport { Preferences } from '@capacitor/preferences';\nimport { ConfigManager } from './config';\nimport { Logger } from './logger';\nimport { SecurityValidator } from './security';\nimport { BundleManager } from '../live-update/bundle-manager';\nimport { DownloadManager } from '../live-update/download-manager';\nimport { VersionManager } from '../live-update/version-manager';\nimport { NativeUpdateError, ErrorCode } from './errors';\n/**\n * Central manager for all plugin components\n */\nexport class PluginManager {\n constructor() {\n this.bundleManager = null;\n this.downloadManager = null;\n this.versionManager = null;\n this.initialized = false;\n this.configManager = ConfigManager.getInstance();\n this.logger = Logger.getInstance();\n this.securityValidator = SecurityValidator.getInstance();\n }\n static getInstance() {\n if (!PluginManager.instance) {\n PluginManager.instance = new PluginManager();\n }\n return PluginManager.instance;\n }\n /**\n * Initialize the plugin with configuration\n */\n async initialize(config) {\n if (this.initialized) {\n this.logger.warn('Plugin already initialized');\n return;\n }\n try {\n // Configure the plugin\n this.configManager.configure(config);\n // Use Capacitor plugins directly if not provided\n if (!config.filesystem) {\n config.filesystem = Filesystem;\n }\n if (!config.preferences) {\n config.preferences = Preferences;\n }\n // Initialize managers\n this.bundleManager = new BundleManager();\n await this.bundleManager.initialize();\n this.downloadManager = new DownloadManager();\n await this.downloadManager.initialize();\n this.versionManager = new VersionManager();\n await this.versionManager.initialize();\n this.initialized = true;\n this.logger.info('Plugin initialized successfully');\n }\n catch (error) {\n this.logger.error('Failed to initialize plugin', error);\n throw error;\n }\n }\n /**\n * Check if plugin is initialized\n */\n isInitialized() {\n return this.initialized && this.configManager.isConfigured();\n }\n /**\n * Ensure plugin is initialized\n */\n ensureInitialized() {\n if (!this.isInitialized()) {\n throw new NativeUpdateError(ErrorCode.NOT_CONFIGURED, 'Plugin not initialized. Please call initialize() first.');\n }\n }\n /**\n * Get bundle manager\n */\n getBundleManager() {\n this.ensureInitialized();\n return this.bundleManager;\n }\n /**\n * Get download manager\n */\n getDownloadManager() {\n this.ensureInitialized();\n return this.downloadManager;\n }\n /**\n * Get version manager\n */\n getVersionManager() {\n this.ensureInitialized();\n return this.versionManager;\n }\n /**\n * Get configuration manager\n */\n getConfigManager() {\n return this.configManager;\n }\n /**\n * Get logger\n */\n getLogger() {\n return this.logger;\n }\n /**\n * Get security validator\n */\n getSecurityValidator() {\n return this.securityValidator;\n }\n /**\n * Reset plugin state\n */\n async reset() {\n this.logger.info('Resetting plugin state');\n // Clear all data\n if (this.bundleManager) {\n await this.bundleManager.clearAllBundles();\n }\n if (this.versionManager) {\n await this.versionManager.clearVersionCache();\n }\n if (this.downloadManager) {\n this.downloadManager.cancelAllDownloads();\n }\n // Reset initialization state\n this.bundleManager = null;\n this.downloadManager = null;\n this.versionManager = null;\n this.initialized = false;\n this.logger.info('Plugin reset complete');\n }\n /**\n * Clean up resources\n */\n async cleanup() {\n this.logger.info('Cleaning up plugin resources');\n // Cancel any active downloads\n if (this.downloadManager) {\n this.downloadManager.cancelAllDownloads();\n }\n // Clean expired bundles\n if (this.bundleManager) {\n await this.bundleManager.cleanExpiredBundles();\n }\n this.logger.info('Cleanup complete');\n }\n}\n//# sourceMappingURL=plugin-manager.js.map","import { registerPlugin } from '@capacitor/core';\nimport { SyncStatus, BundleStatus, UpdateErrorCode } from './definitions';\nimport { PluginManager } from './core/plugin-manager';\nimport { NativeUpdateError, ErrorCode } from './core/errors';\n/**\n * Web implementation of the Native Update Plugin\n */\nclass NativeUpdatePluginWeb {\n constructor() {\n this.initialized = false;\n this.pluginManager = PluginManager.getInstance();\n }\n // Main plugin methods\n async initialize(config) {\n await this.pluginManager.initialize(config);\n this.initialized = true;\n }\n isInitialized() {\n return this.initialized && this.pluginManager.isInitialized();\n }\n async reset() {\n await this.pluginManager.reset();\n }\n async cleanup() {\n await this.pluginManager.cleanup();\n }\n // NativeUpdatePlugin methods\n async configure(config) {\n var _a;\n // Handle both UpdateConfig and wrapped PluginInitConfig formats\n let initConfig;\n if ('config' in config && typeof config.config === 'object') {\n // Format: { config: PluginInitConfig }\n initConfig = config.config;\n }\n else {\n // Format: UpdateConfig - convert to PluginInitConfig\n initConfig = {\n // Auto-imported Capacitor plugins will be added by plugin-manager\n baseUrl: (_a = config.liveUpdate) === null || _a === void 0 ? void 0 : _a.serverUrl,\n };\n }\n if (!this.initialized) {\n // Auto-initialize with the provided config\n await this.initialize(initConfig);\n }\n else {\n // Apply plugin configuration\n const configManager = this.pluginManager.getConfigManager();\n configManager.configure(initConfig);\n }\n }\n async getSecurityInfo() {\n return {\n enforceHttps: true,\n certificatePinning: {\n enabled: false,\n pins: [],\n },\n validateInputs: true,\n secureStorage: true,\n };\n }\n // LiveUpdatePlugin methods\n async sync(_options) {\n const bundleManager = this.pluginManager.getBundleManager();\n try {\n // Check for updates\n const currentBundle = await bundleManager.getActiveBundle();\n const currentVersion = (currentBundle === null || currentBundle === void 0 ? void 0 : currentBundle.version) || '1.0.0';\n // For now, return up-to-date status\n return {\n status: SyncStatus.UP_TO_DATE,\n version: currentVersion,\n };\n }\n catch (error) {\n return {\n status: SyncStatus.ERROR,\n error: {\n code: UpdateErrorCode.UNKNOWN_ERROR,\n message: error instanceof Error ? error.message : 'Sync failed',\n },\n };\n }\n }\n async download(options) {\n const downloadManager = this.pluginManager.getDownloadManager();\n const bundleManager = this.pluginManager.getBundleManager();\n const blob = await downloadManager.downloadWithRetry(options.url, options.version);\n const path = await downloadManager.saveBlob(options.version, blob);\n const bundleInfo = {\n bundleId: options.version,\n version: options.version,\n path,\n downloadTime: Date.now(),\n size: blob.size,\n status: BundleStatus.READY,\n checksum: options.checksum,\n signature: options.signature,\n verified: false,\n };\n await bundleManager.saveBundleInfo(bundleInfo);\n return bundleInfo;\n }\n async set(bundle) {\n const bundleManager = this.pluginManager.getBundleManager();\n await bundleManager.setActiveBundle(bundle.bundleId);\n }\n async reload() {\n // In web implementation, we can reload the page\n if (typeof window !== 'undefined') {\n window.location.reload();\n }\n }\n async current() {\n const bundleManager = this.pluginManager.getBundleManager();\n const bundle = await bundleManager.getActiveBundle();\n if (!bundle) {\n throw new NativeUpdateError(ErrorCode.FILE_NOT_FOUND, 'No active bundle found');\n }\n return bundle;\n }\n async list() {\n const bundleManager = this.pluginManager.getBundleManager();\n return bundleManager.getAllBundles();\n }\n async delete(options) {\n const bundleManager = this.pluginManager.getBundleManager();\n if (options.bundleId) {\n await bundleManager.deleteBundle(options.bundleId);\n }\n else if (options.keepVersions !== undefined) {\n // Delete old versions keeping the specified number\n const bundles = await bundleManager.getAllBundles();\n const sortedBundles = bundles.sort((a, b) => b.downloadTime - a.downloadTime);\n for (let i = options.keepVersions; i < sortedBundles.length; i++) {\n await bundleManager.deleteBundle(sortedBundles[i].bundleId);\n }\n }\n }\n async notifyAppReady() {\n // Mark the current bundle as stable\n const bundleManager = this.pluginManager.getBundleManager();\n const activeBundle = await bundleManager.getActiveBundle();\n if (activeBundle) {\n activeBundle.status = BundleStatus.ACTIVE;\n await bundleManager.saveBundleInfo(activeBundle);\n }\n }\n async getLatest() {\n // For web, we'll return no update available\n return {\n available: false,\n };\n }\n async setChannel(channel) {\n // Store the channel preference\n const preferences = this.pluginManager\n .getConfigManager()\n .get('preferences');\n if (preferences) {\n await preferences.set({\n key: 'update_channel',\n value: channel,\n });\n }\n }\n async setUpdateUrl(url) {\n const configManager = this.pluginManager.getConfigManager();\n configManager.configure({ baseUrl: url });\n }\n async validateUpdate(options) {\n const securityValidator = this.pluginManager.getSecurityValidator();\n try {\n // Validate checksum\n const isValid = await securityValidator.validateChecksum(new ArrayBuffer(0), // Placeholder for bundle data\n options.checksum);\n return {\n isValid,\n details: {\n checksumValid: isValid,\n signatureValid: true,\n sizeValid: true,\n versionValid: true,\n },\n };\n }\n catch (error) {\n return {\n isValid: false,\n error: error instanceof Error ? error.message : 'Validation failed',\n };\n }\n }\n // AppUpdatePlugin methods\n async getAppUpdateInfo() {\n // Web doesn't have native app updates\n return {\n updateAvailable: false,\n currentVersion: '1.0.0',\n };\n }\n async performImmediateUpdate() {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');\n }\n async startFlexibleUpdate() {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');\n }\n async completeFlexibleUpdate() {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');\n }\n async openAppStore(_options) {\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'App store is not available on web');\n }\n // AppReviewPlugin methods\n async requestReview() {\n return {\n displayed: false,\n error: 'Reviews are not supported on web',\n };\n }\n async canRequestReview() {\n return {\n canRequest: false,\n reason: 'Reviews are not supported on web',\n };\n }\n // BackgroundUpdatePlugin methods\n async enableBackgroundUpdates(config) {\n // Store the configuration\n const preferences = this.pluginManager\n .getConfigManager()\n .get('preferences');\n if (preferences) {\n await preferences.set({\n key: 'background_update_config',\n value: JSON.stringify(config),\n });\n }\n }\n async disableBackgroundUpdates() {\n const preferences = this.pluginManager\n .getConfigManager()\n .get('preferences');\n if (preferences) {\n await preferences.remove({ key: 'background_update_config' });\n }\n }\n async getBackgroundUpdateStatus() {\n return {\n enabled: false,\n isRunning: false,\n checkCount: 0,\n failureCount: 0,\n };\n }\n async scheduleBackgroundCheck(_interval) {\n // Not supported on web\n throw new NativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Background updates are not supported on web');\n }\n async triggerBackgroundCheck() {\n return {\n success: false,\n updatesFound: false,\n notificationSent: false,\n error: {\n code: UpdateErrorCode.PLATFORM_NOT_SUPPORTED,\n message: 'Background updates are not supported on web',\n },\n };\n }\n async setNotificationPreferences(preferences) {\n // Store preferences but notifications aren't supported on web\n const prefs = this.pluginManager.getConfigManager().get('preferences');\n if (prefs) {\n await prefs.set({\n key: 'notification_preferences',\n value: JSON.stringify(preferences),\n });\n }\n }\n async getNotificationPermissions() {\n return {\n granted: false,\n canRequest: false,\n };\n }\n async requestNotificationPermissions() {\n return false;\n }\n}\n/**\n * Register the plugin\n */\nconst NativeUpdate = registerPlugin('NativeUpdate', {\n web: () => new NativeUpdatePluginWeb(),\n});\nexport { NativeUpdate };\n//# sourceMappingURL=plugin.js.map","import { ConfigManager } from './config';\nimport { Logger } from './logger';\nimport { Directory, Encoding } from '@capacitor/filesystem';\n/**\n * Manages caching with expiration for various data types\n */\nexport class CacheManager {\n constructor() {\n this.filesystem = null;\n this.memoryCache = new Map();\n this.CACHE_DIR = 'cache';\n this.logger = Logger.getInstance();\n this.configManager = ConfigManager.getInstance();\n }\n /**\n * Initialize cache manager\n */\n async initialize() {\n this.filesystem = this.configManager.get('filesystem');\n if (!this.filesystem) {\n throw new Error('Filesystem not configured');\n }\n // Create cache directory if it doesn't exist\n try {\n await this.filesystem.mkdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n recursive: true,\n });\n }\n catch (error) {\n this.logger.debug('Cache directory may already exist', error);\n }\n // Clean expired cache on initialization\n await this.cleanExpiredCache();\n }\n /**\n * Set cache entry with expiration\n */\n async set(key, data, ttlMs) {\n const expiry = Date.now() + (ttlMs || this.configManager.get('cacheExpiration'));\n const entry = {\n data,\n timestamp: Date.now(),\n expiry,\n };\n // Update memory cache\n this.memoryCache.set(key, entry);\n // Persist to filesystem for larger data\n if (this.shouldPersist(data)) {\n await this.persistToFile(key, entry);\n }\n this.logger.debug('Cache entry set', { key, expiry: new Date(expiry) });\n }\n /**\n * Get cache entry\n */\n async get(key) {\n // Check memory cache first\n const memEntry = this.memoryCache.get(key);\n if (memEntry) {\n if (Date.now() < memEntry.expiry) {\n return memEntry.data;\n }\n else {\n // Expired - remove from memory\n this.memoryCache.delete(key);\n }\n }\n // Check filesystem cache\n const fileEntry = await this.loadFromFile(key);\n if (fileEntry) {\n if (Date.now() < fileEntry.expiry) {\n // Update memory cache\n this.memoryCache.set(key, fileEntry);\n return fileEntry.data;\n }\n else {\n // Expired - remove file\n await this.removeFile(key);\n }\n }\n return null;\n }\n /**\n * Check if cache entry exists and is valid\n */\n async has(key) {\n const value = await this.get(key);\n return value !== null;\n }\n /**\n * Remove cache entry\n */\n async remove(key) {\n this.memoryCache.delete(key);\n await this.removeFile(key);\n this.logger.debug('Cache entry removed', { key });\n }\n /**\n * Clear all cache\n */\n async clear() {\n this.memoryCache.clear();\n // Remove cache directory\n try {\n await this.filesystem.rmdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n recursive: true,\n });\n // Recreate empty cache directory\n await this.filesystem.mkdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n recursive: true,\n });\n }\n catch (error) {\n this.logger.warn('Failed to clear cache directory', error);\n }\n this.logger.info('Cache cleared');\n }\n /**\n * Clean expired cache entries\n */\n async cleanExpiredCache() {\n const now = Date.now();\n let cleanedCount = 0;\n // Clean memory cache\n for (const [key, entry] of this.memoryCache) {\n if (now >= entry.expiry) {\n this.memoryCache.delete(key);\n cleanedCount++;\n }\n }\n // Clean filesystem cache\n try {\n const files = await this.filesystem.readdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n });\n for (const file of files.files) {\n const key = file.name.replace('.json', '');\n const entry = await this.loadFromFile(key);\n if (!entry || now >= entry.expiry) {\n await this.removeFile(key);\n cleanedCount++;\n }\n }\n }\n catch (error) {\n this.logger.debug('Failed to clean filesystem cache', error);\n }\n if (cleanedCount > 0) {\n this.logger.info('Cleaned expired cache entries', {\n count: cleanedCount,\n });\n }\n }\n /**\n * Get cache statistics\n */\n async getStats() {\n let fileEntries = 0;\n let totalSize = 0;\n try {\n const files = await this.filesystem.readdir({\n path: this.CACHE_DIR,\n directory: Directory.Data,\n });\n fileEntries = files.files.length;\n // Estimate size (this is approximate)\n for (const file of files.files) {\n const stat = await this.filesystem.stat({\n path: `${this.CACHE_DIR}/${file.name}`,\n directory: Directory.Data,\n });\n totalSize += stat.size || 0;\n }\n }\n catch (error) {\n this.logger.debug('Failed to get cache stats', error);\n }\n return {\n memoryEntries: this.memoryCache.size,\n fileEntries,\n totalSize,\n };\n }\n /**\n * Cache bundle metadata\n */\n async cacheBundleMetadata(bundle) {\n const key = `bundle_meta_${bundle.bundleId}`;\n await this.set(key, bundle, 24 * 60 * 60 * 1000); // 24 hours\n }\n /**\n * Get cached bundle metadata\n */\n async getCachedBundleMetadata(bundleId) {\n const key = `bundle_meta_${bundleId}`;\n return this.get(key);\n }\n /**\n * Check if data should be persisted to filesystem\n */\n shouldPersist(data) {\n // Persist objects and large strings\n if (typeof data === 'object')\n return true;\n if (typeof data === 'string' && data.length > 1024)\n return true;\n return false;\n }\n /**\n * Persist cache entry to file\n */\n async persistToFile(key, entry) {\n if (!this.filesystem)\n return;\n try {\n const path = `${this.CACHE_DIR}/${key}.json`;\n const data = JSON.stringify(entry);\n await this.filesystem.writeFile({\n path,\n data,\n directory: Directory.Data,\n encoding: Encoding.UTF8,\n });\n }\n catch (error) {\n this.logger.warn('Failed to persist cache to file', { key, error });\n }\n }\n /**\n * Load cache entry from file\n */\n async loadFromFile(key) {\n if (!this.filesystem)\n return null;\n try {\n const path = `${this.CACHE_DIR}/${key}.json`;\n const result = await this.filesystem.readFile({\n path,\n directory: Directory.Data,\n encoding: Encoding.UTF8,\n });\n return JSON.parse(result.data);\n }\n catch (_a) {\n // File doesn't exist or is corrupted\n return null;\n }\n }\n /**\n * Remove cache file\n */\n async removeFile(key) {\n if (!this.filesystem)\n return;\n try {\n const path = `${this.CACHE_DIR}/${key}.json`;\n await this.filesystem.deleteFile({\n path,\n directory: Directory.Data,\n });\n }\n catch (error) {\n // File may not exist\n this.logger.debug('Failed to remove cache file', { key, error });\n }\n }\n}\n//# sourceMappingURL=cache-manager.js.map","import { PluginManager } from '../core/plugin-manager';\nimport { UpdateError, ValidationError, ErrorCode } from '../core/errors';\nimport { SecurityValidator } from '../core/security';\nimport { Directory } from '@capacitor/filesystem';\n/**\n * Manages atomic bundle installation with rollback capability\n */\nexport class UpdateManager {\n constructor() {\n this.filesystem = null;\n this.updateInProgress = false;\n this.currentState = null;\n this.pluginManager = PluginManager.getInstance();\n this.securityValidator = SecurityValidator.getInstance();\n }\n /**\n * Initialize update manager\n */\n async initialize() {\n this.filesystem = this.pluginManager.getConfigManager().get('filesystem');\n if (!this.filesystem) {\n throw new UpdateError(ErrorCode.MISSING_DEPENDENCY, 'Filesystem not configured');\n }\n }\n /**\n * Apply bundle update atomically\n */\n async applyUpdate(bundleId, options) {\n if (this.updateInProgress) {\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Another update is already in progress');\n }\n const logger = this.pluginManager.getLogger();\n const bundleManager = this.pluginManager.getBundleManager();\n try {\n this.updateInProgress = true;\n logger.info('Starting bundle update', { bundleId });\n // Get the new bundle\n const newBundle = await bundleManager.getBundle(bundleId);\n if (!newBundle) {\n throw new UpdateError(ErrorCode.FILE_NOT_FOUND, `Bundle ${bundleId} not found`);\n }\n // Verify bundle is ready\n if (newBundle.status !== 'READY' && newBundle.status !== 'ACTIVE') {\n throw new UpdateError(ErrorCode.BUNDLE_NOT_READY, `Bundle ${bundleId} is not ready for installation`);\n }\n // Get current active bundle\n const currentBundle = await bundleManager.getActiveBundle();\n // Initialize update state\n this.currentState = {\n currentBundle,\n newBundle,\n backupPath: null,\n startTime: Date.now(),\n };\n // Validate update\n await this.validateUpdate(currentBundle, newBundle, options);\n // Create backup of current state\n if (currentBundle && currentBundle.bundleId !== 'default') {\n this.currentState.backupPath = await this.createBackup(currentBundle);\n }\n // Apply the update\n await this.performUpdate(newBundle);\n // Verify the update\n await this.verifyUpdate(newBundle);\n // Mark as active\n await bundleManager.setActiveBundle(bundleId);\n // Clean up old bundles if configured\n if (options === null || options === void 0 ? void 0 : options.cleanupOldBundles) {\n await bundleManager.cleanupOldBundles(options.keepBundleCount || 3);\n }\n logger.info('Bundle update completed successfully', {\n bundleId,\n version: newBundle.version,\n duration: Date.now() - this.currentState.startTime,\n });\n // Clear state\n this.currentState = null;\n }\n catch (error) {\n logger.error('Bundle update failed', error);\n // Attempt rollback\n if (this.currentState) {\n await this.rollback();\n }\n throw error;\n }\n finally {\n this.updateInProgress = false;\n }\n }\n /**\n * Validate update before applying\n */\n async validateUpdate(currentBundle, newBundle, options) {\n const logger = this.pluginManager.getLogger();\n const versionManager = this.pluginManager.getVersionManager();\n // Check if downgrade\n if (currentBundle && !(options === null || options === void 0 ? void 0 : options.allowDowngrade)) {\n if (versionManager.shouldBlockDowngrade(currentBundle.version, newBundle.version)) {\n throw new ValidationError(ErrorCode.VERSION_DOWNGRADE, `Cannot downgrade from ${currentBundle.version} to ${newBundle.version}`);\n }\n }\n // Verify bundle integrity\n if (!newBundle.verified) {\n logger.warn('Bundle not verified, verifying now', {\n bundleId: newBundle.bundleId,\n });\n // Load bundle data\n const downloadManager = this.pluginManager.getDownloadManager();\n const blob = await downloadManager.loadBlob(newBundle.bundleId);\n if (!blob) {\n throw new UpdateError(ErrorCode.FILE_NOT_FOUND, 'Bundle data not found');\n }\n // Verify checksum\n const arrayBuffer = await blob.arrayBuffer();\n const isValid = await this.securityValidator.verifyChecksum(arrayBuffer, newBundle.checksum);\n if (!isValid) {\n throw new ValidationError(ErrorCode.CHECKSUM_MISMATCH, 'Bundle checksum verification failed');\n }\n // Verify signature if enabled\n if (newBundle.signature) {\n const signatureValid = await this.securityValidator.verifySignature(arrayBuffer, newBundle.signature);\n if (!signatureValid) {\n throw new ValidationError(ErrorCode.SIGNATURE_INVALID, 'Bundle signature verification failed');\n }\n }\n // Mark as verified\n await this.pluginManager\n .getBundleManager()\n .markBundleAsVerified(newBundle.bundleId);\n }\n logger.debug('Bundle validation passed', { bundleId: newBundle.bundleId });\n }\n /**\n * Create backup of current bundle\n */\n async createBackup(bundle) {\n const backupPath = `backups/${bundle.bundleId}_${Date.now()}`;\n const logger = this.pluginManager.getLogger();\n try {\n // Create backup directory\n await this.filesystem.mkdir({\n path: backupPath,\n directory: Directory.Data,\n recursive: true,\n });\n // Copy bundle files\n await this.filesystem.copy({\n from: bundle.path,\n to: backupPath,\n directory: Directory.Data,\n });\n logger.info('Backup created', { bundleId: bundle.bundleId, backupPath });\n return backupPath;\n }\n catch (error) {\n logger.error('Failed to create backup', error);\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Failed to create backup', undefined, error);\n }\n }\n /**\n * Perform the actual update\n */\n async performUpdate(bundle) {\n const logger = this.pluginManager.getLogger();\n try {\n // Extract bundle to target location\n const targetPath = `active/${bundle.bundleId}`;\n // Create target directory\n await this.filesystem.mkdir({\n path: targetPath,\n directory: Directory.Data,\n recursive: true,\n });\n // Copy bundle files\n await this.filesystem.copy({\n from: bundle.path,\n to: targetPath,\n directory: Directory.Data,\n });\n // Update bundle path\n bundle.path = targetPath;\n logger.debug('Bundle files installed', {\n bundleId: bundle.bundleId,\n targetPath,\n });\n }\n catch (error) {\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Failed to install bundle files', undefined, error);\n }\n }\n /**\n * Verify update was successful\n */\n async verifyUpdate(bundle) {\n try {\n // Check if main bundle files exist\n const indexPath = `${bundle.path}/index.html`;\n await this.filesystem.stat({\n path: indexPath,\n directory: Directory.Data,\n });\n // Additional verification can be added here\n }\n catch (error) {\n throw new UpdateError(ErrorCode.UPDATE_FAILED, 'Bundle verification failed after installation', undefined, error);\n }\n }\n /**\n * Rollback to previous state\n */\n async rollback() {\n var _a;\n if (!this.currentState) {\n throw new UpdateError(ErrorCode.ROLLBACK_FAILED, 'No update state to rollback');\n }\n const logger = this.pluginManager.getLogger();\n logger.warn('Starting rollback', {\n from: this.currentState.newBundle.bundleId,\n to: ((_a = this.currentState.currentBundle) === null || _a === void 0 ? void 0 : _a.bundleId) || 'default',\n });\n try {\n const bundleManager = this.pluginManager.getBundleManager();\n // Restore from backup if available\n if (this.currentState.backupPath && this.currentState.currentBundle) {\n const restoredPath = `active/${this.currentState.currentBundle.bundleId}`;\n await this.filesystem.copy({\n from: this.currentState.backupPath,\n to: restoredPath,\n directory: Directory.Data,\n });\n // Update bundle path\n this.currentState.currentBundle.path = restoredPath;\n await bundleManager.saveBundleInfo(this.currentState.currentBundle);\n }\n // Restore active bundle\n if (this.currentState.currentBundle) {\n await bundleManager.setActiveBundle(this.currentState.currentBundle.bundleId);\n }\n else {\n // No previous bundle, clear active\n await bundleManager.clearActiveBundle();\n }\n logger.info('Rollback completed successfully');\n }\n catch (error) {\n logger.error('Rollback failed', error);\n throw new UpdateError(ErrorCode.ROLLBACK_FAILED, 'Failed to rollback update', undefined, error);\n }\n finally {\n // Clean up backup\n if (this.currentState.backupPath) {\n try {\n await this.filesystem.rmdir({\n path: this.currentState.backupPath,\n directory: Directory.Data,\n recursive: true,\n });\n }\n catch (error) {\n logger.warn('Failed to clean up backup', error);\n }\n }\n }\n }\n /**\n * Get current update progress\n */\n getUpdateProgress() {\n var _a, _b;\n return {\n inProgress: this.updateInProgress,\n bundleId: (_a = this.currentState) === null || _a === void 0 ? void 0 : _a.newBundle.bundleId,\n startTime: (_b = this.currentState) === null || _b === void 0 ? void 0 : _b.startTime,\n };\n }\n /**\n * Cancel current update (if possible)\n */\n async cancelUpdate() {\n if (!this.updateInProgress || !this.currentState) {\n return;\n }\n const logger = this.pluginManager.getLogger();\n logger.warn('Cancelling update', {\n bundleId: this.currentState.newBundle.bundleId,\n });\n // Attempt rollback\n await this.rollback();\n this.updateInProgress = false;\n this.currentState = null;\n }\n}\n//# sourceMappingURL=update-manager.js.map"],"names":["BackgroundUpdateType","NotificationPriority","UpdateStrategy","UpdateMode","InstallMode","ChecksumAlgorithm","SyncStatus","BundleStatus","InstallStatus","UpdateErrorCode","LogLevel","ErrorCode","ConfigManager","constructor","this","config","getDefaultConfig","getInstance","instance","filesystem","preferences","baseUrl","allowedHosts","maxBundleSize","downloadTimeout","retryAttempts","retryDelay","enableSignatureValidation","publicKey","cacheExpiration","enableLogging","serverUrl","channel","autoCheck","autoUpdate","updateStrategy","requireSignature","checksumAlgorithm","checkInterval","security","enforceHttps","validateInputs","secureStorage","logSecurityEvents","promptAfterPositiveEvents","maxPromptsPerVersion","minimumDaysSinceLastPrompt","isPremiumUser","appStoreId","iosAppId","packageName","webReviewUrl","minimumVersion","configure","Object","assign","validateConfig","Error","get","key","set","value","getAll","isConfigured","Logger","context","configManager","shouldLog","sanitize","data","sanitized","replace","Array","isArray","map","item","dataObj","toLowerCase","includes","log","message","logWithLevel","INFO","level","timestamp","Date","toISOString","sanitizedData","undefined","logEntry","DEBUG","console","debug","info","WARN","warn","ERROR","error","errorData","name","stack","NativeUpdateError","code","details","originalError","super","setPrototypeOf","prototype","toJSON","DownloadError","ValidationError","StorageError","UpdateError","SecurityValidator","logger","validateUrl","url","URL","protocol","_a","validateChecksum","checksum","test","sanitizeInput","input","validateBundleSize","size","calculateChecksum","hashBuffer","crypto","subtle","digest","from","Uint8Array","b","toString","padStart","join","verifyChecksum","expectedChecksum","actualChecksum","isValid","expected","actual","verifySignature","signature","SIGNATURE_INVALID","cryptoKey","importKey","pemToArrayBuffer","hash","verify","saltLength","base64ToArrayBuffer","pem","base64","binaryString","atob","bytes","length","i","charCodeAt","buffer","sanitizePath","path","split","filter","part","validateBundleId","bundleId","INVALID_BUNDLE_FORMAT","validateVersion","version","isVersionDowngrade","currentVersion","newVersion","current","parseVersion","next","major","minor","patch","parts","parseInt","INVALID_URL","parsedUrl","hostname","UNAUTHORIZED_HOST","some","pattern","validateFileSize","maxSize","BUNDLE_TOO_LARGE","generateSecureId","array","getRandomValues","byte","validateCertificatePin","certificate","certificatePins","hostPins","pin","certificateHash","calculateCertificateHash","sha256","expectedPins","p","actualHash","TextEncoder","encode","hashArray","btoa","String","fromCharCode","validateMetadata","metadata","JSON","stringify","BundleManager","STORAGE_KEY","ACTIVE_BUNDLE_KEY","cache","Map","cacheExpiry","initialize","MISSING_DEPENDENCY","loadCache","now","bundles","parse","clear","forEach","bundle","saveCache","values","count","STORAGE_FULL","saveBundleInfo","validateBundleInfo","getAllBundles","getBundle","deleteBundle","delete","getActiveBundleId","clearActiveBundle","getActiveBundle","activeBundleId","setActiveBundle","FILE_NOT_FOUND","previousActive","status","remove","clearAllBundles","cleanupOldBundles","keepCount","INVALID_CONFIG","sorted","sort","a","downloadTime","toKeep","Set","add","kept","has","deletedCount","deleted","getBundlesOlderThan","markBundleAsVerified","verified","getTotalStorageUsed","reduce","total","isStorageLimitExceeded","additionalSize","createDefaultBundle","cleanExpiredBundles","expirationTime","cutoffTime","expiredBundles","DownloadManager","activeDownloads","download","onProgress","DOWNLOAD_FAILED","abortController","AbortController","downloadState","controller","startTime","timeout","timeoutId","setTimeout","abort","response","fetch","signal","headers","Accept","clearTimeout","ok","statusText","contentType","isValidContentType","contentLength","totalBytes","body","blob","validateBlobSize","reader","getReader","chunks","receivedBytes","done","read","push","percent","Math","round","bytesDownloaded","Blob","duration","isTimeout","DOWNLOAD_TIMEOUT","type","cancelDownload","state","cancelAllDownloads","isDownloading","getActiveDownloadCount","downloadWithRetry","maxRetries","lastError","attempt","delay","min","pow","Promise","resolve","attempts","blobToArrayBuffer","arrayBuffer","saveBlob","writeFile","directory","Directory","Data","recursive","loadBlob","result","readFile","deleteBlob","rmdir","VersionManager","VERSION_CHECK_CACHE_KEY","CACHE_DURATION","memoryCache","securityValidator","compareVersions","version1","version2","v1Base","v1Pre","v2Base","v2Pre","v1Parts","Number","v2Parts","v1Part","v2Part","localeCompare","isValidVersion","shouldUpdate","minAppVersion","checkForUpdates","appId","cacheKey","cached","getCachedVersionInfo","searchParams","append","method","AbortSignal","json","bundleUrl","cacheVersionInfo","latestVersion","updateAvailable","isNewerVersion","v1","v2","prerelease","isUpdateMandatory","match","build","buildVersionString","components","isCompatibleWithNativeVersion","bundleVersion","nativeVersion","compatibility","requiredNativeVersion","memCached","cacheEntry","allCached","clearVersionCache","shouldBlockDowngrade","PluginManager","bundleManager","downloadManager","versionManager","initialized","Filesystem","Preferences","isInitialized","ensureInitialized","NOT_CONFIGURED","getBundleManager","getDownloadManager","getVersionManager","getConfigManager","getLogger","getSecurityValidator","reset","cleanup","NativeUpdatePluginWeb","pluginManager","initConfig","liveUpdate","getSecurityInfo","certificatePinning","enabled","pins","sync","_options","currentBundle","UP_TO_DATE","UNKNOWN_ERROR","options","bundleInfo","READY","reload","window","location","list","keepVersions","sortedBundles","notifyAppReady","activeBundle","ACTIVE","getLatest","available","setChannel","setUpdateUrl","validateUpdate","ArrayBuffer","checksumValid","signatureValid","sizeValid","versionValid","getAppUpdateInfo","performImmediateUpdate","PLATFORM_NOT_SUPPORTED","startFlexibleUpdate","completeFlexibleUpdate","openAppStore","requestReview","displayed","canRequestReview","canRequest","reason","enableBackgroundUpdates","disableBackgroundUpdates","getBackgroundUpdateStatus","isRunning","checkCount","failureCount","scheduleBackgroundCheck","_interval","triggerBackgroundCheck","success","updatesFound","notificationSent","setNotificationPreferences","prefs","getNotificationPermissions","granted","requestNotificationPermissions","NativeUpdate","registerPlugin","web","CACHE_DIR","mkdir","cleanExpiredCache","ttlMs","expiry","entry","shouldPersist","persistToFile","memEntry","fileEntry","loadFromFile","removeFile","cleanedCount","files","readdir","file","getStats","fileEntries","totalSize","stat","memoryEntries","cacheBundleMetadata","getCachedBundleMetadata","encoding","Encoding","UTF8","deleteFile","updateInProgress","currentState","applyUpdate","UPDATE_FAILED","newBundle","BUNDLE_NOT_READY","backupPath","createBackup","performUpdate","verifyUpdate","keepBundleCount","rollback","allowDowngrade","VERSION_DOWNGRADE","CHECKSUM_MISMATCH","copy","to","targetPath","indexPath","ROLLBACK_FAILED","restoredPath","getUpdateProgress","_b","inProgress","cancelUpdate"],"mappings":"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"}