electron-incremental-update 0.7.2 → 0.7.4
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 +5 -5
- package/dist/{chunk-CRBEZBU5.mjs → chunk-L3QO4PD3.mjs} +17 -15
- package/dist/index.d.mts +27 -25
- package/dist/index.d.ts +27 -25
- package/dist/index.js +83 -66
- package/dist/index.mjs +75 -56
- package/dist/utils.js +15 -13
- package/dist/utils.mjs +1 -1
- package/dist/vite.d.mts +16 -17
- package/dist/vite.d.ts +16 -17
- package/dist/vite.js +61 -40
- package/dist/vite.mjs +55 -38
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ import { name, repository } from '../package.json'
|
|
|
61
61
|
const SIGNATURE_CERT = '' // auto generate certificate when start app
|
|
62
62
|
|
|
63
63
|
// create updater when init, no need to set productName
|
|
64
|
-
initApp({
|
|
64
|
+
initApp({ onStart: console.log }, { productName: name, SIGNATURE_CERT, repository })
|
|
65
65
|
|
|
66
66
|
// or create updater manually
|
|
67
67
|
const { cdnPrefix } = getGithubReleaseCdnGroup()[0]
|
|
@@ -73,7 +73,7 @@ const updater = createUpdater({
|
|
|
73
73
|
releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
|
|
74
74
|
debug: true,
|
|
75
75
|
})
|
|
76
|
-
initApp(
|
|
76
|
+
initApp().setUpdater(updater)
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
### usage in main process
|
|
@@ -115,7 +115,7 @@ const startup: StartupWithUpdater = (updater: Updater) => {
|
|
|
115
115
|
buttons: ['Download', 'Later'],
|
|
116
116
|
message: 'Application update available!',
|
|
117
117
|
})
|
|
118
|
-
response === 0 && console.log(await updater.
|
|
118
|
+
response === 0 && console.log(await updater.download())
|
|
119
119
|
}
|
|
120
120
|
})
|
|
121
121
|
}
|
|
@@ -201,9 +201,9 @@ export default defineConfig(({ command }) => {
|
|
|
201
201
|
### electron-builder config
|
|
202
202
|
|
|
203
203
|
```js
|
|
204
|
-
const { name
|
|
204
|
+
const { name } = require('./package.json')
|
|
205
205
|
|
|
206
|
-
const target = `${name}
|
|
206
|
+
const target = `${name}.asar`
|
|
207
207
|
/**
|
|
208
208
|
* @type {import('electron-builder').Configuration}
|
|
209
209
|
*/
|
|
@@ -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();
|
|
@@ -70,17 +70,15 @@ async function unzipFile(gzipPath, targetFilePath) {
|
|
|
70
70
|
if (!existsSync(gzipPath)) {
|
|
71
71
|
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
72
72
|
}
|
|
73
|
+
const compressedBuffer = readFileSync(gzipPath);
|
|
73
74
|
return new Promise((resolve, reject) => {
|
|
74
|
-
|
|
75
|
-
const input = createReadStream(gzipPath);
|
|
76
|
-
const output = createWriteStream(targetFilePath);
|
|
77
|
-
input.pipe(gunzip).pipe(output).on("finish", () => {
|
|
75
|
+
gunzip(compressedBuffer, (err, buffer) => {
|
|
78
76
|
rmSync(gzipPath);
|
|
77
|
+
if (err) {
|
|
78
|
+
reject(err);
|
|
79
|
+
}
|
|
80
|
+
writeFileSync(targetFilePath, buffer);
|
|
79
81
|
resolve(null);
|
|
80
|
-
}).on("error", (err) => {
|
|
81
|
-
rmSync(gzipPath);
|
|
82
|
-
output.destroy(err);
|
|
83
|
-
reject(err);
|
|
84
82
|
});
|
|
85
83
|
});
|
|
86
84
|
}
|
|
@@ -88,11 +86,15 @@ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
|
|
|
88
86
|
if (!existsSync(filePath)) {
|
|
89
87
|
throw new Error(`path to be zipped not exist: ${filePath}`);
|
|
90
88
|
}
|
|
89
|
+
const buffer = readFileSync(filePath);
|
|
91
90
|
return new Promise((resolve, reject) => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
gzip(buffer, (err, buffer2) => {
|
|
92
|
+
if (err) {
|
|
93
|
+
reject(err);
|
|
94
|
+
}
|
|
95
|
+
writeFileSync(targetFilePath, buffer2);
|
|
96
|
+
resolve(null);
|
|
97
|
+
});
|
|
96
98
|
});
|
|
97
99
|
}
|
|
98
100
|
function handleUnexpectedErrors(callback) {
|
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,28 +137,31 @@ 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;
|
|
164
166
|
/**
|
|
165
167
|
* create updater manually
|
|
@@ -179,7 +181,7 @@ type StartupWithUpdater = (updater: Updater) => void;
|
|
|
179
181
|
* releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
|
|
180
182
|
* debug: true,
|
|
181
183
|
* })
|
|
182
|
-
* initApp(
|
|
184
|
+
* initApp().setUpdater(updater)
|
|
183
185
|
* ```
|
|
184
186
|
*/
|
|
185
187
|
declare function initApp(appOptions: AppOption): {
|
|
@@ -195,9 +197,9 @@ declare function initApp(appOptions: AppOption): {
|
|
|
195
197
|
*
|
|
196
198
|
* const SIGNATURE_CERT = '' // auto generate
|
|
197
199
|
*
|
|
198
|
-
* initApp({
|
|
200
|
+
* initApp({ onStart: console.log }, { productName: name, SIGNATURE_CERT, repository })
|
|
199
201
|
* ```
|
|
200
202
|
*/
|
|
201
|
-
declare function initApp(appOptions: AppOption, updaterOptions:
|
|
203
|
+
declare function initApp(appOptions: AppOption, updaterOptions: UpdaterOption): undefined;
|
|
202
204
|
|
|
203
|
-
export { AppOption, FunctionCompareVersion, FunctionVerifySignature,
|
|
205
|
+
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,28 +137,31 @@ 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;
|
|
164
166
|
/**
|
|
165
167
|
* create updater manually
|
|
@@ -179,7 +181,7 @@ type StartupWithUpdater = (updater: Updater) => void;
|
|
|
179
181
|
* releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
|
|
180
182
|
* debug: true,
|
|
181
183
|
* })
|
|
182
|
-
* initApp(
|
|
184
|
+
* initApp().setUpdater(updater)
|
|
183
185
|
* ```
|
|
184
186
|
*/
|
|
185
187
|
declare function initApp(appOptions: AppOption): {
|
|
@@ -195,9 +197,9 @@ declare function initApp(appOptions: AppOption): {
|
|
|
195
197
|
*
|
|
196
198
|
* const SIGNATURE_CERT = '' // auto generate
|
|
197
199
|
*
|
|
198
|
-
* initApp({
|
|
200
|
+
* initApp({ onStart: console.log }, { productName: name, SIGNATURE_CERT, repository })
|
|
199
201
|
* ```
|
|
200
202
|
*/
|
|
201
|
-
declare function initApp(appOptions: AppOption, updaterOptions:
|
|
203
|
+
declare function initApp(appOptions: AppOption, updaterOptions: UpdaterOption): undefined;
|
|
202
204
|
|
|
203
|
-
export { AppOption, FunctionCompareVersion, FunctionVerifySignature,
|
|
205
|
+
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,22 +334,44 @@ function createUpdater({
|
|
|
339
334
|
}
|
|
340
335
|
|
|
341
336
|
// src/index.ts
|
|
342
|
-
function initApp(
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
337
|
+
function initApp({
|
|
338
|
+
electronDevDistPath = "dist-electron",
|
|
339
|
+
mainPath = "main/index.js",
|
|
340
|
+
onStart,
|
|
341
|
+
onStartError
|
|
342
|
+
}, updaterOptions) {
|
|
343
|
+
function startup(updater) {
|
|
344
|
+
try {
|
|
345
|
+
const asarPath = getProductAsarPath(updater.productName);
|
|
346
|
+
if ((0, import_node_fs3.existsSync)(`${asarPath}.tmp`)) {
|
|
347
|
+
(0, import_node_fs3.renameSync)(`${asarPath}.tmp`, asarPath);
|
|
348
|
+
}
|
|
349
|
+
const mainDir = import_electron4.app.isPackaged ? asarPath : electronDevDistPath;
|
|
350
|
+
const entry = (0, import_node_path2.resolve)(__dirname, mainDir, mainPath);
|
|
351
|
+
onStart?.(entry);
|
|
352
|
+
require(entry)(updater);
|
|
353
|
+
} catch (error) {
|
|
354
|
+
if (onStartError) {
|
|
355
|
+
onStartError(error);
|
|
356
|
+
} else {
|
|
357
|
+
console.error("fail to start app,", error);
|
|
358
|
+
import_electron4.app.quit();
|
|
359
|
+
process.exit(1);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
350
363
|
if (updaterOptions) {
|
|
351
|
-
|
|
352
|
-
createUpdater({ ...updaterOptions, productName })
|
|
353
|
-
);
|
|
364
|
+
startup(createUpdater(updaterOptions));
|
|
354
365
|
} else {
|
|
366
|
+
let timer = setTimeout(() => {
|
|
367
|
+
console.error("start app timeout, please call .setUpdater() to set updater and start");
|
|
368
|
+
import_electron4.app.quit();
|
|
369
|
+
process.exit(1);
|
|
370
|
+
}, 3e3);
|
|
355
371
|
return {
|
|
356
372
|
setUpdater(updater) {
|
|
357
|
-
|
|
373
|
+
clearTimeout(timer);
|
|
374
|
+
startup(updater);
|
|
358
375
|
}
|
|
359
376
|
};
|
|
360
377
|
}
|
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-L3QO4PD3.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,22 +258,44 @@ function createUpdater({
|
|
|
261
258
|
}
|
|
262
259
|
|
|
263
260
|
// src/index.ts
|
|
264
|
-
function initApp(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
261
|
+
function initApp({
|
|
262
|
+
electronDevDistPath = "dist-electron",
|
|
263
|
+
mainPath = "main/index.js",
|
|
264
|
+
onStart,
|
|
265
|
+
onStartError
|
|
266
|
+
}, updaterOptions) {
|
|
267
|
+
function startup(updater) {
|
|
268
|
+
try {
|
|
269
|
+
const asarPath = getProductAsarPath(updater.productName);
|
|
270
|
+
if (existsSync2(`${asarPath}.tmp`)) {
|
|
271
|
+
renameSync(`${asarPath}.tmp`, asarPath);
|
|
272
|
+
}
|
|
273
|
+
const mainDir = app2.isPackaged ? asarPath : electronDevDistPath;
|
|
274
|
+
const entry = resolve(__dirname, mainDir, mainPath);
|
|
275
|
+
onStart?.(entry);
|
|
276
|
+
__require(entry)(updater);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
if (onStartError) {
|
|
279
|
+
onStartError(error);
|
|
280
|
+
} else {
|
|
281
|
+
console.error("fail to start app,", error);
|
|
282
|
+
app2.quit();
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
272
287
|
if (updaterOptions) {
|
|
273
|
-
|
|
274
|
-
createUpdater({ ...updaterOptions, productName })
|
|
275
|
-
);
|
|
288
|
+
startup(createUpdater(updaterOptions));
|
|
276
289
|
} else {
|
|
290
|
+
let timer = setTimeout(() => {
|
|
291
|
+
console.error("start app timeout, please call .setUpdater() to set updater and start");
|
|
292
|
+
app2.quit();
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}, 3e3);
|
|
277
295
|
return {
|
|
278
296
|
setUpdater(updater) {
|
|
279
|
-
|
|
297
|
+
clearTimeout(timer);
|
|
298
|
+
startup(updater);
|
|
280
299
|
}
|
|
281
300
|
};
|
|
282
301
|
}
|
package/dist/utils.js
CHANGED
|
@@ -38,7 +38,7 @@ var import_node_path = require("path");
|
|
|
38
38
|
var import_node_zlib = require("zlib");
|
|
39
39
|
var import_electron = require("electron");
|
|
40
40
|
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";
|
|
41
|
+
return import_electron.app.isPackaged ? (0, import_node_path.join)((0, import_node_path.dirname)(import_electron.app.getAppPath()), `${name}.asar`) : "dev.asar";
|
|
42
42
|
}
|
|
43
43
|
function getEntryVersion() {
|
|
44
44
|
return import_electron.app.getVersion();
|
|
@@ -96,17 +96,15 @@ async function unzipFile(gzipPath, targetFilePath) {
|
|
|
96
96
|
if (!(0, import_node_fs.existsSync)(gzipPath)) {
|
|
97
97
|
throw new Error(`path to zipped file not exist: ${gzipPath}`);
|
|
98
98
|
}
|
|
99
|
+
const compressedBuffer = (0, import_node_fs.readFileSync)(gzipPath);
|
|
99
100
|
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", () => {
|
|
101
|
+
(0, import_node_zlib.gunzip)(compressedBuffer, (err, buffer) => {
|
|
104
102
|
(0, import_node_fs.rmSync)(gzipPath);
|
|
103
|
+
if (err) {
|
|
104
|
+
reject(err);
|
|
105
|
+
}
|
|
106
|
+
(0, import_node_fs.writeFileSync)(targetFilePath, buffer);
|
|
105
107
|
resolve(null);
|
|
106
|
-
}).on("error", (err) => {
|
|
107
|
-
(0, import_node_fs.rmSync)(gzipPath);
|
|
108
|
-
output.destroy(err);
|
|
109
|
-
reject(err);
|
|
110
108
|
});
|
|
111
109
|
});
|
|
112
110
|
}
|
|
@@ -114,11 +112,15 @@ async function zipFile(filePath, targetFilePath = `${filePath}.gz`) {
|
|
|
114
112
|
if (!(0, import_node_fs.existsSync)(filePath)) {
|
|
115
113
|
throw new Error(`path to be zipped not exist: ${filePath}`);
|
|
116
114
|
}
|
|
115
|
+
const buffer = (0, import_node_fs.readFileSync)(filePath);
|
|
117
116
|
return new Promise((resolve, reject) => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
(0, import_node_zlib.gzip)(buffer, (err, buffer2) => {
|
|
118
|
+
if (err) {
|
|
119
|
+
reject(err);
|
|
120
|
+
}
|
|
121
|
+
(0, import_node_fs.writeFileSync)(targetFilePath, buffer2);
|
|
122
|
+
resolve(null);
|
|
123
|
+
});
|
|
122
124
|
});
|
|
123
125
|
}
|
|
124
126
|
function handleUnexpectedErrors(callback) {
|
package/dist/utils.mjs
CHANGED
package/dist/vite.d.mts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
import { Buffer } from 'node:buffer';
|
|
3
|
-
import { DistinguishedName } from '@cyyynthia/jscert';
|
|
4
3
|
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
type DistinguishedName = {
|
|
5
|
+
countryName?: string;
|
|
6
|
+
stateOrProvinceName?: string;
|
|
7
|
+
localityName?: string;
|
|
8
|
+
organizationName?: string;
|
|
9
|
+
organizationalUnitName?: string;
|
|
10
|
+
commonName?: string;
|
|
11
|
+
serialNumber?: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
businessCategory?: string;
|
|
15
|
+
emailAddress?: string;
|
|
8
16
|
};
|
|
9
17
|
type FunctionGenerateSignature = (buffer: Buffer, privateKey: string, cert: string, version: string) => string;
|
|
10
18
|
type Options = {
|
|
@@ -98,26 +106,17 @@ type Options = {
|
|
|
98
106
|
/**
|
|
99
107
|
* the subject of the certificate
|
|
100
108
|
*
|
|
101
|
-
* @default { commonName: productName,
|
|
109
|
+
* @default { commonName: productName, organizationName: `org.${productName}` }
|
|
102
110
|
*/
|
|
103
111
|
subject?: DistinguishedName;
|
|
104
112
|
/**
|
|
105
|
-
*
|
|
106
|
-
* - `Date`: expire date
|
|
107
|
-
* - `number`: expire duration in seconds
|
|
113
|
+
* expire days of the certificate
|
|
108
114
|
*
|
|
109
|
-
* @default
|
|
115
|
+
* @default 365
|
|
110
116
|
*/
|
|
111
|
-
|
|
117
|
+
days?: number;
|
|
112
118
|
};
|
|
113
119
|
overrideFunctions?: {
|
|
114
|
-
/**
|
|
115
|
-
* custom key pair generate function {@link FunctionGenerateKeyPair}
|
|
116
|
-
* @param keyLength key length
|
|
117
|
-
* @param subject subject info
|
|
118
|
-
* @param expires expire date
|
|
119
|
-
*/
|
|
120
|
-
generateKeyPair?: FunctionGenerateKeyPair;
|
|
121
120
|
/**
|
|
122
121
|
* custom signature generate function {@link FunctionGenerateSignature}
|
|
123
122
|
* @param buffer file buffer
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
import { Buffer } from 'node:buffer';
|
|
3
|
-
import { DistinguishedName } from '@cyyynthia/jscert';
|
|
4
3
|
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
type DistinguishedName = {
|
|
5
|
+
countryName?: string;
|
|
6
|
+
stateOrProvinceName?: string;
|
|
7
|
+
localityName?: string;
|
|
8
|
+
organizationName?: string;
|
|
9
|
+
organizationalUnitName?: string;
|
|
10
|
+
commonName?: string;
|
|
11
|
+
serialNumber?: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
businessCategory?: string;
|
|
15
|
+
emailAddress?: string;
|
|
8
16
|
};
|
|
9
17
|
type FunctionGenerateSignature = (buffer: Buffer, privateKey: string, cert: string, version: string) => string;
|
|
10
18
|
type Options = {
|
|
@@ -98,26 +106,17 @@ type Options = {
|
|
|
98
106
|
/**
|
|
99
107
|
* the subject of the certificate
|
|
100
108
|
*
|
|
101
|
-
* @default { commonName: productName,
|
|
109
|
+
* @default { commonName: productName, organizationName: `org.${productName}` }
|
|
102
110
|
*/
|
|
103
111
|
subject?: DistinguishedName;
|
|
104
112
|
/**
|
|
105
|
-
*
|
|
106
|
-
* - `Date`: expire date
|
|
107
|
-
* - `number`: expire duration in seconds
|
|
113
|
+
* expire days of the certificate
|
|
108
114
|
*
|
|
109
|
-
* @default
|
|
115
|
+
* @default 365
|
|
110
116
|
*/
|
|
111
|
-
|
|
117
|
+
days?: number;
|
|
112
118
|
};
|
|
113
119
|
overrideFunctions?: {
|
|
114
|
-
/**
|
|
115
|
-
* custom key pair generate function {@link FunctionGenerateKeyPair}
|
|
116
|
-
* @param keyLength key length
|
|
117
|
-
* @param subject subject info
|
|
118
|
-
* @param expires expire date
|
|
119
|
-
*/
|
|
120
|
-
generateKeyPair?: FunctionGenerateKeyPair;
|
|
121
120
|
/**
|
|
122
121
|
* custom signature generate function {@link FunctionGenerateSignature}
|
|
123
122
|
* @param buffer file buffer
|
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
|
|
|
@@ -142,20 +146,44 @@ var import_ci_info = require("ci-info");
|
|
|
142
146
|
var import_node_fs2 = require("fs");
|
|
143
147
|
var import_node_path2 = require("path");
|
|
144
148
|
var import_node_os = require("os");
|
|
145
|
-
var
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
var import_node_child_process = require("child_process");
|
|
150
|
+
function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
151
|
+
const starter = `try {
|
|
152
|
+
require('selfsigned')
|
|
153
|
+
} catch (e) {
|
|
154
|
+
console.error('to generate private key, please run "npm install --dev selfsigned"')
|
|
150
155
|
}
|
|
151
|
-
|
|
152
|
-
const {
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
156
|
+
try {
|
|
157
|
+
const { existsSync, mkdirSync, writeFileSync } = require('node:fs')
|
|
158
|
+
const { dirname } = require('node:path')
|
|
159
|
+
const { generate } = require('selfsigned')
|
|
160
|
+
const privateKeyPath = '${privateKeyPath.replace(/\\/g, "/")}'
|
|
161
|
+
const certPath = '${certPath.replace(/\\/g, "/")}'
|
|
162
|
+
const privateKeyDir = dirname(privateKeyPath)
|
|
163
|
+
existsSync(privateKeyDir) || mkdirSync(privateKeyDir, { recursive: true })
|
|
164
|
+
const certDir = dirname(certPath)
|
|
165
|
+
existsSync(certDir) || mkdirSync(certDir, { recursive: true })
|
|
166
|
+
|
|
167
|
+
const { cert, private: privateKey } = generate(${JSON.stringify(subject)}, {
|
|
168
|
+
keySize: ${keyLength}, algorithm: 'sha256', days: ${days},
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
writeFileSync(privateKeyPath, privateKey.replace(/\\r\\n?/g, '\\n'))
|
|
172
|
+
writeFileSync(certPath, cert.replace(/\\r\\n?/g, '\\n'))
|
|
173
|
+
} catch (e) {
|
|
174
|
+
console.error(e)
|
|
175
|
+
process.exit(-1)
|
|
176
|
+
} finally {
|
|
177
|
+
process.exit(0)
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
const fileName = "key-gen.js";
|
|
181
|
+
(0, import_node_fs2.writeFileSync)(`./${fileName}`, starter);
|
|
182
|
+
try {
|
|
183
|
+
(0, import_node_child_process.execSync)(`npx electron ${fileName}`, { stdio: "inherit" });
|
|
184
|
+
} finally {
|
|
185
|
+
(0, import_node_fs2.rmSync)(`./${fileName}`);
|
|
186
|
+
}
|
|
159
187
|
}
|
|
160
188
|
function writeCertToMain(entryPath, cert) {
|
|
161
189
|
const file = (0, import_node_fs2.readFileSync)(entryPath, "utf-8");
|
|
@@ -188,29 +216,29 @@ function parseKeys({
|
|
|
188
216
|
certPath,
|
|
189
217
|
entryPath,
|
|
190
218
|
subject,
|
|
191
|
-
|
|
192
|
-
generateKeyPair
|
|
219
|
+
days
|
|
193
220
|
}) {
|
|
194
221
|
const keysDir = (0, import_node_path2.dirname)(privateKeyPath);
|
|
195
222
|
!(0, import_node_fs2.existsSync)(keysDir) && (0, import_node_fs2.mkdirSync)(keysDir);
|
|
196
|
-
let privateKey, cert;
|
|
197
223
|
if (!(0, import_node_fs2.existsSync)(privateKeyPath) || !(0, import_node_fs2.existsSync)(certPath)) {
|
|
198
|
-
|
|
199
|
-
const keys = _func(keyLength, subject, expires);
|
|
200
|
-
privateKey = keys.privateKey;
|
|
201
|
-
cert = keys.cert;
|
|
202
|
-
(0, import_node_fs2.writeFileSync)(privateKeyPath, privateKey);
|
|
203
|
-
(0, import_node_fs2.writeFileSync)(certPath, cert);
|
|
204
|
-
} else {
|
|
205
|
-
privateKey = (0, import_node_fs2.readFileSync)(privateKeyPath, "utf-8");
|
|
206
|
-
cert = (0, import_node_fs2.readFileSync)(certPath, "utf-8");
|
|
224
|
+
generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
|
|
207
225
|
}
|
|
226
|
+
const privateKey = (0, import_node_fs2.readFileSync)(privateKeyPath, "utf-8");
|
|
227
|
+
const cert = (0, import_node_fs2.readFileSync)(certPath, "utf-8");
|
|
208
228
|
writeCertToMain(entryPath, cert);
|
|
209
229
|
return {
|
|
210
230
|
privateKey,
|
|
211
231
|
cert
|
|
212
232
|
};
|
|
213
233
|
}
|
|
234
|
+
function parseSubjects(subject) {
|
|
235
|
+
const ret = [];
|
|
236
|
+
Object.keys(subject).forEach((name) => {
|
|
237
|
+
const value = subject[name];
|
|
238
|
+
value && ret.push({ name, value });
|
|
239
|
+
});
|
|
240
|
+
return ret;
|
|
241
|
+
}
|
|
214
242
|
|
|
215
243
|
// src/build-plugins/option.ts
|
|
216
244
|
function parseOptions(options) {
|
|
@@ -236,16 +264,13 @@ function parseOptions(options) {
|
|
|
236
264
|
overrideFunctions = {}
|
|
237
265
|
} = {}
|
|
238
266
|
} = options;
|
|
239
|
-
const {
|
|
240
|
-
generateKeyPair,
|
|
241
|
-
generateSignature
|
|
242
|
-
} = overrideFunctions;
|
|
267
|
+
const { generateSignature } = overrideFunctions;
|
|
243
268
|
let {
|
|
244
269
|
subject = {
|
|
245
270
|
commonName: productName,
|
|
246
|
-
|
|
271
|
+
organizationName: `org.${productName}`
|
|
247
272
|
},
|
|
248
|
-
|
|
273
|
+
days = 365
|
|
249
274
|
} = certInfo;
|
|
250
275
|
const buildAsarOption = {
|
|
251
276
|
version,
|
|
@@ -261,17 +286,13 @@ function parseOptions(options) {
|
|
|
261
286
|
};
|
|
262
287
|
let buildVersionOption;
|
|
263
288
|
if (!import_ci_info.isCI) {
|
|
264
|
-
if (typeof expires === "number") {
|
|
265
|
-
expires = new Date(Date.now() + expires);
|
|
266
|
-
}
|
|
267
289
|
const { privateKey, cert } = parseKeys({
|
|
268
290
|
keyLength,
|
|
269
291
|
privateKeyPath,
|
|
270
292
|
certPath,
|
|
271
293
|
entryPath,
|
|
272
294
|
subject,
|
|
273
|
-
|
|
274
|
-
generateKeyPair
|
|
295
|
+
days
|
|
275
296
|
});
|
|
276
297
|
buildVersionOption = {
|
|
277
298
|
version,
|
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-L3QO4PD3.mjs";
|
|
7
7
|
|
|
8
8
|
// src/vite.ts
|
|
9
9
|
import { createLogger } from "vite";
|
|
@@ -75,23 +75,47 @@ async function buildEntry({
|
|
|
75
75
|
import { isCI } from "ci-info";
|
|
76
76
|
|
|
77
77
|
// src/build-plugins/key.ts
|
|
78
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
78
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
79
79
|
import { dirname } from "node:path";
|
|
80
80
|
import { EOL } from "node:os";
|
|
81
|
-
import {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
import { execSync } from "node:child_process";
|
|
82
|
+
function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
83
|
+
const starter = `try {
|
|
84
|
+
require('selfsigned')
|
|
85
|
+
} catch (e) {
|
|
86
|
+
console.error('to generate private key, please run "npm install --dev selfsigned"')
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
-
const {
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
88
|
+
try {
|
|
89
|
+
const { existsSync, mkdirSync, writeFileSync } = require('node:fs')
|
|
90
|
+
const { dirname } = require('node:path')
|
|
91
|
+
const { generate } = require('selfsigned')
|
|
92
|
+
const privateKeyPath = '${privateKeyPath.replace(/\\/g, "/")}'
|
|
93
|
+
const certPath = '${certPath.replace(/\\/g, "/")}'
|
|
94
|
+
const privateKeyDir = dirname(privateKeyPath)
|
|
95
|
+
existsSync(privateKeyDir) || mkdirSync(privateKeyDir, { recursive: true })
|
|
96
|
+
const certDir = dirname(certPath)
|
|
97
|
+
existsSync(certDir) || mkdirSync(certDir, { recursive: true })
|
|
98
|
+
|
|
99
|
+
const { cert, private: privateKey } = generate(${JSON.stringify(subject)}, {
|
|
100
|
+
keySize: ${keyLength}, algorithm: 'sha256', days: ${days},
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
writeFileSync(privateKeyPath, privateKey.replace(/\\r\\n?/g, '\\n'))
|
|
104
|
+
writeFileSync(certPath, cert.replace(/\\r\\n?/g, '\\n'))
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.error(e)
|
|
107
|
+
process.exit(-1)
|
|
108
|
+
} finally {
|
|
109
|
+
process.exit(0)
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
const fileName = "key-gen.js";
|
|
113
|
+
writeFileSync(`./${fileName}`, starter);
|
|
114
|
+
try {
|
|
115
|
+
execSync(`npx electron ${fileName}`, { stdio: "inherit" });
|
|
116
|
+
} finally {
|
|
117
|
+
rmSync(`./${fileName}`);
|
|
118
|
+
}
|
|
95
119
|
}
|
|
96
120
|
function writeCertToMain(entryPath, cert) {
|
|
97
121
|
const file = readFileSync(entryPath, "utf-8");
|
|
@@ -124,29 +148,29 @@ function parseKeys({
|
|
|
124
148
|
certPath,
|
|
125
149
|
entryPath,
|
|
126
150
|
subject,
|
|
127
|
-
|
|
128
|
-
generateKeyPair
|
|
151
|
+
days
|
|
129
152
|
}) {
|
|
130
153
|
const keysDir = dirname(privateKeyPath);
|
|
131
154
|
!existsSync(keysDir) && mkdirSync(keysDir);
|
|
132
|
-
let privateKey, cert;
|
|
133
155
|
if (!existsSync(privateKeyPath) || !existsSync(certPath)) {
|
|
134
|
-
|
|
135
|
-
const keys = _func(keyLength, subject, expires);
|
|
136
|
-
privateKey = keys.privateKey;
|
|
137
|
-
cert = keys.cert;
|
|
138
|
-
writeFileSync(privateKeyPath, privateKey);
|
|
139
|
-
writeFileSync(certPath, cert);
|
|
140
|
-
} else {
|
|
141
|
-
privateKey = readFileSync(privateKeyPath, "utf-8");
|
|
142
|
-
cert = readFileSync(certPath, "utf-8");
|
|
156
|
+
generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
|
|
143
157
|
}
|
|
158
|
+
const privateKey = readFileSync(privateKeyPath, "utf-8");
|
|
159
|
+
const cert = readFileSync(certPath, "utf-8");
|
|
144
160
|
writeCertToMain(entryPath, cert);
|
|
145
161
|
return {
|
|
146
162
|
privateKey,
|
|
147
163
|
cert
|
|
148
164
|
};
|
|
149
165
|
}
|
|
166
|
+
function parseSubjects(subject) {
|
|
167
|
+
const ret = [];
|
|
168
|
+
Object.keys(subject).forEach((name) => {
|
|
169
|
+
const value = subject[name];
|
|
170
|
+
value && ret.push({ name, value });
|
|
171
|
+
});
|
|
172
|
+
return ret;
|
|
173
|
+
}
|
|
150
174
|
|
|
151
175
|
// src/build-plugins/option.ts
|
|
152
176
|
function parseOptions(options) {
|
|
@@ -172,16 +196,13 @@ function parseOptions(options) {
|
|
|
172
196
|
overrideFunctions = {}
|
|
173
197
|
} = {}
|
|
174
198
|
} = options;
|
|
175
|
-
const {
|
|
176
|
-
generateKeyPair,
|
|
177
|
-
generateSignature
|
|
178
|
-
} = overrideFunctions;
|
|
199
|
+
const { generateSignature } = overrideFunctions;
|
|
179
200
|
let {
|
|
180
201
|
subject = {
|
|
181
202
|
commonName: productName,
|
|
182
|
-
|
|
203
|
+
organizationName: `org.${productName}`
|
|
183
204
|
},
|
|
184
|
-
|
|
205
|
+
days = 365
|
|
185
206
|
} = certInfo;
|
|
186
207
|
const buildAsarOption = {
|
|
187
208
|
version,
|
|
@@ -197,17 +218,13 @@ function parseOptions(options) {
|
|
|
197
218
|
};
|
|
198
219
|
let buildVersionOption;
|
|
199
220
|
if (!isCI) {
|
|
200
|
-
if (typeof expires === "number") {
|
|
201
|
-
expires = new Date(Date.now() + expires);
|
|
202
|
-
}
|
|
203
221
|
const { privateKey, cert } = parseKeys({
|
|
204
222
|
keyLength,
|
|
205
223
|
privateKeyPath,
|
|
206
224
|
certPath,
|
|
207
225
|
entryPath,
|
|
208
226
|
subject,
|
|
209
|
-
|
|
210
|
-
generateKeyPair
|
|
227
|
+
days
|
|
211
228
|
});
|
|
212
229
|
buildVersionOption = {
|
|
213
230
|
version,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electron-incremental-update",
|
|
3
3
|
"author": "subframe7536",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.4",
|
|
5
5
|
"description": "electron incremental update tools, powered by vite",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "tsup && node fix-module.js",
|
|
@@ -56,7 +56,9 @@
|
|
|
56
56
|
"vitest": "^0.32.2"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@cyyynthia/jscert": "^0.1.2",
|
|
60
59
|
"ci-info": "^3.8.0"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"selfsigned": "^2.1.1"
|
|
61
63
|
}
|
|
62
64
|
}
|