electron-incremental-update 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.cjs CHANGED
@@ -36,11 +36,44 @@ module.exports = __toCommonJS(vite_exports);
36
36
  var import_vite = require("vite");
37
37
 
38
38
  // src/build-plugins/asar.ts
39
- var import_node_crypto = require("crypto");
40
39
  var import_node_fs = require("fs");
41
40
  var import_promises = require("fs/promises");
42
41
  var import_node_zlib = __toESM(require("zlib"), 1);
43
- var import_ci_info = require("ci-info");
42
+
43
+ // src/crypto.ts
44
+ var import_node_crypto = require("crypto");
45
+ var import_node_buffer = require("buffer");
46
+ var aesEncode = "base64url";
47
+ function generateRSA(length = 2048) {
48
+ const pair = (0, import_node_crypto.generateKeyPairSync)("rsa", { modulusLength: length });
49
+ const privateKey = pair.privateKey.export({ type: "pkcs1", format: "pem" });
50
+ const publicKey = pair.publicKey.export({ type: "pkcs1", format: "pem" });
51
+ return {
52
+ privateKey,
53
+ publicKey
54
+ };
55
+ }
56
+ function encrypt(plainText, key, iv) {
57
+ const cipher = (0, import_node_crypto.createCipheriv)("aes-256-cbc", key, iv);
58
+ let encrypted = cipher.update(plainText, "utf8", aesEncode);
59
+ encrypted += cipher.final(aesEncode);
60
+ return encrypted;
61
+ }
62
+ function generateKey(buffer, str, length) {
63
+ str += (0, import_node_crypto.createHash)("md5").update(buffer.map((v, i) => i & length / 4 && v)).digest("hex");
64
+ const hash = (0, import_node_crypto.createHash)("SHA256").update(str).digest("binary");
65
+ return import_node_buffer.Buffer.from(hash).subarray(0, length);
66
+ }
67
+ function signature(buffer, privateKey, publicKey, name) {
68
+ const sig = (0, import_node_crypto.createSign)("RSA-SHA256").update(buffer).sign({
69
+ key: privateKey,
70
+ padding: import_node_crypto.constants.RSA_PKCS1_PADDING,
71
+ saltLength: import_node_crypto.constants.RSA_PSS_SALTLEN_DIGEST
72
+ }, "base64");
73
+ return encrypt(sig, generateKey(buffer, publicKey, 32), generateKey(buffer, name, 16));
74
+ }
75
+
76
+ // src/build-plugins/asar.ts
44
77
  function gzipFile(filePath) {
45
78
  return new Promise((resolve, reject) => {
46
79
  const gzip = import_node_zlib.default.createGzip();
@@ -49,13 +82,6 @@ function gzipFile(filePath) {
49
82
  input.pipe(gzip).pipe(output).on("finish", () => resolve(null)).on("error", (err) => reject(err));
50
83
  });
51
84
  }
52
- function generateSignature(buffer, privateKey) {
53
- return (0, import_node_crypto.createSign)("RSA-SHA256").update(buffer).sign({
54
- key: privateKey,
55
- padding: import_node_crypto.constants.RSA_PKCS1_PADDING,
56
- saltLength: import_node_crypto.constants.RSA_PSS_SALTLEN_DIGEST
57
- }, "base64");
58
- }
59
85
  async function pack(dir, target) {
60
86
  let asar = null;
61
87
  try {
@@ -76,47 +102,61 @@ async function pack(dir, target) {
76
102
  async function buildAsar({
77
103
  version,
78
104
  asarOutputPath,
79
- privateKeyPath,
80
105
  electronDistPath,
81
- rendererDistPath,
82
- versionPath
106
+ rendererDistPath
83
107
  }) {
84
108
  await (0, import_promises.rename)(rendererDistPath, `${electronDistPath}/renderer`);
85
109
  await (0, import_promises.writeFile)(`${electronDistPath}/version`, version);
86
110
  await pack(electronDistPath, asarOutputPath);
87
111
  await gzipFile(asarOutputPath);
88
- if (import_ci_info.isCI) {
89
- return;
90
- }
112
+ }
113
+ async function generateVersion({
114
+ asarOutputPath,
115
+ versionPath,
116
+ privateKey,
117
+ publicKey,
118
+ productName,
119
+ version
120
+ }) {
91
121
  const buffer = await (0, import_promises.readFile)(`${asarOutputPath}.gz`);
92
- const signature = generateSignature(buffer, await (0, import_promises.readFile)(privateKeyPath, "utf-8"));
93
122
  await (0, import_promises.writeFile)(versionPath, JSON.stringify({
94
- signature,
123
+ signature: signature(buffer, privateKey, publicKey, productName),
95
124
  version,
96
125
  size: buffer.length
97
126
  }, null, 2));
98
127
  }
99
128
 
100
129
  // src/build-plugins/entry.ts
130
+ var import_esbuild = require("esbuild");
131
+ async function buildEntry({
132
+ entryPath,
133
+ entryOutputPath: outfile,
134
+ minify
135
+ }) {
136
+ await (0, import_esbuild.build)({
137
+ entryPoints: [entryPath],
138
+ bundle: true,
139
+ platform: "node",
140
+ outfile,
141
+ minify,
142
+ external: ["electron"]
143
+ });
144
+ }
145
+
146
+ // src/build-plugins/key.ts
101
147
  var import_node_fs2 = require("fs");
102
148
  var import_node_path = require("path");
103
- var import_promises2 = require("fs/promises");
104
- var import_node_crypto2 = require("crypto");
105
149
  var import_node_os = require("os");
106
- var import_ci_info2 = require("ci-info");
107
- var import_esbuild = require("esbuild");
108
- async function generateKey(privateKeyPath, publicKeyPath, length) {
109
- const pair = (0, import_node_crypto2.generateKeyPairSync)("rsa", { modulusLength: length });
110
- const privateKey = pair.privateKey.export({ type: "pkcs1", format: "pem" });
111
- const publicKey = pair.publicKey.export({ type: "pkcs1", format: "pem" });
112
- await (0, import_promises2.writeFile)(privateKeyPath, privateKey);
113
- await (0, import_promises2.writeFile)(publicKeyPath, publicKey);
150
+ function generateKey2(privateKeyPath, publicKeyPath, length) {
151
+ const ret = generateRSA(length);
152
+ (0, import_node_fs2.writeFileSync)(privateKeyPath, ret.privateKey);
153
+ (0, import_node_fs2.writeFileSync)(publicKeyPath, ret.publicKey);
154
+ return ret;
114
155
  }
115
- async function writePublicKeyToMain(updatePath, publicKeyPath) {
116
- const file = await (0, import_promises2.readFile)(updatePath, "utf-8");
117
- const key = await (0, import_promises2.readFile)(publicKeyPath, "utf-8");
156
+ function writePublicKeyToMain(entryPath, publicKey) {
157
+ const file = (0, import_node_fs2.readFileSync)(entryPath, "utf-8");
118
158
  const regex = /const SIGNATURE_PUB = ['`][\s\S]*?['`]/;
119
- const replacement = `const SIGNATURE_PUB = \`${key}\``;
159
+ const replacement = `const SIGNATURE_PUB = \`${publicKey}\``;
120
160
  let replaced = file;
121
161
  const signaturePubExists = regex.test(file);
122
162
  if (signaturePubExists) {
@@ -136,33 +176,34 @@ async function writePublicKeyToMain(updatePath, publicKeyPath) {
136
176
  !isMatched && lines.push(r);
137
177
  replaced = lines.join(import_node_os.EOL);
138
178
  }
139
- await (0, import_promises2.writeFile)(updatePath, replaced);
179
+ (0, import_node_fs2.writeFileSync)(entryPath, replaced);
140
180
  }
141
- async function buildEntry({
181
+ function getKeys({
182
+ keyLength,
142
183
  privateKeyPath,
143
184
  publicKeyPath,
144
- entryPath,
145
- entryOutputPath: outfile,
146
- minify,
147
- keyLength
185
+ entryPath
148
186
  }) {
149
- if (!import_ci_info2.isCI) {
150
- const keysDir = (0, import_node_path.dirname)(privateKeyPath);
151
- !(0, import_node_fs2.existsSync)(keysDir) && await (0, import_promises2.mkdir)(keysDir);
152
- !(0, import_node_fs2.existsSync)(privateKeyPath) && await generateKey(privateKeyPath, publicKeyPath, keyLength);
153
- await writePublicKeyToMain(entryPath, publicKeyPath);
187
+ const keysDir = (0, import_node_path.dirname)(privateKeyPath);
188
+ !(0, import_node_fs2.existsSync)(keysDir) && (0, import_node_fs2.mkdirSync)(keysDir);
189
+ let privateKey, publicKey;
190
+ if (!(0, import_node_fs2.existsSync)(privateKeyPath)) {
191
+ const keys = generateKey2(privateKeyPath, publicKeyPath, keyLength);
192
+ privateKey = keys.privateKey;
193
+ publicKey = keys.publicKey;
194
+ } else {
195
+ privateKey = (0, import_node_fs2.readFileSync)(privateKeyPath, "utf-8");
196
+ publicKey = (0, import_node_fs2.readFileSync)(publicKeyPath, "utf-8");
154
197
  }
155
- await (0, import_esbuild.build)({
156
- entryPoints: [entryPath],
157
- bundle: true,
158
- platform: "node",
159
- outfile,
160
- minify,
161
- external: ["electron"]
162
- });
198
+ writePublicKeyToMain(entryPath, publicKey);
199
+ return {
200
+ privateKey,
201
+ publicKey
202
+ };
163
203
  }
164
204
 
165
205
  // src/build-plugins/option.ts
206
+ var import_ci_info = require("ci-info");
166
207
  function parseOptions(options) {
167
208
  const { isBuild, productName, version, minify = false, paths = {}, keys = {} } = options;
168
209
  const {
@@ -181,25 +222,37 @@ function parseOptions(options) {
181
222
  const buildAsarOption = {
182
223
  version,
183
224
  asarOutputPath,
184
- privateKeyPath,
185
225
  electronDistPath,
186
- rendererDistPath,
187
- versionPath
226
+ rendererDistPath
188
227
  };
189
228
  const buildEntryOption = {
190
- privateKeyPath,
191
- publicKeyPath,
192
229
  entryPath,
193
230
  entryOutputPath,
194
- minify,
195
- keyLength
231
+ minify
196
232
  };
197
- return { isBuild, buildAsarOption, buildEntryOption };
233
+ let buildVersionOption;
234
+ if (!import_ci_info.isCI) {
235
+ const { privateKey, publicKey } = getKeys({
236
+ keyLength,
237
+ privateKeyPath,
238
+ publicKeyPath,
239
+ entryPath
240
+ });
241
+ buildVersionOption = {
242
+ version,
243
+ asarOutputPath,
244
+ privateKey,
245
+ publicKey,
246
+ productName,
247
+ versionPath
248
+ };
249
+ }
250
+ return { isBuild, buildAsarOption, buildEntryOption, buildVersionOption };
198
251
  }
199
252
 
200
253
  // src/vite.ts
201
254
  function vite_default(options) {
202
- const { isBuild, buildAsarOption, buildEntryOption } = parseOptions(options);
255
+ const { isBuild, buildAsarOption, buildEntryOption, buildVersionOption } = parseOptions(options);
203
256
  const { entryPath, entryOutputPath } = buildEntryOption;
204
257
  const { asarOutputPath } = buildAsarOption;
205
258
  const id = "electron-incremental-updater";
@@ -216,6 +269,7 @@ function vite_default(options) {
216
269
  }
217
270
  log.info("build asar start");
218
271
  await buildAsar(buildAsarOption);
272
+ buildVersionOption && await generateVersion(buildVersionOption);
219
273
  log.info(`build asar end, output to ${asarOutputPath}`);
220
274
  }
221
275
  };
package/dist/vite.mjs CHANGED
@@ -1,14 +1,15 @@
1
- import "./chunk-AKU6F3WT.mjs";
1
+ import {
2
+ generateRSA,
3
+ signature
4
+ } from "./chunk-SSJ6PDMK.mjs";
2
5
 
3
6
  // src/vite.ts
4
7
  import { createLogger } from "vite";
5
8
 
6
9
  // src/build-plugins/asar.ts
7
- import { constants, createSign } from "node:crypto";
8
10
  import { createReadStream, createWriteStream } from "node:fs";
9
11
  import { readFile, rename, writeFile } from "node:fs/promises";
10
12
  import zlib from "node:zlib";
11
- import { isCI } from "ci-info";
12
13
  function gzipFile(filePath) {
13
14
  return new Promise((resolve, reject) => {
14
15
  const gzip = zlib.createGzip();
@@ -17,13 +18,6 @@ function gzipFile(filePath) {
17
18
  input.pipe(gzip).pipe(output).on("finish", () => resolve(null)).on("error", (err) => reject(err));
18
19
  });
19
20
  }
20
- function generateSignature(buffer, privateKey) {
21
- return createSign("RSA-SHA256").update(buffer).sign({
22
- key: privateKey,
23
- padding: constants.RSA_PKCS1_PADDING,
24
- saltLength: constants.RSA_PSS_SALTLEN_DIGEST
25
- }, "base64");
26
- }
27
21
  async function pack(dir, target) {
28
22
  let asar = null;
29
23
  try {
@@ -44,47 +38,61 @@ async function pack(dir, target) {
44
38
  async function buildAsar({
45
39
  version,
46
40
  asarOutputPath,
47
- privateKeyPath,
48
41
  electronDistPath,
49
- rendererDistPath,
50
- versionPath
42
+ rendererDistPath
51
43
  }) {
52
44
  await rename(rendererDistPath, `${electronDistPath}/renderer`);
53
45
  await writeFile(`${electronDistPath}/version`, version);
54
46
  await pack(electronDistPath, asarOutputPath);
55
47
  await gzipFile(asarOutputPath);
56
- if (isCI) {
57
- return;
58
- }
48
+ }
49
+ async function generateVersion({
50
+ asarOutputPath,
51
+ versionPath,
52
+ privateKey,
53
+ publicKey,
54
+ productName,
55
+ version
56
+ }) {
59
57
  const buffer = await readFile(`${asarOutputPath}.gz`);
60
- const signature = generateSignature(buffer, await readFile(privateKeyPath, "utf-8"));
61
58
  await writeFile(versionPath, JSON.stringify({
62
- signature,
59
+ signature: signature(buffer, privateKey, publicKey, productName),
63
60
  version,
64
61
  size: buffer.length
65
62
  }, null, 2));
66
63
  }
67
64
 
68
65
  // src/build-plugins/entry.ts
69
- import { existsSync } from "node:fs";
66
+ import { build } from "esbuild";
67
+ async function buildEntry({
68
+ entryPath,
69
+ entryOutputPath: outfile,
70
+ minify
71
+ }) {
72
+ await build({
73
+ entryPoints: [entryPath],
74
+ bundle: true,
75
+ platform: "node",
76
+ outfile,
77
+ minify,
78
+ external: ["electron"]
79
+ });
80
+ }
81
+
82
+ // src/build-plugins/key.ts
83
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
70
84
  import { dirname } from "node:path";
71
- import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
72
- import { generateKeyPairSync } from "node:crypto";
73
85
  import { EOL } from "node:os";
74
- import { isCI as isCI2 } from "ci-info";
75
- import { build } from "esbuild";
76
- async function generateKey(privateKeyPath, publicKeyPath, length) {
77
- const pair = generateKeyPairSync("rsa", { modulusLength: length });
78
- const privateKey = pair.privateKey.export({ type: "pkcs1", format: "pem" });
79
- const publicKey = pair.publicKey.export({ type: "pkcs1", format: "pem" });
80
- await writeFile2(privateKeyPath, privateKey);
81
- await writeFile2(publicKeyPath, publicKey);
86
+ function generateKey(privateKeyPath, publicKeyPath, length) {
87
+ const ret = generateRSA(length);
88
+ writeFileSync(privateKeyPath, ret.privateKey);
89
+ writeFileSync(publicKeyPath, ret.publicKey);
90
+ return ret;
82
91
  }
83
- async function writePublicKeyToMain(updatePath, publicKeyPath) {
84
- const file = await readFile2(updatePath, "utf-8");
85
- const key = await readFile2(publicKeyPath, "utf-8");
92
+ function writePublicKeyToMain(entryPath, publicKey) {
93
+ const file = readFileSync(entryPath, "utf-8");
86
94
  const regex = /const SIGNATURE_PUB = ['`][\s\S]*?['`]/;
87
- const replacement = `const SIGNATURE_PUB = \`${key}\``;
95
+ const replacement = `const SIGNATURE_PUB = \`${publicKey}\``;
88
96
  let replaced = file;
89
97
  const signaturePubExists = regex.test(file);
90
98
  if (signaturePubExists) {
@@ -104,33 +112,34 @@ async function writePublicKeyToMain(updatePath, publicKeyPath) {
104
112
  !isMatched && lines.push(r);
105
113
  replaced = lines.join(EOL);
106
114
  }
107
- await writeFile2(updatePath, replaced);
115
+ writeFileSync(entryPath, replaced);
108
116
  }
109
- async function buildEntry({
117
+ function getKeys({
118
+ keyLength,
110
119
  privateKeyPath,
111
120
  publicKeyPath,
112
- entryPath,
113
- entryOutputPath: outfile,
114
- minify,
115
- keyLength
121
+ entryPath
116
122
  }) {
117
- if (!isCI2) {
118
- const keysDir = dirname(privateKeyPath);
119
- !existsSync(keysDir) && await mkdir(keysDir);
120
- !existsSync(privateKeyPath) && await generateKey(privateKeyPath, publicKeyPath, keyLength);
121
- await writePublicKeyToMain(entryPath, publicKeyPath);
123
+ const keysDir = dirname(privateKeyPath);
124
+ !existsSync(keysDir) && mkdirSync(keysDir);
125
+ let privateKey, publicKey;
126
+ if (!existsSync(privateKeyPath)) {
127
+ const keys = generateKey(privateKeyPath, publicKeyPath, keyLength);
128
+ privateKey = keys.privateKey;
129
+ publicKey = keys.publicKey;
130
+ } else {
131
+ privateKey = readFileSync(privateKeyPath, "utf-8");
132
+ publicKey = readFileSync(publicKeyPath, "utf-8");
122
133
  }
123
- await build({
124
- entryPoints: [entryPath],
125
- bundle: true,
126
- platform: "node",
127
- outfile,
128
- minify,
129
- external: ["electron"]
130
- });
134
+ writePublicKeyToMain(entryPath, publicKey);
135
+ return {
136
+ privateKey,
137
+ publicKey
138
+ };
131
139
  }
132
140
 
133
141
  // src/build-plugins/option.ts
142
+ import { isCI } from "ci-info";
134
143
  function parseOptions(options) {
135
144
  const { isBuild, productName, version, minify = false, paths = {}, keys = {} } = options;
136
145
  const {
@@ -149,25 +158,37 @@ function parseOptions(options) {
149
158
  const buildAsarOption = {
150
159
  version,
151
160
  asarOutputPath,
152
- privateKeyPath,
153
161
  electronDistPath,
154
- rendererDistPath,
155
- versionPath
162
+ rendererDistPath
156
163
  };
157
164
  const buildEntryOption = {
158
- privateKeyPath,
159
- publicKeyPath,
160
165
  entryPath,
161
166
  entryOutputPath,
162
- minify,
163
- keyLength
167
+ minify
164
168
  };
165
- return { isBuild, buildAsarOption, buildEntryOption };
169
+ let buildVersionOption;
170
+ if (!isCI) {
171
+ const { privateKey, publicKey } = getKeys({
172
+ keyLength,
173
+ privateKeyPath,
174
+ publicKeyPath,
175
+ entryPath
176
+ });
177
+ buildVersionOption = {
178
+ version,
179
+ asarOutputPath,
180
+ privateKey,
181
+ publicKey,
182
+ productName,
183
+ versionPath
184
+ };
185
+ }
186
+ return { isBuild, buildAsarOption, buildEntryOption, buildVersionOption };
166
187
  }
167
188
 
168
189
  // src/vite.ts
169
190
  function vite_default(options) {
170
- const { isBuild, buildAsarOption, buildEntryOption } = parseOptions(options);
191
+ const { isBuild, buildAsarOption, buildEntryOption, buildVersionOption } = parseOptions(options);
171
192
  const { entryPath, entryOutputPath } = buildEntryOption;
172
193
  const { asarOutputPath } = buildAsarOption;
173
194
  const id = "electron-incremental-updater";
@@ -184,6 +205,7 @@ function vite_default(options) {
184
205
  }
185
206
  log.info("build asar start");
186
207
  await buildAsar(buildAsarOption);
208
+ buildVersionOption && await generateVersion(buildVersionOption);
187
209
  log.info(`build asar end, output to ${asarOutputPath}`);
188
210
  }
189
211
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "electron incremental update tools, powered by vite",
5
5
  "scripts": {
6
6
  "build": "tsup",
@@ -1,11 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined")
5
- return require.apply(this, arguments);
6
- throw new Error('Dynamic require of "' + x + '" is not supported');
7
- });
8
-
9
- export {
10
- __require
11
- };