electron-incremental-update 2.0.0-beta.2 → 2.0.0-beta.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/dist/chunk-BVFQWBLK.js +76 -0
- package/dist/chunk-JSYIRKTR.js +53 -0
- package/dist/chunk-PNYRQYFC.js +77 -0
- package/dist/core-CW7TMqi7.d.cts +134 -0
- package/dist/core-D6QlpOgp.d.ts +134 -0
- package/dist/index.cjs +83 -152
- package/dist/index.d.cts +8 -133
- package/dist/index.d.ts +8 -133
- package/dist/index.js +60 -84
- package/dist/provider.cjs +85 -123
- package/dist/provider.d.cts +44 -17
- package/dist/provider.d.ts +44 -17
- package/dist/provider.js +50 -44
- package/dist/{types-CPq1MrYZ.d.ts → types-Bz1VD18z.d.cts} +39 -3
- package/dist/{types-COqp44eg.d.cts → types-Bz1VD18z.d.ts} +39 -3
- package/dist/utils.cjs +108 -174
- package/dist/utils.d.cts +10 -16
- package/dist/utils.d.ts +10 -16
- package/dist/utils.js +12 -62
- package/dist/vite.d.ts +397 -0
- package/dist/vite.js +138 -155
- package/dist/zip-WRrEMkgp.d.cts +10 -0
- package/dist/zip-WRrEMkgp.d.ts +10 -0
- package/package.json +7 -7
- package/dist/chunk-BG22XZAB.js +0 -257
- package/dist/decrypt-D9WdXYjH.d.cts +0 -4
- package/dist/decrypt-D9WdXYjH.d.ts +0 -4
- package/dist/version-CffZWDhZ.d.cts +0 -32
- package/dist/version-CffZWDhZ.d.ts +0 -32
package/dist/vite.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
1
|
+
import path2, { join, resolve, basename, dirname } from 'node:path';
|
|
2
|
+
import fs, { rmSync, renameSync, writeFileSync, readFileSync, existsSync, cpSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { createLogger, normalizePath, mergeConfig, createFilter } from 'vite';
|
|
4
|
+
import ElectronSimple from 'vite-plugin-electron/simple';
|
|
5
|
+
import { startup } from 'vite-plugin-electron';
|
|
6
|
+
import { notBundle } from 'vite-plugin-electron/plugin';
|
|
7
|
+
import { getPackageInfoSync, loadPackageJSON } from 'local-pkg';
|
|
8
|
+
import Asar from '@electron/asar';
|
|
9
|
+
import { build } from 'esbuild';
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import * as babel from '@babel/core';
|
|
12
|
+
import MagicString from 'magic-string';
|
|
13
|
+
import { brotliCompress } from 'node:zlib';
|
|
14
|
+
import { createSign, createPrivateKey, createHash, createCipheriv } from 'node:crypto';
|
|
15
|
+
import { generate } from 'selfsigned';
|
|
9
16
|
|
|
10
|
-
// src/
|
|
11
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
12
|
-
import { basename, join } from "node:path";
|
|
13
|
-
import Asar from "@electron/asar";
|
|
14
|
-
import { build } from "esbuild";
|
|
15
|
-
import { mergeConfig } from "vite";
|
|
17
|
+
// src/vite.ts
|
|
16
18
|
|
|
17
19
|
// src/utils/version.ts
|
|
18
20
|
function parseVersion(version) {
|
|
@@ -42,48 +44,21 @@ function isUpdateJSON(json) {
|
|
|
42
44
|
const is = (j) => !!(j && j.minimumVersion && j.signature && j.size && j.version);
|
|
43
45
|
return is(json) && is(json?.beta);
|
|
44
46
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
function defaultVersionJsonGenerator(existingJson, buffer, signature, version, minimumVersion) {
|
|
48
|
+
existingJson.beta = {
|
|
49
|
+
version,
|
|
50
|
+
minimumVersion,
|
|
51
|
+
signature,
|
|
52
|
+
size: buffer.length
|
|
53
|
+
};
|
|
54
|
+
if (!parseVersion(version).stage) {
|
|
55
|
+
existingJson.version = version;
|
|
56
|
+
existingJson.minimumVersion = minimumVersion;
|
|
57
|
+
existingJson.signature = signature;
|
|
58
|
+
existingJson.size = buffer.length;
|
|
52
59
|
}
|
|
53
|
-
|
|
54
|
-
return new Promise((resolve2, reject) => {
|
|
55
|
-
brotliCompress(buffer, (err, buffer2) => {
|
|
56
|
-
if (err) {
|
|
57
|
-
reject(err);
|
|
58
|
-
}
|
|
59
|
-
writeFileSync(targetFilePath, buffer2);
|
|
60
|
-
resolve2();
|
|
61
|
-
});
|
|
62
|
-
});
|
|
60
|
+
return existingJson;
|
|
63
61
|
}
|
|
64
|
-
|
|
65
|
-
// src/utils/crypto/utils.ts
|
|
66
|
-
import { createHash } from "node:crypto";
|
|
67
|
-
function hashString(data, length) {
|
|
68
|
-
const hash = createHash("SHA256").update(data).digest("binary");
|
|
69
|
-
return Buffer.from(hash).subarray(0, length);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// src/utils/crypto/encrypt.ts
|
|
73
|
-
import { createCipheriv, createPrivateKey, createSign } from "node:crypto";
|
|
74
|
-
function encrypt(plainText, key, iv) {
|
|
75
|
-
const cipher = createCipheriv("aes-256-cbc", key, iv);
|
|
76
|
-
let encrypted = cipher.update(plainText, "utf8", "base64url");
|
|
77
|
-
encrypted += cipher.final("base64url");
|
|
78
|
-
return encrypted;
|
|
79
|
-
}
|
|
80
|
-
function signature(buffer, privateKey, cert, version) {
|
|
81
|
-
const sig = createSign("RSA-SHA256").update(buffer).sign(createPrivateKey(privateKey), "base64");
|
|
82
|
-
return encrypt(`${sig}%${version}`, hashString(cert, 32), hashString(buffer, 16));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// src/build-plugins/constant.ts
|
|
86
|
-
import { createLogger } from "vite";
|
|
87
62
|
var id = "electron-incremental-updater";
|
|
88
63
|
var bytecodeId = `${id}-bytecode`;
|
|
89
64
|
var log = createLogger("info", { prefix: `[${id}]` });
|
|
@@ -92,14 +67,6 @@ var bytecodeLog = createLogger("info", { prefix: `[${bytecodeId}]` });
|
|
|
92
67
|
// src/build-plugins/bytecode/code.ts
|
|
93
68
|
var bytecodeGeneratorScript = "const vm = require('vm')\nconst v8 = require('v8')\nconst wrap = require('module').wrap\nv8.setFlagsFromString('--no-lazy')\nv8.setFlagsFromString('--no-flush-bytecode')\nlet code = ''\nprocess.stdin.setEncoding('utf-8')\nprocess.stdin.on('readable', () => {\n const data = process.stdin.read()\n if (data !== null) {\n code += data\n }\n})\nprocess.stdin.on('end', () => {\n try {\n if (typeof code !== 'string') {\n throw new Error('javascript code must be string.')\n }\n const script = new vm.Script(wrap(code), { produceCachedData: true })\n const bytecodeBuffer = script.createCachedData()\n process.stdout.write(bytecodeBuffer)\n } catch (error) {\n console.error(error)\n }\n})\n";
|
|
94
69
|
var bytecodeModuleLoaderCode = '"use strict";\nconst fs = require("fs");\nconst path = require("path");\nconst vm = require("vm");\nconst v8 = require("v8");\nconst Module = require("module");\nv8.setFlagsFromString("--no-lazy");\nv8.setFlagsFromString("--no-flush-bytecode");\nconst FLAG_HASH_OFFSET = 12;\nconst SOURCE_HASH_OFFSET = 8;\nlet dummyBytecode;\nfunction setFlagHashHeader(bytecodeBuffer) {\n if (!dummyBytecode) {\n const script = new vm.Script("", {\n produceCachedData: true\n });\n dummyBytecode = script.createCachedData();\n }\n dummyBytecode.slice(FLAG_HASH_OFFSET, FLAG_HASH_OFFSET + 4).copy(bytecodeBuffer, FLAG_HASH_OFFSET);\n};\nfunction getSourceHashHeader(bytecodeBuffer) {\n return bytecodeBuffer.slice(SOURCE_HASH_OFFSET, SOURCE_HASH_OFFSET + 4);\n};\nfunction buffer2Number(buffer) {\n let ret = 0;\n ret |= buffer[3] << 24;\n ret |= buffer[2] << 16;\n ret |= buffer[1] << 8;\n ret |= buffer[0];\n return ret;\n};\nModule._extensions[".jsc"] = Module._extensions[".cjsc"] = function (module, filename) {\n const bytecodeBuffer = fs.readFileSync(filename);\n if (!Buffer.isBuffer(bytecodeBuffer)) {\n throw new Error("BytecodeBuffer must be a buffer object.");\n }\n setFlagHashHeader(bytecodeBuffer);\n const length = buffer2Number(getSourceHashHeader(bytecodeBuffer));\n let dummyCode = "";\n if (length > 1) {\n dummyCode = "\\"" + "\\u200b".repeat(length - 2) + "\\"";\n }\n const script = new vm.Script(dummyCode, {\n filename: filename,\n lineOffset: 0,\n displayErrors: true,\n cachedData: bytecodeBuffer\n });\n if (script.cachedDataRejected) {\n throw new Error("Invalid or incompatible cached data (cachedDataRejected)");\n }\n const require = function (id) {\n return module.require(id);\n };\n require.resolve = function (request, options) {\n return Module._resolveFilename(request, module, false, options);\n };\n if (process.mainModule) {\n require.main = process.mainModule;\n }\n require.extensions = Module._extensions;\n require.cache = Module._cache;\n const compiledWrapper = script.runInThisContext({\n filename: filename,\n lineOffset: 0,\n columnOffset: 0,\n displayErrors: true\n });\n const dirname = path.dirname(filename);\n const args = [module.exports, require, module, filename, dirname, process, global];\n return compiledWrapper.apply(module.exports, args);\n};\n';
|
|
95
|
-
|
|
96
|
-
// src/build-plugins/bytecode/utils.ts
|
|
97
|
-
import path from "node:path";
|
|
98
|
-
import fs from "node:fs";
|
|
99
|
-
import { spawn } from "node:child_process";
|
|
100
|
-
import * as babel from "@babel/core";
|
|
101
|
-
import MagicString from "magic-string";
|
|
102
|
-
import { getPackageInfoSync } from "local-pkg";
|
|
103
70
|
var electronModulePath = getPackageInfoSync("electron")?.rootPath;
|
|
104
71
|
var useStrict = "'use strict';";
|
|
105
72
|
var bytecodeModuleLoader = "__loader__.js";
|
|
@@ -109,13 +76,13 @@ function getElectronPath() {
|
|
|
109
76
|
if (!electronModulePath) {
|
|
110
77
|
throw new Error("Electron is not installed");
|
|
111
78
|
}
|
|
112
|
-
const pathFile =
|
|
79
|
+
const pathFile = path2.join(electronModulePath, "path.txt");
|
|
113
80
|
let executablePath;
|
|
114
81
|
if (fs.existsSync(pathFile)) {
|
|
115
82
|
executablePath = fs.readFileSync(pathFile, "utf-8");
|
|
116
83
|
}
|
|
117
84
|
if (executablePath) {
|
|
118
|
-
electronExecPath =
|
|
85
|
+
electronExecPath = path2.join(electronModulePath, "dist", executablePath);
|
|
119
86
|
process.env.ELECTRON_EXEC_PATH = electronExecPath;
|
|
120
87
|
} else {
|
|
121
88
|
throw new Error("Electron executable file is not existed");
|
|
@@ -124,14 +91,14 @@ function getElectronPath() {
|
|
|
124
91
|
return electronExecPath;
|
|
125
92
|
}
|
|
126
93
|
function getBytecodeCompilerPath() {
|
|
127
|
-
const scriptPath =
|
|
94
|
+
const scriptPath = path2.join(electronModulePath, "bytenode.cjs");
|
|
128
95
|
if (!fs.existsSync(scriptPath)) {
|
|
129
96
|
fs.writeFileSync(scriptPath, bytecodeGeneratorScript);
|
|
130
97
|
}
|
|
131
98
|
return scriptPath;
|
|
132
99
|
}
|
|
133
100
|
function toRelativePath(filename, importer) {
|
|
134
|
-
const relPath =
|
|
101
|
+
const relPath = path2.posix.relative(path2.dirname(importer), filename);
|
|
135
102
|
return relPath.startsWith(".") ? relPath : `./${relPath}`;
|
|
136
103
|
}
|
|
137
104
|
function compileToBytecode(code) {
|
|
@@ -198,15 +165,17 @@ async function buildAsar({
|
|
|
198
165
|
asarOutputPath,
|
|
199
166
|
gzipPath,
|
|
200
167
|
electronDistPath,
|
|
201
|
-
rendererDistPath
|
|
168
|
+
rendererDistPath,
|
|
169
|
+
generateGzipFile
|
|
202
170
|
}) {
|
|
203
171
|
renameSync(rendererDistPath, join(electronDistPath, "renderer"));
|
|
204
|
-
|
|
172
|
+
writeFileSync(join(electronDistPath, "version"), version);
|
|
205
173
|
await Asar.createPackage(electronDistPath, asarOutputPath);
|
|
206
|
-
await
|
|
174
|
+
const buf = await generateGzipFile(readFileSync(asarOutputPath));
|
|
175
|
+
writeFileSync(gzipPath, buf);
|
|
176
|
+
return buf;
|
|
207
177
|
}
|
|
208
178
|
async function buildVersion({
|
|
209
|
-
gzipPath,
|
|
210
179
|
versionPath,
|
|
211
180
|
privateKey,
|
|
212
181
|
cert,
|
|
@@ -214,7 +183,7 @@ async function buildVersion({
|
|
|
214
183
|
minimumVersion,
|
|
215
184
|
generateSignature,
|
|
216
185
|
generateVersionJson
|
|
217
|
-
}) {
|
|
186
|
+
}, asarBuffer) {
|
|
218
187
|
let _json = {
|
|
219
188
|
beta: {
|
|
220
189
|
minimumVersion: version,
|
|
@@ -227,39 +196,23 @@ async function buildVersion({
|
|
|
227
196
|
size: 0,
|
|
228
197
|
version
|
|
229
198
|
};
|
|
230
|
-
if (
|
|
199
|
+
if (existsSync(versionPath)) {
|
|
231
200
|
try {
|
|
232
|
-
const oldVersionJson = JSON.parse(
|
|
201
|
+
const oldVersionJson = JSON.parse(readFileSync(versionPath, "utf-8"));
|
|
233
202
|
if (isUpdateJSON(oldVersionJson)) {
|
|
234
203
|
_json = oldVersionJson;
|
|
235
204
|
} else {
|
|
236
|
-
log.warn("old version json is invalid, ignore it");
|
|
205
|
+
log.warn("old version json is invalid, ignore it", { timestamp: true });
|
|
237
206
|
}
|
|
238
207
|
} catch {
|
|
239
208
|
}
|
|
240
209
|
}
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
if (
|
|
244
|
-
|
|
245
|
-
if (!isUpdateJSON(_json)) {
|
|
246
|
-
throw new Error("invalid version info");
|
|
247
|
-
}
|
|
248
|
-
} else {
|
|
249
|
-
_json.beta = {
|
|
250
|
-
version,
|
|
251
|
-
minimumVersion,
|
|
252
|
-
signature: sig,
|
|
253
|
-
size: buffer.length
|
|
254
|
-
};
|
|
255
|
-
if (!parseVersion(version).stage) {
|
|
256
|
-
_json.version = version;
|
|
257
|
-
_json.minimumVersion = minimumVersion;
|
|
258
|
-
_json.signature = sig;
|
|
259
|
-
_json.size = buffer.length;
|
|
260
|
-
}
|
|
210
|
+
const sig = await generateSignature(asarBuffer, privateKey, cert, version);
|
|
211
|
+
_json = await generateVersionJson(_json, asarBuffer, sig, version, minimumVersion);
|
|
212
|
+
if (!isUpdateJSON(_json)) {
|
|
213
|
+
throw new Error("invalid version info");
|
|
261
214
|
}
|
|
262
|
-
|
|
215
|
+
writeFileSync(versionPath, JSON.stringify(_json, null, 2));
|
|
263
216
|
}
|
|
264
217
|
async function buildEntry({
|
|
265
218
|
sourcemap,
|
|
@@ -297,7 +250,7 @@ async function buildEntry({
|
|
|
297
250
|
}
|
|
298
251
|
const filePaths = Object.keys(metafile?.outputs ?? []);
|
|
299
252
|
for (const filePath of filePaths) {
|
|
300
|
-
let code =
|
|
253
|
+
let code = readFileSync(filePath, "utf-8");
|
|
301
254
|
const fileName = basename(filePath);
|
|
302
255
|
const isEntry = fileName.endsWith("entry.js");
|
|
303
256
|
if (isEntry) {
|
|
@@ -311,8 +264,8 @@ async function buildEntry({
|
|
|
311
264
|
[...protectedStrings, ...isEntry ? getCert(code) : []]
|
|
312
265
|
).code;
|
|
313
266
|
const buffer = await compileToBytecode(transformedCode);
|
|
314
|
-
|
|
315
|
-
|
|
267
|
+
writeFileSync(`${filePath}c`, buffer);
|
|
268
|
+
writeFileSync(
|
|
316
269
|
filePath,
|
|
317
270
|
`${isEntry ? bytecodeModuleLoaderCode : useStrict}${isEntry ? "" : "module.exports = "}require("./${fileName}c")`
|
|
318
271
|
);
|
|
@@ -327,18 +280,36 @@ function getCert(code) {
|
|
|
327
280
|
const cert = code.match(/-----BEGIN CERTIFICATE-----[\s\S]*-----END CERTIFICATE-----\\n/)?.[0];
|
|
328
281
|
return cert ? [cert] : [];
|
|
329
282
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
283
|
+
async function defaultZipFile(buffer) {
|
|
284
|
+
return new Promise((resolve2, reject) => {
|
|
285
|
+
brotliCompress(buffer, (err, buffer2) => {
|
|
286
|
+
if (err) {
|
|
287
|
+
reject(err);
|
|
288
|
+
} else {
|
|
289
|
+
resolve2(buffer2);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
function hashBuffer(data, length) {
|
|
295
|
+
const hash = createHash("SHA256").update(data).digest("binary");
|
|
296
|
+
return Buffer.from(hash).subarray(0, length);
|
|
297
|
+
}
|
|
298
|
+
function aesEncrypt(plainText, key, iv) {
|
|
299
|
+
const cipher = createCipheriv("aes-256-cbc", key, iv);
|
|
300
|
+
return cipher.update(plainText, "utf8", "base64url") + cipher.final("base64url");
|
|
301
|
+
}
|
|
302
|
+
function defaultSignature(buffer, privateKey, cert, version) {
|
|
303
|
+
const sig = createSign("RSA-SHA256").update(buffer).sign(createPrivateKey(privateKey), "base64");
|
|
304
|
+
return aesEncrypt(`${sig}%${version}`, hashBuffer(cert, 32), hashBuffer(buffer, 16));
|
|
305
|
+
}
|
|
335
306
|
function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
336
307
|
const privateKeyDir = dirname(privateKeyPath);
|
|
337
|
-
if (!
|
|
308
|
+
if (!existsSync(privateKeyDir)) {
|
|
338
309
|
mkdirSync(privateKeyDir, { recursive: true });
|
|
339
310
|
}
|
|
340
311
|
const certDir = dirname(certPath);
|
|
341
|
-
if (!
|
|
312
|
+
if (!existsSync(certDir)) {
|
|
342
313
|
mkdirSync(certDir, { recursive: true });
|
|
343
314
|
}
|
|
344
315
|
const { cert, private: privateKey } = generate(subject, {
|
|
@@ -346,8 +317,8 @@ function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
|
346
317
|
algorithm: "sha256",
|
|
347
318
|
days
|
|
348
319
|
});
|
|
349
|
-
|
|
350
|
-
|
|
320
|
+
writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
|
|
321
|
+
writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
|
|
351
322
|
}
|
|
352
323
|
function parseKeys({
|
|
353
324
|
keyLength,
|
|
@@ -357,15 +328,21 @@ function parseKeys({
|
|
|
357
328
|
days
|
|
358
329
|
}) {
|
|
359
330
|
const keysDir = dirname(privateKeyPath);
|
|
360
|
-
|
|
331
|
+
let privateKey = process.env.UPDATER_PK;
|
|
332
|
+
let cert = process.env.UPDATER_CERT;
|
|
333
|
+
if (privateKey && cert) {
|
|
334
|
+
log.info("use UPDATER_PK and UPDATER_CERT from environment variables", { timestamp: true });
|
|
335
|
+
return { privateKey, cert };
|
|
336
|
+
}
|
|
337
|
+
if (!existsSync(keysDir)) {
|
|
361
338
|
mkdirSync(keysDir);
|
|
362
339
|
}
|
|
363
|
-
if (!
|
|
364
|
-
log.
|
|
340
|
+
if (!existsSync(privateKeyPath) || !existsSync(certPath)) {
|
|
341
|
+
log.info("no key pair found, generate new key pair", { timestamp: true });
|
|
365
342
|
generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
|
|
366
343
|
}
|
|
367
|
-
|
|
368
|
-
|
|
344
|
+
privateKey = readFileSync(privateKeyPath, "utf-8");
|
|
345
|
+
cert = readFileSync(certPath, "utf-8");
|
|
369
346
|
return { privateKey, cert };
|
|
370
347
|
}
|
|
371
348
|
function parseSubjects(subject) {
|
|
@@ -396,24 +373,27 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
396
373
|
privateKeyPath = "keys/private.pem",
|
|
397
374
|
certPath = "keys/cert.pem",
|
|
398
375
|
keyLength = 2048,
|
|
399
|
-
certInfo
|
|
400
|
-
|
|
376
|
+
certInfo: {
|
|
377
|
+
subject = {
|
|
378
|
+
commonName: pkg.name,
|
|
379
|
+
organizationName: `org.${pkg.name}`
|
|
380
|
+
},
|
|
381
|
+
days = 3650
|
|
382
|
+
} = {}
|
|
383
|
+
} = {},
|
|
384
|
+
overrideGenerator: {
|
|
385
|
+
generateGzipFile = defaultZipFile,
|
|
386
|
+
generateSignature = defaultSignature,
|
|
387
|
+
generateVersionJson = defaultVersionJsonGenerator
|
|
401
388
|
} = {}
|
|
402
389
|
} = options;
|
|
403
|
-
const { generateSignature, generateVersionJson } = overrideGenerator;
|
|
404
|
-
let {
|
|
405
|
-
subject = {
|
|
406
|
-
commonName: pkg.name,
|
|
407
|
-
organizationName: `org.${pkg.name}`
|
|
408
|
-
},
|
|
409
|
-
days = 3650
|
|
410
|
-
} = certInfo;
|
|
411
390
|
const buildAsarOption = {
|
|
412
391
|
version: pkg.version,
|
|
413
392
|
asarOutputPath,
|
|
414
393
|
gzipPath,
|
|
415
394
|
electronDistPath,
|
|
416
|
-
rendererDistPath
|
|
395
|
+
rendererDistPath,
|
|
396
|
+
generateGzipFile
|
|
417
397
|
};
|
|
418
398
|
const buildEntryOption = {
|
|
419
399
|
minify: entryMinify ?? minify,
|
|
@@ -433,7 +413,6 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
433
413
|
const buildVersionOption = {
|
|
434
414
|
version: pkg.version,
|
|
435
415
|
minimumVersion,
|
|
436
|
-
gzipPath,
|
|
437
416
|
privateKey,
|
|
438
417
|
cert,
|
|
439
418
|
versionPath,
|
|
@@ -443,11 +422,18 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
443
422
|
return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert };
|
|
444
423
|
}
|
|
445
424
|
|
|
425
|
+
// src/build-plugins/utils.ts
|
|
426
|
+
function readableSize(size) {
|
|
427
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
428
|
+
let i = 0;
|
|
429
|
+
while (size >= 1024 && i < units.length - 1) {
|
|
430
|
+
size /= 1024;
|
|
431
|
+
i++;
|
|
432
|
+
}
|
|
433
|
+
return `${size.toFixed(2)} ${units[i]}`;
|
|
434
|
+
}
|
|
435
|
+
|
|
446
436
|
// src/build-plugins/bytecode/index.ts
|
|
447
|
-
import path2 from "node:path";
|
|
448
|
-
import fs2 from "node:fs";
|
|
449
|
-
import { createFilter, normalizePath } from "vite";
|
|
450
|
-
import MagicString2 from "magic-string";
|
|
451
437
|
function bytecodePlugin(isBuild, env, options = {}) {
|
|
452
438
|
if (!isBuild) {
|
|
453
439
|
return null;
|
|
@@ -525,7 +511,7 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
525
511
|
let _code = chunk.code;
|
|
526
512
|
if (bytecodeRE && _code.match(bytecodeRE)) {
|
|
527
513
|
let match;
|
|
528
|
-
const s = new
|
|
514
|
+
const s = new MagicString(_code);
|
|
529
515
|
while (match = bytecodeRE.exec(_code)) {
|
|
530
516
|
const [prefix, chunkName] = match;
|
|
531
517
|
const len = prefix.length + chunkName.length;
|
|
@@ -538,7 +524,7 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
538
524
|
const chunkFilePath = path2.resolve(outDir, name);
|
|
539
525
|
if (bytecodeChunks.includes(name)) {
|
|
540
526
|
const bytecodeBuffer = await compileToBytecode(_code);
|
|
541
|
-
|
|
527
|
+
fs.writeFileSync(path2.resolve(outDir, name + "c"), bytecodeBuffer);
|
|
542
528
|
if (chunk.isEntry) {
|
|
543
529
|
const bytecodeLoaderBlock = getBytecodeLoaderBlock(chunk.fileName);
|
|
544
530
|
const bytecodeModuleBlock = `require("./${path2.basename(name) + "c"}");`;
|
|
@@ -546,9 +532,9 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
546
532
|
${bytecodeLoaderBlock}
|
|
547
533
|
module.exports=${bytecodeModuleBlock}
|
|
548
534
|
`;
|
|
549
|
-
|
|
535
|
+
fs.writeFileSync(chunkFilePath, code);
|
|
550
536
|
} else {
|
|
551
|
-
|
|
537
|
+
fs.unlinkSync(chunkFilePath);
|
|
552
538
|
}
|
|
553
539
|
bytecodeFiles.push({ name: name + "c", size: bytecodeBuffer.length });
|
|
554
540
|
} else {
|
|
@@ -575,7 +561,7 @@ module.exports=${bytecodeModuleBlock}
|
|
|
575
561
|
_code = hasBytecodeMoudle ? _code.replace(useStrict, `${useStrict}
|
|
576
562
|
${bytecodeLoaderBlock}`) : _code;
|
|
577
563
|
}
|
|
578
|
-
|
|
564
|
+
fs.writeFileSync(chunkFilePath, _code);
|
|
579
565
|
}
|
|
580
566
|
}
|
|
581
567
|
})
|
|
@@ -584,9 +570,8 @@ ${bytecodeLoaderBlock}`) : _code;
|
|
|
584
570
|
closeBundle() {
|
|
585
571
|
const outDir = `${normalizePath(path2.relative(config.root, path2.resolve(config.root, config.build.outDir)))}/`;
|
|
586
572
|
bytecodeFiles.forEach((file) => {
|
|
587
|
-
const kbs = file.size / 1e3;
|
|
588
573
|
bytecodeLog.info(
|
|
589
|
-
`${outDir}${file.name} => ${
|
|
574
|
+
`${outDir}${file.name} => ${readableSize(file.size)}`,
|
|
590
575
|
{ timestamp: true }
|
|
591
576
|
);
|
|
592
577
|
});
|
|
@@ -607,9 +592,9 @@ function debugStartup(args) {
|
|
|
607
592
|
function getMainFilePath(options) {
|
|
608
593
|
let mainFilePath;
|
|
609
594
|
if (typeof options === "string") {
|
|
610
|
-
mainFilePath =
|
|
595
|
+
mainFilePath = basename(options);
|
|
611
596
|
} else if (Array.isArray(options)) {
|
|
612
|
-
mainFilePath =
|
|
597
|
+
mainFilePath = basename(options[0]);
|
|
613
598
|
} else {
|
|
614
599
|
const name = options?.index ?? options?.main;
|
|
615
600
|
if (!name) {
|
|
@@ -620,7 +605,7 @@ function getMainFilePath(options) {
|
|
|
620
605
|
return mainFilePath.replace(/\.[cm]?ts$/, ".js");
|
|
621
606
|
}
|
|
622
607
|
function parseVersionPath(versionPath) {
|
|
623
|
-
versionPath =
|
|
608
|
+
versionPath = normalizePath(versionPath);
|
|
624
609
|
if (!versionPath.startsWith("./")) {
|
|
625
610
|
versionPath = "./" + versionPath;
|
|
626
611
|
}
|
|
@@ -661,8 +646,8 @@ async function electronWithUpdater(options) {
|
|
|
661
646
|
const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert } = _options;
|
|
662
647
|
const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
|
|
663
648
|
sourcemap ??= isBuild || !!process.env.VSCODE_DEBUG;
|
|
664
|
-
const _appPath =
|
|
665
|
-
if (resolve(
|
|
649
|
+
const _appPath = normalizePath(join(entryOutputDirPath, "entry.js"));
|
|
650
|
+
if (resolve(normalizePath(pkg.main)) !== resolve(_appPath)) {
|
|
666
651
|
throw new Error(`wrong "main" field in package.json: "${pkg.main}", it should be "${_appPath}"`);
|
|
667
652
|
}
|
|
668
653
|
const define = {
|
|
@@ -672,7 +657,7 @@ async function electronWithUpdater(options) {
|
|
|
672
657
|
__EIU_MAIN_DEV_DIR__: JSON.stringify(buildAsarOption.electronDistPath),
|
|
673
658
|
__EIU_MAIN_FILE__: JSON.stringify(getMainFilePath(_main.files)),
|
|
674
659
|
__EIU_SIGNATURE_CERT__: JSON.stringify(cert),
|
|
675
|
-
|
|
660
|
+
__EIU_VERSION_PATH__: JSON.stringify(parseVersionPath(buildVersionOption.versionPath))
|
|
676
661
|
};
|
|
677
662
|
const _buildEntry = async () => {
|
|
678
663
|
await buildEntry(
|
|
@@ -684,12 +669,12 @@ async function electronWithUpdater(options) {
|
|
|
684
669
|
};
|
|
685
670
|
const _postBuild = postBuild ? async () => await postBuild({
|
|
686
671
|
getPathFromEntryOutputDir(...paths) {
|
|
687
|
-
return
|
|
672
|
+
return join(entryOutputDirPath, ...paths);
|
|
688
673
|
},
|
|
689
674
|
copyToEntryOutputDir({ from, to, skipIfExist = true }) {
|
|
690
|
-
if (
|
|
691
|
-
const target =
|
|
692
|
-
if (!skipIfExist || !
|
|
675
|
+
if (existsSync(from)) {
|
|
676
|
+
const target = join(entryOutputDirPath, to ?? basename(from));
|
|
677
|
+
if (!skipIfExist || !existsSync(target)) {
|
|
693
678
|
try {
|
|
694
679
|
cpSync(from, target);
|
|
695
680
|
} catch (error) {
|
|
@@ -719,7 +704,7 @@ async function electronWithUpdater(options) {
|
|
|
719
704
|
args.startup();
|
|
720
705
|
}
|
|
721
706
|
},
|
|
722
|
-
vite:
|
|
707
|
+
vite: mergeConfig(
|
|
723
708
|
{
|
|
724
709
|
plugins: [
|
|
725
710
|
!isBuild && useNotBundle ? notBundle() : void 0,
|
|
@@ -739,7 +724,7 @@ async function electronWithUpdater(options) {
|
|
|
739
724
|
preload: {
|
|
740
725
|
input: _preload.files,
|
|
741
726
|
onstart: _preload.onstart,
|
|
742
|
-
vite:
|
|
727
|
+
vite: mergeConfig(
|
|
743
728
|
{
|
|
744
729
|
plugins: [
|
|
745
730
|
bytecodeOptions && bytecodePlugin(isBuild, "preload", bytecodeOptions),
|
|
@@ -752,9 +737,9 @@ async function electronWithUpdater(options) {
|
|
|
752
737
|
async closeBundle() {
|
|
753
738
|
await _buildEntry();
|
|
754
739
|
await _postBuild();
|
|
755
|
-
await buildAsar(buildAsarOption);
|
|
756
|
-
log.info(`build asar to '${buildAsarOption.
|
|
757
|
-
await buildVersion(buildVersionOption);
|
|
740
|
+
const buffer = await buildAsar(buildAsarOption);
|
|
741
|
+
log.info(`build update asar to '${buildAsarOption.gzipPath}' => ${readableSize(buffer.length)}`, { timestamp: true });
|
|
742
|
+
await buildVersion(buildVersionOption, buffer);
|
|
758
743
|
log.info(`build version info to '${buildVersionOption.versionPath}'`, { timestamp: true });
|
|
759
744
|
}
|
|
760
745
|
}
|
|
@@ -786,7 +771,7 @@ async function electronWithUpdater(options) {
|
|
|
786
771
|
}
|
|
787
772
|
let extraHmrPlugin;
|
|
788
773
|
if (nativeModuleEntryMap) {
|
|
789
|
-
const files = [...Object.values(nativeModuleEntryMap), appEntryPath].map((file) => resolve(
|
|
774
|
+
const files = [...Object.values(nativeModuleEntryMap), appEntryPath].map((file) => resolve(normalizePath(file)));
|
|
790
775
|
extraHmrPlugin = {
|
|
791
776
|
name: `${id}-dev`,
|
|
792
777
|
apply() {
|
|
@@ -806,7 +791,5 @@ async function electronWithUpdater(options) {
|
|
|
806
791
|
}
|
|
807
792
|
return [ElectronSimple(electronPluginOptions), extraHmrPlugin];
|
|
808
793
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
electronWithUpdater
|
|
812
|
-
};
|
|
794
|
+
|
|
795
|
+
export { debugStartup, electronWithUpdater };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare function hashBuffer(data: string | Buffer, length: number): Buffer;
|
|
2
|
+
declare function aesEncrypt(plainText: string, key: Buffer, iv: Buffer): string;
|
|
3
|
+
declare function defaultSignature(buffer: Buffer, privateKey: string, cert: string, version: string): string;
|
|
4
|
+
declare function aesDecrypt(encryptedText: string, key: Buffer, iv: Buffer): string;
|
|
5
|
+
declare function defaultVerify(buffer: Buffer, signature: string, cert: string): string | undefined;
|
|
6
|
+
|
|
7
|
+
declare function defaultZipFile(buffer: Buffer): Promise<Buffer>;
|
|
8
|
+
declare function defaultUnzipFile(buffer: Buffer): Promise<Buffer>;
|
|
9
|
+
|
|
10
|
+
export { defaultUnzipFile as a, aesEncrypt as b, defaultSignature as c, defaultZipFile as d, aesDecrypt as e, defaultVerify as f, hashBuffer as h };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare function hashBuffer(data: string | Buffer, length: number): Buffer;
|
|
2
|
+
declare function aesEncrypt(plainText: string, key: Buffer, iv: Buffer): string;
|
|
3
|
+
declare function defaultSignature(buffer: Buffer, privateKey: string, cert: string, version: string): string;
|
|
4
|
+
declare function aesDecrypt(encryptedText: string, key: Buffer, iv: Buffer): string;
|
|
5
|
+
declare function defaultVerify(buffer: Buffer, signature: string, cert: string): string | undefined;
|
|
6
|
+
|
|
7
|
+
declare function defaultZipFile(buffer: Buffer): Promise<Buffer>;
|
|
8
|
+
declare function defaultUnzipFile(buffer: Buffer): Promise<Buffer>;
|
|
9
|
+
|
|
10
|
+
export { defaultUnzipFile as a, aesEncrypt as b, defaultSignature as c, defaultZipFile as d, aesDecrypt as e, defaultVerify as f, hashBuffer as h };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "electron-incremental-update",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.4",
|
|
5
5
|
"description": "electron incremental update tools, powered by vite",
|
|
6
6
|
"author": "subframe7536",
|
|
7
7
|
"license": "MIT",
|
|
@@ -52,17 +52,17 @@
|
|
|
52
52
|
"registry": "https://registry.npmjs.org/"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@babel/core": "^7.24.7",
|
|
56
|
-
"@babel/plugin-transform-arrow-functions": "^7.24.7",
|
|
57
55
|
"@electron/asar": "*",
|
|
58
56
|
"esbuild": "*",
|
|
59
|
-
"magic-string": "*"
|
|
60
|
-
"vite-plugin-electron": "^0.15.6 || ^0.28"
|
|
57
|
+
"magic-string": "*"
|
|
61
58
|
},
|
|
62
59
|
"dependencies": {
|
|
60
|
+
"@babel/core": "^7.24.7",
|
|
61
|
+
"@babel/plugin-transform-arrow-functions": "^7.24.7",
|
|
63
62
|
"@subframe7536/type-utils": "^0.1.6",
|
|
64
63
|
"local-pkg": "^0.5.0",
|
|
65
|
-
"selfsigned": "^2.4.1"
|
|
64
|
+
"selfsigned": "^2.4.1",
|
|
65
|
+
"vite-plugin-electron": "^0.28.7"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@subframe7536/eslint-config": "^0.7.2",
|
|
@@ -78,4 +78,4 @@
|
|
|
78
78
|
"vite-plugin-electron": "^0.28.7",
|
|
79
79
|
"vitest": "^2.0.3"
|
|
80
80
|
}
|
|
81
|
-
}
|
|
81
|
+
}
|