electron-incremental-update 0.7.3 → 0.7.5
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 +15 -18
- package/dist/{chunk-CRBEZBU5.mjs → chunk-67MCNA7W.mjs} +41 -29
- package/dist/index.d.mts +43 -50
- package/dist/index.d.ts +43 -50
- package/dist/index.js +86 -70
- package/dist/index.mjs +78 -60
- package/dist/utils.d.mts +9 -2
- package/dist/utils.d.ts +9 -2
- package/dist/utils.js +40 -27
- package/dist/utils.mjs +3 -1
- package/dist/vite.js +10 -6
- package/dist/vite.mjs +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,30 +55,27 @@ src
|
|
|
55
55
|
|
|
56
56
|
```ts
|
|
57
57
|
// electron/app.ts
|
|
58
|
-
import {
|
|
58
|
+
import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
|
|
59
59
|
import { name, repository } from '../package.json'
|
|
60
60
|
|
|
61
61
|
const SIGNATURE_CERT = '' // auto generate certificate when start app
|
|
62
62
|
|
|
63
|
-
// create updater when init, no need to set productName
|
|
64
|
-
initApp({ name }, { SIGNATURE_CERT, repository })
|
|
65
|
-
|
|
66
|
-
// or create updater manually
|
|
67
63
|
const { cdnPrefix } = getGithubReleaseCdnGroup()[0]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})
|
|
76
|
-
|
|
64
|
+
initApp({ onStart: console.log })
|
|
65
|
+
// can be updater option or function that return updater
|
|
66
|
+
.setUpdater({
|
|
67
|
+
SIGNATURE_CERT,
|
|
68
|
+
productName: name,
|
|
69
|
+
repository,
|
|
70
|
+
updateJsonURL: parseGithubCdnURL(repository, 'fastly.jsdelivr.net/gh', 'version.json'),
|
|
71
|
+
releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
|
|
72
|
+
debug: true,
|
|
73
|
+
})
|
|
77
74
|
```
|
|
78
75
|
|
|
79
76
|
### usage in main process
|
|
80
77
|
|
|
81
|
-
To utilize the electron `net` module for requesting update information, the `checkUpdate` and `
|
|
78
|
+
To utilize the electron `net` module for requesting update information, the `checkUpdate` and `download` functions must be called after the app is ready by default.
|
|
82
79
|
|
|
83
80
|
However, you have the option to customize the download function when creating the updater.
|
|
84
81
|
|
|
@@ -115,7 +112,7 @@ const startup: StartupWithUpdater = (updater: Updater) => {
|
|
|
115
112
|
buttons: ['Download', 'Later'],
|
|
116
113
|
message: 'Application update available!',
|
|
117
114
|
})
|
|
118
|
-
response === 0 && console.log(await updater.
|
|
115
|
+
response === 0 && console.log(await updater.download())
|
|
119
116
|
}
|
|
120
117
|
})
|
|
121
118
|
}
|
|
@@ -201,9 +198,9 @@ export default defineConfig(({ command }) => {
|
|
|
201
198
|
### electron-builder config
|
|
202
199
|
|
|
203
200
|
```js
|
|
204
|
-
const { name
|
|
201
|
+
const { name } = require('./package.json')
|
|
205
202
|
|
|
206
|
-
const target = `${name}
|
|
203
|
+
const target = `${name}.asar`
|
|
207
204
|
/**
|
|
208
205
|
* @type {import('electron-builder').Configuration}
|
|
209
206
|
*/
|
|
@@ -7,12 +7,12 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
// src/utils.ts
|
|
10
|
-
import {
|
|
10
|
+
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
|
-
import {
|
|
12
|
+
import { gunzip, gzip } from "node:zlib";
|
|
13
13
|
import { app } from "electron";
|
|
14
14
|
function getProductAsarPath(name) {
|
|
15
|
-
return app.isPackaged ? join(dirname(app.getAppPath()), `${name}.asar`) : "dev";
|
|
15
|
+
return app.isPackaged ? join(dirname(app.getAppPath()), `${name}.asar`) : "dev.asar";
|
|
16
16
|
}
|
|
17
17
|
function getEntryVersion() {
|
|
18
18
|
return app.getVersion();
|
|
@@ -33,22 +33,31 @@ function parseGithubCdnURL(repository, cdnPrefix, relativeFilePath) {
|
|
|
33
33
|
cdnPrefix = cdnPrefix.trim().replace(/^\/?|\/?$/g, "").trim();
|
|
34
34
|
return repository.replace("github.com", cdnPrefix) + relativeFilePath;
|
|
35
35
|
}
|
|
36
|
+
function getGithubFileCdnGroup() {
|
|
37
|
+
return [
|
|
38
|
+
{ cdnPrefix: "cdn.jsdelivr.net/gh", source: "jsdelivr" },
|
|
39
|
+
{ cdnPrefix: "fastly.jsdelivr.net/gh", source: "jsdelivr-fastly" },
|
|
40
|
+
{ cdnPrefix: "cdn.statically.io/gh", source: "statically" },
|
|
41
|
+
{ cdnPrefix: "rawcdn.githack.com/gh", source: "githack" },
|
|
42
|
+
{ cdnPrefix: "raw.githack.com/gh", source: "githack-dev" }
|
|
43
|
+
];
|
|
44
|
+
}
|
|
36
45
|
function getGithubReleaseCdnGroup() {
|
|
37
46
|
return [
|
|
38
|
-
{ cdnPrefix: "gh.gh2233.ml",
|
|
39
|
-
{ cdnPrefix: "ghproxy.com",
|
|
40
|
-
{ cdnPrefix: "gh.ddlc.top",
|
|
41
|
-
{ cdnPrefix: "ghdl.feizhuqwq.cf",
|
|
42
|
-
{ cdnPrefix: "slink.ltd",
|
|
43
|
-
{ cdnPrefix: "git.xfj0.cn",
|
|
44
|
-
{ cdnPrefix: "gh.con.sh",
|
|
45
|
-
{ cdnPrefix: "ghps.cc",
|
|
46
|
-
{ cdnPrefix: "cors.isteed.cc/github.com",
|
|
47
|
-
{ cdnPrefix: "hub.gitmirror.com",
|
|
48
|
-
{ cdnPrefix: "js.xxooo.ml",
|
|
49
|
-
{ cdnPrefix: "download.njuu.cf",
|
|
50
|
-
{ cdnPrefix: "download.yzuu.cf",
|
|
51
|
-
{ cdnPrefix: "download.nuaa.cf",
|
|
47
|
+
{ cdnPrefix: "gh.gh2233.ml", source: "@X.I.U/XIU2" },
|
|
48
|
+
{ cdnPrefix: "ghproxy.com", source: "gh-proxy" },
|
|
49
|
+
{ cdnPrefix: "gh.ddlc.top", source: "@mtr-static-official" },
|
|
50
|
+
{ cdnPrefix: "ghdl.feizhuqwq.cf", source: "feizhuqwq.com" },
|
|
51
|
+
{ cdnPrefix: "slink.ltd", source: "\u77E5\u4E86\u5C0F\u7AD9" },
|
|
52
|
+
{ cdnPrefix: "git.xfj0.cn", source: "anonymous1" },
|
|
53
|
+
{ cdnPrefix: "gh.con.sh", source: "anonymous2" },
|
|
54
|
+
{ cdnPrefix: "ghps.cc", source: "anonymous3" },
|
|
55
|
+
{ cdnPrefix: "cors.isteed.cc/github.com", source: "Lufs's" },
|
|
56
|
+
{ cdnPrefix: "hub.gitmirror.com", source: "GitMirror" },
|
|
57
|
+
{ cdnPrefix: "js.xxooo.ml", source: "\u996D\u592A\u786C" },
|
|
58
|
+
{ cdnPrefix: "download.njuu.cf", source: "LibraryCloud-njuu" },
|
|
59
|
+
{ cdnPrefix: "download.yzuu.cf", source: "LibraryCloud-yzuu" },
|
|
60
|
+
{ cdnPrefix: "download.nuaa.cf", source: "LibraryCloud-nuaa" }
|
|
52
61
|
];
|
|
53
62
|
}
|
|
54
63
|
function restartApp() {
|
|
@@ -70,17 +79,15 @@ async function unzipFile(gzipPath, targetFilePath) {
|
|
|
70
79
|
if (!existsSync(gzipPath)) {
|
|
71
80
|
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
72
81
|
}
|
|
82
|
+
const compressedBuffer = readFileSync(gzipPath);
|
|
73
83
|
return new Promise((resolve, reject) => {
|
|
74
|
-
|
|
75
|
-
const input = createReadStream(gzipPath);
|
|
76
|
-
const output = createWriteStream(targetFilePath);
|
|
77
|
-
input.pipe(gunzip).pipe(output).on("finish", () => {
|
|
84
|
+
gunzip(compressedBuffer, (err, buffer) => {
|
|
78
85
|
rmSync(gzipPath);
|
|
86
|
+
if (err) {
|
|
87
|
+
reject(err);
|
|
88
|
+
}
|
|
89
|
+
writeFileSync(targetFilePath, buffer);
|
|
79
90
|
resolve(null);
|
|
80
|
-
}).on("error", (err) => {
|
|
81
|
-
rmSync(gzipPath);
|
|
82
|
-
output.destroy(err);
|
|
83
|
-
reject(err);
|
|
84
91
|
});
|
|
85
92
|
});
|
|
86
93
|
}
|
|
@@ -88,11 +95,15 @@ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
|
|
|
88
95
|
if (!existsSync(filePath)) {
|
|
89
96
|
throw new Error(`path to be zipped not exist: ${filePath}`);
|
|
90
97
|
}
|
|
98
|
+
const buffer = readFileSync(filePath);
|
|
91
99
|
return new Promise((resolve, reject) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
gzip(buffer, (err, buffer2) => {
|
|
101
|
+
if (err) {
|
|
102
|
+
reject(err);
|
|
103
|
+
}
|
|
104
|
+
writeFileSync(targetFilePath, buffer2);
|
|
105
|
+
resolve(null);
|
|
106
|
+
});
|
|
96
107
|
});
|
|
97
108
|
}
|
|
98
109
|
function handleUnexpectedErrors(callback) {
|
|
@@ -111,6 +122,7 @@ export {
|
|
|
111
122
|
getProductVersion,
|
|
112
123
|
requireNative,
|
|
113
124
|
parseGithubCdnURL,
|
|
125
|
+
getGithubFileCdnGroup,
|
|
114
126
|
getGithubReleaseCdnGroup,
|
|
115
127
|
restartApp,
|
|
116
128
|
waitAppReady,
|
package/dist/index.d.mts
CHANGED
|
@@ -30,7 +30,7 @@ interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event
|
|
|
30
30
|
*/
|
|
31
31
|
checkUpdate(data?: string | UpdateJSON): Promise<CheckResultType>;
|
|
32
32
|
/**
|
|
33
|
-
* download update
|
|
33
|
+
* download update
|
|
34
34
|
*
|
|
35
35
|
* if you want to update **offline**, you can set both `src` and `sig` to verify and install
|
|
36
36
|
* @param data asar download url or buffer
|
|
@@ -39,17 +39,16 @@ interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event
|
|
|
39
39
|
* - `true`: success
|
|
40
40
|
* - `Error`: fail
|
|
41
41
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
download(data?: string | Buffer, sig?: string): Promise<InstallResult>;
|
|
43
|
+
setDebugMode(debug: boolean): void;
|
|
44
|
+
productName: string;
|
|
44
45
|
}
|
|
45
46
|
type FunctionVerifySignature = (buffer: Buffer, signature: string, cert: string) => string | false;
|
|
46
47
|
type FunctionCompareVersion = (oldVersion: string, newVersion: string) => boolean;
|
|
47
48
|
type Updater = TypedUpdater<UpdateEvents>;
|
|
48
49
|
interface UpdaterOption {
|
|
49
50
|
/**
|
|
50
|
-
* public key of signature
|
|
51
|
-
*
|
|
52
|
-
* it will be auto generated by plugin
|
|
51
|
+
* public key of signature, which will be auto generated by plugin
|
|
53
52
|
* @example
|
|
54
53
|
* ```ts
|
|
55
54
|
* // auto filled by plugin
|
|
@@ -85,7 +84,7 @@ interface UpdaterOption {
|
|
|
85
84
|
updateJsonURL?: string;
|
|
86
85
|
/**
|
|
87
86
|
* URL of release asar.gz
|
|
88
|
-
* @default `${repository}/releases/download/
|
|
87
|
+
* @default `${repository}/releases/download/v${version}/${productName}-${version}.asar.gz`
|
|
89
88
|
* @throws if `releaseAsarURL` and `repository` are all not set
|
|
90
89
|
*/
|
|
91
90
|
releaseAsarURL?: string;
|
|
@@ -98,7 +97,7 @@ interface UpdaterOption {
|
|
|
98
97
|
* custom version compare function {@link FunctionCompareVersion}
|
|
99
98
|
* @param oldVersion old version string
|
|
100
99
|
* @param newVersion new version string
|
|
101
|
-
* @returns whether
|
|
100
|
+
* @returns whether oldVersion < newVersion
|
|
102
101
|
*/
|
|
103
102
|
compareVersion?: FunctionCompareVersion;
|
|
104
103
|
/**
|
|
@@ -138,66 +137,60 @@ interface UpdaterOption {
|
|
|
138
137
|
};
|
|
139
138
|
}
|
|
140
139
|
|
|
141
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Creates an updater based on the provided options
|
|
142
|
+
*/
|
|
143
|
+
declare function createUpdater(updaterOptions: UpdaterOption): Updater;
|
|
142
144
|
|
|
143
145
|
type AppOption = {
|
|
144
146
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* you can use the `name` in `package.json`
|
|
148
|
-
*/
|
|
149
|
-
name: string;
|
|
150
|
-
/**
|
|
151
|
-
* path of electron output dist
|
|
147
|
+
* path of electron output dist when in development
|
|
152
148
|
* @default 'dist-electron'
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
*/
|
|
150
|
+
electronDevDistPath?: string;
|
|
155
151
|
/**
|
|
156
152
|
* relative path of main entry in electron dist
|
|
157
153
|
* @default 'main/index.js'
|
|
158
|
-
|
|
154
|
+
*/
|
|
159
155
|
mainPath?: string;
|
|
156
|
+
/**
|
|
157
|
+
* hooks for start up
|
|
158
|
+
*/
|
|
159
|
+
onStart?: (productAsarPath: string) => void;
|
|
160
|
+
/**
|
|
161
|
+
* hooks for start up error
|
|
162
|
+
*/
|
|
163
|
+
onStartError?: (err: unknown) => void;
|
|
160
164
|
};
|
|
161
|
-
type OptionalProperty<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
162
|
-
type InitUpdaterOptions = OptionalProperty<UpdaterOption, 'productName'>;
|
|
163
165
|
type StartupWithUpdater = (updater: Updater) => void;
|
|
166
|
+
type SetUpdater = {
|
|
167
|
+
/**
|
|
168
|
+
* set updater option or create function
|
|
169
|
+
*/
|
|
170
|
+
setUpdater: (updater: (() => Updater | Promise<Updater>) | UpdaterOption) => void;
|
|
171
|
+
};
|
|
164
172
|
/**
|
|
165
173
|
* create updater manually
|
|
166
174
|
* @example
|
|
167
175
|
* ```ts
|
|
168
|
-
* import {
|
|
176
|
+
* import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
|
|
169
177
|
* import { name, repository } from '../package.json'
|
|
170
178
|
*
|
|
171
|
-
* const SIGNATURE_CERT = '' // auto generate
|
|
179
|
+
* const SIGNATURE_CERT = '' // auto generate certificate when start app
|
|
172
180
|
*
|
|
173
181
|
* const { cdnPrefix } = getGithubReleaseCdnGroup()[0]
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* })
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*/
|
|
185
|
-
declare function initApp(appOptions: AppOption): {
|
|
186
|
-
setUpdater: (updater: Updater) => void;
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* create updater when init, no need to set productName
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```ts
|
|
193
|
-
* import { initApp } from 'electron-incremental-update'
|
|
194
|
-
* import { name, repository } from '../package.json'
|
|
195
|
-
*
|
|
196
|
-
* const SIGNATURE_CERT = '' // auto generate
|
|
197
|
-
*
|
|
198
|
-
* initApp({ name }, { SIGNATURE_CERT, repository })
|
|
182
|
+
* initApp({ onStart: console.log })
|
|
183
|
+
* // can be updater option or function that return updater
|
|
184
|
+
* .setUpdater({
|
|
185
|
+
* SIGNATURE_CERT,
|
|
186
|
+
* productName: name,
|
|
187
|
+
* repository,
|
|
188
|
+
* updateJsonURL: parseGithubCdnURL(repository, 'fastly.jsdelivr.net/gh', 'version.json'),
|
|
189
|
+
* releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
|
|
190
|
+
* debug: true,
|
|
191
|
+
* })
|
|
199
192
|
* ```
|
|
200
193
|
*/
|
|
201
|
-
declare function initApp(appOptions
|
|
194
|
+
declare function initApp(appOptions?: AppOption): SetUpdater;
|
|
202
195
|
|
|
203
|
-
export { AppOption, FunctionCompareVersion, FunctionVerifySignature,
|
|
196
|
+
export { AppOption, FunctionCompareVersion, FunctionVerifySignature, StartupWithUpdater, UpdateJSON, Updater, UpdaterOption, createUpdater, initApp };
|
package/dist/index.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event
|
|
|
30
30
|
*/
|
|
31
31
|
checkUpdate(data?: string | UpdateJSON): Promise<CheckResultType>;
|
|
32
32
|
/**
|
|
33
|
-
* download update
|
|
33
|
+
* download update
|
|
34
34
|
*
|
|
35
35
|
* if you want to update **offline**, you can set both `src` and `sig` to verify and install
|
|
36
36
|
* @param data asar download url or buffer
|
|
@@ -39,17 +39,16 @@ interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event
|
|
|
39
39
|
* - `true`: success
|
|
40
40
|
* - `Error`: fail
|
|
41
41
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
download(data?: string | Buffer, sig?: string): Promise<InstallResult>;
|
|
43
|
+
setDebugMode(debug: boolean): void;
|
|
44
|
+
productName: string;
|
|
44
45
|
}
|
|
45
46
|
type FunctionVerifySignature = (buffer: Buffer, signature: string, cert: string) => string | false;
|
|
46
47
|
type FunctionCompareVersion = (oldVersion: string, newVersion: string) => boolean;
|
|
47
48
|
type Updater = TypedUpdater<UpdateEvents>;
|
|
48
49
|
interface UpdaterOption {
|
|
49
50
|
/**
|
|
50
|
-
* public key of signature
|
|
51
|
-
*
|
|
52
|
-
* it will be auto generated by plugin
|
|
51
|
+
* public key of signature, which will be auto generated by plugin
|
|
53
52
|
* @example
|
|
54
53
|
* ```ts
|
|
55
54
|
* // auto filled by plugin
|
|
@@ -85,7 +84,7 @@ interface UpdaterOption {
|
|
|
85
84
|
updateJsonURL?: string;
|
|
86
85
|
/**
|
|
87
86
|
* URL of release asar.gz
|
|
88
|
-
* @default `${repository}/releases/download/
|
|
87
|
+
* @default `${repository}/releases/download/v${version}/${productName}-${version}.asar.gz`
|
|
89
88
|
* @throws if `releaseAsarURL` and `repository` are all not set
|
|
90
89
|
*/
|
|
91
90
|
releaseAsarURL?: string;
|
|
@@ -98,7 +97,7 @@ interface UpdaterOption {
|
|
|
98
97
|
* custom version compare function {@link FunctionCompareVersion}
|
|
99
98
|
* @param oldVersion old version string
|
|
100
99
|
* @param newVersion new version string
|
|
101
|
-
* @returns whether
|
|
100
|
+
* @returns whether oldVersion < newVersion
|
|
102
101
|
*/
|
|
103
102
|
compareVersion?: FunctionCompareVersion;
|
|
104
103
|
/**
|
|
@@ -138,66 +137,60 @@ interface UpdaterOption {
|
|
|
138
137
|
};
|
|
139
138
|
}
|
|
140
139
|
|
|
141
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Creates an updater based on the provided options
|
|
142
|
+
*/
|
|
143
|
+
declare function createUpdater(updaterOptions: UpdaterOption): Updater;
|
|
142
144
|
|
|
143
145
|
type AppOption = {
|
|
144
146
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* you can use the `name` in `package.json`
|
|
148
|
-
*/
|
|
149
|
-
name: string;
|
|
150
|
-
/**
|
|
151
|
-
* path of electron output dist
|
|
147
|
+
* path of electron output dist when in development
|
|
152
148
|
* @default 'dist-electron'
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
*/
|
|
150
|
+
electronDevDistPath?: string;
|
|
155
151
|
/**
|
|
156
152
|
* relative path of main entry in electron dist
|
|
157
153
|
* @default 'main/index.js'
|
|
158
|
-
|
|
154
|
+
*/
|
|
159
155
|
mainPath?: string;
|
|
156
|
+
/**
|
|
157
|
+
* hooks for start up
|
|
158
|
+
*/
|
|
159
|
+
onStart?: (productAsarPath: string) => void;
|
|
160
|
+
/**
|
|
161
|
+
* hooks for start up error
|
|
162
|
+
*/
|
|
163
|
+
onStartError?: (err: unknown) => void;
|
|
160
164
|
};
|
|
161
|
-
type OptionalProperty<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
162
|
-
type InitUpdaterOptions = OptionalProperty<UpdaterOption, 'productName'>;
|
|
163
165
|
type StartupWithUpdater = (updater: Updater) => void;
|
|
166
|
+
type SetUpdater = {
|
|
167
|
+
/**
|
|
168
|
+
* set updater option or create function
|
|
169
|
+
*/
|
|
170
|
+
setUpdater: (updater: (() => Updater | Promise<Updater>) | UpdaterOption) => void;
|
|
171
|
+
};
|
|
164
172
|
/**
|
|
165
173
|
* create updater manually
|
|
166
174
|
* @example
|
|
167
175
|
* ```ts
|
|
168
|
-
* import {
|
|
176
|
+
* import { getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
|
|
169
177
|
* import { name, repository } from '../package.json'
|
|
170
178
|
*
|
|
171
|
-
* const SIGNATURE_CERT = '' // auto generate
|
|
179
|
+
* const SIGNATURE_CERT = '' // auto generate certificate when start app
|
|
172
180
|
*
|
|
173
181
|
* const { cdnPrefix } = getGithubReleaseCdnGroup()[0]
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* })
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*/
|
|
185
|
-
declare function initApp(appOptions: AppOption): {
|
|
186
|
-
setUpdater: (updater: Updater) => void;
|
|
187
|
-
};
|
|
188
|
-
/**
|
|
189
|
-
* create updater when init, no need to set productName
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```ts
|
|
193
|
-
* import { initApp } from 'electron-incremental-update'
|
|
194
|
-
* import { name, repository } from '../package.json'
|
|
195
|
-
*
|
|
196
|
-
* const SIGNATURE_CERT = '' // auto generate
|
|
197
|
-
*
|
|
198
|
-
* initApp({ name }, { SIGNATURE_CERT, repository })
|
|
182
|
+
* initApp({ onStart: console.log })
|
|
183
|
+
* // can be updater option or function that return updater
|
|
184
|
+
* .setUpdater({
|
|
185
|
+
* SIGNATURE_CERT,
|
|
186
|
+
* productName: name,
|
|
187
|
+
* repository,
|
|
188
|
+
* updateJsonURL: parseGithubCdnURL(repository, 'fastly.jsdelivr.net/gh', 'version.json'),
|
|
189
|
+
* releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
|
|
190
|
+
* debug: true,
|
|
191
|
+
* })
|
|
199
192
|
* ```
|
|
200
193
|
*/
|
|
201
|
-
declare function initApp(appOptions
|
|
194
|
+
declare function initApp(appOptions?: AppOption): SetUpdater;
|
|
202
195
|
|
|
203
|
-
export { AppOption, FunctionCompareVersion, FunctionVerifySignature,
|
|
196
|
+
export { AppOption, FunctionCompareVersion, FunctionVerifySignature, StartupWithUpdater, UpdateJSON, Updater, UpdaterOption, createUpdater, initApp };
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,8 @@ __export(src_exports, {
|
|
|
24
24
|
initApp: () => initApp
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(src_exports);
|
|
27
|
-
var
|
|
27
|
+
var import_node_path2 = require("path");
|
|
28
|
+
var import_node_fs3 = require("fs");
|
|
28
29
|
var import_electron4 = require("electron");
|
|
29
30
|
|
|
30
31
|
// src/updater/index.ts
|
|
@@ -32,7 +33,6 @@ var import_node_events = require("events");
|
|
|
32
33
|
var import_node_buffer3 = require("buffer");
|
|
33
34
|
var import_node_fs2 = require("fs");
|
|
34
35
|
var import_promises = require("fs/promises");
|
|
35
|
-
var import_node_path2 = require("path");
|
|
36
36
|
var import_electron3 = require("electron");
|
|
37
37
|
|
|
38
38
|
// src/crypto.ts
|
|
@@ -64,19 +64,19 @@ var import_node_path = require("path");
|
|
|
64
64
|
var import_node_zlib = require("zlib");
|
|
65
65
|
var import_electron = require("electron");
|
|
66
66
|
function getProductAsarPath(name) {
|
|
67
|
-
return import_electron.app.isPackaged ? (0, import_node_path.join)((0, import_node_path.dirname)(import_electron.app.getAppPath()), `${name}.asar`) : "dev";
|
|
67
|
+
return import_electron.app.isPackaged ? (0, import_node_path.join)((0, import_node_path.dirname)(import_electron.app.getAppPath()), `${name}.asar`) : "dev.asar";
|
|
68
68
|
}
|
|
69
69
|
function getEntryVersion() {
|
|
70
70
|
return import_electron.app.getVersion();
|
|
71
71
|
}
|
|
72
72
|
function waitAppReady(duration = 1e3) {
|
|
73
|
-
return new Promise((
|
|
73
|
+
return new Promise((resolve2, reject) => {
|
|
74
74
|
const timeout = setTimeout(() => {
|
|
75
75
|
reject(new Error("app is not ready"));
|
|
76
76
|
}, duration);
|
|
77
77
|
import_electron.app.whenReady().then(() => {
|
|
78
78
|
clearTimeout(timeout);
|
|
79
|
-
|
|
79
|
+
resolve2(null);
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
}
|
|
@@ -84,17 +84,15 @@ async function unzipFile(gzipPath, targetFilePath) {
|
|
|
84
84
|
if (!(0, import_node_fs.existsSync)(gzipPath)) {
|
|
85
85
|
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const output = (0, import_node_fs.createWriteStream)(targetFilePath);
|
|
91
|
-
input.pipe(gunzip).pipe(output).on("finish", () => {
|
|
92
|
-
(0, import_node_fs.rmSync)(gzipPath);
|
|
93
|
-
resolve3(null);
|
|
94
|
-
}).on("error", (err) => {
|
|
87
|
+
const compressedBuffer = (0, import_node_fs.readFileSync)(gzipPath);
|
|
88
|
+
return new Promise((resolve2, reject) => {
|
|
89
|
+
(0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
|
|
95
90
|
(0, import_node_fs.rmSync)(gzipPath);
|
|
96
|
-
|
|
97
|
-
|
|
91
|
+
if (err) {
|
|
92
|
+
reject(err);
|
|
93
|
+
}
|
|
94
|
+
(0, import_node_fs.writeFileSync)(targetFilePath, buffer);
|
|
95
|
+
resolve2(null);
|
|
98
96
|
});
|
|
99
97
|
});
|
|
100
98
|
}
|
|
@@ -111,7 +109,7 @@ function isUpdateJSON(json) {
|
|
|
111
109
|
// src/updater/defaultFunctions.ts
|
|
112
110
|
async function downloadJSONDefault(url, updater, headers) {
|
|
113
111
|
await waitAppReady();
|
|
114
|
-
return new Promise((
|
|
112
|
+
return new Promise((resolve2, reject) => {
|
|
115
113
|
const request = import_electron2.net.request({
|
|
116
114
|
url,
|
|
117
115
|
method: "GET",
|
|
@@ -127,7 +125,7 @@ async function downloadJSONDefault(url, updater, headers) {
|
|
|
127
125
|
try {
|
|
128
126
|
const json = JSON.parse(data);
|
|
129
127
|
if (isUpdateJSON(json)) {
|
|
130
|
-
|
|
128
|
+
resolve2(json);
|
|
131
129
|
} else {
|
|
132
130
|
throw Error;
|
|
133
131
|
}
|
|
@@ -145,7 +143,7 @@ async function downloadJSONDefault(url, updater, headers) {
|
|
|
145
143
|
async function downloadBufferDefault(url, updater, headers) {
|
|
146
144
|
await waitAppReady();
|
|
147
145
|
let progress = 0;
|
|
148
|
-
return new Promise((
|
|
146
|
+
return new Promise((resolve2, reject) => {
|
|
149
147
|
const request = import_electron2.net.request({
|
|
150
148
|
url,
|
|
151
149
|
method: "GET",
|
|
@@ -162,7 +160,7 @@ async function downloadBufferDefault(url, updater, headers) {
|
|
|
162
160
|
data.push(chunk);
|
|
163
161
|
});
|
|
164
162
|
res.on("end", () => {
|
|
165
|
-
|
|
163
|
+
resolve2(import_node_buffer2.Buffer.concat(data));
|
|
166
164
|
});
|
|
167
165
|
}).on("error", (e) => {
|
|
168
166
|
reject(e);
|
|
@@ -171,11 +169,14 @@ async function downloadBufferDefault(url, updater, headers) {
|
|
|
171
169
|
});
|
|
172
170
|
}
|
|
173
171
|
var compareVersionDefault = (oldVersion, newVersion) => {
|
|
174
|
-
if (!oldVersion || !newVersion) {
|
|
172
|
+
if (!oldVersion || !newVersion || typeof oldVersion !== "string" || typeof newVersion !== "string") {
|
|
175
173
|
throw new TypeError("invalid version");
|
|
176
174
|
}
|
|
177
175
|
const parseVersion = (version) => {
|
|
178
|
-
const [versionNumber, stage] = version.split("-");
|
|
176
|
+
const [versionNumber, stage] = version.split("-", 2);
|
|
177
|
+
if (!versionNumber || !versionNumber.includes(".")) {
|
|
178
|
+
throw new TypeError("invalid version");
|
|
179
|
+
}
|
|
179
180
|
const [major, minor, patch] = versionNumber.split(".").map(Number);
|
|
180
181
|
if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
|
|
181
182
|
throw new TypeError("invalid version");
|
|
@@ -194,28 +195,31 @@ var compareVersionDefault = (oldVersion, newVersion) => {
|
|
|
194
195
|
};
|
|
195
196
|
|
|
196
197
|
// src/updater/index.ts
|
|
197
|
-
function createUpdater({
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
198
|
+
function createUpdater(updaterOptions) {
|
|
199
|
+
const {
|
|
200
|
+
SIGNATURE_CERT,
|
|
201
|
+
repository,
|
|
202
|
+
productName,
|
|
203
|
+
releaseAsarURL: _release,
|
|
204
|
+
updateJsonURL: _update,
|
|
205
|
+
debug = false,
|
|
206
|
+
downloadConfig: { extraHeader, userAgent } = {},
|
|
207
|
+
overrideFunctions: {
|
|
208
|
+
compareVersion,
|
|
209
|
+
verifySignaure,
|
|
210
|
+
downloadBuffer,
|
|
211
|
+
downloadJSON
|
|
212
|
+
} = {}
|
|
213
|
+
} = updaterOptions;
|
|
212
214
|
const updater = new import_node_events.EventEmitter();
|
|
213
|
-
let signature
|
|
215
|
+
let signature;
|
|
216
|
+
let version;
|
|
217
|
+
let _debug = debug;
|
|
214
218
|
const asarPath = getProductAsarPath(productName);
|
|
215
219
|
const gzipPath = `${asarPath}.gz`;
|
|
216
|
-
const tmpFilePath =
|
|
220
|
+
const tmpFilePath = `${asarPath}.tmp`;
|
|
217
221
|
function log(msg) {
|
|
218
|
-
|
|
222
|
+
_debug && updater.emit("debug", msg);
|
|
219
223
|
}
|
|
220
224
|
function needUpdate(version2) {
|
|
221
225
|
if (!import_electron3.app.isPackaged) {
|
|
@@ -280,7 +284,8 @@ function createUpdater({
|
|
|
280
284
|
throw new Error(`invalid type at format '${format}': ${data}`);
|
|
281
285
|
}
|
|
282
286
|
}
|
|
283
|
-
updater.
|
|
287
|
+
updater.productName = productName;
|
|
288
|
+
updater.setDebugMode = (isDebug) => _debug = isDebug;
|
|
284
289
|
updater.checkUpdate = async (data) => {
|
|
285
290
|
try {
|
|
286
291
|
const { signature: _sig, size, version: _ver } = await parseData("json", data);
|
|
@@ -299,7 +304,7 @@ function createUpdater({
|
|
|
299
304
|
return error;
|
|
300
305
|
}
|
|
301
306
|
};
|
|
302
|
-
updater.
|
|
307
|
+
updater.download = async (data, sig) => {
|
|
303
308
|
try {
|
|
304
309
|
const _sig = sig ?? signature;
|
|
305
310
|
if (!_sig) {
|
|
@@ -313,21 +318,11 @@ function createUpdater({
|
|
|
313
318
|
throw new Error("verify failed, invalid signature");
|
|
314
319
|
}
|
|
315
320
|
log("verify success");
|
|
316
|
-
|
|
317
|
-
throw new Error(`update unavailable: ${_ver}`);
|
|
318
|
-
}
|
|
319
|
-
log(`write file: ${gzipPath}`);
|
|
321
|
+
log(`write to ${gzipPath}`);
|
|
320
322
|
await (0, import_promises.writeFile)(gzipPath, buffer);
|
|
321
|
-
log(`extract
|
|
323
|
+
log(`extract to ${tmpFilePath}`);
|
|
322
324
|
await unzipFile(gzipPath, tmpFilePath);
|
|
323
|
-
|
|
324
|
-
if (asarVersion !== _ver) {
|
|
325
|
-
(0, import_node_fs2.rmSync)(tmpFilePath);
|
|
326
|
-
throw new Error(`update failed: asar version is ${asarVersion}, but it should be ${_ver}`);
|
|
327
|
-
} else {
|
|
328
|
-
await (0, import_promises.rename)(tmpFilePath, asarPath);
|
|
329
|
-
}
|
|
330
|
-
log(`update success, version: ${_ver}`);
|
|
325
|
+
log(`download success, version: ${_ver}`);
|
|
331
326
|
signature = "";
|
|
332
327
|
return true;
|
|
333
328
|
} catch (error) {
|
|
@@ -339,25 +334,46 @@ function createUpdater({
|
|
|
339
334
|
}
|
|
340
335
|
|
|
341
336
|
// src/index.ts
|
|
342
|
-
function initApp(appOptions
|
|
337
|
+
function initApp(appOptions) {
|
|
343
338
|
const {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
339
|
+
electronDevDistPath = "dist-electron",
|
|
340
|
+
mainPath = "main/index.js",
|
|
341
|
+
onStart,
|
|
342
|
+
onStartError
|
|
343
|
+
} = appOptions || {};
|
|
344
|
+
function handleError(msg) {
|
|
345
|
+
onStartError?.(new Error(msg));
|
|
346
|
+
import_electron4.app.quit();
|
|
347
|
+
}
|
|
348
|
+
function startup(updater) {
|
|
349
|
+
try {
|
|
350
|
+
const asarPath = getProductAsarPath(updater.productName);
|
|
351
|
+
if ((0, import_node_fs3.existsSync)(`${asarPath}.tmp`)) {
|
|
352
|
+
(0, import_node_fs3.renameSync)(`${asarPath}.tmp`, asarPath);
|
|
358
353
|
}
|
|
359
|
-
|
|
354
|
+
const mainDir = import_electron4.app.isPackaged ? asarPath : electronDevDistPath;
|
|
355
|
+
const entry = (0, import_node_path2.resolve)(__dirname, mainDir, mainPath);
|
|
356
|
+
onStart?.(entry);
|
|
357
|
+
require(entry)(updater);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
handleError(`failed to start app, ${error}`);
|
|
360
|
+
}
|
|
360
361
|
}
|
|
362
|
+
let timer = setTimeout(() => {
|
|
363
|
+
handleError("start app timeout, please call .setUpdater() to set updater and start");
|
|
364
|
+
}, 3e3);
|
|
365
|
+
return {
|
|
366
|
+
async setUpdater(updater) {
|
|
367
|
+
clearTimeout(timer);
|
|
368
|
+
if (typeof updater === "object") {
|
|
369
|
+
startup(createUpdater(updater));
|
|
370
|
+
} else if (typeof updater === "function") {
|
|
371
|
+
startup(await updater());
|
|
372
|
+
} else {
|
|
373
|
+
handleError("invalid updater option or updater is not a function");
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
};
|
|
361
377
|
}
|
|
362
378
|
// Annotate the CommonJS export names for ESM import in node:
|
|
363
379
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -7,18 +7,18 @@ import {
|
|
|
7
7
|
getProductAsarPath,
|
|
8
8
|
unzipFile,
|
|
9
9
|
waitAppReady
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-67MCNA7W.mjs";
|
|
11
11
|
|
|
12
12
|
// src/index.ts
|
|
13
|
-
import { resolve
|
|
13
|
+
import { resolve } from "node:path";
|
|
14
|
+
import { existsSync as existsSync2, renameSync } from "node:fs";
|
|
14
15
|
import { app as app2 } from "electron";
|
|
15
16
|
|
|
16
17
|
// src/updater/index.ts
|
|
17
18
|
import { EventEmitter } from "node:events";
|
|
18
19
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
19
|
-
import { existsSync
|
|
20
|
-
import {
|
|
21
|
-
import { resolve } from "node:path";
|
|
20
|
+
import { existsSync } from "node:fs";
|
|
21
|
+
import { rm, writeFile } from "node:fs/promises";
|
|
22
22
|
import { app } from "electron";
|
|
23
23
|
|
|
24
24
|
// src/updater/defaultFunctions.ts
|
|
@@ -33,7 +33,7 @@ function isUpdateJSON(json) {
|
|
|
33
33
|
// src/updater/defaultFunctions.ts
|
|
34
34
|
async function downloadJSONDefault(url, updater, headers) {
|
|
35
35
|
await waitAppReady();
|
|
36
|
-
return new Promise((
|
|
36
|
+
return new Promise((resolve2, reject) => {
|
|
37
37
|
const request = net.request({
|
|
38
38
|
url,
|
|
39
39
|
method: "GET",
|
|
@@ -49,7 +49,7 @@ async function downloadJSONDefault(url, updater, headers) {
|
|
|
49
49
|
try {
|
|
50
50
|
const json = JSON.parse(data);
|
|
51
51
|
if (isUpdateJSON(json)) {
|
|
52
|
-
|
|
52
|
+
resolve2(json);
|
|
53
53
|
} else {
|
|
54
54
|
throw Error;
|
|
55
55
|
}
|
|
@@ -67,7 +67,7 @@ async function downloadJSONDefault(url, updater, headers) {
|
|
|
67
67
|
async function downloadBufferDefault(url, updater, headers) {
|
|
68
68
|
await waitAppReady();
|
|
69
69
|
let progress = 0;
|
|
70
|
-
return new Promise((
|
|
70
|
+
return new Promise((resolve2, reject) => {
|
|
71
71
|
const request = net.request({
|
|
72
72
|
url,
|
|
73
73
|
method: "GET",
|
|
@@ -84,7 +84,7 @@ async function downloadBufferDefault(url, updater, headers) {
|
|
|
84
84
|
data.push(chunk);
|
|
85
85
|
});
|
|
86
86
|
res.on("end", () => {
|
|
87
|
-
|
|
87
|
+
resolve2(Buffer.concat(data));
|
|
88
88
|
});
|
|
89
89
|
}).on("error", (e) => {
|
|
90
90
|
reject(e);
|
|
@@ -93,11 +93,14 @@ async function downloadBufferDefault(url, updater, headers) {
|
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
var compareVersionDefault = (oldVersion, newVersion) => {
|
|
96
|
-
if (!oldVersion || !newVersion) {
|
|
96
|
+
if (!oldVersion || !newVersion || typeof oldVersion !== "string" || typeof newVersion !== "string") {
|
|
97
97
|
throw new TypeError("invalid version");
|
|
98
98
|
}
|
|
99
99
|
const parseVersion = (version) => {
|
|
100
|
-
const [versionNumber, stage] = version.split("-");
|
|
100
|
+
const [versionNumber, stage] = version.split("-", 2);
|
|
101
|
+
if (!versionNumber || !versionNumber.includes(".")) {
|
|
102
|
+
throw new TypeError("invalid version");
|
|
103
|
+
}
|
|
101
104
|
const [major, minor, patch] = versionNumber.split(".").map(Number);
|
|
102
105
|
if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
|
|
103
106
|
throw new TypeError("invalid version");
|
|
@@ -116,28 +119,31 @@ var compareVersionDefault = (oldVersion, newVersion) => {
|
|
|
116
119
|
};
|
|
117
120
|
|
|
118
121
|
// src/updater/index.ts
|
|
119
|
-
function createUpdater({
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
122
|
+
function createUpdater(updaterOptions) {
|
|
123
|
+
const {
|
|
124
|
+
SIGNATURE_CERT,
|
|
125
|
+
repository,
|
|
126
|
+
productName,
|
|
127
|
+
releaseAsarURL: _release,
|
|
128
|
+
updateJsonURL: _update,
|
|
129
|
+
debug = false,
|
|
130
|
+
downloadConfig: { extraHeader, userAgent } = {},
|
|
131
|
+
overrideFunctions: {
|
|
132
|
+
compareVersion,
|
|
133
|
+
verifySignaure,
|
|
134
|
+
downloadBuffer,
|
|
135
|
+
downloadJSON
|
|
136
|
+
} = {}
|
|
137
|
+
} = updaterOptions;
|
|
134
138
|
const updater = new EventEmitter();
|
|
135
|
-
let signature
|
|
139
|
+
let signature;
|
|
140
|
+
let version;
|
|
141
|
+
let _debug = debug;
|
|
136
142
|
const asarPath = getProductAsarPath(productName);
|
|
137
143
|
const gzipPath = `${asarPath}.gz`;
|
|
138
|
-
const tmpFilePath =
|
|
144
|
+
const tmpFilePath = `${asarPath}.tmp`;
|
|
139
145
|
function log(msg) {
|
|
140
|
-
|
|
146
|
+
_debug && updater.emit("debug", msg);
|
|
141
147
|
}
|
|
142
148
|
function needUpdate(version2) {
|
|
143
149
|
if (!app.isPackaged) {
|
|
@@ -202,7 +208,8 @@ function createUpdater({
|
|
|
202
208
|
throw new Error(`invalid type at format '${format}': ${data}`);
|
|
203
209
|
}
|
|
204
210
|
}
|
|
205
|
-
updater.
|
|
211
|
+
updater.productName = productName;
|
|
212
|
+
updater.setDebugMode = (isDebug) => _debug = isDebug;
|
|
206
213
|
updater.checkUpdate = async (data) => {
|
|
207
214
|
try {
|
|
208
215
|
const { signature: _sig, size, version: _ver } = await parseData("json", data);
|
|
@@ -221,7 +228,7 @@ function createUpdater({
|
|
|
221
228
|
return error;
|
|
222
229
|
}
|
|
223
230
|
};
|
|
224
|
-
updater.
|
|
231
|
+
updater.download = async (data, sig) => {
|
|
225
232
|
try {
|
|
226
233
|
const _sig = sig ?? signature;
|
|
227
234
|
if (!_sig) {
|
|
@@ -235,21 +242,11 @@ function createUpdater({
|
|
|
235
242
|
throw new Error("verify failed, invalid signature");
|
|
236
243
|
}
|
|
237
244
|
log("verify success");
|
|
238
|
-
|
|
239
|
-
throw new Error(`update unavailable: ${_ver}`);
|
|
240
|
-
}
|
|
241
|
-
log(`write file: ${gzipPath}`);
|
|
245
|
+
log(`write to ${gzipPath}`);
|
|
242
246
|
await writeFile(gzipPath, buffer);
|
|
243
|
-
log(`extract
|
|
247
|
+
log(`extract to ${tmpFilePath}`);
|
|
244
248
|
await unzipFile(gzipPath, tmpFilePath);
|
|
245
|
-
|
|
246
|
-
if (asarVersion !== _ver) {
|
|
247
|
-
rmSync(tmpFilePath);
|
|
248
|
-
throw new Error(`update failed: asar version is ${asarVersion}, but it should be ${_ver}`);
|
|
249
|
-
} else {
|
|
250
|
-
await rename(tmpFilePath, asarPath);
|
|
251
|
-
}
|
|
252
|
-
log(`update success, version: ${_ver}`);
|
|
249
|
+
log(`download success, version: ${_ver}`);
|
|
253
250
|
signature = "";
|
|
254
251
|
return true;
|
|
255
252
|
} catch (error) {
|
|
@@ -261,25 +258,46 @@ function createUpdater({
|
|
|
261
258
|
}
|
|
262
259
|
|
|
263
260
|
// src/index.ts
|
|
264
|
-
function initApp(appOptions
|
|
261
|
+
function initApp(appOptions) {
|
|
265
262
|
const {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
263
|
+
electronDevDistPath = "dist-electron",
|
|
264
|
+
mainPath = "main/index.js",
|
|
265
|
+
onStart,
|
|
266
|
+
onStartError
|
|
267
|
+
} = appOptions || {};
|
|
268
|
+
function handleError(msg) {
|
|
269
|
+
onStartError?.(new Error(msg));
|
|
270
|
+
app2.quit();
|
|
271
|
+
}
|
|
272
|
+
function startup(updater) {
|
|
273
|
+
try {
|
|
274
|
+
const asarPath = getProductAsarPath(updater.productName);
|
|
275
|
+
if (existsSync2(`${asarPath}.tmp`)) {
|
|
276
|
+
renameSync(`${asarPath}.tmp`, asarPath);
|
|
280
277
|
}
|
|
281
|
-
|
|
278
|
+
const mainDir = app2.isPackaged ? asarPath : electronDevDistPath;
|
|
279
|
+
const entry = resolve(__dirname, mainDir, mainPath);
|
|
280
|
+
onStart?.(entry);
|
|
281
|
+
__require(entry)(updater);
|
|
282
|
+
} catch (error) {
|
|
283
|
+
handleError(`failed to start app, ${error}`);
|
|
284
|
+
}
|
|
282
285
|
}
|
|
286
|
+
let timer = setTimeout(() => {
|
|
287
|
+
handleError("start app timeout, please call .setUpdater() to set updater and start");
|
|
288
|
+
}, 3e3);
|
|
289
|
+
return {
|
|
290
|
+
async setUpdater(updater) {
|
|
291
|
+
clearTimeout(timer);
|
|
292
|
+
if (typeof updater === "object") {
|
|
293
|
+
startup(createUpdater(updater));
|
|
294
|
+
} else if (typeof updater === "function") {
|
|
295
|
+
startup(await updater());
|
|
296
|
+
} else {
|
|
297
|
+
handleError("invalid updater option or updater is not a function");
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
};
|
|
283
301
|
}
|
|
284
302
|
export {
|
|
285
303
|
createUpdater,
|
package/dist/utils.d.mts
CHANGED
|
@@ -21,12 +21,19 @@ declare function requireNative<T = any>(packageName: string): T;
|
|
|
21
21
|
* get github version.json CDN URL for accelerating the speed of downloading version info
|
|
22
22
|
*/
|
|
23
23
|
declare function parseGithubCdnURL(repository: string, cdnPrefix: string, relativeFilePath: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* get group of github file CDN prefix for accelerating the speed of downloading release
|
|
26
|
+
*/
|
|
27
|
+
declare function getGithubFileCdnGroup(): {
|
|
28
|
+
cdnPrefix: string;
|
|
29
|
+
source: string;
|
|
30
|
+
}[];
|
|
24
31
|
/**
|
|
25
32
|
* get group of github release CDN prefix for accelerating the speed of downloading release
|
|
26
33
|
*/
|
|
27
34
|
declare function getGithubReleaseCdnGroup(): {
|
|
28
35
|
cdnPrefix: string;
|
|
29
|
-
|
|
36
|
+
source: string;
|
|
30
37
|
}[];
|
|
31
38
|
declare function restartApp(): void;
|
|
32
39
|
declare function waitAppReady(duration?: number): Promise<unknown>;
|
|
@@ -34,4 +41,4 @@ declare function unzipFile(gzipPath: string, targetFilePath: string): Promise<un
|
|
|
34
41
|
declare function zipFile(filePath: string, targetFilePath?: string): Promise<unknown>;
|
|
35
42
|
declare function handleUnexpectedErrors(callback: (err: Error) => void): void;
|
|
36
43
|
|
|
37
|
-
export { getEntryVersion, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, handleUnexpectedErrors, parseGithubCdnURL, requireNative, restartApp, unzipFile, waitAppReady, zipFile };
|
|
44
|
+
export { getEntryVersion, getGithubFileCdnGroup, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, handleUnexpectedErrors, parseGithubCdnURL, requireNative, restartApp, unzipFile, waitAppReady, zipFile };
|
package/dist/utils.d.ts
CHANGED
|
@@ -21,12 +21,19 @@ declare function requireNative<T = any>(packageName: string): T;
|
|
|
21
21
|
* get github version.json CDN URL for accelerating the speed of downloading version info
|
|
22
22
|
*/
|
|
23
23
|
declare function parseGithubCdnURL(repository: string, cdnPrefix: string, relativeFilePath: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* get group of github file CDN prefix for accelerating the speed of downloading release
|
|
26
|
+
*/
|
|
27
|
+
declare function getGithubFileCdnGroup(): {
|
|
28
|
+
cdnPrefix: string;
|
|
29
|
+
source: string;
|
|
30
|
+
}[];
|
|
24
31
|
/**
|
|
25
32
|
* get group of github release CDN prefix for accelerating the speed of downloading release
|
|
26
33
|
*/
|
|
27
34
|
declare function getGithubReleaseCdnGroup(): {
|
|
28
35
|
cdnPrefix: string;
|
|
29
|
-
|
|
36
|
+
source: string;
|
|
30
37
|
}[];
|
|
31
38
|
declare function restartApp(): void;
|
|
32
39
|
declare function waitAppReady(duration?: number): Promise<unknown>;
|
|
@@ -34,4 +41,4 @@ declare function unzipFile(gzipPath: string, targetFilePath: string): Promise<un
|
|
|
34
41
|
declare function zipFile(filePath: string, targetFilePath?: string): Promise<unknown>;
|
|
35
42
|
declare function handleUnexpectedErrors(callback: (err: Error) => void): void;
|
|
36
43
|
|
|
37
|
-
export { getEntryVersion, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, handleUnexpectedErrors, parseGithubCdnURL, requireNative, restartApp, unzipFile, waitAppReady, zipFile };
|
|
44
|
+
export { getEntryVersion, getGithubFileCdnGroup, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, handleUnexpectedErrors, parseGithubCdnURL, requireNative, restartApp, unzipFile, waitAppReady, zipFile };
|
package/dist/utils.js
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var utils_exports = {};
|
|
22
22
|
__export(utils_exports, {
|
|
23
23
|
getEntryVersion: () => getEntryVersion,
|
|
24
|
+
getGithubFileCdnGroup: () => getGithubFileCdnGroup,
|
|
24
25
|
getGithubReleaseCdnGroup: () => getGithubReleaseCdnGroup,
|
|
25
26
|
getProductAsarPath: () => getProductAsarPath,
|
|
26
27
|
getProductVersion: () => getProductVersion,
|
|
@@ -38,7 +39,7 @@ var import_node_path = require("path");
|
|
|
38
39
|
var import_node_zlib = require("zlib");
|
|
39
40
|
var import_electron = require("electron");
|
|
40
41
|
function getProductAsarPath(name) {
|
|
41
|
-
return import_electron.app.isPackaged ? (0, import_node_path.join)((0, import_node_path.dirname)(import_electron.app.getAppPath()), `${name}.asar`) : "dev";
|
|
42
|
+
return import_electron.app.isPackaged ? (0, import_node_path.join)((0, import_node_path.dirname)(import_electron.app.getAppPath()), `${name}.asar`) : "dev.asar";
|
|
42
43
|
}
|
|
43
44
|
function getEntryVersion() {
|
|
44
45
|
return import_electron.app.getVersion();
|
|
@@ -59,22 +60,31 @@ function parseGithubCdnURL(repository, cdnPrefix, relativeFilePath) {
|
|
|
59
60
|
cdnPrefix = cdnPrefix.trim().replace(/^\/?|\/?$/g, "").trim();
|
|
60
61
|
return repository.replace("github.com", cdnPrefix) + relativeFilePath;
|
|
61
62
|
}
|
|
63
|
+
function getGithubFileCdnGroup() {
|
|
64
|
+
return [
|
|
65
|
+
{ cdnPrefix: "cdn.jsdelivr.net/gh", source: "jsdelivr" },
|
|
66
|
+
{ cdnPrefix: "fastly.jsdelivr.net/gh", source: "jsdelivr-fastly" },
|
|
67
|
+
{ cdnPrefix: "cdn.statically.io/gh", source: "statically" },
|
|
68
|
+
{ cdnPrefix: "rawcdn.githack.com/gh", source: "githack" },
|
|
69
|
+
{ cdnPrefix: "raw.githack.com/gh", source: "githack-dev" }
|
|
70
|
+
];
|
|
71
|
+
}
|
|
62
72
|
function getGithubReleaseCdnGroup() {
|
|
63
73
|
return [
|
|
64
|
-
{ cdnPrefix: "gh.gh2233.ml",
|
|
65
|
-
{ cdnPrefix: "ghproxy.com",
|
|
66
|
-
{ cdnPrefix: "gh.ddlc.top",
|
|
67
|
-
{ cdnPrefix: "ghdl.feizhuqwq.cf",
|
|
68
|
-
{ cdnPrefix: "slink.ltd",
|
|
69
|
-
{ cdnPrefix: "git.xfj0.cn",
|
|
70
|
-
{ cdnPrefix: "gh.con.sh",
|
|
71
|
-
{ cdnPrefix: "ghps.cc",
|
|
72
|
-
{ cdnPrefix: "cors.isteed.cc/github.com",
|
|
73
|
-
{ cdnPrefix: "hub.gitmirror.com",
|
|
74
|
-
{ cdnPrefix: "js.xxooo.ml",
|
|
75
|
-
{ cdnPrefix: "download.njuu.cf",
|
|
76
|
-
{ cdnPrefix: "download.yzuu.cf",
|
|
77
|
-
{ cdnPrefix: "download.nuaa.cf",
|
|
74
|
+
{ cdnPrefix: "gh.gh2233.ml", source: "@X.I.U/XIU2" },
|
|
75
|
+
{ cdnPrefix: "ghproxy.com", source: "gh-proxy" },
|
|
76
|
+
{ cdnPrefix: "gh.ddlc.top", source: "@mtr-static-official" },
|
|
77
|
+
{ cdnPrefix: "ghdl.feizhuqwq.cf", source: "feizhuqwq.com" },
|
|
78
|
+
{ cdnPrefix: "slink.ltd", source: "\u77E5\u4E86\u5C0F\u7AD9" },
|
|
79
|
+
{ cdnPrefix: "git.xfj0.cn", source: "anonymous1" },
|
|
80
|
+
{ cdnPrefix: "gh.con.sh", source: "anonymous2" },
|
|
81
|
+
{ cdnPrefix: "ghps.cc", source: "anonymous3" },
|
|
82
|
+
{ cdnPrefix: "cors.isteed.cc/github.com", source: "Lufs's" },
|
|
83
|
+
{ cdnPrefix: "hub.gitmirror.com", source: "GitMirror" },
|
|
84
|
+
{ cdnPrefix: "js.xxooo.ml", source: "\u996D\u592A\u786C" },
|
|
85
|
+
{ cdnPrefix: "download.njuu.cf", source: "LibraryCloud-njuu" },
|
|
86
|
+
{ cdnPrefix: "download.yzuu.cf", source: "LibraryCloud-yzuu" },
|
|
87
|
+
{ cdnPrefix: "download.nuaa.cf", source: "LibraryCloud-nuaa" }
|
|
78
88
|
];
|
|
79
89
|
}
|
|
80
90
|
function restartApp() {
|
|
@@ -96,17 +106,15 @@ async function unzipFile(gzipPath, targetFilePath) {
|
|
|
96
106
|
if (!(0, import_node_fs.existsSync)(gzipPath)) {
|
|
97
107
|
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
98
108
|
}
|
|
109
|
+
const compressedBuffer = (0, import_node_fs.readFileSync)(gzipPath);
|
|
99
110
|
return new Promise((resolve, reject) => {
|
|
100
|
-
|
|
101
|
-
const input = (0, import_node_fs.createReadStream)(gzipPath);
|
|
102
|
-
const output = (0, import_node_fs.createWriteStream)(targetFilePath);
|
|
103
|
-
input.pipe(gunzip).pipe(output).on("finish", () => {
|
|
111
|
+
(0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
|
|
104
112
|
(0, import_node_fs.rmSync)(gzipPath);
|
|
113
|
+
if (err) {
|
|
114
|
+
reject(err);
|
|
115
|
+
}
|
|
116
|
+
(0, import_node_fs.writeFileSync)(targetFilePath, buffer);
|
|
105
117
|
resolve(null);
|
|
106
|
-
}).on("error", (err) => {
|
|
107
|
-
(0, import_node_fs.rmSync)(gzipPath);
|
|
108
|
-
output.destroy(err);
|
|
109
|
-
reject(err);
|
|
110
118
|
});
|
|
111
119
|
});
|
|
112
120
|
}
|
|
@@ -114,11 +122,15 @@ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
|
|
|
114
122
|
if (!(0, import_node_fs.existsSync)(filePath)) {
|
|
115
123
|
throw new Error(`path to be zipped not exist: ${filePath}`);
|
|
116
124
|
}
|
|
125
|
+
const buffer = (0, import_node_fs.readFileSync)(filePath);
|
|
117
126
|
return new Promise((resolve, reject) => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
127
|
+
(0, import_node_zlib.gzip)(buffer, (err, buffer2) => {
|
|
128
|
+
if (err) {
|
|
129
|
+
reject(err);
|
|
130
|
+
}
|
|
131
|
+
(0, import_node_fs.writeFileSync)(targetFilePath, buffer2);
|
|
132
|
+
resolve(null);
|
|
133
|
+
});
|
|
122
134
|
});
|
|
123
135
|
}
|
|
124
136
|
function handleUnexpectedErrors(callback) {
|
|
@@ -132,6 +144,7 @@ function handleUnexpectedErrors(callback) {
|
|
|
132
144
|
// Annotate the CommonJS export names for ESM import in node:
|
|
133
145
|
0 && (module.exports = {
|
|
134
146
|
getEntryVersion,
|
|
147
|
+
getGithubFileCdnGroup,
|
|
135
148
|
getGithubReleaseCdnGroup,
|
|
136
149
|
getProductAsarPath,
|
|
137
150
|
getProductVersion,
|
package/dist/utils.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getEntryVersion,
|
|
3
|
+
getGithubFileCdnGroup,
|
|
3
4
|
getGithubReleaseCdnGroup,
|
|
4
5
|
getProductAsarPath,
|
|
5
6
|
getProductVersion,
|
|
@@ -10,9 +11,10 @@ import {
|
|
|
10
11
|
unzipFile,
|
|
11
12
|
waitAppReady,
|
|
12
13
|
zipFile
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-67MCNA7W.mjs";
|
|
14
15
|
export {
|
|
15
16
|
getEntryVersion,
|
|
17
|
+
getGithubFileCdnGroup,
|
|
16
18
|
getGithubReleaseCdnGroup,
|
|
17
19
|
getProductAsarPath,
|
|
18
20
|
getProductVersion,
|
package/dist/vite.js
CHANGED
|
@@ -66,11 +66,15 @@ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
|
|
|
66
66
|
if (!(0, import_node_fs.existsSync)(filePath)) {
|
|
67
67
|
throw new Error(`path to be zipped not exist: ${filePath}`);
|
|
68
68
|
}
|
|
69
|
+
const buffer = (0, import_node_fs.readFileSync)(filePath);
|
|
69
70
|
return new Promise((resolve, reject) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
(0, import_node_zlib.gzip)(buffer, (err, buffer2) => {
|
|
72
|
+
if (err) {
|
|
73
|
+
reject(err);
|
|
74
|
+
}
|
|
75
|
+
(0, import_node_fs.writeFileSync)(targetFilePath, buffer2);
|
|
76
|
+
resolve(null);
|
|
77
|
+
});
|
|
74
78
|
});
|
|
75
79
|
}
|
|
76
80
|
|
|
@@ -164,8 +168,8 @@ try {
|
|
|
164
168
|
keySize: ${keyLength}, algorithm: 'sha256', days: ${days},
|
|
165
169
|
})
|
|
166
170
|
|
|
167
|
-
writeFileSync(privateKeyPath, privateKey.replace(/\\r
|
|
168
|
-
writeFileSync(certPath, cert.replace(/\\r
|
|
171
|
+
writeFileSync(privateKeyPath, privateKey.replace(/\\r\\n?/g, '\\n'))
|
|
172
|
+
writeFileSync(certPath, cert.replace(/\\r\\n?/g, '\\n'))
|
|
169
173
|
} catch (e) {
|
|
170
174
|
console.error(e)
|
|
171
175
|
process.exit(-1)
|
package/dist/vite.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-Q2K52LOG.mjs";
|
|
4
4
|
import {
|
|
5
5
|
zipFile
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-67MCNA7W.mjs";
|
|
7
7
|
|
|
8
8
|
// src/vite.ts
|
|
9
9
|
import { createLogger } from "vite";
|
|
@@ -100,8 +100,8 @@ try {
|
|
|
100
100
|
keySize: ${keyLength}, algorithm: 'sha256', days: ${days},
|
|
101
101
|
})
|
|
102
102
|
|
|
103
|
-
writeFileSync(privateKeyPath, privateKey.replace(/\\r
|
|
104
|
-
writeFileSync(certPath, cert.replace(/\\r
|
|
103
|
+
writeFileSync(privateKeyPath, privateKey.replace(/\\r\\n?/g, '\\n'))
|
|
104
|
+
writeFileSync(certPath, cert.replace(/\\r\\n?/g, '\\n'))
|
|
105
105
|
} catch (e) {
|
|
106
106
|
console.error(e)
|
|
107
107
|
process.exit(-1)
|
package/package.json
CHANGED