electron-incremental-update 2.0.0-beta.2 → 2.0.0-beta.3
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/dist/chunk-5WFXC5GU.js +43 -0
- package/dist/chunk-BVFQWBLK.js +76 -0
- package/dist/chunk-PNYRQYFC.js +77 -0
- package/dist/index.cjs +81 -144
- package/dist/index.d.cts +23 -18
- package/dist/index.d.ts +23 -18
- package/dist/index.js +56 -74
- package/dist/provider.cjs +78 -112
- package/dist/provider.d.cts +37 -11
- package/dist/provider.d.ts +37 -11
- package/dist/provider.js +42 -33
- package/dist/{types-CPq1MrYZ.d.ts → types-DxhNaNgR.d.ts} +8 -2
- package/dist/{types-COqp44eg.d.cts → types-Tequ_V2o.d.cts} +8 -2
- package/dist/unzip-JjYLjJkH.d.cts +9 -0
- package/dist/unzip-JjYLjJkH.d.ts +9 -0
- package/dist/utils.cjs +99 -173
- package/dist/utils.d.cts +4 -16
- package/dist/utils.d.ts +4 -16
- package/dist/utils.js +19 -62
- package/dist/{version-CffZWDhZ.d.cts → version-CemSHimT.d.cts} +3 -2
- package/dist/{version-CffZWDhZ.d.ts → version-CemSHimT.d.ts} +3 -2
- package/dist/vite.js +106 -139
- package/package.json +6 -6
- package/dist/chunk-BG22XZAB.js +0 -257
- package/dist/decrypt-D9WdXYjH.d.cts +0 -4
- package/dist/decrypt-D9WdXYjH.d.ts +0 -4
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs';
|
|
2
|
+
import { brotliDecompress } from 'node:zlib';
|
|
3
|
+
import { createHash, createCipheriv, createSign, createPrivateKey, createDecipheriv, createVerify } from 'node:crypto';
|
|
4
|
+
|
|
5
|
+
// src/utils/unzip.ts
|
|
6
|
+
async function defaultUnzipFile(buffer, targetFilePath) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
brotliDecompress(buffer, (err, buffer2) => {
|
|
9
|
+
if (err) {
|
|
10
|
+
reject(err);
|
|
11
|
+
}
|
|
12
|
+
writeFileSync(targetFilePath, buffer2);
|
|
13
|
+
resolve();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function hashBuffer(data, length) {
|
|
18
|
+
const hash = createHash("SHA256").update(data).digest("binary");
|
|
19
|
+
return Buffer.from(hash).subarray(0, length);
|
|
20
|
+
}
|
|
21
|
+
function aesEncrypt(plainText, key, iv) {
|
|
22
|
+
const cipher = createCipheriv("aes-256-cbc", key, iv);
|
|
23
|
+
return cipher.update(plainText, "utf8", "base64url") + cipher.final("base64url");
|
|
24
|
+
}
|
|
25
|
+
function defaultSignature(buffer, privateKey, cert, version) {
|
|
26
|
+
const sig = createSign("RSA-SHA256").update(buffer).sign(createPrivateKey(privateKey), "base64");
|
|
27
|
+
return aesEncrypt(`${sig}%${version}`, hashBuffer(cert, 32), hashBuffer(buffer, 16));
|
|
28
|
+
}
|
|
29
|
+
function aesDecrypt(encryptedText, key, iv) {
|
|
30
|
+
const decipher = createDecipheriv("aes-256-cbc", key, iv);
|
|
31
|
+
return decipher.update(encryptedText, "base64url", "utf8") + decipher.final("utf8");
|
|
32
|
+
}
|
|
33
|
+
function defaultVerify(buffer, signature, cert) {
|
|
34
|
+
try {
|
|
35
|
+
const [sig, version] = aesDecrypt(signature, hashBuffer(cert, 32), hashBuffer(buffer, 16)).split("%");
|
|
36
|
+
const result = createVerify("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
|
|
37
|
+
return result ? version : void 0;
|
|
38
|
+
} catch {
|
|
39
|
+
return void 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { aesDecrypt, aesEncrypt, defaultSignature, defaultUnzipFile, defaultVerify, hashBuffer };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/utils/version.ts
|
|
9
|
+
function handleUnexpectedErrors(callback) {
|
|
10
|
+
process.on("uncaughtException", callback);
|
|
11
|
+
process.on("unhandledRejection", callback);
|
|
12
|
+
}
|
|
13
|
+
function parseVersion(version) {
|
|
14
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:-([a-z0-9.-]+))?/i.exec(version);
|
|
15
|
+
if (!match) {
|
|
16
|
+
throw new TypeError(`invalid version: ${version}`);
|
|
17
|
+
}
|
|
18
|
+
const [major, minor, patch] = match.slice(1, 4).map(Number);
|
|
19
|
+
const ret = {
|
|
20
|
+
major,
|
|
21
|
+
minor,
|
|
22
|
+
patch,
|
|
23
|
+
stage: "",
|
|
24
|
+
stageVersion: -1
|
|
25
|
+
};
|
|
26
|
+
if (match[4]) {
|
|
27
|
+
let [stage, _v] = match[4].split(".");
|
|
28
|
+
ret.stage = stage;
|
|
29
|
+
ret.stageVersion = Number(_v) || -1;
|
|
30
|
+
}
|
|
31
|
+
if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch) || Number.isNaN(ret.stageVersion)) {
|
|
32
|
+
throw new TypeError(`invalid version: ${version}`);
|
|
33
|
+
}
|
|
34
|
+
return ret;
|
|
35
|
+
}
|
|
36
|
+
function defaultIsLowerVersion(oldVer, newVer) {
|
|
37
|
+
const oldV = parseVersion(oldVer);
|
|
38
|
+
const newV = parseVersion(newVer);
|
|
39
|
+
function compareStrings(str1, str2) {
|
|
40
|
+
if (str1 === "") {
|
|
41
|
+
return str2 !== "";
|
|
42
|
+
} else if (str2 === "") {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
return str1 < str2;
|
|
46
|
+
}
|
|
47
|
+
for (let key of Object.keys(oldV)) {
|
|
48
|
+
if (key === "stage" && compareStrings(oldV[key], newV[key])) {
|
|
49
|
+
return true;
|
|
50
|
+
} else if (oldV[key] !== newV[key]) {
|
|
51
|
+
return oldV[key] < newV[key];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
function isUpdateJSON(json) {
|
|
57
|
+
const is = (j) => !!(j && j.minimumVersion && j.signature && j.size && j.version);
|
|
58
|
+
return is(json) && is(json?.beta);
|
|
59
|
+
}
|
|
60
|
+
function defaultVersionJsonGenerator(existingJson, buffer, signature, version, minimumVersion) {
|
|
61
|
+
existingJson.beta = {
|
|
62
|
+
version,
|
|
63
|
+
minimumVersion,
|
|
64
|
+
signature,
|
|
65
|
+
size: buffer.length
|
|
66
|
+
};
|
|
67
|
+
if (!parseVersion(version).stage) {
|
|
68
|
+
existingJson.version = version;
|
|
69
|
+
existingJson.minimumVersion = minimumVersion;
|
|
70
|
+
existingJson.signature = signature;
|
|
71
|
+
existingJson.size = buffer.length;
|
|
72
|
+
}
|
|
73
|
+
return existingJson;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { __require, defaultIsLowerVersion, defaultVersionJsonGenerator, handleUnexpectedErrors, isUpdateJSON, parseVersion };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { __require } from './chunk-BVFQWBLK.js';
|
|
2
|
+
import { readFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { app } from 'electron';
|
|
5
|
+
|
|
6
|
+
var isDev = __EIU_IS_DEV__;
|
|
7
|
+
var isWin = process.platform === "win32";
|
|
8
|
+
var isMac = process.platform === "darwin";
|
|
9
|
+
var isLinux = process.platform === "linux";
|
|
10
|
+
function getPathFromAppNameAsar(...path) {
|
|
11
|
+
return isDev ? "DEV.asar" : join(dirname(app.getAppPath()), `${app.name}.asar`, ...path);
|
|
12
|
+
}
|
|
13
|
+
function getAppVersion() {
|
|
14
|
+
return isDev ? getEntryVersion() : readFileSync(getPathFromAppNameAsar("version"), "utf-8");
|
|
15
|
+
}
|
|
16
|
+
function getEntryVersion() {
|
|
17
|
+
return app.getVersion();
|
|
18
|
+
}
|
|
19
|
+
function requireNative(moduleName) {
|
|
20
|
+
return __require(join(app.getAppPath(), __EIU_ENTRY_DIST_PATH__, moduleName));
|
|
21
|
+
}
|
|
22
|
+
function restartApp() {
|
|
23
|
+
app.relaunch();
|
|
24
|
+
app.quit();
|
|
25
|
+
}
|
|
26
|
+
function setAppUserModelId(id) {
|
|
27
|
+
if (isWin) {
|
|
28
|
+
app.setAppUserModelId(id ?? `org.${app.name}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function disableHWAccForWin7() {
|
|
32
|
+
if (__require("node:os").release().startsWith("6.1")) {
|
|
33
|
+
app.disableHardwareAcceleration();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function singleInstance(window) {
|
|
37
|
+
const result = app.requestSingleInstanceLock();
|
|
38
|
+
if (result) {
|
|
39
|
+
app.on("second-instance", () => {
|
|
40
|
+
if (window) {
|
|
41
|
+
window.show();
|
|
42
|
+
if (window.isMinimized()) {
|
|
43
|
+
window.restore();
|
|
44
|
+
}
|
|
45
|
+
window.focus();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
} else {
|
|
49
|
+
app.quit();
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
function setPortableAppDataPath(dirName = "data") {
|
|
54
|
+
const portablePath = join(dirname(app.getPath("exe")), dirName);
|
|
55
|
+
if (!existsSync(portablePath)) {
|
|
56
|
+
mkdirSync(portablePath);
|
|
57
|
+
}
|
|
58
|
+
app.setPath("appData", portablePath);
|
|
59
|
+
}
|
|
60
|
+
function loadPage(win, htmlFilePath = "index.html") {
|
|
61
|
+
if (isDev) {
|
|
62
|
+
win.loadURL(process.env.VITE_DEV_SERVER_URL + htmlFilePath);
|
|
63
|
+
} else {
|
|
64
|
+
win.loadFile(getPathFromAppNameAsar("renderer", htmlFilePath));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function getPathFromPreload(...paths) {
|
|
68
|
+
return isDev ? join(app.getAppPath(), __EIU_ELECTRON_DIST_PATH__, "preload", ...paths) : getPathFromAppNameAsar("preload", ...paths);
|
|
69
|
+
}
|
|
70
|
+
function getPathFromPublic(...paths) {
|
|
71
|
+
return isDev ? join(app.getAppPath(), "public", ...paths) : getPathFromAppNameAsar("renderer", ...paths);
|
|
72
|
+
}
|
|
73
|
+
function getPathFromEntryAsar(...paths) {
|
|
74
|
+
return join(app.getAppPath(), __EIU_ENTRY_DIST_PATH__, ...paths);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { disableHWAccForWin7, getAppVersion, getEntryVersion, getPathFromAppNameAsar, getPathFromEntryAsar, getPathFromPreload, getPathFromPublic, isDev, isLinux, isMac, isWin, loadPage, requireNative, restartApp, setAppUserModelId, setPortableAppDataPath, singleInstance };
|
package/dist/index.cjs
CHANGED
|
@@ -1,94 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
'use strict';
|
|
19
2
|
|
|
20
|
-
|
|
21
|
-
var
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Updater: () => Updater,
|
|
25
|
-
UpdaterError: () => UpdaterError,
|
|
26
|
-
initApp: () => initApp,
|
|
27
|
-
startupWithUpdater: () => startupWithUpdater
|
|
28
|
-
});
|
|
29
|
-
module.exports = __toCommonJS(entry_exports);
|
|
30
|
-
var import_node_path2 = require("path");
|
|
31
|
-
var import_node_fs5 = require("fs");
|
|
32
|
-
var import_electron4 = require("electron");
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var fs = require('fs');
|
|
5
|
+
var electron = require('electron');
|
|
6
|
+
var events = require('events');
|
|
33
7
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
8
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
+
}) : x)(function(x) {
|
|
11
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
+
});
|
|
38
14
|
|
|
39
15
|
// src/utils/version.ts
|
|
40
16
|
function isUpdateJSON(json) {
|
|
41
17
|
const is = (j) => !!(j && j.minimumVersion && j.signature && j.size && j.version);
|
|
42
18
|
return is(json) && is(json?.beta);
|
|
43
19
|
}
|
|
44
|
-
|
|
45
|
-
// src/utils/electron.ts
|
|
46
|
-
var import_node_fs = require("fs");
|
|
47
|
-
var import_node_path = require("path");
|
|
48
|
-
var import_electron = require("electron");
|
|
49
20
|
var isDev = __EIU_IS_DEV__;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
function getPathFromAppNameAsar(...path) {
|
|
54
|
-
return isDev ? "DEV.asar" :
|
|
21
|
+
process.platform === "win32";
|
|
22
|
+
process.platform === "darwin";
|
|
23
|
+
process.platform === "linux";
|
|
24
|
+
function getPathFromAppNameAsar(...path$1) {
|
|
25
|
+
return isDev ? "DEV.asar" : path.join(path.dirname(electron.app.getAppPath()), `${electron.app.name}.asar`, ...path$1);
|
|
55
26
|
}
|
|
56
27
|
function getAppVersion() {
|
|
57
|
-
return isDev ? getEntryVersion() :
|
|
28
|
+
return isDev ? getEntryVersion() : fs.readFileSync(getPathFromAppNameAsar("version"), "utf-8");
|
|
58
29
|
}
|
|
59
30
|
function getEntryVersion() {
|
|
60
|
-
return
|
|
31
|
+
return electron.app.getVersion();
|
|
61
32
|
}
|
|
62
33
|
function restartApp() {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// src/utils/unzip.ts
|
|
68
|
-
var import_node_fs2 = require("fs");
|
|
69
|
-
var import_node_zlib = require("zlib");
|
|
70
|
-
async function unzipFile(gzipPath, targetFilePath = gzipPath.slice(0, -3)) {
|
|
71
|
-
if (!(0, import_node_fs2.existsSync)(gzipPath)) {
|
|
72
|
-
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
73
|
-
}
|
|
74
|
-
const compressedBuffer = (0, import_node_fs2.readFileSync)(gzipPath);
|
|
75
|
-
return new Promise((resolve, reject) => {
|
|
76
|
-
(0, import_node_zlib.brotliDecompress)(compressedBuffer, (err, buffer) => {
|
|
77
|
-
(0, import_node_fs2.rmSync)(gzipPath);
|
|
78
|
-
if (err) {
|
|
79
|
-
reject(err);
|
|
80
|
-
}
|
|
81
|
-
(0, import_node_fs2.writeFileSync)(targetFilePath, buffer);
|
|
82
|
-
resolve();
|
|
83
|
-
});
|
|
84
|
-
});
|
|
34
|
+
electron.app.relaunch();
|
|
35
|
+
electron.app.quit();
|
|
85
36
|
}
|
|
86
37
|
|
|
87
38
|
// src/updater/types.ts
|
|
88
39
|
var ErrorInfo = {
|
|
89
40
|
download: "Download failed",
|
|
90
41
|
validate: "Validate failed",
|
|
91
|
-
param: "Missing params"
|
|
42
|
+
param: "Missing params",
|
|
43
|
+
network: "Network error"
|
|
92
44
|
};
|
|
93
45
|
var UpdaterError = class extends Error {
|
|
94
46
|
code;
|
|
@@ -99,12 +51,10 @@ var UpdaterError = class extends Error {
|
|
|
99
51
|
};
|
|
100
52
|
|
|
101
53
|
// src/updater/core.ts
|
|
102
|
-
var Updater = class extends
|
|
54
|
+
var Updater = class extends events.EventEmitter {
|
|
103
55
|
CERT = __EIU_SIGNATURE_CERT__;
|
|
104
56
|
info;
|
|
105
|
-
options;
|
|
106
57
|
asarPath;
|
|
107
|
-
gzipPath;
|
|
108
58
|
tmpFilePath;
|
|
109
59
|
provider;
|
|
110
60
|
/**
|
|
@@ -112,22 +62,13 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
112
62
|
*/
|
|
113
63
|
logger;
|
|
114
64
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDNs}
|
|
118
|
-
* @param url source url
|
|
119
|
-
* @param isDownloadAsar whether is download asar
|
|
65
|
+
* whether to receive beta update
|
|
120
66
|
*/
|
|
121
|
-
|
|
67
|
+
receiveBeta;
|
|
122
68
|
/**
|
|
123
|
-
* whether
|
|
69
|
+
* whether force update in DEV
|
|
124
70
|
*/
|
|
125
|
-
|
|
126
|
-
return !!this.options.receiveBeta;
|
|
127
|
-
}
|
|
128
|
-
set receiveBeta(receiveBeta) {
|
|
129
|
-
this.options.receiveBeta = receiveBeta;
|
|
130
|
-
}
|
|
71
|
+
forceUpdate;
|
|
131
72
|
/**
|
|
132
73
|
* initialize incremental updater
|
|
133
74
|
* @param provider update provider
|
|
@@ -136,7 +77,7 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
136
77
|
constructor(provider, option = {}) {
|
|
137
78
|
super();
|
|
138
79
|
this.provider = provider;
|
|
139
|
-
this.
|
|
80
|
+
this.receiveBeta = option.receiveBeta;
|
|
140
81
|
if (option.SIGNATURE_CERT) {
|
|
141
82
|
this.CERT = option.SIGNATURE_CERT;
|
|
142
83
|
}
|
|
@@ -153,17 +94,12 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
153
94
|
this.logger.info("no logger set, enable dev-only logger");
|
|
154
95
|
}
|
|
155
96
|
this.asarPath = getPathFromAppNameAsar();
|
|
156
|
-
this.gzipPath = `${this.asarPath}.gz`;
|
|
157
97
|
this.tmpFilePath = `${this.asarPath}.tmp`;
|
|
158
98
|
}
|
|
159
99
|
async fetch(format, data) {
|
|
160
|
-
if (
|
|
100
|
+
if (fs.existsSync(this.tmpFilePath)) {
|
|
161
101
|
this.logger?.warn(`remove tmp file: ${this.tmpFilePath}`);
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
if ((0, import_node_fs3.existsSync)(this.gzipPath)) {
|
|
165
|
-
this.logger?.warn(`remove .gz file: ${this.gzipPath}`);
|
|
166
|
-
(0, import_node_fs3.rmSync)(this.gzipPath);
|
|
102
|
+
fs.rmSync(this.tmpFilePath);
|
|
167
103
|
}
|
|
168
104
|
if (typeof data === "object") {
|
|
169
105
|
if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) {
|
|
@@ -175,11 +111,11 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
175
111
|
}
|
|
176
112
|
this.logger?.debug(`download from ${this.provider.name}`);
|
|
177
113
|
try {
|
|
178
|
-
const result = format === "json" ? await this.provider.downloadJSON(data ?? __EIU_VERSION_PATH__) : await this.provider.downloadAsar(
|
|
114
|
+
const result = format === "json" ? await this.provider.downloadJSON(data ?? __EIU_VERSION_PATH__) : await this.provider.downloadAsar(electron.app.name, this.info, (data2) => this.emit("download-progress", data2));
|
|
179
115
|
this.logger?.debug(`download ${format} success${format === "buffer" ? `, file size: ${result.length}` : ""}`);
|
|
180
116
|
return result;
|
|
181
117
|
} catch (e) {
|
|
182
|
-
this.err(`
|
|
118
|
+
this.err(`fetch ${format} failed`, "network", `download ${format} failed: ${e}`);
|
|
183
119
|
}
|
|
184
120
|
}
|
|
185
121
|
/**
|
|
@@ -194,11 +130,11 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
194
130
|
const emitUnavailable = (msg) => {
|
|
195
131
|
this.logger?.info(msg);
|
|
196
132
|
this.emit("update-unavailable", msg);
|
|
133
|
+
return false;
|
|
197
134
|
};
|
|
198
135
|
const _data = await this.fetch("json", data);
|
|
199
136
|
if (!_data) {
|
|
200
|
-
emitUnavailable("failed to get update info");
|
|
201
|
-
return false;
|
|
137
|
+
return emitUnavailable("failed to get update info");
|
|
202
138
|
}
|
|
203
139
|
let { signature, size, version, minimumVersion, beta } = _data;
|
|
204
140
|
if (this.receiveBeta) {
|
|
@@ -208,21 +144,18 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
208
144
|
size = beta.size;
|
|
209
145
|
}
|
|
210
146
|
this.logger?.debug(`checked update, version: ${version}, size: ${size}, signature: ${signature}`);
|
|
211
|
-
if (isDev) {
|
|
212
|
-
emitUnavailable("in dev mode,
|
|
213
|
-
return false;
|
|
147
|
+
if (isDev && !this.forceUpdate && !data) {
|
|
148
|
+
return emitUnavailable("skip check update in dev mode, to force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON");
|
|
214
149
|
}
|
|
215
150
|
const isLowerVersion = this.provider.isLowerVersion;
|
|
216
151
|
const entryVersion = getEntryVersion();
|
|
217
152
|
const appVersion = getAppVersion();
|
|
218
153
|
if (isLowerVersion(entryVersion, minimumVersion)) {
|
|
219
|
-
emitUnavailable(`entry version (${entryVersion}) < minimumVersion (${minimumVersion})`);
|
|
220
|
-
return false;
|
|
154
|
+
return emitUnavailable(`entry version (${entryVersion}) < minimumVersion (${minimumVersion})`);
|
|
221
155
|
}
|
|
222
156
|
this.logger?.info(`check update: current version is ${appVersion}, new version is ${version}`);
|
|
223
157
|
if (!isLowerVersion(appVersion, version)) {
|
|
224
|
-
emitUnavailable(`current version (${appVersion}) < new version (${version})`);
|
|
225
|
-
return false;
|
|
158
|
+
return emitUnavailable(`current version (${appVersion}) < new version (${version})`);
|
|
226
159
|
}
|
|
227
160
|
this.logger?.info(`update available: ${version}`);
|
|
228
161
|
this.info = { signature, minimumVersion, version, size };
|
|
@@ -230,11 +163,11 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
230
163
|
return true;
|
|
231
164
|
}
|
|
232
165
|
async download(data, sig) {
|
|
233
|
-
|
|
234
|
-
|
|
166
|
+
const _sig = sig ?? this.info?.signature;
|
|
167
|
+
if (!_sig) {
|
|
168
|
+
this.err("download failed", "param", "no update signature, please call `checkUpdate` first");
|
|
235
169
|
return false;
|
|
236
170
|
}
|
|
237
|
-
const _sig = sig ?? this.info.signature;
|
|
238
171
|
const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
|
|
239
172
|
if (!buffer) {
|
|
240
173
|
this.err("download failed", "param", "no update asar file buffer");
|
|
@@ -243,21 +176,19 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
243
176
|
this.logger?.debug("verify start");
|
|
244
177
|
const _ver = await this.provider.verifySignaure(buffer, _sig, this.CERT);
|
|
245
178
|
if (!_ver) {
|
|
246
|
-
this.err("
|
|
179
|
+
this.err("download failed", "validate", "invalid signature / certificate pair");
|
|
247
180
|
return false;
|
|
248
181
|
}
|
|
249
182
|
this.logger?.debug("verify success");
|
|
250
183
|
try {
|
|
251
|
-
this.logger?.debug(`write to ${this.gzipPath}`);
|
|
252
|
-
(0, import_node_fs3.writeFileSync)(this.gzipPath, buffer);
|
|
253
184
|
this.logger?.debug(`extract to ${this.tmpFilePath}`);
|
|
254
|
-
await unzipFile(
|
|
185
|
+
await this.provider.unzipFile(buffer, this.tmpFilePath);
|
|
255
186
|
this.logger?.info(`download success, version: ${_ver}`);
|
|
256
187
|
this.info = void 0;
|
|
257
188
|
this.emit("update-downloaded");
|
|
258
189
|
return true;
|
|
259
190
|
} catch (error) {
|
|
260
|
-
this.err("
|
|
191
|
+
this.err("download failed", "download", `fail to unwrap asar file, ${error}`);
|
|
261
192
|
return false;
|
|
262
193
|
}
|
|
263
194
|
}
|
|
@@ -268,28 +199,28 @@ var Updater = class extends import_node_stream.EventEmitter {
|
|
|
268
199
|
this.logger?.info("quit and install");
|
|
269
200
|
restartApp();
|
|
270
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* setup provider URL handler
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* updater.setURLHandler((url, isDownloadingAsar) => {
|
|
207
|
+
* if (isDownloadingAsar) {
|
|
208
|
+
* return url.replace('https://raw.githubusercontent.com', 'https://cdn.jsdelivr.net/gh')
|
|
209
|
+
* }
|
|
210
|
+
* })
|
|
211
|
+
*/
|
|
212
|
+
setURLHandler(handler) {
|
|
213
|
+
this.provider.urlHandler = handler;
|
|
214
|
+
}
|
|
271
215
|
};
|
|
272
216
|
|
|
273
|
-
// src/utils/zip.ts
|
|
274
|
-
var import_node_fs4 = require("fs");
|
|
275
|
-
var import_node_zlib2 = require("zlib");
|
|
276
|
-
|
|
277
|
-
// src/utils/crypto/decrypt.ts
|
|
278
|
-
var import_node_crypto2 = require("crypto");
|
|
279
|
-
|
|
280
|
-
// src/utils/crypto/utils.ts
|
|
281
|
-
var import_node_crypto = require("crypto");
|
|
282
|
-
|
|
283
|
-
// src/utils/crypto/encrypt.ts
|
|
284
|
-
var import_node_crypto3 = require("crypto");
|
|
285
|
-
|
|
286
217
|
// src/entry.ts
|
|
287
218
|
function startupWithUpdater(fn) {
|
|
288
219
|
return fn;
|
|
289
220
|
}
|
|
290
221
|
var defaultOnInstall = (install, _, __, logger) => {
|
|
291
222
|
install();
|
|
292
|
-
logger
|
|
223
|
+
logger?.info(`update success!`);
|
|
293
224
|
};
|
|
294
225
|
async function initApp(appOptions) {
|
|
295
226
|
const {
|
|
@@ -305,32 +236,38 @@ async function initApp(appOptions) {
|
|
|
305
236
|
} else {
|
|
306
237
|
updaterInstance = await updater();
|
|
307
238
|
}
|
|
308
|
-
|
|
239
|
+
let logger = updaterInstance.logger;
|
|
240
|
+
if (isDev && !logger) {
|
|
241
|
+
logger = {
|
|
242
|
+
info: (...args) => console.log("[EIU-INFO ]", ...args),
|
|
243
|
+
debug: (...args) => console.log("[EIU-DEBUG]", ...args),
|
|
244
|
+
warn: (...args) => console.log("[EIU-WARN ]", ...args),
|
|
245
|
+
error: (...args) => console.error("[EIU-ERROR]", ...args)
|
|
246
|
+
};
|
|
247
|
+
}
|
|
309
248
|
try {
|
|
310
249
|
const appNameAsarPath = getPathFromAppNameAsar();
|
|
311
250
|
const tempAsarPath = `${appNameAsarPath}.tmp`;
|
|
312
|
-
if (
|
|
313
|
-
logger
|
|
314
|
-
await onInstall(() =>
|
|
251
|
+
if (fs.existsSync(tempAsarPath)) {
|
|
252
|
+
logger?.info(`installing new asar: ${tempAsarPath}`);
|
|
253
|
+
await onInstall(() => fs.renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
|
|
315
254
|
}
|
|
316
|
-
const mainFilePath =
|
|
317
|
-
isDev ?
|
|
255
|
+
const mainFilePath = path.join(
|
|
256
|
+
isDev ? path.join(electron.app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
|
|
318
257
|
"main",
|
|
319
258
|
__EIU_MAIN_FILE__
|
|
320
259
|
);
|
|
321
260
|
await beforeStart?.(mainFilePath, logger);
|
|
322
|
-
|
|
261
|
+
__require(mainFilePath)(updaterInstance);
|
|
323
262
|
} catch (error) {
|
|
324
|
-
logger
|
|
263
|
+
logger?.error("startup error", error);
|
|
325
264
|
onStartError?.(error, logger);
|
|
326
|
-
|
|
265
|
+
electron.app.quit();
|
|
327
266
|
}
|
|
328
267
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
startupWithUpdater
|
|
336
|
-
});
|
|
268
|
+
|
|
269
|
+
exports.ErrorInfo = ErrorInfo;
|
|
270
|
+
exports.Updater = Updater;
|
|
271
|
+
exports.UpdaterError = UpdaterError;
|
|
272
|
+
exports.initApp = initApp;
|
|
273
|
+
exports.startupWithUpdater = startupWithUpdater;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { EventEmitter } from 'node:
|
|
2
|
-
import { U as UpdateJSON, a as UpdateInfo } from './version-
|
|
3
|
-
import { D as DownloadingInfo,
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { U as UpdateJSON, a as UpdateInfo } from './version-CemSHimT.cjs';
|
|
3
|
+
import { D as DownloadingInfo, I as IProvider, U as URLHandler } from './types-Tequ_V2o.cjs';
|
|
4
4
|
import '@subframe7536/type-utils';
|
|
5
5
|
|
|
6
6
|
declare const ErrorInfo: {
|
|
7
7
|
readonly download: "Download failed";
|
|
8
8
|
readonly validate: "Validate failed";
|
|
9
9
|
readonly param: "Missing params";
|
|
10
|
+
readonly network: "Network error";
|
|
10
11
|
};
|
|
11
12
|
declare class UpdaterError extends Error {
|
|
12
13
|
code: keyof typeof ErrorInfo;
|
|
@@ -60,9 +61,7 @@ declare class Updater extends EventEmitter<{
|
|
|
60
61
|
}> {
|
|
61
62
|
private CERT;
|
|
62
63
|
private info?;
|
|
63
|
-
private options;
|
|
64
64
|
private asarPath;
|
|
65
|
-
private gzipPath;
|
|
66
65
|
private tmpFilePath;
|
|
67
66
|
private provider;
|
|
68
67
|
/**
|
|
@@ -70,18 +69,13 @@ declare class Updater extends EventEmitter<{
|
|
|
70
69
|
*/
|
|
71
70
|
logger?: Logger;
|
|
72
71
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDNs}
|
|
76
|
-
* @param url source url
|
|
77
|
-
* @param isDownloadAsar whether is download asar
|
|
72
|
+
* whether to receive beta update
|
|
78
73
|
*/
|
|
79
|
-
|
|
74
|
+
receiveBeta?: boolean;
|
|
80
75
|
/**
|
|
81
|
-
* whether
|
|
76
|
+
* whether force update in DEV
|
|
82
77
|
*/
|
|
83
|
-
|
|
84
|
-
set receiveBeta(receiveBeta: boolean);
|
|
78
|
+
forceUpdate?: boolean;
|
|
85
79
|
/**
|
|
86
80
|
* initialize incremental updater
|
|
87
81
|
* @param provider update provider
|
|
@@ -122,11 +116,22 @@ declare class Updater extends EventEmitter<{
|
|
|
122
116
|
* @param data existing `asar.gz` buffer
|
|
123
117
|
* @param sig signature
|
|
124
118
|
*/
|
|
125
|
-
download(data: Uint8Array, sig: string): Promise<boolean>;
|
|
119
|
+
download(data: Uint8Array | Buffer, sig: string): Promise<boolean>;
|
|
126
120
|
/**
|
|
127
121
|
* quit App and install
|
|
128
122
|
*/
|
|
129
123
|
quitAndInstall(): void;
|
|
124
|
+
/**
|
|
125
|
+
* setup provider URL handler
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* updater.setURLHandler((url, isDownloadingAsar) => {
|
|
129
|
+
* if (isDownloadingAsar) {
|
|
130
|
+
* return url.replace('https://raw.githubusercontent.com', 'https://cdn.jsdelivr.net/gh')
|
|
131
|
+
* }
|
|
132
|
+
* })
|
|
133
|
+
*/
|
|
134
|
+
setURLHandler(handler: URLHandler): void;
|
|
130
135
|
}
|
|
131
136
|
|
|
132
137
|
type Promisable<T> = T | Promise<T>;
|
|
@@ -138,7 +143,7 @@ type Promisable<T> = T | Promise<T>;
|
|
|
138
143
|
* @param logger logger
|
|
139
144
|
* @default install(); logger.info(`update success!`)
|
|
140
145
|
*/
|
|
141
|
-
type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger
|
|
146
|
+
type OnInstallFunction = (install: VoidFunction, tempAsarPath: string, appNameAsarPath: string, logger?: Logger) => Promisable<void>;
|
|
142
147
|
interface AppOption {
|
|
143
148
|
/**
|
|
144
149
|
* update provider
|
|
@@ -157,13 +162,13 @@ interface AppOption {
|
|
|
157
162
|
* @param mainFilePath main file path of `${app.name}.asar`
|
|
158
163
|
* @param logger logger
|
|
159
164
|
*/
|
|
160
|
-
beforeStart?: (mainFilePath: string, logger
|
|
165
|
+
beforeStart?: (mainFilePath: string, logger?: Logger) => Promisable<void>;
|
|
161
166
|
/**
|
|
162
167
|
* hooks on app start up error
|
|
163
168
|
* @param err installing or startup error
|
|
164
169
|
* @param logger logger
|
|
165
170
|
*/
|
|
166
|
-
onStartError?: (err: unknown, logger
|
|
171
|
+
onStartError?: (err: unknown, logger?: Logger) => void;
|
|
167
172
|
}
|
|
168
173
|
/**
|
|
169
174
|
* utils for startuping with updater
|