electron-incremental-update 2.0.0-beta.1 → 2.0.0-beta.11
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 +3 -3
- package/dist/chunk-IABBXJFB.js +87 -0
- package/dist/chunk-KZSYEXLO.js +55 -0
- package/dist/chunk-RCRKUKFX.js +70 -0
- package/dist/index.cjs +193 -233
- package/dist/index.d.cts +89 -117
- package/dist/index.d.ts +89 -117
- package/dist/index.js +166 -169
- package/dist/provider.cjs +165 -146
- package/dist/provider.d.cts +94 -22
- package/dist/provider.d.ts +94 -22
- package/dist/provider.js +125 -71
- package/dist/types-C8JhnJjU.d.ts +80 -0
- package/dist/types-CGSkHX4Y.d.cts +80 -0
- package/dist/utils.cjs +142 -191
- package/dist/utils.d.cts +42 -30
- package/dist/utils.d.ts +42 -30
- package/dist/utils.js +3 -62
- package/dist/version-BYVQ367i.d.cts +62 -0
- package/dist/version-BYVQ367i.d.ts +62 -0
- package/dist/vite.d.ts +372 -0
- package/dist/vite.js +326 -274
- package/dist/zip-rm9ED9nU.d.cts +33 -0
- package/dist/zip-rm9ED9nU.d.ts +33 -0
- package/package.json +21 -15
- package/dist/chunk-RSLOPAIZ.js +0 -247
- package/dist/decrypt-BNBcodiO.d.cts +0 -4
- package/dist/decrypt-BNBcodiO.d.ts +0 -4
- package/dist/types-DxPmQmaq.d.cts +0 -61
- package/dist/types-seJf3Wbc.d.ts +0 -61
- package/dist/version-CffZWDhZ.d.cts +0 -32
- package/dist/version-CffZWDhZ.d.ts +0 -32
package/dist/index.js
CHANGED
|
@@ -1,207 +1,210 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
isUpdateJSON,
|
|
8
|
-
restartApp,
|
|
9
|
-
unzipFile
|
|
10
|
-
} from "./chunk-RSLOPAIZ.js";
|
|
1
|
+
import { isDev, getEntryVersion, getAppVersion, getPathFromAppNameAsar, restartApp } from './chunk-IABBXJFB.js';
|
|
2
|
+
import { isUpdateJSON, __require } from './chunk-RCRKUKFX.js';
|
|
3
|
+
import fs2 from 'node:fs';
|
|
4
|
+
import { EventEmitter } from 'node:events';
|
|
5
|
+
import { app } from 'electron';
|
|
6
|
+
import path from 'node:path';
|
|
11
7
|
|
|
12
|
-
// src/entry.ts
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
import { existsSync as existsSync2, renameSync } from "node:fs";
|
|
15
|
-
import { app as app2 } from "electron";
|
|
16
|
-
|
|
17
|
-
// src/updater/core.ts
|
|
18
|
-
import { existsSync, rmSync, writeFileSync } from "node:fs";
|
|
19
|
-
import { app } from "electron";
|
|
20
|
-
|
|
21
|
-
// src/updater/types.ts
|
|
8
|
+
// src/entry/types.ts
|
|
22
9
|
var ErrorInfo = {
|
|
23
|
-
download: "Download
|
|
24
|
-
validate: "Validate
|
|
25
|
-
param: "Missing
|
|
26
|
-
|
|
10
|
+
download: "Download Failed",
|
|
11
|
+
validate: "Validate Failed",
|
|
12
|
+
param: "Missing Params",
|
|
13
|
+
network: "Network Error"
|
|
27
14
|
};
|
|
28
15
|
var UpdaterError = class extends Error {
|
|
16
|
+
code;
|
|
29
17
|
constructor(msg, info) {
|
|
30
|
-
super(msg + "
|
|
18
|
+
super("[" + ErrorInfo[msg] + "] " + info);
|
|
19
|
+
this.code = msg;
|
|
31
20
|
}
|
|
32
21
|
};
|
|
33
22
|
|
|
34
|
-
// src/updater
|
|
35
|
-
var Updater = class {
|
|
36
|
-
CERT
|
|
23
|
+
// src/entry/updater.ts
|
|
24
|
+
var Updater = class extends EventEmitter {
|
|
25
|
+
CERT;
|
|
26
|
+
controller;
|
|
37
27
|
info;
|
|
38
|
-
options;
|
|
39
|
-
asarPath;
|
|
40
|
-
gzipPath;
|
|
41
|
-
tmpFilePath;
|
|
42
28
|
provider;
|
|
43
29
|
/**
|
|
44
|
-
*
|
|
30
|
+
* Updater logger
|
|
45
31
|
*/
|
|
46
32
|
logger;
|
|
47
33
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @param progress download progress
|
|
50
|
-
* @example
|
|
51
|
-
* updater.onDownloading = ({ percent, total, current }) => {
|
|
52
|
-
* console.log(`download progress: ${percent}, total: ${total}, current: ${current}`)
|
|
53
|
-
* }
|
|
34
|
+
* Whether to receive beta update
|
|
54
35
|
*/
|
|
55
|
-
|
|
36
|
+
receiveBeta;
|
|
56
37
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDN links}
|
|
60
|
-
* @param url source url
|
|
61
|
-
* @param isDownloadAsar whether is download asar
|
|
38
|
+
* Whether force update in DEV
|
|
62
39
|
*/
|
|
63
|
-
|
|
40
|
+
forceUpdate;
|
|
64
41
|
/**
|
|
65
|
-
*
|
|
42
|
+
* Initialize incremental updater
|
|
43
|
+
* @param options UpdaterOption
|
|
66
44
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.options.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.CERT = option.SIGNATURE_CERT;
|
|
83
|
-
}
|
|
84
|
-
if (option.logger) {
|
|
85
|
-
this.logger = option.logger;
|
|
86
|
-
}
|
|
87
|
-
this.asarPath = getPathFromAppNameAsar();
|
|
88
|
-
this.gzipPath = `${this.asarPath}.gz`;
|
|
89
|
-
this.tmpFilePath = `${this.asarPath}.tmp`;
|
|
90
|
-
}
|
|
91
|
-
async needUpdate(version, minVersion) {
|
|
92
|
-
if (isDev) {
|
|
93
|
-
this.logger?.warn(`in dev mode, skip check update`);
|
|
94
|
-
return false;
|
|
45
|
+
constructor(options = {}) {
|
|
46
|
+
super();
|
|
47
|
+
this.provider = options.provider;
|
|
48
|
+
this.receiveBeta = options.receiveBeta;
|
|
49
|
+
this.CERT = options.SIGNATURE_CERT || __EIU_SIGNATURE_CERT__;
|
|
50
|
+
this.logger = options.logger;
|
|
51
|
+
this.controller = new AbortController();
|
|
52
|
+
if (isDev && !this.logger) {
|
|
53
|
+
this.logger = {
|
|
54
|
+
info: (...args) => console.log("[EIU-INFO ]", ...args),
|
|
55
|
+
debug: (...args) => console.log("[EIU-DEBUG]", ...args),
|
|
56
|
+
warn: (...args) => console.log("[EIU-WARN ]", ...args),
|
|
57
|
+
error: (...args) => console.error("[EIU-ERROR]", ...args)
|
|
58
|
+
};
|
|
59
|
+
this.logger.info("No logger set, enable dev-only logger");
|
|
95
60
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const appVersion = getAppVersion();
|
|
99
|
-
if (await isLowerVersion(entryVersion, minVersion)) {
|
|
100
|
-
throw new UpdaterError(ErrorInfo.version, `entry version (${entryVersion}) < minimumVersion (${minVersion})`);
|
|
61
|
+
if (!this.provider) {
|
|
62
|
+
this.logger?.debug("WARN: No update provider");
|
|
101
63
|
}
|
|
102
|
-
this.logger?.info(`check update: current version is ${appVersion}, new version is ${version}`);
|
|
103
|
-
return await isLowerVersion(appVersion, version);
|
|
104
64
|
}
|
|
105
|
-
async
|
|
106
|
-
if (existsSync(this.tmpFilePath)) {
|
|
107
|
-
this.logger?.warn(`remove tmp file: ${this.tmpFilePath}`);
|
|
108
|
-
rmSync(this.tmpFilePath);
|
|
109
|
-
}
|
|
110
|
-
if (existsSync(this.gzipPath)) {
|
|
111
|
-
this.logger?.warn(`remove .gz file: ${this.gzipPath}`);
|
|
112
|
-
rmSync(this.gzipPath);
|
|
113
|
-
}
|
|
65
|
+
async fetch(format, data) {
|
|
114
66
|
if (typeof data === "object") {
|
|
115
67
|
if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) {
|
|
116
68
|
return data;
|
|
117
69
|
} else {
|
|
118
|
-
|
|
70
|
+
this.err("Invalid type", "param", `Invalid type at format '${format}': ${JSON.stringify(data)}`);
|
|
71
|
+
return;
|
|
119
72
|
}
|
|
120
73
|
}
|
|
121
|
-
this.logger?.debug(`
|
|
74
|
+
this.logger?.debug(`Download from \`${this.provider.name}\``);
|
|
122
75
|
try {
|
|
123
|
-
const result = format === "json" ? await this.provider.downloadJSON(
|
|
124
|
-
this.logger?.debug(`
|
|
76
|
+
const result = format === "json" ? await this.provider.downloadJSON(__EIU_VERSION_PATH__, this.controller.signal) : await this.provider.downloadAsar(app.name, this.info, this.controller.signal, (info) => this.emit("download-progress", info));
|
|
77
|
+
this.logger?.debug(`Download ${format} success${format === "buffer" ? `, file size: ${result.length}` : ""}`);
|
|
125
78
|
return result;
|
|
126
79
|
} catch (e) {
|
|
127
|
-
this.
|
|
128
|
-
throw new UpdaterError(ErrorInfo.download, `download ${format} failed: ${e}`);
|
|
80
|
+
this.err(`Fetch ${format} failed`, "network", `Download ${format} failed: ${e}`);
|
|
129
81
|
}
|
|
130
82
|
}
|
|
131
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Handle error message and emit error event
|
|
85
|
+
*/
|
|
86
|
+
err(msg, code, errorInfo) {
|
|
87
|
+
const err = new UpdaterError(code, errorInfo);
|
|
88
|
+
this.logger?.error(msg, err);
|
|
89
|
+
this.emit("error", err);
|
|
90
|
+
}
|
|
91
|
+
async checkForUpdates(data) {
|
|
92
|
+
const emitUnavailable = (msg) => {
|
|
93
|
+
this.logger?.info(msg);
|
|
94
|
+
this.emit("update-not-available", msg);
|
|
95
|
+
return false;
|
|
96
|
+
};
|
|
97
|
+
if (!data && !this.provider) {
|
|
98
|
+
const errorInfo = "No update json or provider";
|
|
99
|
+
this.err("Check update failed", "param", errorInfo);
|
|
100
|
+
return emitUnavailable(errorInfo);
|
|
101
|
+
}
|
|
102
|
+
const _data = await this.fetch("json", data);
|
|
103
|
+
if (!_data) {
|
|
104
|
+
return emitUnavailable("Failed to get update info");
|
|
105
|
+
}
|
|
106
|
+
let { signature, version, minimumVersion, beta } = _data;
|
|
107
|
+
if (this.receiveBeta) {
|
|
108
|
+
version = beta.version;
|
|
109
|
+
signature = beta.signature;
|
|
110
|
+
minimumVersion = beta.minimumVersion;
|
|
111
|
+
}
|
|
112
|
+
this.logger?.debug(`Checked update, version: ${version}, signature: ${signature}`);
|
|
113
|
+
if (isDev && !this.forceUpdate && !data) {
|
|
114
|
+
return emitUnavailable("Skip check update in dev mode. To force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON");
|
|
115
|
+
}
|
|
116
|
+
const isLowerVersion = this.provider.isLowerVersion;
|
|
117
|
+
const entryVersion = getEntryVersion();
|
|
118
|
+
const appVersion = getAppVersion();
|
|
132
119
|
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
version = beta.version;
|
|
136
|
-
signature = beta.signature;
|
|
137
|
-
minimumVersion = beta.minimumVersion;
|
|
138
|
-
size = beta.size;
|
|
120
|
+
if (isLowerVersion(entryVersion, minimumVersion)) {
|
|
121
|
+
return emitUnavailable(`Entry Version (${entryVersion}) < MinimumVersion (${minimumVersion})`);
|
|
139
122
|
}
|
|
140
|
-
this.logger?.
|
|
141
|
-
if (!
|
|
142
|
-
|
|
143
|
-
return { success: false, data: version };
|
|
144
|
-
} else {
|
|
145
|
-
this.logger?.info(`update available: ${version}`);
|
|
146
|
-
this.info = { signature, minimumVersion, version, size };
|
|
147
|
-
return { success: true, data: this.info };
|
|
123
|
+
this.logger?.info(`Check update: current version is ${appVersion}, new version is ${version}`);
|
|
124
|
+
if (!isLowerVersion(appVersion, version)) {
|
|
125
|
+
return emitUnavailable(`Current version (${appVersion}) < New version (${version})`);
|
|
148
126
|
}
|
|
149
|
-
|
|
150
|
-
this.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
127
|
+
this.logger?.info(`Update available: ${version}`);
|
|
128
|
+
this.info = { signature, minimumVersion, version };
|
|
129
|
+
this.emit("update-available", this.info);
|
|
130
|
+
return true;
|
|
131
|
+
} catch {
|
|
132
|
+
this.err("Fail to parse version", "validate", "Fail to parse version string");
|
|
133
|
+
return false;
|
|
155
134
|
}
|
|
156
135
|
}
|
|
157
|
-
async
|
|
136
|
+
async downloadUpdate(data, info) {
|
|
137
|
+
const _sig = info?.signature ?? this.info?.signature;
|
|
138
|
+
const _version = info?.version ?? this.info?.version;
|
|
139
|
+
if (!_sig || !_version) {
|
|
140
|
+
this.err("Download failed", "param", "No update signature, please call `checkUpdate` first or manually setup params");
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (!data && !this.provider) {
|
|
144
|
+
this.err("Download failed", "param", "No update asar buffer and provider");
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
|
|
148
|
+
if (!buffer) {
|
|
149
|
+
this.err("Download failed", "param", "No update asar file buffer");
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
this.logger?.debug("verify start");
|
|
153
|
+
if (!await this.provider.verifySignaure(buffer, _version, _sig, this.CERT)) {
|
|
154
|
+
this.err("Download failed", "validate", "Invalid update asar file");
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
this.logger?.debug("Verify success");
|
|
158
158
|
try {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const buffer = await this.parseData("buffer", data);
|
|
164
|
-
this.logger?.debug("verify start");
|
|
165
|
-
const _ver = await this.provider.verifySignaure(buffer, _sig, this.CERT);
|
|
166
|
-
if (!_ver) {
|
|
167
|
-
throw new UpdaterError(ErrorInfo.validate, "invalid signature or certificate");
|
|
168
|
-
}
|
|
169
|
-
this.logger?.debug("verify success");
|
|
170
|
-
this.logger?.debug(`write to ${this.gzipPath}`);
|
|
171
|
-
writeFileSync(this.gzipPath, buffer);
|
|
172
|
-
this.logger?.debug(`extract to ${this.tmpFilePath}`);
|
|
173
|
-
await unzipFile(this.gzipPath, this.tmpFilePath);
|
|
174
|
-
this.logger?.info(`download success, version: ${_ver}`);
|
|
159
|
+
const tmpFilePath = getPathFromAppNameAsar() + ".tmp";
|
|
160
|
+
this.logger?.debug(`Install to ${tmpFilePath}`);
|
|
161
|
+
fs2.writeFileSync(tmpFilePath, await this.provider.unzipFile(buffer));
|
|
162
|
+
this.logger?.info(`Download success, version: ${_version}`);
|
|
175
163
|
this.info = void 0;
|
|
176
|
-
|
|
164
|
+
this.emit("update-downloaded");
|
|
165
|
+
return true;
|
|
177
166
|
} catch (error) {
|
|
178
|
-
this.
|
|
179
|
-
return
|
|
180
|
-
success: false,
|
|
181
|
-
data: error instanceof UpdaterError ? error : new UpdaterError(ErrorInfo.download, error.toString())
|
|
182
|
-
};
|
|
167
|
+
this.err("Download failed", "download", `Fail to unwrap asar file, ${error}`);
|
|
168
|
+
return false;
|
|
183
169
|
}
|
|
184
170
|
}
|
|
185
171
|
/**
|
|
186
172
|
* quit App and install
|
|
187
173
|
*/
|
|
188
174
|
quitAndInstall() {
|
|
189
|
-
this.logger?.info("
|
|
175
|
+
this.logger?.info("Quit and install");
|
|
190
176
|
restartApp();
|
|
191
177
|
}
|
|
178
|
+
cancel() {
|
|
179
|
+
if (this.controller.signal.aborted) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
this.controller.abort();
|
|
183
|
+
this.logger?.info("Cancel update");
|
|
184
|
+
this.emit("update-cancelled");
|
|
185
|
+
this.controller = new AbortController();
|
|
186
|
+
}
|
|
192
187
|
};
|
|
193
|
-
|
|
194
|
-
|
|
188
|
+
async function autoUpdate(updater) {
|
|
189
|
+
if (await updater.checkForUpdates() && await updater.downloadUpdate()) {
|
|
190
|
+
updater.quitAndInstall();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
195
193
|
function startupWithUpdater(fn) {
|
|
196
194
|
return fn;
|
|
197
195
|
}
|
|
198
196
|
var defaultOnInstall = (install, _, __, logger) => {
|
|
199
197
|
install();
|
|
200
|
-
logger
|
|
198
|
+
logger?.info(`update success!`);
|
|
201
199
|
};
|
|
202
|
-
async function
|
|
200
|
+
async function createElectronApp(appOptions = {}) {
|
|
201
|
+
const appNameAsarPath = getPathFromAppNameAsar();
|
|
203
202
|
const {
|
|
204
|
-
|
|
203
|
+
mainPath = path.join(
|
|
204
|
+
isDev ? path.join(app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
|
|
205
|
+
"main",
|
|
206
|
+
__EIU_MAIN_FILE__
|
|
207
|
+
),
|
|
205
208
|
updater,
|
|
206
209
|
onInstall = defaultOnInstall,
|
|
207
210
|
beforeStart,
|
|
@@ -209,35 +212,29 @@ async function initApp(appOptions) {
|
|
|
209
212
|
} = appOptions;
|
|
210
213
|
let updaterInstance;
|
|
211
214
|
if (typeof updater === "object" || !updater) {
|
|
212
|
-
updaterInstance = new Updater(
|
|
215
|
+
updaterInstance = new Updater(updater);
|
|
213
216
|
} else {
|
|
214
217
|
updaterInstance = await updater();
|
|
215
218
|
}
|
|
216
|
-
const logger = updaterInstance.logger
|
|
219
|
+
const logger = updaterInstance.logger;
|
|
217
220
|
try {
|
|
218
|
-
const appNameAsarPath = getPathFromAppNameAsar();
|
|
219
221
|
const tempAsarPath = `${appNameAsarPath}.tmp`;
|
|
220
|
-
if (
|
|
221
|
-
logger
|
|
222
|
-
await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
|
|
222
|
+
if (fs2.existsSync(tempAsarPath)) {
|
|
223
|
+
logger?.info(`Installing new asar from ${tempAsarPath}`);
|
|
224
|
+
await onInstall(() => fs2.renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
|
|
225
|
+
}
|
|
226
|
+
await beforeStart?.(mainPath, logger);
|
|
227
|
+
if (__EIU_IS_ESM__) {
|
|
228
|
+
(await import("file://" + mainPath)).default(updaterInstance);
|
|
229
|
+
} else {
|
|
230
|
+
__require(mainPath)(updaterInstance);
|
|
223
231
|
}
|
|
224
|
-
const mainFilePath = join(
|
|
225
|
-
isDev ? join(app2.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
|
|
226
|
-
"main",
|
|
227
|
-
__EIU_MAIN_FILE__
|
|
228
|
-
);
|
|
229
|
-
await beforeStart?.(mainFilePath, logger);
|
|
230
|
-
__require(mainFilePath)(updaterInstance);
|
|
231
232
|
} catch (error) {
|
|
232
|
-
logger
|
|
233
|
+
logger?.error("startup error", error);
|
|
233
234
|
onStartError?.(error, logger);
|
|
234
|
-
|
|
235
|
+
app.quit();
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
UpdaterError,
|
|
241
|
-
initApp,
|
|
242
|
-
startupWithUpdater
|
|
243
|
-
};
|
|
238
|
+
var initApp = createElectronApp;
|
|
239
|
+
|
|
240
|
+
export { ErrorInfo, Updater, UpdaterError, autoUpdate, createElectronApp, initApp, startupWithUpdater };
|