1 | import path from 'path'
|
2 | import axios from 'axios';
|
3 | import electron from 'electron'
|
4 | import {compare} from 'compare-versions';
|
5 | import gh from 'github-url-to-object';
|
6 |
|
7 | interface Options {
|
8 | repository?: string
|
9 | token?: string,
|
10 | debug?: boolean,
|
11 | silent?: boolean,
|
12 | }
|
13 |
|
14 | interface GithubReleaseObject {
|
15 | tag_name: string,
|
16 | body: string,
|
17 | html_url: string,
|
18 | }
|
19 |
|
20 | export const defaultOptions: Options = {
|
21 | debug: false,
|
22 | silent: true,
|
23 | };
|
24 |
|
25 | export function setUpdateNotification(options: Options = defaultOptions) {
|
26 | const withDefaults = Object.assign(defaultOptions, options);
|
27 |
|
28 | if (electron.app.isReady()) {
|
29 | checkForUpdates(withDefaults)
|
30 | } else {
|
31 | electron.app.on('ready', () => {
|
32 | checkForUpdates(withDefaults)
|
33 | })
|
34 | }
|
35 | }
|
36 |
|
37 | export async function checkForUpdates({repository, token, debug, silent}: Options = defaultOptions) {
|
38 | if (!electron.app.isPackaged && !debug) return
|
39 |
|
40 | if (!repository) {
|
41 | const pkg = require(path.join(electron.app.getAppPath(), 'package.json'))
|
42 | const ghObj = gh(pkg.repository)
|
43 |
|
44 | if (!ghObj) {
|
45 | throw new Error('Repository URL not found in package.json file.');
|
46 | }
|
47 |
|
48 | repository = ghObj.user + '/' + ghObj.repo
|
49 | }
|
50 |
|
51 | let latestRelease: null | GithubReleaseObject = null;
|
52 |
|
53 | try {
|
54 | const {data: releases} = await axios.get(`https://api.github.com/repos/${repository}/releases`,
|
55 | {
|
56 | headers: token ? {authorization: `token ${token}`} : {},
|
57 | },
|
58 | )
|
59 |
|
60 | latestRelease = releases[0] as GithubReleaseObject
|
61 | } catch (error) {
|
62 | console.error(error)
|
63 |
|
64 | if (!silent) {
|
65 | showDialog('Unable to check for updates at this moment. Try again.', 'error');
|
66 | }
|
67 | }
|
68 |
|
69 | if (!latestRelease) return
|
70 |
|
71 | if (compare(latestRelease.tag_name, electron.app.getVersion(), '>')) {
|
72 | showUpdateDialog(latestRelease)
|
73 | } else {
|
74 | if (!silent) {
|
75 | showDialog(`You are already running the latest version.`);
|
76 | }
|
77 | }
|
78 | }
|
79 |
|
80 | export function showUpdateDialog(release: GithubReleaseObject) {
|
81 | electron.dialog.showMessageBox(
|
82 | {
|
83 | title: electron.app.getName(),
|
84 | type: 'info',
|
85 | message: `New release available`,
|
86 | detail: `Installed Version: ${electron.app.getVersion()}\nLatest Version: ${release.tag_name}\n\n${release.body}`.trim(),
|
87 | buttons: ['Download', 'Later'],
|
88 | defaultId: 0,
|
89 | cancelId: 1,
|
90 | },
|
91 | )
|
92 | .then(({response}) => {
|
93 | if (response === 0) {
|
94 | setImmediate(() => {
|
95 | electron.shell.openExternal(release.html_url)
|
96 | })
|
97 | }
|
98 | })
|
99 | .catch((error) => {
|
100 | throw new Error(error)
|
101 | })
|
102 | }
|
103 |
|
104 | const showDialog = (detail: string, type: string = 'info') => {
|
105 | electron.dialog.showMessageBox(
|
106 | {
|
107 | title: electron.app.getName(),
|
108 | message: 'Update checker',
|
109 | buttons: ['Close'],
|
110 | defaultId: 0,
|
111 | cancelId: 0,
|
112 | type,
|
113 | detail,
|
114 | },
|
115 | )
|
116 | }
|