electron-incremental-update 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,25 +1,37 @@
1
1
  ## electron incremental updater
2
2
 
3
- inspired by Obsidian's update strategy, using RSA + Signature to sign the update asar and replace the old one when verified
3
+ provider a vite plugin and useful functions to generate updater and split entry file and real app
4
+
5
+ ### principle
6
+
7
+ using two asar, `app.asar` and `main.asar` (if "main" is your app's name)
8
+
9
+ the `app.asar` is used to load `main.asar` and initialize the updater
10
+
11
+ using RSA + Signature to sign the new `main.asar` downloaded from remote and replace the old one when verified
12
+
13
+ - inspired by Obsidian's update strategy
14
+
15
+ ### notice
4
16
 
5
17
  develop with [vite-plugin-electron](https://github.com/electron-vite/vite-plugin-electron), and may be effect in other electron vite frameworks
6
18
 
7
- ### install
19
+ ## install
8
20
 
9
- #### npm
21
+ ### npm
10
22
  ```bash
11
23
  npm install electron-incremental-update
12
24
  ```
13
- #### yarn
25
+ ### yarn
14
26
  ```bash
15
27
  yarn add electron-incremental-update
16
28
  ```
17
- #### pnpm
29
+ ### pnpm
18
30
  ```bash
19
31
  pnpm add electron-incremental-update
20
32
  ```
21
33
 
22
- ### usage
34
+ ## usage
23
35
 
24
36
  base on [electron-vite-vue](https://github.com/electron-vite/electron-vite-vue)
25
37
 
@@ -36,7 +48,7 @@ src
36
48
  └── ...
37
49
  ```
38
50
 
39
- #### setup app
51
+ ### setup app
40
52
 
41
53
  ```ts
42
54
  // electron/app.ts
@@ -47,13 +59,13 @@ const SIGNATURE_PUB = '' // auto generate RSA public key when start app
47
59
 
48
60
  const updater = createUpdater({
49
61
  SIGNATURE_PUB,
50
- githubRepository: repository,
62
+ repository,
51
63
  productName: name,
52
64
  })
53
65
  initApp(name, updater)
54
66
  ```
55
67
 
56
- #### setup main
68
+ ### setup main
57
69
 
58
70
  ```ts
59
71
  // electron/main/index.ts
@@ -103,7 +115,7 @@ export default function (updater: Updater) {
103
115
  }
104
116
  ```
105
117
 
106
- #### use native modules
118
+ ### use native modules
107
119
 
108
120
  ```ts
109
121
  // db.ts
@@ -128,7 +140,7 @@ console.log(r)
128
140
  db.close()
129
141
  ```
130
142
 
131
- #### setup vite.config.ts
143
+ ### setup vite.config.ts
132
144
 
133
145
  ```ts
134
146
  import { rmSync } from 'node:fs'
@@ -189,7 +201,7 @@ export default defineConfig(({ command }) => {
189
201
  })
190
202
  ```
191
203
 
192
- ##### option
204
+ #### option
193
205
 
194
206
  ```ts
195
207
  type Options = {
@@ -213,6 +225,9 @@ type Options = {
213
225
  * Whether to minify
214
226
  */
215
227
  minify?: boolean
228
+ /**
229
+ * path config
230
+ */
216
231
  paths?: {
217
232
  /**
218
233
  * Path to app entry file
@@ -225,7 +240,7 @@ type Options = {
225
240
  */
226
241
  entryOutputPath?: string
227
242
  /**
228
- * Path to app entry file
243
+ * Path to asar file
229
244
  * @default `release/${ProductName}.asar`
230
245
  */
231
246
  asarOutputPath?: string
@@ -239,7 +254,15 @@ type Options = {
239
254
  * @default `dist`
240
255
  */
241
256
  rendererDistPath?: string
257
+ /**
258
+ * Path to version info output
259
+ * @default `version.json`
260
+ */
261
+ versionPath?: string
242
262
  }
263
+ /**
264
+ * signature config
265
+ */
243
266
  keys?: {
244
267
  /**
245
268
  * Path to the pem file that contains private key
@@ -262,7 +285,7 @@ type Options = {
262
285
  }
263
286
  ```
264
287
 
265
- #### electron-builder config
288
+ ### electron-builder config
266
289
 
267
290
  ```js
268
291
  const { name } = require('./package.json')
package/dist/index.cjs CHANGED
@@ -89,49 +89,68 @@ var import_node_fs2 = require("fs");
89
89
  var import_promises = require("fs/promises");
90
90
  var import_node_https = __toESM(require("https"), 1);
91
91
  var import_electron2 = require("electron");
92
+ function downloadJSONDefault(url, updater, headers) {
93
+ return new Promise((resolve2, reject) => {
94
+ import_node_https.default.get(url, (res) => {
95
+ let data = "";
96
+ res.setEncoding("utf8");
97
+ res.headers = headers;
98
+ res.on("data", (chunk) => data += chunk);
99
+ res.on("end", () => {
100
+ updater.emit("downloadEnd", true);
101
+ const json = JSON.parse(data);
102
+ if ("signature" in json && "version" in json && "size" in json) {
103
+ resolve2(json);
104
+ } else {
105
+ throw new Error("invalid update json");
106
+ }
107
+ });
108
+ }).on("error", (e) => {
109
+ e && updater.emit("donwnloadError", e);
110
+ updater.emit("downloadEnd", false);
111
+ reject(e);
112
+ });
113
+ });
114
+ }
115
+ function downloadBufferDefault(url, updater, headers) {
116
+ return new Promise((resolve2, reject) => {
117
+ import_node_https.default.get(url, (res) => {
118
+ let data = [];
119
+ res.headers = headers;
120
+ res.on("data", (chunk) => {
121
+ updater.emit("downloading", chunk.length);
122
+ data.push(chunk);
123
+ });
124
+ res.on("end", () => {
125
+ updater.emit("downloadEnd", true);
126
+ resolve2(import_node_buffer.Buffer.concat(data));
127
+ });
128
+ }).on("error", (e) => {
129
+ e && updater.emit("donwnloadError", e);
130
+ updater.emit("downloadEnd", false);
131
+ reject(e);
132
+ });
133
+ });
134
+ }
92
135
  function createUpdater({
93
136
  SIGNATURE_PUB,
94
- githubRepository,
137
+ repository,
95
138
  productName,
96
- releaseCdnPrefix: _release,
97
- updateJsonURL: _update
139
+ releaseAsarURL: _release,
140
+ updateJsonURL: _update,
141
+ downloadConfig
98
142
  }) {
99
143
  const updater = new import_node_events.EventEmitter();
144
+ const { downloadBuffer, downloadJSON, extraHeader, userAgent } = downloadConfig || {};
100
145
  async function download(url, format) {
101
- const ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
102
- return await new Promise((resolve2, reject) => {
103
- import_node_https.default.get(url, (res) => {
104
- if (format === "json") {
105
- let data = "";
106
- res.setEncoding("utf8");
107
- res.headers = {
108
- Accept: "application/json",
109
- UserAgent: ua
110
- };
111
- res.on("data", (chunk) => data += chunk);
112
- res.on("end", () => {
113
- resolve2(JSON.parse(data));
114
- });
115
- } else if (format === "buffer") {
116
- let data = [];
117
- res.headers = {
118
- Accept: "application/octet-stream",
119
- UserAgent: ua
120
- };
121
- res.on("data", (chunk) => {
122
- updater.emit("downloading", chunk.length);
123
- data.push(chunk);
124
- });
125
- res.on("end", () => {
126
- updater.emit("downloadEnd", true);
127
- resolve2(import_node_buffer.Buffer.concat(data));
128
- });
129
- }
130
- }).on("error", (e) => {
131
- e && updater.emit("donwnloadError", e);
132
- reject(e);
133
- });
134
- });
146
+ const ua = userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
147
+ const headers = {
148
+ Accept: `application/${format === "json" ? "json" : "octet-stream"}`,
149
+ UserAgent: ua,
150
+ ...extraHeader
151
+ };
152
+ const downloadFn = format === "json" ? downloadJSON ?? downloadJSONDefault : downloadBuffer ?? downloadBufferDefault;
153
+ return await downloadFn(url, updater, headers);
135
154
  }
136
155
  async function extractFile(gzipFilePath) {
137
156
  if (!gzipFilePath.endsWith(".asar.gz") || !(0, import_node_fs2.existsSync)(gzipFilePath)) {
@@ -164,17 +183,21 @@ function createUpdater({
164
183
  return import_electron2.app.isPackaged && parseVersion(import_electron2.app.getVersion()) < parseVersion(version);
165
184
  }
166
185
  async function checkUpdate(option) {
167
- const { releaseCdnPrefix, updateJsonURL } = option || {};
186
+ let {
187
+ updateJsonURL = _update,
188
+ releaseAsarURL = _release
189
+ } = option || {};
190
+ if ((!updateJsonURL || !releaseAsarURL) && !repository) {
191
+ throw new Error("updateJsonURL or releaseAsarURL are not set");
192
+ }
193
+ updateJsonURL ??= `${repository}/version.json`;
194
+ releaseAsarURL ??= `${repository}/releases/download/latest/${productName}.asar.gz`;
168
195
  const gzipPath = `../${productName}.asar.gz`;
169
196
  const tmpFile = gzipPath.replace(".asar.gz", ".tmp.gz");
170
- const base = githubRepository.replace("https://github.com", "");
171
- const updateJSONUrl = updateJsonURL ?? _update ?? `https://cdn.jsdelivr.net/gh/${base}/version.json`;
172
- const prefix = releaseCdnPrefix ?? _release;
173
- const downloadUrl = `${prefix ? `${prefix}/${base}` : githubRepository}/releases/download/latest/${productName}.asar.gz`;
174
197
  if ((0, import_node_fs2.existsSync)(tmpFile)) {
175
198
  await (0, import_promises.rm)(tmpFile);
176
199
  }
177
- const json = await download(updateJSONUrl, "json");
200
+ const json = await download(updateJsonURL, "json");
178
201
  if (!json) {
179
202
  throw new Error("fetch update json failed");
180
203
  }
@@ -183,12 +206,11 @@ function createUpdater({
183
206
  version,
184
207
  size
185
208
  } = json;
186
- console.log(version, size, signature);
187
209
  if (!needUpdate(version)) {
188
210
  return "unavailable";
189
211
  }
190
212
  updater.emit("downloadStart", size);
191
- const buffer = await download(downloadUrl, "buffer");
213
+ const buffer = await download(releaseAsarURL, "buffer");
192
214
  if (!verify(buffer, signature)) {
193
215
  throw new Error("file broken, invalid signature!");
194
216
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Buffer } from 'node:buffer';
2
+
1
3
  type CheckResultType = 'success' | 'fail' | 'unavailable';
2
4
  type UpdateEvents = {
3
5
  check: null;
@@ -7,10 +9,25 @@ type UpdateEvents = {
7
9
  downloadEnd: [success: boolean];
8
10
  donwnloadError: [error: unknown];
9
11
  };
12
+ type UpdateJSON = {
13
+ signature: string;
14
+ version: string;
15
+ size: number;
16
+ };
10
17
  type MaybeArray<T> = T extends undefined | null | never ? [] : T extends any[] ? T['length'] extends 1 ? [data: T[0]] : T : [data: T];
11
- interface CheckUpdateOption {
18
+ interface UpdateOption {
19
+ /**
20
+ * URL of version info json
21
+ * @default `${repository}/version.json`
22
+ * @throws if `updateJsonURL` and `repository` are all not set
23
+ */
12
24
  updateJsonURL?: string;
13
- releaseCdnPrefix?: string;
25
+ /**
26
+ * URL of release asar.gz
27
+ * @default `${repository}/releases/download/latest/${productName}.asar.gz`
28
+ * @throws if `releaseAsarURL` and `repository` are all not set
29
+ */
30
+ releaseAsarURL?: string;
14
31
  }
15
32
  interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event extends Exclude<keyof T, number> = Exclude<keyof T, number>> {
16
33
  removeAllListeners<E extends Event>(event?: E): this;
@@ -20,15 +37,70 @@ interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event
20
37
  once<E extends Event>(eventName: E, listener: (...args: MaybeArray<T[E]>) => void): this;
21
38
  emit<E extends Event>(eventName: E, ...args: MaybeArray<T[E]>): boolean;
22
39
  off<E extends Event>(eventName: E, listener: (...args: MaybeArray<T[E]>) => void): this;
23
- checkUpdate(options?: CheckUpdateOption): Promise<void>;
40
+ checkUpdate(options?: UpdateOption): Promise<void>;
24
41
  }
25
42
  type Updater = TypedUpdater<UpdateEvents>;
26
- interface Options extends CheckUpdateOption {
43
+ interface Options extends UpdateOption {
44
+ /**
45
+ * public key of signature
46
+ *
47
+ * it will be auto generated by plugin
48
+ * @example
49
+ * ```ts
50
+ * // auto filled by plugin
51
+ * const SIGNATURE_PUB = ''
52
+ *
53
+ * const updater = createUpdater({
54
+ * SIGNATURE_PUB,
55
+ * ...
56
+ * })
57
+ * ```
58
+ */
27
59
  SIGNATURE_PUB: string;
60
+ /**
61
+ * product name
62
+ *
63
+ * you can use the `name` in `package.json`
64
+ */
28
65
  productName: string;
29
- githubRepository: string;
66
+ /**
67
+ * repository url, e.g. `https://github.com/electron/electron`
68
+ *
69
+ * you can use the `repository` in `package.json`
70
+ *
71
+ * if `updateJsonURL` or `releaseAsarURL` are absent,
72
+ * `repository` will be used to determine the url
73
+ */
74
+ repository?: string;
75
+ downloadConfig?: {
76
+ /**
77
+ * download user agent
78
+ * @default 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
79
+ */
80
+ userAgent?: string;
81
+ /**
82
+ * extra download header, `accept` and `user-agent` is set by default
83
+ */
84
+ extraHeader?: Record<string, string>;
85
+ /**
86
+ * download JSON function
87
+ * @param url download url
88
+ * @param updater updater, emit events
89
+ * @param header download header
90
+ * @returns `UpdateJSON`
91
+ */
92
+ downloadJSON?: (url: string, updater: Updater, headers: Record<string, any>) => Promise<UpdateJSON>;
93
+ /**
94
+ * download buffer function
95
+ * @param url download url
96
+ * @param updater updater, emit events
97
+ * @param header download header
98
+ * @returns `Buffer`
99
+ */
100
+ downloadBuffer?: (url: string, updater: Updater, headers: Record<string, any>) => Promise<Buffer>;
101
+ };
30
102
  }
31
- declare function createUpdater({ SIGNATURE_PUB, githubRepository, productName, releaseCdnPrefix: _release, updateJsonURL: _update, }: Options): Updater;
103
+ declare function createUpdater({ SIGNATURE_PUB, repository, productName, releaseAsarURL: _release, updateJsonURL: _update, downloadConfig, }: Options): Updater;
32
104
 
33
105
  declare function getAppAsarPath(name: string): string;
34
106
  declare function getElectronVersion(): string;
package/dist/index.mjs CHANGED
@@ -53,49 +53,68 @@ import { createReadStream, createWriteStream, existsSync } from "node:fs";
53
53
  import { rm, writeFile } from "node:fs/promises";
54
54
  import https from "node:https";
55
55
  import { app as app2 } from "electron";
56
+ function downloadJSONDefault(url, updater, headers) {
57
+ return new Promise((resolve2, reject) => {
58
+ https.get(url, (res) => {
59
+ let data = "";
60
+ res.setEncoding("utf8");
61
+ res.headers = headers;
62
+ res.on("data", (chunk) => data += chunk);
63
+ res.on("end", () => {
64
+ updater.emit("downloadEnd", true);
65
+ const json = JSON.parse(data);
66
+ if ("signature" in json && "version" in json && "size" in json) {
67
+ resolve2(json);
68
+ } else {
69
+ throw new Error("invalid update json");
70
+ }
71
+ });
72
+ }).on("error", (e) => {
73
+ e && updater.emit("donwnloadError", e);
74
+ updater.emit("downloadEnd", false);
75
+ reject(e);
76
+ });
77
+ });
78
+ }
79
+ function downloadBufferDefault(url, updater, headers) {
80
+ return new Promise((resolve2, reject) => {
81
+ https.get(url, (res) => {
82
+ let data = [];
83
+ res.headers = headers;
84
+ res.on("data", (chunk) => {
85
+ updater.emit("downloading", chunk.length);
86
+ data.push(chunk);
87
+ });
88
+ res.on("end", () => {
89
+ updater.emit("downloadEnd", true);
90
+ resolve2(Buffer.concat(data));
91
+ });
92
+ }).on("error", (e) => {
93
+ e && updater.emit("donwnloadError", e);
94
+ updater.emit("downloadEnd", false);
95
+ reject(e);
96
+ });
97
+ });
98
+ }
56
99
  function createUpdater({
57
100
  SIGNATURE_PUB,
58
- githubRepository,
101
+ repository,
59
102
  productName,
60
- releaseCdnPrefix: _release,
61
- updateJsonURL: _update
103
+ releaseAsarURL: _release,
104
+ updateJsonURL: _update,
105
+ downloadConfig
62
106
  }) {
63
107
  const updater = new EventEmitter();
108
+ const { downloadBuffer, downloadJSON, extraHeader, userAgent } = downloadConfig || {};
64
109
  async function download(url, format) {
65
- const ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
66
- return await new Promise((resolve2, reject) => {
67
- https.get(url, (res) => {
68
- if (format === "json") {
69
- let data = "";
70
- res.setEncoding("utf8");
71
- res.headers = {
72
- Accept: "application/json",
73
- UserAgent: ua
74
- };
75
- res.on("data", (chunk) => data += chunk);
76
- res.on("end", () => {
77
- resolve2(JSON.parse(data));
78
- });
79
- } else if (format === "buffer") {
80
- let data = [];
81
- res.headers = {
82
- Accept: "application/octet-stream",
83
- UserAgent: ua
84
- };
85
- res.on("data", (chunk) => {
86
- updater.emit("downloading", chunk.length);
87
- data.push(chunk);
88
- });
89
- res.on("end", () => {
90
- updater.emit("downloadEnd", true);
91
- resolve2(Buffer.concat(data));
92
- });
93
- }
94
- }).on("error", (e) => {
95
- e && updater.emit("donwnloadError", e);
96
- reject(e);
97
- });
98
- });
110
+ const ua = userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
111
+ const headers = {
112
+ Accept: `application/${format === "json" ? "json" : "octet-stream"}`,
113
+ UserAgent: ua,
114
+ ...extraHeader
115
+ };
116
+ const downloadFn = format === "json" ? downloadJSON ?? downloadJSONDefault : downloadBuffer ?? downloadBufferDefault;
117
+ return await downloadFn(url, updater, headers);
99
118
  }
100
119
  async function extractFile(gzipFilePath) {
101
120
  if (!gzipFilePath.endsWith(".asar.gz") || !existsSync(gzipFilePath)) {
@@ -128,17 +147,21 @@ function createUpdater({
128
147
  return app2.isPackaged && parseVersion(app2.getVersion()) < parseVersion(version);
129
148
  }
130
149
  async function checkUpdate(option) {
131
- const { releaseCdnPrefix, updateJsonURL } = option || {};
150
+ let {
151
+ updateJsonURL = _update,
152
+ releaseAsarURL = _release
153
+ } = option || {};
154
+ if ((!updateJsonURL || !releaseAsarURL) && !repository) {
155
+ throw new Error("updateJsonURL or releaseAsarURL are not set");
156
+ }
157
+ updateJsonURL ??= `${repository}/version.json`;
158
+ releaseAsarURL ??= `${repository}/releases/download/latest/${productName}.asar.gz`;
132
159
  const gzipPath = `../${productName}.asar.gz`;
133
160
  const tmpFile = gzipPath.replace(".asar.gz", ".tmp.gz");
134
- const base = githubRepository.replace("https://github.com", "");
135
- const updateJSONUrl = updateJsonURL ?? _update ?? `https://cdn.jsdelivr.net/gh/${base}/version.json`;
136
- const prefix = releaseCdnPrefix ?? _release;
137
- const downloadUrl = `${prefix ? `${prefix}/${base}` : githubRepository}/releases/download/latest/${productName}.asar.gz`;
138
161
  if (existsSync(tmpFile)) {
139
162
  await rm(tmpFile);
140
163
  }
141
- const json = await download(updateJSONUrl, "json");
164
+ const json = await download(updateJsonURL, "json");
142
165
  if (!json) {
143
166
  throw new Error("fetch update json failed");
144
167
  }
@@ -147,12 +170,11 @@ function createUpdater({
147
170
  version,
148
171
  size
149
172
  } = json;
150
- console.log(version, size, signature);
151
173
  if (!needUpdate(version)) {
152
174
  return "unavailable";
153
175
  }
154
176
  updater.emit("downloadStart", size);
155
- const buffer = await download(downloadUrl, "buffer");
177
+ const buffer = await download(releaseAsarURL, "buffer");
156
178
  if (!verify(buffer, signature)) {
157
179
  throw new Error("file broken, invalid signature!");
158
180
  }
package/dist/vite.cjs CHANGED
@@ -140,7 +140,8 @@ async function buildAsar({
140
140
  asarOutputPath,
141
141
  privateKeyPath,
142
142
  electronDistPath,
143
- rendererDistPath
143
+ rendererDistPath,
144
+ versionPath
144
145
  }) {
145
146
  await (0, import_promises2.rename)(rendererDistPath, `${electronDistPath}/renderer`);
146
147
  await (0, import_promises2.writeFile)(`${electronDistPath}/version`, version);
@@ -151,7 +152,7 @@ async function buildAsar({
151
152
  await gzipFile(asarOutputPath);
152
153
  const buffer = await (0, import_promises2.readFile)(`${asarOutputPath}.gz`);
153
154
  const signature = generateSignature(buffer, await (0, import_promises2.readFile)(privateKeyPath, "utf-8"));
154
- await (0, import_promises2.writeFile)("version.json", JSON.stringify({
155
+ await (0, import_promises2.writeFile)(versionPath, JSON.stringify({
155
156
  signature,
156
157
  version,
157
158
  size: buffer.length
@@ -166,7 +167,8 @@ function parseOptions(options) {
166
167
  entryOutputPath = "app.js",
167
168
  asarOutputPath = `release/${productName}.asar`,
168
169
  electronDistPath = "dist-electron",
169
- rendererDistPath = "dist"
170
+ rendererDistPath = "dist",
171
+ versionPath = "version.json"
170
172
  } = paths;
171
173
  const {
172
174
  privateKeyPath = "public/private.pem",
@@ -175,11 +177,11 @@ function parseOptions(options) {
175
177
  } = keys;
176
178
  const buildAsarOption = {
177
179
  version,
178
- productName,
179
180
  asarOutputPath,
180
181
  privateKeyPath,
181
182
  electronDistPath,
182
- rendererDistPath
183
+ rendererDistPath,
184
+ versionPath
183
185
  };
184
186
  const buildEntryOption = {
185
187
  privateKeyPath,
package/dist/vite.d.ts CHANGED
@@ -8,19 +8,22 @@ type Options = {
8
8
  /**
9
9
  * the name of you application
10
10
  *
11
- * you can set as 'name' in package.json
11
+ * you can set as 'name' in `package.json`
12
12
  */
13
13
  productName: string;
14
14
  /**
15
15
  * the version of you application
16
16
  *
17
- * you can set as 'version' in package.json
17
+ * you can set as 'version' in `package.json`
18
18
  */
19
19
  version: string;
20
20
  /**
21
- * Whether to minify
21
+ * Whether to minify entry file
22
22
  */
23
23
  minify?: boolean;
24
+ /**
25
+ * paths config
26
+ */
24
27
  paths?: {
25
28
  /**
26
29
  * Path to app entry file
@@ -33,7 +36,7 @@ type Options = {
33
36
  */
34
37
  entryOutputPath?: string;
35
38
  /**
36
- * Path to app entry file
39
+ * Path to asar file
37
40
  * @default `release/${ProductName}.asar`
38
41
  */
39
42
  asarOutputPath?: string;
@@ -47,7 +50,15 @@ type Options = {
47
50
  * @default `dist`
48
51
  */
49
52
  rendererDistPath?: string;
53
+ /**
54
+ * Path to version info output
55
+ * @default `version.json`
56
+ */
57
+ versionPath?: string;
50
58
  };
59
+ /**
60
+ * signature config
61
+ */
51
62
  keys?: {
52
63
  /**
53
64
  * Path to the pem file that contains private key
package/dist/vite.mjs CHANGED
@@ -108,7 +108,8 @@ async function buildAsar({
108
108
  asarOutputPath,
109
109
  privateKeyPath,
110
110
  electronDistPath,
111
- rendererDistPath
111
+ rendererDistPath,
112
+ versionPath
112
113
  }) {
113
114
  await rename(rendererDistPath, `${electronDistPath}/renderer`);
114
115
  await writeFile2(`${electronDistPath}/version`, version);
@@ -119,7 +120,7 @@ async function buildAsar({
119
120
  await gzipFile(asarOutputPath);
120
121
  const buffer = await readFile2(`${asarOutputPath}.gz`);
121
122
  const signature = generateSignature(buffer, await readFile2(privateKeyPath, "utf-8"));
122
- await writeFile2("version.json", JSON.stringify({
123
+ await writeFile2(versionPath, JSON.stringify({
123
124
  signature,
124
125
  version,
125
126
  size: buffer.length
@@ -134,7 +135,8 @@ function parseOptions(options) {
134
135
  entryOutputPath = "app.js",
135
136
  asarOutputPath = `release/${productName}.asar`,
136
137
  electronDistPath = "dist-electron",
137
- rendererDistPath = "dist"
138
+ rendererDistPath = "dist",
139
+ versionPath = "version.json"
138
140
  } = paths;
139
141
  const {
140
142
  privateKeyPath = "public/private.pem",
@@ -143,11 +145,11 @@ function parseOptions(options) {
143
145
  } = keys;
144
146
  const buildAsarOption = {
145
147
  version,
146
- productName,
147
148
  asarOutputPath,
148
149
  privateKeyPath,
149
150
  electronDistPath,
150
- rendererDistPath
151
+ rendererDistPath,
152
+ versionPath
151
153
  };
152
154
  const buildEntryOption = {
153
155
  privateKeyPath,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "electron incremental update tools, powered by vite",
5
5
  "scripts": {
6
6
  "build": "tsup",