capacitor-native-update
Version:
Native Update Plugin for Capacitor
283 lines • 10.2 kB
JavaScript
import { registerPlugin } from '@capacitor/core';
import { SyncStatus, BundleStatus, UpdateErrorCode } from './definitions';
import { PluginManager } from './core/plugin-manager';
import { CapacitorNativeUpdateError, ErrorCode } from './core/errors';
/**
* Web implementation of the Capacitor Native Update Plugin
*/
class CapacitorNativeUpdatePluginWeb {
constructor() {
this.initialized = false;
this.pluginManager = PluginManager.getInstance();
}
// Main plugin methods
async initialize(config) {
await this.pluginManager.initialize(config);
this.initialized = true;
}
isInitialized() {
return this.initialized && this.pluginManager.isInitialized();
}
async reset() {
await this.pluginManager.reset();
}
async cleanup() {
await this.pluginManager.cleanup();
}
// NativeUpdatePlugin methods
async configure(options) {
var _a, _b;
if (!this.initialized) {
throw new CapacitorNativeUpdateError(ErrorCode.NOT_CONFIGURED, 'Plugin not initialized. Call initialize() first.');
}
// Apply update configuration
const configManager = this.pluginManager.getConfigManager();
if ((_a = options.liveUpdate) === null || _a === void 0 ? void 0 : _a.allowedHosts) {
configManager.configure({ allowedHosts: options.liveUpdate.allowedHosts });
}
if ((_b = options.liveUpdate) === null || _b === void 0 ? void 0 : _b.maxBundleSize) {
configManager.configure({ maxBundleSize: options.liveUpdate.maxBundleSize });
}
}
async getSecurityInfo() {
return {
enforceHttps: true,
certificatePinning: {
enabled: false,
certificates: [],
},
validateInputs: true,
secureStorage: true,
};
}
// LiveUpdatePlugin methods
async sync(_options) {
const bundleManager = this.pluginManager.getBundleManager();
try {
// Check for updates
const currentBundle = await bundleManager.getActiveBundle();
const currentVersion = (currentBundle === null || currentBundle === void 0 ? void 0 : currentBundle.version) || '1.0.0';
// For now, return up-to-date status
return {
status: SyncStatus.UP_TO_DATE,
version: currentVersion,
};
}
catch (error) {
return {
status: SyncStatus.ERROR,
error: {
code: UpdateErrorCode.UNKNOWN_ERROR,
message: error instanceof Error ? error.message : 'Sync failed',
},
};
}
}
async download(options) {
const downloadManager = this.pluginManager.getDownloadManager();
const bundleManager = this.pluginManager.getBundleManager();
const blob = await downloadManager.downloadWithRetry(options.url, options.version);
const path = await downloadManager.saveBlob(options.version, blob);
const bundleInfo = {
bundleId: options.version,
version: options.version,
path,
downloadTime: Date.now(),
size: blob.size,
status: BundleStatus.READY,
checksum: options.checksum,
signature: options.signature,
verified: false,
};
await bundleManager.saveBundleInfo(bundleInfo);
return bundleInfo;
}
async set(bundle) {
const bundleManager = this.pluginManager.getBundleManager();
await bundleManager.setActiveBundle(bundle.bundleId);
}
async reload() {
// In web implementation, we can reload the page
if (typeof window !== 'undefined') {
window.location.reload();
}
}
async current() {
const bundleManager = this.pluginManager.getBundleManager();
const bundle = await bundleManager.getActiveBundle();
if (!bundle) {
throw new CapacitorNativeUpdateError(ErrorCode.FILE_NOT_FOUND, 'No active bundle found');
}
return bundle;
}
async list() {
const bundleManager = this.pluginManager.getBundleManager();
return bundleManager.getAllBundles();
}
async delete(options) {
const bundleManager = this.pluginManager.getBundleManager();
if (options.bundleId) {
await bundleManager.deleteBundle(options.bundleId);
}
else if (options.keepVersions !== undefined) {
// Delete old versions keeping the specified number
const bundles = await bundleManager.getAllBundles();
const sortedBundles = bundles.sort((a, b) => b.downloadTime - a.downloadTime);
for (let i = options.keepVersions; i < sortedBundles.length; i++) {
await bundleManager.deleteBundle(sortedBundles[i].bundleId);
}
}
}
async notifyAppReady() {
// Mark the current bundle as stable
const bundleManager = this.pluginManager.getBundleManager();
const activeBundle = await bundleManager.getActiveBundle();
if (activeBundle) {
activeBundle.status = BundleStatus.ACTIVE;
await bundleManager.saveBundleInfo(activeBundle);
}
}
async getLatest() {
// For web, we'll return no update available
return {
available: false,
};
}
async setChannel(channel) {
// Store the channel preference
const preferences = this.pluginManager.getConfigManager().get('preferences');
if (preferences) {
await preferences.set({
key: 'update_channel',
value: channel,
});
}
}
async setUpdateUrl(url) {
const configManager = this.pluginManager.getConfigManager();
configManager.configure({ baseUrl: url });
}
async validateUpdate(options) {
const securityValidator = this.pluginManager.getSecurityValidator();
try {
// Validate checksum
const isValid = await securityValidator.validateChecksum(new ArrayBuffer(0), // Placeholder for bundle data
options.checksum);
return {
isValid,
details: {
checksumValid: isValid,
signatureValid: true,
sizeValid: true,
versionValid: true,
},
};
}
catch (error) {
return {
isValid: false,
error: error instanceof Error ? error.message : 'Validation failed',
};
}
}
// AppUpdatePlugin methods
async getAppUpdateInfo() {
// Web doesn't have native app updates
return {
updateAvailable: false,
currentVersion: '1.0.0',
};
}
async performImmediateUpdate() {
throw new CapacitorNativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');
}
async startFlexibleUpdate() {
throw new CapacitorNativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');
}
async completeFlexibleUpdate() {
throw new CapacitorNativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Native app updates are not supported on web');
}
async openAppStore(_options) {
throw new CapacitorNativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'App store is not available on web');
}
// AppReviewPlugin methods
async requestReview() {
return {
shown: false,
error: 'Reviews are not supported on web',
};
}
async canRequestReview() {
return {
allowed: false,
reason: 'Reviews are not supported on web',
};
}
// BackgroundUpdatePlugin methods
async enableBackgroundUpdates(config) {
// Store the configuration
const preferences = this.pluginManager.getConfigManager().get('preferences');
if (preferences) {
await preferences.set({
key: 'background_update_config',
value: JSON.stringify(config),
});
}
}
async disableBackgroundUpdates() {
const preferences = this.pluginManager.getConfigManager().get('preferences');
if (preferences) {
await preferences.remove({ key: 'background_update_config' });
}
}
async getBackgroundUpdateStatus() {
return {
enabled: false,
isRunning: false,
checkCount: 0,
failureCount: 0,
};
}
async scheduleBackgroundCheck(_interval) {
// Not supported on web
throw new CapacitorNativeUpdateError(ErrorCode.PLATFORM_NOT_SUPPORTED, 'Background updates are not supported on web');
}
async triggerBackgroundCheck() {
return {
success: false,
updatesFound: false,
notificationSent: false,
error: {
code: UpdateErrorCode.PLATFORM_NOT_SUPPORTED,
message: 'Background updates are not supported on web',
},
};
}
async setNotificationPreferences(preferences) {
// Store preferences but notifications aren't supported on web
const prefs = this.pluginManager.getConfigManager().get('preferences');
if (prefs) {
await prefs.set({
key: 'notification_preferences',
value: JSON.stringify(preferences),
});
}
}
async getNotificationPermissions() {
return {
granted: false,
canRequest: false,
};
}
async requestNotificationPermissions() {
return false;
}
}
/**
* Register the plugin
*/
const CapacitorNativeUpdate = registerPlugin('CapacitorNativeUpdate', {
web: () => new CapacitorNativeUpdatePluginWeb(),
});
export { CapacitorNativeUpdate };
//# sourceMappingURL=plugin.js.map