hyper/app/updater.ts

135 lines
3.7 KiB
TypeScript
Raw Normal View History

// Packages
2023-06-26 01:29:50 -08:00
import electron, {app} from 'electron';
import type {BrowserWindow, AutoUpdater as OriginalAutoUpdater} from 'electron';
2023-07-25 09:30:19 -08:00
2019-11-28 05:17:01 -09:00
import retry from 'async-retry';
2023-07-25 09:30:19 -08:00
import ms from 'ms';
2016-07-06 06:58:39 -08:00
// Utilities
2019-12-27 05:16:56 -09:00
import autoUpdaterLinux from './auto-updater-linux';
2023-06-28 22:21:51 -08:00
import {getDefaultProfile} from './config';
2023-07-25 09:30:19 -08:00
import {version} from './package.json';
import {getDecoratedConfig} from './plugins';
// Necessary due to typescript not handling overloads well
type AutoUpdaterEvent =
| 'error'
| 'checking-for-update'
| 'before-quit-for-update'
| 'update-downloaded'
| 'update-available'
| 'update-not-available';
interface AutoUpdater extends OriginalAutoUpdater {
on(event: AutoUpdaterEvent, listener: Function): this;
removeListener(event: AutoUpdaterEvent, listener: Function): this;
}
2017-08-04 13:52:38 -08:00
const {platform} = process;
const isLinux = platform === 'linux';
2019-12-27 05:16:56 -09:00
const autoUpdater: AutoUpdater = isLinux ? autoUpdaterLinux : electron.autoUpdater;
2017-08-04 13:52:38 -08:00
const getDecoratedConfigWithRetry = async () => {
return await retry(() => {
2023-06-28 22:21:51 -08:00
const content = getDecoratedConfig(getDefaultProfile());
if (!content) {
throw new Error('No config content loaded');
}
return content;
});
};
const checkForUpdates = async () => {
const config = await getDecoratedConfigWithRetry();
if (!config.disableAutoUpdates) {
autoUpdater.checkForUpdates();
}
};
2016-07-07 15:19:39 -08:00
let isInit = false;
// Default to the "stable" update channel
let canaryUpdates = false;
2019-12-27 05:16:56 -09:00
const buildFeedUrl = (canary: boolean, currentVersion: string) => {
const updatePrefix = canary ? 'releases-canary' : 'releases';
2022-01-31 08:49:25 -09:00
const archSuffix = process.arch === 'arm64' || app.runningUnderARM64Translation ? '_arm64' : '';
2021-07-24 04:17:11 -08:00
return `https://${updatePrefix}.hyper.is/update/${isLinux ? 'deb' : platform}${archSuffix}/${currentVersion}`;
};
2019-12-27 05:16:56 -09:00
const isCanary = (updateChannel: string) => updateChannel === 'canary';
2016-07-06 06:58:39 -08:00
2017-09-20 09:35:50 -08:00
async function init() {
2020-03-25 02:15:08 -08:00
autoUpdater.on('error', (err) => {
2019-12-27 05:16:56 -09:00
console.error('Error fetching updates', `${err.message} (${err.stack})`);
2016-07-06 06:58:39 -08:00
});
const config = await getDecoratedConfigWithRetry();
// If defined in the config, switch to the "canary" channel
if (config.updateChannel && isCanary(config.updateChannel)) {
canaryUpdates = true;
}
const feedURL = buildFeedUrl(canaryUpdates, version);
2019-12-27 05:16:56 -09:00
autoUpdater.setFeedURL({url: feedURL});
2016-07-06 06:58:39 -08:00
2016-07-07 15:19:39 -08:00
setTimeout(() => {
void checkForUpdates();
2016-07-07 15:19:39 -08:00
}, ms('10s'));
setInterval(() => {
void checkForUpdates();
}, ms('30m'));
2016-07-07 15:19:39 -08:00
isInit = true;
}
2023-07-25 08:11:02 -08:00
const updater = (win: BrowserWindow) => {
if (!isInit) {
void init();
}
2016-07-07 15:19:39 -08:00
const {rpc} = win;
2016-07-07 15:19:39 -08:00
2023-06-25 04:27:42 -08:00
const onupdate = (ev: Event, releaseNotes: string, releaseName: string, date: Date, updateUrl: string) => {
const releaseUrl = updateUrl || `https://github.com/vercel/hyper/releases/tag/${releaseName}`;
2023-06-25 04:27:42 -08:00
rpc.emit('update available', {releaseNotes, releaseName, releaseUrl, canInstall: !isLinux});
2016-07-07 15:19:39 -08:00
};
2016-07-06 06:58:39 -08:00
2023-06-25 04:27:42 -08:00
if (isLinux) {
autoUpdater.on('update-available', onupdate);
} else {
autoUpdater.on('update-downloaded', onupdate);
}
2016-07-07 15:19:39 -08:00
rpc.once('quit and install', () => {
2016-07-06 06:58:39 -08:00
autoUpdater.quitAndInstall();
});
app.config.subscribe(async () => {
const {updateChannel} = await getDecoratedConfigWithRetry();
const newUpdateIsCanary = isCanary(updateChannel);
if (newUpdateIsCanary !== canaryUpdates) {
const feedURL = buildFeedUrl(newUpdateIsCanary, version);
2019-12-27 05:16:56 -09:00
autoUpdater.setFeedURL({url: feedURL});
void checkForUpdates();
canaryUpdates = newUpdateIsCanary;
}
});
2016-07-07 15:19:39 -08:00
win.on('close', () => {
2023-06-25 04:27:42 -08:00
if (isLinux) {
autoUpdater.removeListener('update-available', onupdate);
} else {
autoUpdater.removeListener('update-downloaded', onupdate);
}
2016-07-07 15:19:39 -08:00
});
2016-07-06 06:58:39 -08:00
};
2023-07-25 08:11:02 -08:00
export default updater;