// import local dependencies
import {checkForUpdates} from '../utils';
import {download} from '../utils/files'
import {Modules} from '../constants';
import {fs, path} from '../utils/contextuals'
const browserCheck = () => {
if (typeof window !== undefined) {
throw new Error('Forbidden reference of Upgrader in browser environment')
}
}
/**
* The Upgrader class controls the update process using the info passed down from the
* parent application. It ensures that all the fs interactions occur that are necessary
* to treat a local directory as an update stream for nuget packages.
*/
class Upgrader {
constructor ({appDataPath, downloadPath}) {
browserCheck()
this._appData = path.resolve(appDataPath);
this._dir = path.join(downloadPath || this._appData, 'upgrade');
this._initialized = false;
this._updateCache = {};
}
/**
* Initialize the upgrader and ensure the appropriate file directories are accessible.
* @private
*/
_init () {
if (!this._initialized) {
try {
// dynamic reference for browser compatibility
fs.ensureDirSync(this._dir)
this._initialized = true;
} catch (err) {
throw new Error(`Error initializing electron upgrader: ${err.message}`)
}
}
}
/**
* Retrieve and cache the updates available for electron based on the
* specified current version and environment.
* @param currentVersion
* @param environment
* @returns {Promise<Object>}
*/
async _getLatestUpdate ({currentVersion, environment}) {
if (!this._updateCache[environment]) {
this._updateCache[environment] = await checkForUpdates({
module: Modules.ELECTRON,
currentVersion,
environment,
});
}
return this._updateCache[environment];
}
/**
* Returns true if the next electron update is a major version upgrade.
* @param latestUpdate
* @param currentVersion
* @param environment
* @returns {Promise<boolean>}
*/
async shouldUpgrade ({latestUpdate, currentVersion, environment}) {
this._init();
const electronUpdate = latestUpdate || await this._getLatestUpdate({currentVersion, environment});
return !!electronUpdate?.updateAvailable &&
!!electronUpdate?.attributes?.isDependency &&
electronUpdate?.latest?.nupkgUrl && electronUpdate?.latest?.releasesFile;
}
/**
* Download the electron upgrade to the file system and prepare it for installation.
* @param electronUpdate
* @param onDownloadProgress
* @returns {Promise<void>}
*/
async prepareElectronUpgrade ({latestUpdate, currentVersion, environment, onDownloadProgress}) {
this._init();
// get the latest update (presumably cached at this point)
const electronUpdate = latestUpdate || await this._getLatestUpdate({currentVersion, environment});
if (!electronUpdate?.latest?.nupkgUrl || !electronUpdate?.latest.nupkgReleasesFileUrl) {
throw new Error('Missing nupkgUrl or nupkgReleasesFileUrl properties on latest version entry');
}
// download the nuget package
await download(electronUpdate.latest.nupkgUrl, path.join(this._dir, electronUpdate.latest.nupkgUrl.split('/').pop()), onDownloadProgress);
// download the releases file
await download(electronUpdate.latest.nupkgReleasesFileUrl, path.join(this._dir, electronUpdate.latest.nupkgReleasesFileUrl.split('/').pop()), onDownloadProgress);
}
/**
* Get the path to use as the feed url for the electron autoUpdater module.
* @returns {string}
*/
getFeedURL () {
return this._dir;
}
}
export default Upgrader;