UNPKG

native-update

Version:

Foundation package for building a comprehensive update system for Capacitor apps. Provides architecture and interfaces but requires backend implementation.

697 lines (696 loc) 18.3 kB
/** * Live Update Plugin Interface */ export interface LiveUpdatePlugin { /** * Sync with update server and apply updates if available */ sync(options?: SyncOptions): Promise<SyncResult>; /** * Download a specific bundle version */ download(options: DownloadOptions): Promise<BundleInfo>; /** * Set the active bundle */ set(bundle: BundleInfo): Promise<void>; /** * Reload the app with current bundle */ reload(): Promise<void>; /** * Reset to original bundle */ reset(): Promise<void>; /** * Get current bundle info */ current(): Promise<BundleInfo>; /** * List all downloaded bundles */ list(): Promise<BundleInfo[]>; /** * Delete bundles */ delete(options: DeleteOptions): Promise<void>; /** * Notify app is ready after update */ notifyAppReady(): Promise<void>; /** * Check for latest version */ getLatest(): Promise<LatestVersion>; /** * Switch update channel */ setChannel(channel: string): Promise<void>; /** * Set update server URL */ setUpdateUrl(url: string): Promise<void>; /** * Validate an update bundle */ validateUpdate(options: ValidateOptions): Promise<ValidationResult>; } /** * App Update Plugin Interface */ export interface AppUpdatePlugin { /** * Get app update information */ getAppUpdateInfo(): Promise<AppUpdateInfo>; /** * Perform immediate update */ performImmediateUpdate(): Promise<void>; /** * Start flexible update */ startFlexibleUpdate(): Promise<void>; /** * Complete flexible update */ completeFlexibleUpdate(): Promise<void>; /** * Open app store page */ openAppStore(options?: OpenAppStoreOptions): Promise<void>; } /** * App Review Plugin Interface */ export interface AppReviewPlugin { /** * Request in-app review */ requestReview(): Promise<ReviewResult>; /** * Check if review can be requested */ canRequestReview(): Promise<CanRequestReviewResult>; } /** * Background Update Plugin Interface */ export interface BackgroundUpdatePlugin { /** * Enable background update checking */ enableBackgroundUpdates(config: BackgroundUpdateConfig): Promise<void>; /** * Disable background update checking */ disableBackgroundUpdates(): Promise<void>; /** * Get current background update status */ getBackgroundUpdateStatus(): Promise<BackgroundUpdateStatus>; /** * Schedule background update check with specific interval */ scheduleBackgroundCheck(interval: number): Promise<void>; /** * Manually trigger background update check */ triggerBackgroundCheck(): Promise<BackgroundCheckResult>; /** * Configure notification preferences */ setNotificationPreferences(preferences: NotificationPreferences): Promise<void>; /** * Get notification permissions status */ getNotificationPermissions(): Promise<NotificationPermissionStatus>; /** * Request notification permissions */ requestNotificationPermissions(): Promise<boolean>; } /** * Combined plugin interface */ export interface NativeUpdateCombinedPlugin extends LiveUpdatePlugin, AppUpdatePlugin, AppReviewPlugin, BackgroundUpdatePlugin { /** * Configure the plugin with initial settings */ configure(config: UpdateConfig | { config: PluginInitConfig; }): Promise<void>; /** * Get current security configuration */ getSecurityInfo(): Promise<SecurityInfo>; } /** * Configuration Types */ export interface PluginConfig { serverUrl?: string; channel?: string; autoCheck?: boolean; autoUpdate?: boolean; updateStrategy?: UpdateStrategy; publicKey?: string; requireSignature?: boolean; checksumAlgorithm?: ChecksumAlgorithm; checkInterval?: number; security?: SecurityConfig; } export interface UpdateConfig { liveUpdate?: LiveUpdateConfig; appUpdate?: AppUpdateConfig; appReview?: AppReviewConfig; backgroundUpdate?: BackgroundUpdateConfig; security?: SecurityConfig; } export interface LiveUpdateConfig { appId: string; serverUrl: string; channel?: string; autoUpdate?: boolean; updateStrategy?: UpdateStrategy; publicKey?: string; requireSignature?: boolean; checksumAlgorithm?: ChecksumAlgorithm; checkInterval?: number; allowEmulator?: boolean; mandatoryInstallMode?: InstallMode; optionalInstallMode?: InstallMode; maxBundleSize?: number; allowedHosts?: string[]; } export interface AppUpdateConfig { minimumVersion?: string; updatePriority?: number; storeUrl?: { android?: string; ios?: string; }; checkOnAppStart?: boolean; allowDowngrade?: boolean; } export interface AppReviewConfig { minimumDaysSinceInstall?: number; minimumDaysSinceLastPrompt?: number; minimumLaunchCount?: number; customTriggers?: string[]; debugMode?: boolean; } export interface BackgroundUpdateConfig { enabled: boolean; checkInterval: number; updateTypes: BackgroundUpdateType[]; autoInstall?: boolean; notificationPreferences?: NotificationPreferences; respectBatteryOptimization?: boolean; allowMeteredConnection?: boolean; minimumBatteryLevel?: number; requireWifi?: boolean; maxRetries?: number; retryDelay?: number; taskIdentifier?: string; } export interface SecurityConfig { enforceHttps?: boolean; certificatePinning?: CertificatePinning; validateInputs?: boolean; secureStorage?: boolean; logSecurityEvents?: boolean; } export interface CertificatePinning { enabled: boolean; pins: CertificatePin[]; } export interface CertificatePin { hostname: string; sha256: string[]; } /** * Live Update Types */ export interface SyncOptions { channel?: string; updateMode?: UpdateMode; } export interface SyncResult { status: SyncStatus; version?: string; description?: string; mandatory?: boolean; error?: UpdateError; } export interface DownloadOptions { url: string; version: string; checksum: string; signature?: string; maxRetries?: number; timeout?: number; } export interface BundleInfo { bundleId: string; version: string; path: string; downloadTime: number; size: number; status: BundleStatus; checksum: string; signature?: string; verified: boolean; metadata?: Record<string, unknown>; } export interface DeleteOptions { bundleId?: string; keepVersions?: number; olderThan?: number; } export interface UpdateOptions { allowDowngrade?: boolean; cleanupOldBundles?: boolean; keepBundleCount?: number; } export interface LatestVersion { available: boolean; version?: string; url?: string; mandatory?: boolean; notes?: string; size?: number; } export interface ValidateOptions { bundlePath: string; checksum: string; signature?: string; maxSize?: number; } export interface ValidationResult { isValid: boolean; error?: string; details?: { checksumValid?: boolean; signatureValid?: boolean; sizeValid?: boolean; versionValid?: boolean; }; } /** * App Update Types */ export interface AppUpdateInfo { updateAvailable: boolean; currentVersion: string; availableVersion?: string; updatePriority?: number; immediateUpdateAllowed?: boolean; flexibleUpdateAllowed?: boolean; clientVersionStalenessDays?: number; installStatus?: InstallStatus; bytesDownloaded?: number; totalBytesToDownload?: number; } export interface OpenAppStoreOptions { appId?: string; } /** * App Review Types */ export interface ReviewResult { displayed: boolean; error?: string; reason?: string; } export interface CanRequestReviewResult { canRequest: boolean; reason?: string; } /** * Background Update Types */ export interface BackgroundUpdateStatus { enabled: boolean; lastCheckTime?: number; nextCheckTime?: number; lastUpdateTime?: number; currentTaskId?: string; isRunning: boolean; checkCount: number; failureCount: number; lastError?: UpdateError; } export interface BackgroundCheckResult { success: boolean; updatesFound: boolean; appUpdate?: AppUpdateInfo; liveUpdate?: LatestVersion; notificationSent: boolean; error?: UpdateError; } export interface NotificationPreferences { title?: string; description?: string; iconName?: string; soundEnabled?: boolean; vibrationEnabled?: boolean; showActions?: boolean; actionLabels?: { updateNow?: string; updateLater?: string; dismiss?: string; }; channelId?: string; channelName?: string; priority?: NotificationPriority; } export interface NotificationPermissionStatus { granted: boolean; canRequest: boolean; shouldShowRationale?: boolean; } /** * Security Types */ export interface SecurityInfo { enforceHttps: boolean; certificatePinning: CertificatePinning; validateInputs: boolean; secureStorage: boolean; } /** * Error Types */ export interface UpdateError { code: UpdateErrorCode; message: string; details?: unknown; } /** * Enums */ export declare enum BackgroundUpdateType { APP_UPDATE = "app_update", LIVE_UPDATE = "live_update", BOTH = "both" } export declare enum NotificationPriority { MIN = "min", LOW = "low", DEFAULT = "default", HIGH = "high", MAX = "max" } export declare enum UpdateStrategy { IMMEDIATE = "immediate", BACKGROUND = "background", MANUAL = "manual" } export declare enum UpdateMode { IMMEDIATE = "immediate", ON_NEXT_RESTART = "on_next_restart", ON_NEXT_RESUME = "on_next_resume" } export declare enum InstallMode { IMMEDIATE = "immediate", ON_NEXT_RESTART = "on_next_restart", ON_NEXT_RESUME = "on_next_resume" } export declare enum ChecksumAlgorithm { SHA256 = "SHA-256", SHA512 = "SHA-512" } export declare enum SyncStatus { UP_TO_DATE = "UP_TO_DATE", UPDATE_AVAILABLE = "UPDATE_AVAILABLE", UPDATE_INSTALLED = "UPDATE_INSTALLED", ERROR = "ERROR" } export declare enum BundleStatus { PENDING = "PENDING", DOWNLOADING = "DOWNLOADING", READY = "READY", ACTIVE = "ACTIVE", FAILED = "FAILED" } export declare enum InstallStatus { UNKNOWN = "UNKNOWN", PENDING = "PENDING", DOWNLOADING = "DOWNLOADING", DOWNLOADED = "DOWNLOADED", INSTALLING = "INSTALLING", INSTALLED = "INSTALLED", FAILED = "FAILED", CANCELED = "CANCELED" } export declare enum UpdateErrorCode { NETWORK_ERROR = "NETWORK_ERROR", SERVER_ERROR = "SERVER_ERROR", TIMEOUT_ERROR = "TIMEOUT_ERROR", DOWNLOAD_ERROR = "DOWNLOAD_ERROR", STORAGE_ERROR = "STORAGE_ERROR", SIZE_LIMIT_EXCEEDED = "SIZE_LIMIT_EXCEEDED", VERIFICATION_ERROR = "VERIFICATION_ERROR", CHECKSUM_ERROR = "CHECKSUM_ERROR", SIGNATURE_ERROR = "SIGNATURE_ERROR", INSECURE_URL = "INSECURE_URL", INVALID_CERTIFICATE = "INVALID_CERTIFICATE", PATH_TRAVERSAL = "PATH_TRAVERSAL", INSTALL_ERROR = "INSTALL_ERROR", ROLLBACK_ERROR = "ROLLBACK_ERROR", VERSION_MISMATCH = "VERSION_MISMATCH", PERMISSION_DENIED = "PERMISSION_DENIED", UPDATE_NOT_AVAILABLE = "UPDATE_NOT_AVAILABLE", UPDATE_IN_PROGRESS = "UPDATE_IN_PROGRESS", UPDATE_CANCELLED = "UPDATE_CANCELLED", PLATFORM_NOT_SUPPORTED = "PLATFORM_NOT_SUPPORTED", REVIEW_NOT_SUPPORTED = "REVIEW_NOT_SUPPORTED", QUOTA_EXCEEDED = "QUOTA_EXCEEDED", CONDITIONS_NOT_MET = "CONDITIONS_NOT_MET", INVALID_CONFIG = "INVALID_CONFIG", UNKNOWN_ERROR = "UNKNOWN_ERROR" } /** * Event Types */ export interface DownloadProgressEvent { percent: number; bytesDownloaded: number; totalBytes: number; bundleId: string; } export interface UpdateStateChangedEvent { status: BundleStatus; bundleId: string; version: string; } export interface BackgroundUpdateProgressEvent { type: BackgroundUpdateType; status: 'checking' | 'downloading' | 'installing' | 'completed' | 'failed'; percent?: number; error?: UpdateError; } export interface BackgroundUpdateNotificationEvent { type: BackgroundUpdateType; updateAvailable: boolean; version?: string; action?: 'shown' | 'tapped' | 'dismissed'; } /** * App Update Events */ export interface AppUpdateStateChangedEvent { status: InstallStatus; installErrorCode?: number; } export interface AppUpdateProgressEvent { percent: number; bytesDownloaded: number; totalBytes: number; } export interface AppUpdateAvailableEvent { currentVersion: string; availableVersion: string; updatePriority: number; updateSize?: number; releaseNotes?: string[]; storeUrl?: string; } export interface AppUpdateReadyEvent { message: string; } export interface AppUpdateFailedEvent { error: string; code: string; } export interface AppUpdateNotificationClickedEvent { } export interface AppUpdateInstallClickedEvent { } /** * Plugin Events */ export interface PluginListenerHandle { remove: () => Promise<void>; } export interface NativeUpdateListeners { /** * Listen for download progress */ addListener(eventName: 'downloadProgress', listenerFunc: (event: DownloadProgressEvent) => void): Promise<PluginListenerHandle>; /** * Listen for update state changes */ addListener(eventName: 'updateStateChanged', listenerFunc: (event: UpdateStateChangedEvent) => void): Promise<PluginListenerHandle>; /** * Listen for background update progress */ addListener(eventName: 'backgroundUpdateProgress', listenerFunc: (event: BackgroundUpdateProgressEvent) => void): Promise<PluginListenerHandle>; /** * Listen for background update notifications */ addListener(eventName: 'backgroundUpdateNotification', listenerFunc: (event: BackgroundUpdateNotificationEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update state changes */ addListener(eventName: 'appUpdateStateChanged', listenerFunc: (event: AppUpdateStateChangedEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update progress */ addListener(eventName: 'appUpdateProgress', listenerFunc: (event: AppUpdateProgressEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update available */ addListener(eventName: 'appUpdateAvailable', listenerFunc: (event: AppUpdateAvailableEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update ready */ addListener(eventName: 'appUpdateReady', listenerFunc: (event: AppUpdateReadyEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update failed */ addListener(eventName: 'appUpdateFailed', listenerFunc: (event: AppUpdateFailedEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update notification clicked */ addListener(eventName: 'appUpdateNotificationClicked', listenerFunc: (event: AppUpdateNotificationClickedEvent) => void): Promise<PluginListenerHandle>; /** * Listen for app update install clicked */ addListener(eventName: 'appUpdateInstallClicked', listenerFunc: (event: AppUpdateInstallClickedEvent) => void): Promise<PluginListenerHandle>; /** * Remove all listeners */ removeAllListeners(): Promise<void>; } /** * Plugin initialization configuration options */ export interface PluginInitConfig { /** * Capacitor Filesystem instance (required) */ filesystem?: typeof import('@capacitor/filesystem').Filesystem; /** * Capacitor Preferences instance (required) */ preferences?: typeof import('@capacitor/preferences').Preferences; /** * Base URL for update server */ baseUrl?: string; /** * List of allowed hosts for security */ allowedHosts?: string[]; /** * Maximum bundle size in bytes (default: 100MB) */ maxBundleSize?: number; /** * Download timeout in milliseconds (default: 30000) */ downloadTimeout?: number; /** * Number of retry attempts for failed downloads (default: 3) */ retryAttempts?: number; /** * Delay between retry attempts in milliseconds (default: 1000) */ retryDelay?: number; /** * Enable bundle signature validation (default: true) */ enableSignatureValidation?: boolean; /** * Public key for signature validation */ publicKey?: string; /** * Cache expiration time in milliseconds (default: 24 hours) */ cacheExpiration?: number; /** * Enable debug logging (default: false) */ enableLogging?: boolean; /** * Server URL for update checks */ serverUrl?: string; /** * Update channel */ channel?: string; /** * Enable automatic update checking */ autoCheck?: boolean; /** * Enable automatic updates */ autoUpdate?: boolean; /** * Update strategy */ updateStrategy?: UpdateStrategy; /** * Require bundle signatures */ requireSignature?: boolean; /** * Checksum algorithm to use */ checksumAlgorithm?: ChecksumAlgorithm; /** * Update check interval in milliseconds */ checkInterval?: number; /** * Security configuration */ security?: SecurityConfig; } /** * Main plugin interface with initialization */ export interface NativeUpdatePlugin extends NativeUpdateCombinedPlugin, NativeUpdateListeners { /** * Initialize the plugin with configuration */ initialize(config: PluginInitConfig): Promise<void>; /** * Check if plugin is initialized */ isInitialized(): boolean; /** * Reset plugin state */ reset(): Promise<void>; /** * Clean up resources */ cleanup(): Promise<void>; }