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
package/dist/index.d.ts
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.js';
|
|
3
|
+
import { D as DownloadingInfo, I as IProvider, U as URLHandler } from './types-DxhNaNgR.js';
|
|
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
|
package/dist/index.js
CHANGED
|
@@ -1,29 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
isUpdateJSON,
|
|
8
|
-
restartApp,
|
|
9
|
-
unzipFile
|
|
10
|
-
} from "./chunk-BG22XZAB.js";
|
|
11
|
-
|
|
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 { EventEmitter } from "node:stream";
|
|
20
|
-
import { app } from "electron";
|
|
1
|
+
import { isDev, getPathFromAppNameAsar, getEntryVersion, getAppVersion, restartApp } from './chunk-PNYRQYFC.js';
|
|
2
|
+
import { isUpdateJSON, __require } from './chunk-BVFQWBLK.js';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { existsSync, rmSync, renameSync } from 'node:fs';
|
|
5
|
+
import { app } from 'electron';
|
|
6
|
+
import { EventEmitter } from 'node:events';
|
|
21
7
|
|
|
22
8
|
// src/updater/types.ts
|
|
23
9
|
var ErrorInfo = {
|
|
24
10
|
download: "Download failed",
|
|
25
11
|
validate: "Validate failed",
|
|
26
|
-
param: "Missing params"
|
|
12
|
+
param: "Missing params",
|
|
13
|
+
network: "Network error"
|
|
27
14
|
};
|
|
28
15
|
var UpdaterError = class extends Error {
|
|
29
16
|
code;
|
|
@@ -37,9 +24,7 @@ var UpdaterError = class extends Error {
|
|
|
37
24
|
var Updater = class extends EventEmitter {
|
|
38
25
|
CERT = __EIU_SIGNATURE_CERT__;
|
|
39
26
|
info;
|
|
40
|
-
options;
|
|
41
27
|
asarPath;
|
|
42
|
-
gzipPath;
|
|
43
28
|
tmpFilePath;
|
|
44
29
|
provider;
|
|
45
30
|
/**
|
|
@@ -47,22 +32,13 @@ var Updater = class extends EventEmitter {
|
|
|
47
32
|
*/
|
|
48
33
|
logger;
|
|
49
34
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* for Github, there are some {@link https://github.com/XIU2/UserScript/blob/master/GithubEnhanced-High-Speed-Download.user.js#L34 public CDNs}
|
|
53
|
-
* @param url source url
|
|
54
|
-
* @param isDownloadAsar whether is download asar
|
|
35
|
+
* whether to receive beta update
|
|
55
36
|
*/
|
|
56
|
-
|
|
37
|
+
receiveBeta;
|
|
57
38
|
/**
|
|
58
|
-
* whether
|
|
39
|
+
* whether force update in DEV
|
|
59
40
|
*/
|
|
60
|
-
|
|
61
|
-
return !!this.options.receiveBeta;
|
|
62
|
-
}
|
|
63
|
-
set receiveBeta(receiveBeta) {
|
|
64
|
-
this.options.receiveBeta = receiveBeta;
|
|
65
|
-
}
|
|
41
|
+
forceUpdate;
|
|
66
42
|
/**
|
|
67
43
|
* initialize incremental updater
|
|
68
44
|
* @param provider update provider
|
|
@@ -71,7 +47,7 @@ var Updater = class extends EventEmitter {
|
|
|
71
47
|
constructor(provider, option = {}) {
|
|
72
48
|
super();
|
|
73
49
|
this.provider = provider;
|
|
74
|
-
this.
|
|
50
|
+
this.receiveBeta = option.receiveBeta;
|
|
75
51
|
if (option.SIGNATURE_CERT) {
|
|
76
52
|
this.CERT = option.SIGNATURE_CERT;
|
|
77
53
|
}
|
|
@@ -88,7 +64,6 @@ var Updater = class extends EventEmitter {
|
|
|
88
64
|
this.logger.info("no logger set, enable dev-only logger");
|
|
89
65
|
}
|
|
90
66
|
this.asarPath = getPathFromAppNameAsar();
|
|
91
|
-
this.gzipPath = `${this.asarPath}.gz`;
|
|
92
67
|
this.tmpFilePath = `${this.asarPath}.tmp`;
|
|
93
68
|
}
|
|
94
69
|
async fetch(format, data) {
|
|
@@ -96,10 +71,6 @@ var Updater = class extends EventEmitter {
|
|
|
96
71
|
this.logger?.warn(`remove tmp file: ${this.tmpFilePath}`);
|
|
97
72
|
rmSync(this.tmpFilePath);
|
|
98
73
|
}
|
|
99
|
-
if (existsSync(this.gzipPath)) {
|
|
100
|
-
this.logger?.warn(`remove .gz file: ${this.gzipPath}`);
|
|
101
|
-
rmSync(this.gzipPath);
|
|
102
|
-
}
|
|
103
74
|
if (typeof data === "object") {
|
|
104
75
|
if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer.isBuffer(data)) {
|
|
105
76
|
return data;
|
|
@@ -114,7 +85,7 @@ var Updater = class extends EventEmitter {
|
|
|
114
85
|
this.logger?.debug(`download ${format} success${format === "buffer" ? `, file size: ${result.length}` : ""}`);
|
|
115
86
|
return result;
|
|
116
87
|
} catch (e) {
|
|
117
|
-
this.err(`
|
|
88
|
+
this.err(`fetch ${format} failed`, "network", `download ${format} failed: ${e}`);
|
|
118
89
|
}
|
|
119
90
|
}
|
|
120
91
|
/**
|
|
@@ -129,11 +100,11 @@ var Updater = class extends EventEmitter {
|
|
|
129
100
|
const emitUnavailable = (msg) => {
|
|
130
101
|
this.logger?.info(msg);
|
|
131
102
|
this.emit("update-unavailable", msg);
|
|
103
|
+
return false;
|
|
132
104
|
};
|
|
133
105
|
const _data = await this.fetch("json", data);
|
|
134
106
|
if (!_data) {
|
|
135
|
-
emitUnavailable("failed to get update info");
|
|
136
|
-
return false;
|
|
107
|
+
return emitUnavailable("failed to get update info");
|
|
137
108
|
}
|
|
138
109
|
let { signature, size, version, minimumVersion, beta } = _data;
|
|
139
110
|
if (this.receiveBeta) {
|
|
@@ -143,21 +114,18 @@ var Updater = class extends EventEmitter {
|
|
|
143
114
|
size = beta.size;
|
|
144
115
|
}
|
|
145
116
|
this.logger?.debug(`checked update, version: ${version}, size: ${size}, signature: ${signature}`);
|
|
146
|
-
if (isDev) {
|
|
147
|
-
emitUnavailable("in dev mode,
|
|
148
|
-
return false;
|
|
117
|
+
if (isDev && !this.forceUpdate && !data) {
|
|
118
|
+
return emitUnavailable("skip check update in dev mode, to force update, set `updater.forceUpdate` to true or call checkUpdate with UpdateJSON");
|
|
149
119
|
}
|
|
150
120
|
const isLowerVersion = this.provider.isLowerVersion;
|
|
151
121
|
const entryVersion = getEntryVersion();
|
|
152
122
|
const appVersion = getAppVersion();
|
|
153
123
|
if (isLowerVersion(entryVersion, minimumVersion)) {
|
|
154
|
-
emitUnavailable(`entry version (${entryVersion}) < minimumVersion (${minimumVersion})`);
|
|
155
|
-
return false;
|
|
124
|
+
return emitUnavailable(`entry version (${entryVersion}) < minimumVersion (${minimumVersion})`);
|
|
156
125
|
}
|
|
157
126
|
this.logger?.info(`check update: current version is ${appVersion}, new version is ${version}`);
|
|
158
127
|
if (!isLowerVersion(appVersion, version)) {
|
|
159
|
-
emitUnavailable(`current version (${appVersion}) < new version (${version})`);
|
|
160
|
-
return false;
|
|
128
|
+
return emitUnavailable(`current version (${appVersion}) < new version (${version})`);
|
|
161
129
|
}
|
|
162
130
|
this.logger?.info(`update available: ${version}`);
|
|
163
131
|
this.info = { signature, minimumVersion, version, size };
|
|
@@ -165,11 +133,11 @@ var Updater = class extends EventEmitter {
|
|
|
165
133
|
return true;
|
|
166
134
|
}
|
|
167
135
|
async download(data, sig) {
|
|
168
|
-
|
|
169
|
-
|
|
136
|
+
const _sig = sig ?? this.info?.signature;
|
|
137
|
+
if (!_sig) {
|
|
138
|
+
this.err("download failed", "param", "no update signature, please call `checkUpdate` first");
|
|
170
139
|
return false;
|
|
171
140
|
}
|
|
172
|
-
const _sig = sig ?? this.info.signature;
|
|
173
141
|
const buffer = await this.fetch("buffer", data ? Buffer.from(data) : void 0);
|
|
174
142
|
if (!buffer) {
|
|
175
143
|
this.err("download failed", "param", "no update asar file buffer");
|
|
@@ -178,21 +146,19 @@ var Updater = class extends EventEmitter {
|
|
|
178
146
|
this.logger?.debug("verify start");
|
|
179
147
|
const _ver = await this.provider.verifySignaure(buffer, _sig, this.CERT);
|
|
180
148
|
if (!_ver) {
|
|
181
|
-
this.err("
|
|
149
|
+
this.err("download failed", "validate", "invalid signature / certificate pair");
|
|
182
150
|
return false;
|
|
183
151
|
}
|
|
184
152
|
this.logger?.debug("verify success");
|
|
185
153
|
try {
|
|
186
|
-
this.logger?.debug(`write to ${this.gzipPath}`);
|
|
187
|
-
writeFileSync(this.gzipPath, buffer);
|
|
188
154
|
this.logger?.debug(`extract to ${this.tmpFilePath}`);
|
|
189
|
-
await unzipFile(
|
|
155
|
+
await this.provider.unzipFile(buffer, this.tmpFilePath);
|
|
190
156
|
this.logger?.info(`download success, version: ${_ver}`);
|
|
191
157
|
this.info = void 0;
|
|
192
158
|
this.emit("update-downloaded");
|
|
193
159
|
return true;
|
|
194
160
|
} catch (error) {
|
|
195
|
-
this.err("
|
|
161
|
+
this.err("download failed", "download", `fail to unwrap asar file, ${error}`);
|
|
196
162
|
return false;
|
|
197
163
|
}
|
|
198
164
|
}
|
|
@@ -203,6 +169,19 @@ var Updater = class extends EventEmitter {
|
|
|
203
169
|
this.logger?.info("quit and install");
|
|
204
170
|
restartApp();
|
|
205
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* setup provider URL handler
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* updater.setURLHandler((url, isDownloadingAsar) => {
|
|
177
|
+
* if (isDownloadingAsar) {
|
|
178
|
+
* return url.replace('https://raw.githubusercontent.com', 'https://cdn.jsdelivr.net/gh')
|
|
179
|
+
* }
|
|
180
|
+
* })
|
|
181
|
+
*/
|
|
182
|
+
setURLHandler(handler) {
|
|
183
|
+
this.provider.urlHandler = handler;
|
|
184
|
+
}
|
|
206
185
|
};
|
|
207
186
|
|
|
208
187
|
// src/entry.ts
|
|
@@ -211,7 +190,7 @@ function startupWithUpdater(fn) {
|
|
|
211
190
|
}
|
|
212
191
|
var defaultOnInstall = (install, _, __, logger) => {
|
|
213
192
|
install();
|
|
214
|
-
logger
|
|
193
|
+
logger?.info(`update success!`);
|
|
215
194
|
};
|
|
216
195
|
async function initApp(appOptions) {
|
|
217
196
|
const {
|
|
@@ -227,31 +206,34 @@ async function initApp(appOptions) {
|
|
|
227
206
|
} else {
|
|
228
207
|
updaterInstance = await updater();
|
|
229
208
|
}
|
|
230
|
-
|
|
209
|
+
let logger = updaterInstance.logger;
|
|
210
|
+
if (isDev && !logger) {
|
|
211
|
+
logger = {
|
|
212
|
+
info: (...args) => console.log("[EIU-INFO ]", ...args),
|
|
213
|
+
debug: (...args) => console.log("[EIU-DEBUG]", ...args),
|
|
214
|
+
warn: (...args) => console.log("[EIU-WARN ]", ...args),
|
|
215
|
+
error: (...args) => console.error("[EIU-ERROR]", ...args)
|
|
216
|
+
};
|
|
217
|
+
}
|
|
231
218
|
try {
|
|
232
219
|
const appNameAsarPath = getPathFromAppNameAsar();
|
|
233
220
|
const tempAsarPath = `${appNameAsarPath}.tmp`;
|
|
234
|
-
if (
|
|
235
|
-
logger
|
|
221
|
+
if (existsSync(tempAsarPath)) {
|
|
222
|
+
logger?.info(`installing new asar: ${tempAsarPath}`);
|
|
236
223
|
await onInstall(() => renameSync(tempAsarPath, appNameAsarPath), tempAsarPath, appNameAsarPath, logger);
|
|
237
224
|
}
|
|
238
225
|
const mainFilePath = join(
|
|
239
|
-
isDev ? join(
|
|
226
|
+
isDev ? join(app.getAppPath(), __EIU_MAIN_DEV_DIR__) : appNameAsarPath,
|
|
240
227
|
"main",
|
|
241
228
|
__EIU_MAIN_FILE__
|
|
242
229
|
);
|
|
243
230
|
await beforeStart?.(mainFilePath, logger);
|
|
244
231
|
__require(mainFilePath)(updaterInstance);
|
|
245
232
|
} catch (error) {
|
|
246
|
-
logger
|
|
233
|
+
logger?.error("startup error", error);
|
|
247
234
|
onStartError?.(error, logger);
|
|
248
|
-
|
|
235
|
+
app.quit();
|
|
249
236
|
}
|
|
250
237
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
Updater,
|
|
254
|
-
UpdaterError,
|
|
255
|
-
initApp,
|
|
256
|
-
startupWithUpdater
|
|
257
|
-
};
|
|
238
|
+
|
|
239
|
+
export { ErrorInfo, Updater, UpdaterError, initApp, startupWithUpdater };
|
package/dist/provider.cjs
CHANGED
|
@@ -1,58 +1,11 @@
|
|
|
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
|
-
downloadAsarBufferDefault: () => downloadAsarBufferDefault,
|
|
25
|
-
downloadUpdateJSONDefault: () => downloadUpdateJSONDefault
|
|
26
|
-
});
|
|
27
|
-
module.exports = __toCommonJS(provider_exports);
|
|
3
|
+
var electron = require('electron');
|
|
4
|
+
var crypto = require('crypto');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var zlib = require('zlib');
|
|
28
7
|
|
|
29
|
-
// src/
|
|
30
|
-
var import_node_fs = require("fs");
|
|
31
|
-
var import_node_path = require("path");
|
|
32
|
-
var import_electron = require("electron");
|
|
33
|
-
var isDev = __EIU_IS_DEV__;
|
|
34
|
-
var isWin = process.platform === "win32";
|
|
35
|
-
var isMac = process.platform === "darwin";
|
|
36
|
-
var isLinux = process.platform === "linux";
|
|
37
|
-
function waitAppReady(timeout = 1e3) {
|
|
38
|
-
return import_electron.app.isReady() ? Promise.resolve() : new Promise((resolve, reject) => {
|
|
39
|
-
const _ = setTimeout(() => {
|
|
40
|
-
reject(new Error("app is not ready"));
|
|
41
|
-
}, timeout);
|
|
42
|
-
import_electron.app.whenReady().then(() => {
|
|
43
|
-
clearTimeout(_);
|
|
44
|
-
resolve();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// src/utils/zip.ts
|
|
50
|
-
var import_node_fs2 = require("fs");
|
|
51
|
-
var import_node_zlib = require("zlib");
|
|
52
|
-
|
|
53
|
-
// src/utils/unzip.ts
|
|
54
|
-
var import_node_fs3 = require("fs");
|
|
55
|
-
var import_node_zlib2 = require("zlib");
|
|
8
|
+
// src/provider/download.ts
|
|
56
9
|
|
|
57
10
|
// src/utils/version.ts
|
|
58
11
|
function parseVersion(version) {
|
|
@@ -78,7 +31,7 @@ function parseVersion(version) {
|
|
|
78
31
|
}
|
|
79
32
|
return ret;
|
|
80
33
|
}
|
|
81
|
-
function
|
|
34
|
+
function defaultIsLowerVersion(oldVer, newVer) {
|
|
82
35
|
const oldV = parseVersion(oldVer);
|
|
83
36
|
const newV = parseVersion(newVer);
|
|
84
37
|
function compareStrings(str1, str2) {
|
|
@@ -103,42 +56,11 @@ function isUpdateJSON(json) {
|
|
|
103
56
|
return is(json) && is(json?.beta);
|
|
104
57
|
}
|
|
105
58
|
|
|
106
|
-
// src/utils/crypto/decrypt.ts
|
|
107
|
-
var import_node_crypto2 = require("crypto");
|
|
108
|
-
|
|
109
|
-
// src/utils/crypto/utils.ts
|
|
110
|
-
var import_node_crypto = require("crypto");
|
|
111
|
-
function hashString(data, length) {
|
|
112
|
-
const hash = (0, import_node_crypto.createHash)("SHA256").update(data).digest("binary");
|
|
113
|
-
return Buffer.from(hash).subarray(0, length);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// src/utils/crypto/decrypt.ts
|
|
117
|
-
function decrypt(encryptedText, key, iv) {
|
|
118
|
-
const decipher = (0, import_node_crypto2.createDecipheriv)("aes-256-cbc", key, iv);
|
|
119
|
-
let decrypted = decipher.update(encryptedText, "base64url", "utf8");
|
|
120
|
-
decrypted += decipher.final("utf8");
|
|
121
|
-
return decrypted;
|
|
122
|
-
}
|
|
123
|
-
function verifySignatureDefault(buffer, signature, cert) {
|
|
124
|
-
try {
|
|
125
|
-
const [sig, version] = decrypt(signature, hashString(cert, 32), hashString(buffer, 16)).split("%");
|
|
126
|
-
const result = (0, import_node_crypto2.createVerify)("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
|
|
127
|
-
return result ? version : void 0;
|
|
128
|
-
} catch {
|
|
129
|
-
return void 0;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// src/utils/crypto/encrypt.ts
|
|
134
|
-
var import_node_crypto3 = require("crypto");
|
|
135
|
-
|
|
136
59
|
// src/provider/download.ts
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
await waitAppReady();
|
|
60
|
+
async function downloadFn(url, headers, onResponse) {
|
|
61
|
+
await electron.app.whenReady();
|
|
140
62
|
return new Promise((resolve, reject) => {
|
|
141
|
-
const request =
|
|
63
|
+
const request = electron.net.request({ url, method: "GET", redirect: "follow" });
|
|
142
64
|
Object.keys(headers).forEach((key) => request.setHeader(key, headers[key]));
|
|
143
65
|
request.on("response", (resp) => {
|
|
144
66
|
resp.on("aborted", () => reject(new Error("aborted")));
|
|
@@ -149,8 +71,8 @@ async function downlaodFn(url, headers, onResponse) {
|
|
|
149
71
|
request.end();
|
|
150
72
|
});
|
|
151
73
|
}
|
|
152
|
-
async function
|
|
153
|
-
return await
|
|
74
|
+
async function defaultDownloadUpdateJSON(url, headers) {
|
|
75
|
+
return await downloadFn(url, headers, (resp, resolve, reject) => {
|
|
154
76
|
let data = "";
|
|
155
77
|
resp.on("data", (chunk) => data += chunk);
|
|
156
78
|
resp.on("end", () => {
|
|
@@ -167,10 +89,10 @@ async function downloadUpdateJSONDefault(url, headers) {
|
|
|
167
89
|
});
|
|
168
90
|
});
|
|
169
91
|
}
|
|
170
|
-
async function
|
|
92
|
+
async function defaultDownloadAsar(url, headers, total, onDownloading) {
|
|
171
93
|
let transferred = 0;
|
|
172
94
|
let time = Date.now();
|
|
173
|
-
return await
|
|
95
|
+
return await downloadFn(url, headers, (resp, resolve) => {
|
|
174
96
|
let data = [];
|
|
175
97
|
resp.on("data", (chunk) => {
|
|
176
98
|
transferred += chunk.length;
|
|
@@ -188,49 +110,93 @@ async function downloadAsarBufferDefault(url, headers, total, onDownloading) {
|
|
|
188
110
|
resp.on("end", () => resolve(Buffer.concat(data)));
|
|
189
111
|
});
|
|
190
112
|
}
|
|
113
|
+
function hashBuffer(data, length) {
|
|
114
|
+
const hash = crypto.createHash("SHA256").update(data).digest("binary");
|
|
115
|
+
return Buffer.from(hash).subarray(0, length);
|
|
116
|
+
}
|
|
117
|
+
function aesDecrypt(encryptedText, key, iv) {
|
|
118
|
+
const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv);
|
|
119
|
+
return decipher.update(encryptedText, "base64url", "utf8") + decipher.final("utf8");
|
|
120
|
+
}
|
|
121
|
+
function defaultVerify(buffer, signature, cert) {
|
|
122
|
+
try {
|
|
123
|
+
const [sig, version] = aesDecrypt(signature, hashBuffer(cert, 32), hashBuffer(buffer, 16)).split("%");
|
|
124
|
+
const result = crypto.createVerify("RSA-SHA256").update(buffer).verify(cert, sig, "base64");
|
|
125
|
+
return result ? version : void 0;
|
|
126
|
+
} catch {
|
|
127
|
+
return void 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function defaultUnzipFile(buffer, targetFilePath) {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
zlib.brotliDecompress(buffer, (err, buffer2) => {
|
|
133
|
+
if (err) {
|
|
134
|
+
reject(err);
|
|
135
|
+
}
|
|
136
|
+
fs.writeFileSync(targetFilePath, buffer2);
|
|
137
|
+
resolve();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/provider/base.ts
|
|
143
|
+
var BaseProvider = class {
|
|
144
|
+
name = "BaseProvider";
|
|
145
|
+
isLowerVersion = defaultIsLowerVersion;
|
|
146
|
+
verifySignaure = defaultVerify;
|
|
147
|
+
unzipFile = defaultUnzipFile;
|
|
148
|
+
};
|
|
191
149
|
|
|
192
150
|
// src/provider/github.ts
|
|
193
|
-
var GitHubProvider = class {
|
|
151
|
+
var GitHubProvider = class extends BaseProvider {
|
|
194
152
|
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
|
|
195
153
|
name = "GithubProvider";
|
|
196
154
|
urlHandler;
|
|
197
155
|
url;
|
|
198
156
|
extraHeaders;
|
|
157
|
+
/**
|
|
158
|
+
* Update Provider for Github repo
|
|
159
|
+
* - download update json from `https://raw.githubusercontent.com/{user}/{repo}/HEAD/{versionPath}`
|
|
160
|
+
* - download update asar from `https://github.com/{user}/{repo}/releases/download/v{version}/{name}-{version}.asar.gz`
|
|
161
|
+
*
|
|
162
|
+
* you can setup `urlHandler` in {@link GitHubProviderOptions} or `Updater` to modify url before request
|
|
163
|
+
* @param options provider options
|
|
164
|
+
*/
|
|
199
165
|
constructor(options) {
|
|
200
|
-
|
|
166
|
+
super();
|
|
201
167
|
this.extraHeaders = options.extraHeaders;
|
|
202
168
|
this.urlHandler = options.urlHandler;
|
|
203
|
-
if (
|
|
169
|
+
if (!options.url.startsWith("https://github.com")) {
|
|
204
170
|
throw new Error(`${this.name}: invalid github url: ${options.url}`);
|
|
205
171
|
}
|
|
206
|
-
|
|
207
|
-
|
|
172
|
+
this.url = options.url;
|
|
173
|
+
if (!this.url.endsWith("/")) {
|
|
174
|
+
this.url += "/";
|
|
208
175
|
}
|
|
209
176
|
}
|
|
210
|
-
parseURL(isDownloadAsar,
|
|
211
|
-
const
|
|
212
|
-
|
|
177
|
+
async parseURL(isDownloadAsar, extraPath) {
|
|
178
|
+
const _url = new URL(this.url);
|
|
179
|
+
_url.hostname = isDownloadAsar ? "github.com" : "raw.githubusercontent.com";
|
|
180
|
+
_url.pathname += extraPath;
|
|
181
|
+
return (await this.urlHandler?.(_url, isDownloadAsar) || _url).toString();
|
|
213
182
|
}
|
|
214
|
-
isLowerVersion = isLowerVersionDefault;
|
|
215
|
-
verifySignaure = verifySignatureDefault;
|
|
216
183
|
async downloadJSON(versionPath) {
|
|
217
|
-
return await
|
|
218
|
-
this.parseURL(false, `HEAD/${versionPath}`),
|
|
184
|
+
return await defaultDownloadUpdateJSON(
|
|
185
|
+
await this.parseURL(false, `HEAD/${versionPath}`),
|
|
219
186
|
{ userAgent: this.ua, accept: "application/json", ...this.extraHeaders }
|
|
220
187
|
);
|
|
221
188
|
}
|
|
222
189
|
async downloadAsar(name, { version, size }, onDownloading) {
|
|
223
|
-
return await
|
|
224
|
-
this.parseURL(true, `releases/download/v${version}/${name}-${version}.asar.gz`),
|
|
190
|
+
return await defaultDownloadAsar(
|
|
191
|
+
await this.parseURL(true, `releases/download/v${version}/${name}-${version}.asar.gz`),
|
|
225
192
|
{ userAgent: this.ua, accept: "application/octet-stream", ...this.extraHeaders },
|
|
226
193
|
size,
|
|
227
194
|
onDownloading
|
|
228
195
|
);
|
|
229
196
|
}
|
|
230
197
|
};
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
});
|
|
198
|
+
|
|
199
|
+
exports.BaseProvider = BaseProvider;
|
|
200
|
+
exports.GitHubProvider = GitHubProvider;
|
|
201
|
+
exports.defaultDownloadAsar = defaultDownloadAsar;
|
|
202
|
+
exports.defaultDownloadUpdateJSON = defaultDownloadUpdateJSON;
|