electron-incremental-update 0.9.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -112
- package/dist/{chunk-CMBFI77K.mjs → chunk-GB6VLKJZ.mjs} +48 -28
- package/dist/{chunk-5BZLJPHJ.mjs → chunk-GXZSAUBR.mjs} +1 -8
- package/dist/chunk-OUZLSVQC.mjs +148 -0
- package/dist/index.d.mts +102 -80
- package/dist/index.d.ts +102 -80
- package/dist/index.js +134 -71
- package/dist/index.mjs +97 -43
- package/dist/noDep-TvZoKVF8.d.mts +31 -0
- package/dist/noDep-TvZoKVF8.d.ts +31 -0
- package/dist/utils.d.mts +85 -48
- package/dist/utils.d.ts +85 -48
- package/dist/utils.js +127 -86
- package/dist/utils.mjs +14 -20
- package/dist/vite.d.mts +218 -41
- package/dist/vite.d.ts +218 -41
- package/dist/vite.js +245 -122
- package/dist/vite.mjs +222 -98
- package/package.json +18 -11
- package/dist/chunk-SPZL37O5.mjs +0 -124
- package/dist/updateJson-synsK-Pt.d.mts +0 -11
- package/dist/updateJson-synsK-Pt.d.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -20,39 +20,51 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
|
|
23
|
+
DownloadError: () => DownloadError,
|
|
24
|
+
MinimumVersionError: () => MinimumVersionError,
|
|
25
|
+
Updater: () => Updater,
|
|
26
|
+
VerifyFailedError: () => VerifyFailedError,
|
|
24
27
|
createUpdater: () => createUpdater,
|
|
25
|
-
initApp: () => initApp
|
|
28
|
+
initApp: () => initApp,
|
|
29
|
+
startupWithUpdater: () => startupWithUpdater
|
|
26
30
|
});
|
|
27
31
|
module.exports = __toCommonJS(src_exports);
|
|
28
32
|
var import_node_path2 = require("path");
|
|
29
33
|
var import_node_fs4 = require("fs");
|
|
30
|
-
var
|
|
34
|
+
var import_electron4 = require("electron");
|
|
31
35
|
|
|
32
|
-
// src/updater/
|
|
36
|
+
// src/updater/core.ts
|
|
33
37
|
var import_node_fs3 = require("fs");
|
|
34
38
|
var import_promises = require("fs/promises");
|
|
39
|
+
var import_electron3 = require("electron");
|
|
35
40
|
|
|
36
|
-
// src/utils/
|
|
41
|
+
// src/utils/electron.ts
|
|
37
42
|
var import_node_fs = require("fs");
|
|
38
43
|
var import_node_path = require("path");
|
|
39
44
|
var import_node_os = require("os");
|
|
40
45
|
var import_electron = require("electron");
|
|
41
|
-
var DEFAULT_APP_NAME = "product";
|
|
42
46
|
var is = {
|
|
43
47
|
dev: !import_electron.app.isPackaged,
|
|
44
48
|
win: process.platform === "win32",
|
|
45
49
|
mac: process.platform === "darwin",
|
|
46
50
|
linux: process.platform === "linux"
|
|
47
51
|
};
|
|
48
|
-
function
|
|
49
|
-
return
|
|
52
|
+
function getPathFromAppNameAsar(...path) {
|
|
53
|
+
return is.dev ? "DEV.asar" : (0, import_node_path.join)((0, import_node_path.dirname)(import_electron.app.getAppPath()), `${import_electron.app.name}.asar`, ...path);
|
|
50
54
|
}
|
|
51
|
-
function
|
|
52
|
-
|
|
55
|
+
function getVersions() {
|
|
56
|
+
const platform = is.win ? "Windows" : is.mac ? "MacOS" : process.platform.toUpperCase();
|
|
57
|
+
return {
|
|
58
|
+
appVersion: is.dev ? import_electron.app.getVersion() : (0, import_node_fs.readFileSync)(getPathFromAppNameAsar("version"), "utf-8"),
|
|
59
|
+
entryVersion: import_electron.app.getVersion(),
|
|
60
|
+
electronVersion: process.versions.electron,
|
|
61
|
+
nodeVersion: process.versions.node,
|
|
62
|
+
systemVersion: `${platform} ${(0, import_node_os.release)()}`
|
|
63
|
+
};
|
|
53
64
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
65
|
+
function restartApp() {
|
|
66
|
+
import_electron.app.relaunch();
|
|
67
|
+
import_electron.app.quit();
|
|
56
68
|
}
|
|
57
69
|
function waitAppReady(timeout = 1e3) {
|
|
58
70
|
return import_electron.app.isReady() ? Promise.resolve() : new Promise((resolve2, reject) => {
|
|
@@ -66,7 +78,27 @@ function waitAppReady(timeout = 1e3) {
|
|
|
66
78
|
});
|
|
67
79
|
}
|
|
68
80
|
|
|
69
|
-
// src/utils/
|
|
81
|
+
// src/utils/zip.ts
|
|
82
|
+
var import_node_fs2 = require("fs");
|
|
83
|
+
var import_node_zlib = require("zlib");
|
|
84
|
+
async function unzipFile(gzipPath, targetFilePath = gzipPath.slice(0, -3)) {
|
|
85
|
+
if (!(0, import_node_fs2.existsSync)(gzipPath)) {
|
|
86
|
+
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
87
|
+
}
|
|
88
|
+
const compressedBuffer = (0, import_node_fs2.readFileSync)(gzipPath);
|
|
89
|
+
return new Promise((resolve2, reject) => {
|
|
90
|
+
(0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
|
|
91
|
+
(0, import_node_fs2.rmSync)(gzipPath);
|
|
92
|
+
if (err) {
|
|
93
|
+
reject(err);
|
|
94
|
+
}
|
|
95
|
+
(0, import_node_fs2.writeFileSync)(targetFilePath, buffer);
|
|
96
|
+
resolve2(null);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/utils/noDep.ts
|
|
70
102
|
function parseVersion(version) {
|
|
71
103
|
const semver = /^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9\.-]+))?/i;
|
|
72
104
|
const match = semver.exec(version);
|
|
@@ -91,25 +123,9 @@ function parseVersion(version) {
|
|
|
91
123
|
}
|
|
92
124
|
return ret;
|
|
93
125
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
var import_node_zlib = require("zlib");
|
|
98
|
-
async function unzipFile(gzipPath, targetFilePath = gzipPath.slice(0, -3)) {
|
|
99
|
-
if (!(0, import_node_fs2.existsSync)(gzipPath)) {
|
|
100
|
-
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
101
|
-
}
|
|
102
|
-
const compressedBuffer = (0, import_node_fs2.readFileSync)(gzipPath);
|
|
103
|
-
return new Promise((resolve2, reject) => {
|
|
104
|
-
(0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
|
|
105
|
-
(0, import_node_fs2.rmSync)(gzipPath);
|
|
106
|
-
if (err) {
|
|
107
|
-
reject(err);
|
|
108
|
-
}
|
|
109
|
-
(0, import_node_fs2.writeFileSync)(targetFilePath, buffer);
|
|
110
|
-
resolve2(null);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
126
|
+
function isUpdateJSON(json) {
|
|
127
|
+
const is2 = (j) => !!(j && j.minimumVersion && j.signature && j.size && j.version);
|
|
128
|
+
return is2(json) && is2(json?.beta);
|
|
113
129
|
}
|
|
114
130
|
|
|
115
131
|
// src/crypto.ts
|
|
@@ -134,12 +150,6 @@ var verify = (buffer, signature, cert) => {
|
|
|
134
150
|
}
|
|
135
151
|
};
|
|
136
152
|
|
|
137
|
-
// src/updateJson.ts
|
|
138
|
-
function isUpdateJSON(json) {
|
|
139
|
-
const is2 = (j) => "signature" in j && "version" in j && "size" in j && "minimumVersion" in j;
|
|
140
|
-
return is2(json) && "beta" in json && is2(json.beta);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
153
|
// src/updater/types.ts
|
|
144
154
|
var MinimumVersionError = class extends Error {
|
|
145
155
|
currentVersion;
|
|
@@ -255,42 +265,53 @@ var compareVersionDefault = (version1, version2) => {
|
|
|
255
265
|
return false;
|
|
256
266
|
};
|
|
257
267
|
|
|
258
|
-
// src/updater/
|
|
259
|
-
var
|
|
268
|
+
// src/updater/core.ts
|
|
269
|
+
var Updater = class {
|
|
260
270
|
info;
|
|
261
271
|
option;
|
|
262
272
|
asarPath;
|
|
263
273
|
gzipPath;
|
|
264
274
|
tmpFilePath;
|
|
275
|
+
/**
|
|
276
|
+
* updater logger
|
|
277
|
+
*/
|
|
265
278
|
logger;
|
|
279
|
+
/**
|
|
280
|
+
* downloading progress hook
|
|
281
|
+
* @param progress download progress
|
|
282
|
+
* @example
|
|
283
|
+
* updater.onDownloading = ({ percent, total, current }) => {
|
|
284
|
+
* console.log(`download progress: ${percent}, total: ${total}, current: ${current}`)
|
|
285
|
+
* }
|
|
286
|
+
*/
|
|
266
287
|
onDownloading;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
288
|
+
/**
|
|
289
|
+
* whether receive beta version
|
|
290
|
+
*/
|
|
270
291
|
get receiveBeta() {
|
|
271
292
|
return !!this.option.receiveBeta;
|
|
272
293
|
}
|
|
273
294
|
set receiveBeta(receiveBeta) {
|
|
274
295
|
this.option.receiveBeta = receiveBeta;
|
|
275
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* initialize incremental updater
|
|
299
|
+
* @param option UpdaterOption
|
|
300
|
+
*/
|
|
276
301
|
constructor(option) {
|
|
277
302
|
this.option = option;
|
|
278
|
-
|
|
279
|
-
this.option.productName = DEFAULT_APP_NAME;
|
|
280
|
-
}
|
|
281
|
-
this.asarPath = getProductAsarPath(this.productName);
|
|
303
|
+
this.asarPath = getPathFromAppNameAsar();
|
|
282
304
|
this.gzipPath = `${this.asarPath}.gz`;
|
|
283
305
|
this.tmpFilePath = `${this.asarPath}.tmp`;
|
|
284
306
|
}
|
|
285
307
|
async needUpdate(version, minVersion) {
|
|
286
308
|
const compare = this.option.overrideFunctions?.compareVersion ?? compareVersionDefault;
|
|
287
|
-
const
|
|
288
|
-
const entryVersion = getElectronVersion();
|
|
309
|
+
const { appVersion, entryVersion } = getVersions();
|
|
289
310
|
if (await compare(entryVersion, minVersion)) {
|
|
290
311
|
throw new MinimumVersionError(entryVersion, minVersion);
|
|
291
312
|
}
|
|
292
|
-
this.logger?.info(`check update: current version is ${
|
|
293
|
-
return await compare(
|
|
313
|
+
this.logger?.info(`check update: current version is ${appVersion}, new version is ${version}`);
|
|
314
|
+
return await compare(appVersion, version);
|
|
294
315
|
}
|
|
295
316
|
async parseData(format, data) {
|
|
296
317
|
if ((0, import_node_fs3.existsSync)(this.tmpFilePath)) {
|
|
@@ -325,7 +346,7 @@ var IncrementalUpdater = class {
|
|
|
325
346
|
} : {
|
|
326
347
|
name: "releaseAsarURL",
|
|
327
348
|
url: this.option.releaseAsarURL,
|
|
328
|
-
repoFallback: `${this.option.repository}/releases/download/v${this.info?.version}/${
|
|
349
|
+
repoFallback: `${this.option.repository}/releases/download/v${this.info?.version}/${import_electron3.app.name}-${this.info?.version}.asar.gz`,
|
|
329
350
|
fn: this.option.overrideFunctions?.downloadBuffer ?? downloadBufferDefault
|
|
330
351
|
};
|
|
331
352
|
data ??= config.url;
|
|
@@ -348,6 +369,16 @@ var IncrementalUpdater = class {
|
|
|
348
369
|
throw new DownloadError(e.toString());
|
|
349
370
|
}
|
|
350
371
|
}
|
|
372
|
+
/**
|
|
373
|
+
* check update info
|
|
374
|
+
*
|
|
375
|
+
* if you want to update **offline**, you can set `data` and `sig` add update info
|
|
376
|
+
* @param data custom download URL of `updatejson` or existing update json
|
|
377
|
+
* @returns
|
|
378
|
+
* - Available:`{size: number, version: string}`
|
|
379
|
+
* - Unavailable: `undefined`
|
|
380
|
+
* - Fail: `CheckResultError`
|
|
381
|
+
*/
|
|
351
382
|
async checkUpdate(data) {
|
|
352
383
|
try {
|
|
353
384
|
let { signature, size, version, minimumVersion, beta } = await this.parseData("json", data);
|
|
@@ -369,13 +400,23 @@ var IncrementalUpdater = class {
|
|
|
369
400
|
version,
|
|
370
401
|
size
|
|
371
402
|
};
|
|
372
|
-
return
|
|
403
|
+
return this.info;
|
|
373
404
|
}
|
|
374
405
|
} catch (error) {
|
|
375
406
|
this.logger?.error("check update failed", error);
|
|
376
407
|
return error;
|
|
377
408
|
}
|
|
378
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* download update
|
|
412
|
+
*
|
|
413
|
+
* if you want to update **offline**, you can set both `data` and `sig` to verify and install
|
|
414
|
+
* @param data custom download URL of `asar.gz` or existing `asar.gz` buffer
|
|
415
|
+
* @param sig signature
|
|
416
|
+
* @returns
|
|
417
|
+
* - `true`: success
|
|
418
|
+
* - `DownloadResultError`: fail
|
|
419
|
+
*/
|
|
379
420
|
async download(data, sig) {
|
|
380
421
|
try {
|
|
381
422
|
const _sig = sig ?? this.info?.signature;
|
|
@@ -402,48 +443,66 @@ var IncrementalUpdater = class {
|
|
|
402
443
|
return error;
|
|
403
444
|
}
|
|
404
445
|
}
|
|
446
|
+
/**
|
|
447
|
+
* quit App and install
|
|
448
|
+
*/
|
|
449
|
+
quitAndInstall() {
|
|
450
|
+
this.logger?.info("quit and install");
|
|
451
|
+
restartApp();
|
|
452
|
+
}
|
|
405
453
|
};
|
|
454
|
+
|
|
455
|
+
// src/updater/index.ts
|
|
406
456
|
function createUpdater(option) {
|
|
407
|
-
return new
|
|
457
|
+
return new Updater(option);
|
|
408
458
|
}
|
|
409
459
|
|
|
410
460
|
// src/index.ts
|
|
461
|
+
function startupWithUpdater(fn) {
|
|
462
|
+
return fn;
|
|
463
|
+
}
|
|
464
|
+
var defaultOnInstall = (install, _, __, logger) => {
|
|
465
|
+
install();
|
|
466
|
+
logger?.info(`update success!`);
|
|
467
|
+
};
|
|
411
468
|
function initApp(appOptions) {
|
|
412
469
|
const {
|
|
413
|
-
electronDevDistPath = "dist-electron",
|
|
470
|
+
electronDevDistPath = "../dist-electron",
|
|
414
471
|
mainPath = "main/index.js",
|
|
415
472
|
hooks
|
|
416
473
|
} = appOptions || {};
|
|
417
474
|
const {
|
|
418
|
-
|
|
475
|
+
onInstall = defaultOnInstall,
|
|
419
476
|
beforeStart,
|
|
420
477
|
onStartError
|
|
421
478
|
} = hooks || {};
|
|
422
|
-
function handleError(
|
|
423
|
-
|
|
424
|
-
|
|
479
|
+
function handleError(err, logger) {
|
|
480
|
+
console.error(err);
|
|
481
|
+
onStartError?.(err, logger);
|
|
482
|
+
import_electron4.app.quit();
|
|
425
483
|
}
|
|
426
484
|
async function startup(updater) {
|
|
485
|
+
const logger = updater.logger;
|
|
427
486
|
try {
|
|
428
|
-
const
|
|
429
|
-
const
|
|
430
|
-
if ((0, import_node_fs4.existsSync)(
|
|
431
|
-
|
|
432
|
-
(0, import_node_fs4.renameSync)(
|
|
487
|
+
const appNameAsarPath = getPathFromAppNameAsar();
|
|
488
|
+
const tempAsarPath = `${appNameAsarPath}.tmp`;
|
|
489
|
+
if ((0, import_node_fs4.existsSync)(tempAsarPath)) {
|
|
490
|
+
logger?.info(`installing new asar: ${tempAsarPath}`);
|
|
491
|
+
await onInstall(() => (0, import_node_fs4.renameSync)(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
|
|
433
492
|
}
|
|
434
|
-
const mainDir =
|
|
493
|
+
const mainDir = is.dev ? electronDevDistPath : appNameAsarPath;
|
|
435
494
|
const entry = (0, import_node_path2.resolve)(__dirname, mainDir, mainPath);
|
|
436
|
-
await beforeStart?.(entry);
|
|
495
|
+
await beforeStart?.(entry, logger);
|
|
437
496
|
require(entry)(updater);
|
|
438
497
|
} catch (error) {
|
|
439
|
-
handleError(
|
|
498
|
+
handleError(error, logger);
|
|
440
499
|
}
|
|
441
500
|
}
|
|
442
501
|
let timer = setTimeout(() => {
|
|
443
|
-
handleError("start app timeout, please
|
|
502
|
+
handleError("start app timeout, please start app with `initApp(options).startupWithUpdater(options)`");
|
|
444
503
|
}, 3e3);
|
|
445
504
|
return {
|
|
446
|
-
async
|
|
505
|
+
async startupWithUpdater(updater) {
|
|
447
506
|
clearTimeout(timer);
|
|
448
507
|
if (typeof updater === "object") {
|
|
449
508
|
await startup(createUpdater(updater));
|
|
@@ -457,7 +516,11 @@ function initApp(appOptions) {
|
|
|
457
516
|
}
|
|
458
517
|
// Annotate the CommonJS export names for ESM import in node:
|
|
459
518
|
0 && (module.exports = {
|
|
460
|
-
|
|
519
|
+
DownloadError,
|
|
520
|
+
MinimumVersionError,
|
|
521
|
+
Updater,
|
|
522
|
+
VerifyFailedError,
|
|
461
523
|
createUpdater,
|
|
462
|
-
initApp
|
|
524
|
+
initApp,
|
|
525
|
+
startupWithUpdater
|
|
463
526
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
|
-
isUpdateJSON,
|
|
3
2
|
verify
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GXZSAUBR.mjs";
|
|
5
4
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
getPathFromAppNameAsar,
|
|
6
|
+
getVersions,
|
|
7
|
+
is,
|
|
8
|
+
restartApp,
|
|
10
9
|
waitAppReady
|
|
11
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-OUZLSVQC.mjs";
|
|
12
11
|
import {
|
|
13
12
|
__require,
|
|
13
|
+
isUpdateJSON,
|
|
14
14
|
parseVersion,
|
|
15
15
|
unzipFile
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GB6VLKJZ.mjs";
|
|
17
17
|
|
|
18
18
|
// src/index.ts
|
|
19
19
|
import { resolve } from "node:path";
|
|
20
20
|
import { existsSync as existsSync2, renameSync } from "node:fs";
|
|
21
|
-
import { app } from "electron";
|
|
21
|
+
import { app as app2 } from "electron";
|
|
22
22
|
|
|
23
|
-
// src/updater/
|
|
23
|
+
// src/updater/core.ts
|
|
24
24
|
import { existsSync } from "node:fs";
|
|
25
25
|
import { rm, writeFile } from "node:fs/promises";
|
|
26
|
+
import { app } from "electron";
|
|
26
27
|
|
|
27
28
|
// src/updater/types.ts
|
|
28
29
|
var MinimumVersionError = class extends Error {
|
|
@@ -139,42 +140,53 @@ var compareVersionDefault = (version1, version2) => {
|
|
|
139
140
|
return false;
|
|
140
141
|
};
|
|
141
142
|
|
|
142
|
-
// src/updater/
|
|
143
|
-
var
|
|
143
|
+
// src/updater/core.ts
|
|
144
|
+
var Updater = class {
|
|
144
145
|
info;
|
|
145
146
|
option;
|
|
146
147
|
asarPath;
|
|
147
148
|
gzipPath;
|
|
148
149
|
tmpFilePath;
|
|
150
|
+
/**
|
|
151
|
+
* updater logger
|
|
152
|
+
*/
|
|
149
153
|
logger;
|
|
154
|
+
/**
|
|
155
|
+
* downloading progress hook
|
|
156
|
+
* @param progress download progress
|
|
157
|
+
* @example
|
|
158
|
+
* updater.onDownloading = ({ percent, total, current }) => {
|
|
159
|
+
* console.log(`download progress: ${percent}, total: ${total}, current: ${current}`)
|
|
160
|
+
* }
|
|
161
|
+
*/
|
|
150
162
|
onDownloading;
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
163
|
+
/**
|
|
164
|
+
* whether receive beta version
|
|
165
|
+
*/
|
|
154
166
|
get receiveBeta() {
|
|
155
167
|
return !!this.option.receiveBeta;
|
|
156
168
|
}
|
|
157
169
|
set receiveBeta(receiveBeta) {
|
|
158
170
|
this.option.receiveBeta = receiveBeta;
|
|
159
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* initialize incremental updater
|
|
174
|
+
* @param option UpdaterOption
|
|
175
|
+
*/
|
|
160
176
|
constructor(option) {
|
|
161
177
|
this.option = option;
|
|
162
|
-
|
|
163
|
-
this.option.productName = DEFAULT_APP_NAME;
|
|
164
|
-
}
|
|
165
|
-
this.asarPath = getProductAsarPath(this.productName);
|
|
178
|
+
this.asarPath = getPathFromAppNameAsar();
|
|
166
179
|
this.gzipPath = `${this.asarPath}.gz`;
|
|
167
180
|
this.tmpFilePath = `${this.asarPath}.tmp`;
|
|
168
181
|
}
|
|
169
182
|
async needUpdate(version, minVersion) {
|
|
170
183
|
const compare = this.option.overrideFunctions?.compareVersion ?? compareVersionDefault;
|
|
171
|
-
const
|
|
172
|
-
const entryVersion = getElectronVersion();
|
|
184
|
+
const { appVersion, entryVersion } = getVersions();
|
|
173
185
|
if (await compare(entryVersion, minVersion)) {
|
|
174
186
|
throw new MinimumVersionError(entryVersion, minVersion);
|
|
175
187
|
}
|
|
176
|
-
this.logger?.info(`check update: current version is ${
|
|
177
|
-
return await compare(
|
|
188
|
+
this.logger?.info(`check update: current version is ${appVersion}, new version is ${version}`);
|
|
189
|
+
return await compare(appVersion, version);
|
|
178
190
|
}
|
|
179
191
|
async parseData(format, data) {
|
|
180
192
|
if (existsSync(this.tmpFilePath)) {
|
|
@@ -209,7 +221,7 @@ var IncrementalUpdater = class {
|
|
|
209
221
|
} : {
|
|
210
222
|
name: "releaseAsarURL",
|
|
211
223
|
url: this.option.releaseAsarURL,
|
|
212
|
-
repoFallback: `${this.option.repository}/releases/download/v${this.info?.version}/${
|
|
224
|
+
repoFallback: `${this.option.repository}/releases/download/v${this.info?.version}/${app.name}-${this.info?.version}.asar.gz`,
|
|
213
225
|
fn: this.option.overrideFunctions?.downloadBuffer ?? downloadBufferDefault
|
|
214
226
|
};
|
|
215
227
|
data ??= config.url;
|
|
@@ -232,6 +244,16 @@ var IncrementalUpdater = class {
|
|
|
232
244
|
throw new DownloadError(e.toString());
|
|
233
245
|
}
|
|
234
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* check update info
|
|
249
|
+
*
|
|
250
|
+
* if you want to update **offline**, you can set `data` and `sig` add update info
|
|
251
|
+
* @param data custom download URL of `updatejson` or existing update json
|
|
252
|
+
* @returns
|
|
253
|
+
* - Available:`{size: number, version: string}`
|
|
254
|
+
* - Unavailable: `undefined`
|
|
255
|
+
* - Fail: `CheckResultError`
|
|
256
|
+
*/
|
|
235
257
|
async checkUpdate(data) {
|
|
236
258
|
try {
|
|
237
259
|
let { signature, size, version, minimumVersion, beta } = await this.parseData("json", data);
|
|
@@ -253,13 +275,23 @@ var IncrementalUpdater = class {
|
|
|
253
275
|
version,
|
|
254
276
|
size
|
|
255
277
|
};
|
|
256
|
-
return
|
|
278
|
+
return this.info;
|
|
257
279
|
}
|
|
258
280
|
} catch (error) {
|
|
259
281
|
this.logger?.error("check update failed", error);
|
|
260
282
|
return error;
|
|
261
283
|
}
|
|
262
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* download update
|
|
287
|
+
*
|
|
288
|
+
* if you want to update **offline**, you can set both `data` and `sig` to verify and install
|
|
289
|
+
* @param data custom download URL of `asar.gz` or existing `asar.gz` buffer
|
|
290
|
+
* @param sig signature
|
|
291
|
+
* @returns
|
|
292
|
+
* - `true`: success
|
|
293
|
+
* - `DownloadResultError`: fail
|
|
294
|
+
*/
|
|
263
295
|
async download(data, sig) {
|
|
264
296
|
try {
|
|
265
297
|
const _sig = sig ?? this.info?.signature;
|
|
@@ -286,48 +318,66 @@ var IncrementalUpdater = class {
|
|
|
286
318
|
return error;
|
|
287
319
|
}
|
|
288
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* quit App and install
|
|
323
|
+
*/
|
|
324
|
+
quitAndInstall() {
|
|
325
|
+
this.logger?.info("quit and install");
|
|
326
|
+
restartApp();
|
|
327
|
+
}
|
|
289
328
|
};
|
|
329
|
+
|
|
330
|
+
// src/updater/index.ts
|
|
290
331
|
function createUpdater(option) {
|
|
291
|
-
return new
|
|
332
|
+
return new Updater(option);
|
|
292
333
|
}
|
|
293
334
|
|
|
294
335
|
// src/index.ts
|
|
336
|
+
function startupWithUpdater(fn) {
|
|
337
|
+
return fn;
|
|
338
|
+
}
|
|
339
|
+
var defaultOnInstall = (install, _, __, logger) => {
|
|
340
|
+
install();
|
|
341
|
+
logger?.info(`update success!`);
|
|
342
|
+
};
|
|
295
343
|
function initApp(appOptions) {
|
|
296
344
|
const {
|
|
297
|
-
electronDevDistPath = "dist-electron",
|
|
345
|
+
electronDevDistPath = "../dist-electron",
|
|
298
346
|
mainPath = "main/index.js",
|
|
299
347
|
hooks
|
|
300
348
|
} = appOptions || {};
|
|
301
349
|
const {
|
|
302
|
-
|
|
350
|
+
onInstall = defaultOnInstall,
|
|
303
351
|
beforeStart,
|
|
304
352
|
onStartError
|
|
305
353
|
} = hooks || {};
|
|
306
|
-
function handleError(
|
|
307
|
-
|
|
308
|
-
|
|
354
|
+
function handleError(err, logger) {
|
|
355
|
+
console.error(err);
|
|
356
|
+
onStartError?.(err, logger);
|
|
357
|
+
app2.quit();
|
|
309
358
|
}
|
|
310
359
|
async function startup(updater) {
|
|
360
|
+
const logger = updater.logger;
|
|
311
361
|
try {
|
|
312
|
-
const
|
|
313
|
-
const
|
|
314
|
-
if (existsSync2(
|
|
315
|
-
|
|
316
|
-
renameSync(
|
|
362
|
+
const appNameAsarPath = getPathFromAppNameAsar();
|
|
363
|
+
const tempAsarPath = `${appNameAsarPath}.tmp`;
|
|
364
|
+
if (existsSync2(tempAsarPath)) {
|
|
365
|
+
logger?.info(`installing new asar: ${tempAsarPath}`);
|
|
366
|
+
await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
|
|
317
367
|
}
|
|
318
|
-
const mainDir =
|
|
368
|
+
const mainDir = is.dev ? electronDevDistPath : appNameAsarPath;
|
|
319
369
|
const entry = resolve(__dirname, mainDir, mainPath);
|
|
320
|
-
await beforeStart?.(entry);
|
|
370
|
+
await beforeStart?.(entry, logger);
|
|
321
371
|
__require(entry)(updater);
|
|
322
372
|
} catch (error) {
|
|
323
|
-
handleError(
|
|
373
|
+
handleError(error, logger);
|
|
324
374
|
}
|
|
325
375
|
}
|
|
326
376
|
let timer = setTimeout(() => {
|
|
327
|
-
handleError("start app timeout, please
|
|
377
|
+
handleError("start app timeout, please start app with `initApp(options).startupWithUpdater(options)`");
|
|
328
378
|
}, 3e3);
|
|
329
379
|
return {
|
|
330
|
-
async
|
|
380
|
+
async startupWithUpdater(updater) {
|
|
331
381
|
clearTimeout(timer);
|
|
332
382
|
if (typeof updater === "object") {
|
|
333
383
|
await startup(createUpdater(updater));
|
|
@@ -340,7 +390,11 @@ function initApp(appOptions) {
|
|
|
340
390
|
};
|
|
341
391
|
}
|
|
342
392
|
export {
|
|
343
|
-
|
|
393
|
+
DownloadError,
|
|
394
|
+
MinimumVersionError,
|
|
395
|
+
Updater,
|
|
396
|
+
VerifyFailedError,
|
|
344
397
|
createUpdater,
|
|
345
|
-
initApp
|
|
398
|
+
initApp,
|
|
399
|
+
startupWithUpdater
|
|
346
400
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* parse Github CDN URL for accelerating the speed of downloading
|
|
3
|
+
*
|
|
4
|
+
* {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 some public CDN links}
|
|
5
|
+
*/
|
|
6
|
+
declare function parseGithubCdnURL(originRepoURL: string, cdnPrefix: string, relativeFilePath: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* handle all unhandled error
|
|
9
|
+
* @param callback callback function
|
|
10
|
+
*/
|
|
11
|
+
declare function handleUnexpectedErrors(callback: (err: unknown) => void): void;
|
|
12
|
+
interface Version {
|
|
13
|
+
major: number;
|
|
14
|
+
minor: number;
|
|
15
|
+
patch: number;
|
|
16
|
+
stage: string;
|
|
17
|
+
stageVersion: number;
|
|
18
|
+
}
|
|
19
|
+
declare function parseVersion(version: string): Version;
|
|
20
|
+
type UpdateInfo = {
|
|
21
|
+
signature: string;
|
|
22
|
+
minimumVersion: string;
|
|
23
|
+
version: string;
|
|
24
|
+
size: number;
|
|
25
|
+
};
|
|
26
|
+
type UpdateJSON = UpdateInfo & {
|
|
27
|
+
beta: UpdateInfo;
|
|
28
|
+
};
|
|
29
|
+
declare function isUpdateJSON(json: any): json is UpdateJSON;
|
|
30
|
+
|
|
31
|
+
export { type UpdateInfo as U, type Version as V, type UpdateJSON as a, parseVersion as b, handleUnexpectedErrors as h, isUpdateJSON as i, parseGithubCdnURL as p };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* parse Github CDN URL for accelerating the speed of downloading
|
|
3
|
+
*
|
|
4
|
+
* {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 some public CDN links}
|
|
5
|
+
*/
|
|
6
|
+
declare function parseGithubCdnURL(originRepoURL: string, cdnPrefix: string, relativeFilePath: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* handle all unhandled error
|
|
9
|
+
* @param callback callback function
|
|
10
|
+
*/
|
|
11
|
+
declare function handleUnexpectedErrors(callback: (err: unknown) => void): void;
|
|
12
|
+
interface Version {
|
|
13
|
+
major: number;
|
|
14
|
+
minor: number;
|
|
15
|
+
patch: number;
|
|
16
|
+
stage: string;
|
|
17
|
+
stageVersion: number;
|
|
18
|
+
}
|
|
19
|
+
declare function parseVersion(version: string): Version;
|
|
20
|
+
type UpdateInfo = {
|
|
21
|
+
signature: string;
|
|
22
|
+
minimumVersion: string;
|
|
23
|
+
version: string;
|
|
24
|
+
size: number;
|
|
25
|
+
};
|
|
26
|
+
type UpdateJSON = UpdateInfo & {
|
|
27
|
+
beta: UpdateInfo;
|
|
28
|
+
};
|
|
29
|
+
declare function isUpdateJSON(json: any): json is UpdateJSON;
|
|
30
|
+
|
|
31
|
+
export { type UpdateInfo as U, type Version as V, type UpdateJSON as a, parseVersion as b, handleUnexpectedErrors as h, isUpdateJSON as i, parseGithubCdnURL as p };
|