electron-incremental-update 2.0.0-beta.6 → 2.0.0-beta.8
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-DFNDKSE6.js → chunk-4MH6ZXCY.js} +12 -12
- package/dist/{chunk-N77WQ5WB.js → chunk-KZSYEXLO.js} +9 -9
- package/dist/core-DJdvtwvU.d.ts +134 -0
- package/dist/core-ZUlLHadf.d.cts +134 -0
- package/dist/index.cjs +15 -10
- package/dist/index.d.cts +78 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +9 -9
- package/dist/provider.cjs +9 -4
- package/dist/provider.d.cts +76 -0
- package/dist/provider.d.ts +76 -0
- package/dist/provider.js +1 -1
- package/dist/types-CItP6bL-.d.cts +104 -0
- package/dist/types-CItP6bL-.d.ts +104 -0
- package/dist/utils.cjs +24 -22
- package/dist/utils.d.cts +80 -0
- package/dist/utils.d.ts +80 -0
- package/dist/utils.js +2 -3
- package/dist/vite.d.ts +405 -0
- package/dist/vite.js +166 -118
- package/dist/zip-DPF5IFkK.d.cts +10 -0
- package/dist/zip-DPF5IFkK.d.ts +10 -0
- package/package.json +8 -6
package/dist/vite.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import path5 from 'node:path';
|
|
2
|
+
import fs3 from 'node:fs';
|
|
3
3
|
import { createLogger, normalizePath, mergeConfig, createFilter } from 'vite';
|
|
4
4
|
import ElectronSimple from 'vite-plugin-electron/simple';
|
|
5
5
|
import { startup } from 'vite-plugin-electron';
|
|
6
6
|
import { notBundle } from 'vite-plugin-electron/plugin';
|
|
7
7
|
import { getPackageInfoSync, loadPackageJSON } from 'local-pkg';
|
|
8
8
|
import { isCI } from 'ci-info';
|
|
9
|
+
export { isCI } from 'ci-info';
|
|
9
10
|
import Asar from '@electron/asar';
|
|
10
11
|
import { build } from 'esbuild';
|
|
11
|
-
import
|
|
12
|
+
import cp from 'node:child_process';
|
|
12
13
|
import * as babel from '@babel/core';
|
|
13
14
|
import MagicString from 'magic-string';
|
|
14
|
-
import
|
|
15
|
-
import
|
|
15
|
+
import zlib from 'node:zlib';
|
|
16
|
+
import crypto from 'node:crypto';
|
|
16
17
|
import { generate } from 'selfsigned';
|
|
17
18
|
|
|
18
19
|
// src/vite.ts
|
|
@@ -75,13 +76,13 @@ function getElectronPath() {
|
|
|
75
76
|
if (!electronModulePath) {
|
|
76
77
|
throw new Error("Electron is not installed");
|
|
77
78
|
}
|
|
78
|
-
const pathFile =
|
|
79
|
+
const pathFile = path5.join(electronModulePath, "path.txt");
|
|
79
80
|
let executablePath;
|
|
80
|
-
if (
|
|
81
|
-
executablePath =
|
|
81
|
+
if (fs3.existsSync(pathFile)) {
|
|
82
|
+
executablePath = fs3.readFileSync(pathFile, "utf-8");
|
|
82
83
|
}
|
|
83
84
|
if (executablePath) {
|
|
84
|
-
electronExecPath =
|
|
85
|
+
electronExecPath = path5.join(electronModulePath, "dist", executablePath);
|
|
85
86
|
process.env.ELECTRON_EXEC_PATH = electronExecPath;
|
|
86
87
|
} else {
|
|
87
88
|
throw new Error("Electron executable file is not existed");
|
|
@@ -90,23 +91,23 @@ function getElectronPath() {
|
|
|
90
91
|
return electronExecPath;
|
|
91
92
|
}
|
|
92
93
|
function getBytecodeCompilerPath() {
|
|
93
|
-
const scriptPath =
|
|
94
|
-
if (!
|
|
95
|
-
|
|
94
|
+
const scriptPath = path5.join(electronModulePath, "bytenode.cjs");
|
|
95
|
+
if (!fs3.existsSync(scriptPath)) {
|
|
96
|
+
fs3.writeFileSync(scriptPath, bytecodeGeneratorScript);
|
|
96
97
|
}
|
|
97
98
|
return scriptPath;
|
|
98
99
|
}
|
|
99
100
|
function toRelativePath(filename, importer) {
|
|
100
|
-
const relPath =
|
|
101
|
+
const relPath = path5.posix.relative(path5.dirname(importer), filename);
|
|
101
102
|
return relPath.startsWith(".") ? relPath : `./${relPath}`;
|
|
102
103
|
}
|
|
103
104
|
function compileToBytecode(code) {
|
|
104
105
|
let data = Buffer.from([]);
|
|
105
|
-
const logErr = (...args) =>
|
|
106
|
+
const logErr = (...args) => bytecodeLog.error(args.join(" "), { timestamp: true });
|
|
106
107
|
const electronPath = getElectronPath();
|
|
107
108
|
const bytecodePath = getBytecodeCompilerPath();
|
|
108
|
-
return new Promise((
|
|
109
|
-
const proc = spawn(electronPath, [bytecodePath], {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const proc = cp.spawn(electronPath, [bytecodePath], {
|
|
110
111
|
env: { ELECTRON_RUN_AS_NODE: "1" },
|
|
111
112
|
stdio: ["pipe", "pipe", "pipe", "ipc"]
|
|
112
113
|
});
|
|
@@ -117,7 +118,7 @@ function compileToBytecode(code) {
|
|
|
117
118
|
if (proc.stdout) {
|
|
118
119
|
proc.stdout.on("data", (chunk) => data = Buffer.concat([data, chunk]));
|
|
119
120
|
proc.stdout.on("error", (err) => logErr(err));
|
|
120
|
-
proc.stdout.on("end", () =>
|
|
121
|
+
proc.stdout.on("end", () => resolve(data));
|
|
121
122
|
}
|
|
122
123
|
if (proc.stderr) {
|
|
123
124
|
proc.stderr.on("data", (chunk) => logErr("Error: ", chunk.toString()));
|
|
@@ -125,37 +126,77 @@ function compileToBytecode(code) {
|
|
|
125
126
|
}
|
|
126
127
|
proc.addListener("error", (err) => logErr(err));
|
|
127
128
|
proc.on("error", (err) => reject(err));
|
|
128
|
-
proc.on("exit", () =>
|
|
129
|
+
proc.on("exit", () => resolve(data));
|
|
129
130
|
});
|
|
130
131
|
}
|
|
131
132
|
function convertArrowToFunction(code) {
|
|
132
133
|
const result = babel.transform(code, {
|
|
133
|
-
plugins: ["@babel/plugin-transform-arrow-functions"]
|
|
134
|
+
plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-template-literals"]
|
|
134
135
|
});
|
|
135
136
|
return {
|
|
136
137
|
code: result?.code || code,
|
|
137
138
|
map: result?.map
|
|
138
139
|
};
|
|
139
140
|
}
|
|
140
|
-
function
|
|
141
|
-
|
|
141
|
+
var decodeFn = ";function _0xstr_(a,b){return String.fromCharCode.apply(0,a.map(function(x){return x-b}))};";
|
|
142
|
+
function obfuscateString(input, offset = ~~(Math.random() * 16) + 1) {
|
|
143
|
+
const hexArray = input.split("").map((c) => "0x" + (c.charCodeAt(0) + offset).toString(16));
|
|
144
|
+
return `_0xstr_([${hexArray.join(",")}],${offset})`;
|
|
142
145
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
function convertLiteral(code, sourcemap, offset) {
|
|
147
|
+
const s = new MagicString(code);
|
|
148
|
+
let hasTransformed = false;
|
|
149
|
+
const ast = babel.parse(code, { ast: true });
|
|
150
|
+
if (!ast) {
|
|
151
|
+
throw new Error("cannot parse code");
|
|
148
152
|
}
|
|
149
|
-
|
|
153
|
+
babel.traverse(ast, {
|
|
154
|
+
StringLiteral(path6) {
|
|
155
|
+
const parent = path6.parent;
|
|
156
|
+
const node = path6.node;
|
|
157
|
+
if (parent.type === "CallExpression") {
|
|
158
|
+
if (parent.callee.type === "Identifier" && parent.callee.name === "require") {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (parent.callee.type === "Import") {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (parent.type.startsWith("Export")) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (parent.type.startsWith("Import")) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (parent.type === "ObjectProperty" && parent.key === node) {
|
|
172
|
+
const result2 = `[${obfuscateString(node.value, offset)}]`;
|
|
173
|
+
const start2 = node.start;
|
|
174
|
+
const end2 = node.end;
|
|
175
|
+
if (start2 && end2) {
|
|
176
|
+
s.overwrite(start2, end2, result2);
|
|
177
|
+
hasTransformed = true;
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (!node.value.trim()) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const result = obfuscateString(node.value, offset);
|
|
185
|
+
const start = node.start;
|
|
186
|
+
const end = node.end;
|
|
187
|
+
if (start && end) {
|
|
188
|
+
s.overwrite(start, end, result);
|
|
189
|
+
hasTransformed = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
if (hasTransformed) {
|
|
194
|
+
s.append("\n").append(decodeFn);
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
150
197
|
code: s.toString(),
|
|
151
|
-
map: sourcemap ? s.generateMap({ hires:
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function obfuscateString(input) {
|
|
155
|
-
const offset = Math.floor(Math.random() * 2 << 4) + 1;
|
|
156
|
-
const hexArray = Array.from(input).map((c) => "0x" + (c.charCodeAt(0) + offset).toString(16));
|
|
157
|
-
const decodeFn = `function(a,b){return String.fromCharCode.apply(null,a.map(x=>+x-b))}`;
|
|
158
|
-
return `(${decodeFn})([${hexArray.join(",")}],${offset})`;
|
|
198
|
+
map: sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
199
|
+
};
|
|
159
200
|
}
|
|
160
201
|
|
|
161
202
|
// src/build-plugins/utils.ts
|
|
@@ -178,11 +219,11 @@ async function buildAsar({
|
|
|
178
219
|
rendererDistPath,
|
|
179
220
|
generateGzipFile
|
|
180
221
|
}) {
|
|
181
|
-
renameSync(rendererDistPath, join(electronDistPath, "renderer"));
|
|
182
|
-
writeFileSync(join(electronDistPath, "version"), version);
|
|
222
|
+
fs3.renameSync(rendererDistPath, path5.join(electronDistPath, "renderer"));
|
|
223
|
+
fs3.writeFileSync(path5.join(electronDistPath, "version"), version);
|
|
183
224
|
await Asar.createPackage(electronDistPath, asarOutputPath);
|
|
184
|
-
const buf = await generateGzipFile(readFileSync(asarOutputPath));
|
|
185
|
-
writeFileSync(gzipPath, buf);
|
|
225
|
+
const buf = await generateGzipFile(fs3.readFileSync(asarOutputPath));
|
|
226
|
+
fs3.writeFileSync(gzipPath, buf);
|
|
186
227
|
log.info(`build update asar to '${gzipPath}' [${readableSize(buf.length)}]`, { timestamp: true });
|
|
187
228
|
return buf;
|
|
188
229
|
}
|
|
@@ -205,9 +246,9 @@ async function buildVersion({
|
|
|
205
246
|
signature: "",
|
|
206
247
|
version
|
|
207
248
|
};
|
|
208
|
-
if (existsSync(versionPath)) {
|
|
249
|
+
if (fs3.existsSync(versionPath)) {
|
|
209
250
|
try {
|
|
210
|
-
const oldVersionJson = JSON.parse(readFileSync(versionPath, "utf-8"));
|
|
251
|
+
const oldVersionJson = JSON.parse(fs3.readFileSync(versionPath, "utf-8"));
|
|
211
252
|
if (isUpdateJSON(oldVersionJson)) {
|
|
212
253
|
_json = oldVersionJson;
|
|
213
254
|
} else {
|
|
@@ -221,7 +262,7 @@ async function buildVersion({
|
|
|
221
262
|
if (!isUpdateJSON(_json)) {
|
|
222
263
|
throw new Error("invalid version info");
|
|
223
264
|
}
|
|
224
|
-
writeFileSync(versionPath, JSON.stringify(_json, null, 2));
|
|
265
|
+
fs3.writeFileSync(versionPath, JSON.stringify(_json, null, 2));
|
|
225
266
|
log.info(`build version info to '${versionPath}'`, { timestamp: true });
|
|
226
267
|
}
|
|
227
268
|
async function buildEntry({
|
|
@@ -231,7 +272,7 @@ async function buildEntry({
|
|
|
231
272
|
entryOutputDirPath,
|
|
232
273
|
nativeModuleEntryMap,
|
|
233
274
|
overrideEsbuildOptions
|
|
234
|
-
}, define,
|
|
275
|
+
}, define, bytecodeOptions) {
|
|
235
276
|
const option = mergeConfig(
|
|
236
277
|
{
|
|
237
278
|
entryPoints: {
|
|
@@ -247,6 +288,7 @@ async function buildEntry({
|
|
|
247
288
|
entryNames: "[dir]/[name]",
|
|
248
289
|
assetNames: "[dir]/[name]",
|
|
249
290
|
external: ["electron", "original-fs"],
|
|
291
|
+
treeShaking: true,
|
|
250
292
|
loader: {
|
|
251
293
|
".node": "empty"
|
|
252
294
|
},
|
|
@@ -255,13 +297,13 @@ async function buildEntry({
|
|
|
255
297
|
overrideEsbuildOptions ?? {}
|
|
256
298
|
);
|
|
257
299
|
const { metafile } = await build(option);
|
|
258
|
-
if (
|
|
300
|
+
if (!bytecodeOptions || !bytecodeOptions.enable) {
|
|
259
301
|
return;
|
|
260
302
|
}
|
|
261
303
|
const filePaths = Object.keys(metafile?.outputs ?? []);
|
|
262
304
|
for (const filePath of filePaths) {
|
|
263
|
-
let code = readFileSync(filePath, "utf-8");
|
|
264
|
-
const fileName = basename(filePath);
|
|
305
|
+
let code = fs3.readFileSync(filePath, "utf-8");
|
|
306
|
+
const fileName = path5.basename(filePath);
|
|
265
307
|
const isEntry = fileName.endsWith("entry.js");
|
|
266
308
|
if (isEntry) {
|
|
267
309
|
code = code.replace(
|
|
@@ -269,16 +311,19 @@ async function buildEntry({
|
|
|
269
311
|
(_, cert) => `"${cert.slice(1, -1).replace(/\n/g, "\\n")}"`
|
|
270
312
|
);
|
|
271
313
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
314
|
+
let transformedCode = convertLiteral(convertArrowToFunction(code).code).code;
|
|
315
|
+
if (bytecodeOptions.beforeCompile) {
|
|
316
|
+
const result = await bytecodeOptions.beforeCompile(transformedCode, filePath);
|
|
317
|
+
if (result) {
|
|
318
|
+
transformedCode = result;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
276
321
|
const buffer = await compileToBytecode(transformedCode);
|
|
277
|
-
writeFileSync(
|
|
278
|
-
writeFileSync(
|
|
322
|
+
fs3.writeFileSync(
|
|
279
323
|
filePath,
|
|
280
324
|
`${isEntry ? bytecodeModuleLoaderCode : useStrict}${isEntry ? "" : "module.exports = "}require("./${fileName}c")`
|
|
281
325
|
);
|
|
326
|
+
fs3.writeFileSync(`${filePath}c`, buffer);
|
|
282
327
|
bytecodeLog.info(
|
|
283
328
|
`${filePath} [${(buffer.byteLength / 1e3).toFixed(2)} kB]`,
|
|
284
329
|
{ timestamp: true }
|
|
@@ -286,49 +331,45 @@ async function buildEntry({
|
|
|
286
331
|
}
|
|
287
332
|
bytecodeLog.info(`${filePaths.length} file${filePaths.length > 1 ? "s" : ""} compiled into bytecode`, { timestamp: true });
|
|
288
333
|
}
|
|
289
|
-
function getCert(code) {
|
|
290
|
-
const cert = code.match(/-----BEGIN CERTIFICATE-----[\s\S]*-----END CERTIFICATE-----\\n/)?.[0];
|
|
291
|
-
return cert ? [cert] : [];
|
|
292
|
-
}
|
|
293
334
|
async function defaultZipFile(buffer) {
|
|
294
|
-
return new Promise((
|
|
295
|
-
brotliCompress(buffer, (err, buffer2) => {
|
|
335
|
+
return new Promise((resolve, reject) => {
|
|
336
|
+
zlib.brotliCompress(buffer, (err, buffer2) => {
|
|
296
337
|
if (err) {
|
|
297
338
|
reject(err);
|
|
298
339
|
} else {
|
|
299
|
-
|
|
340
|
+
resolve(buffer2);
|
|
300
341
|
}
|
|
301
342
|
});
|
|
302
343
|
});
|
|
303
344
|
}
|
|
304
345
|
function hashBuffer(data, length) {
|
|
305
|
-
const hash = createHash("SHA256").update(data).digest("binary");
|
|
346
|
+
const hash = crypto.createHash("SHA256").update(data).digest("binary");
|
|
306
347
|
return Buffer.from(hash).subarray(0, length);
|
|
307
348
|
}
|
|
308
349
|
function aesEncrypt(plainText, key, iv) {
|
|
309
|
-
const cipher = createCipheriv("aes-256-cbc", key, iv);
|
|
350
|
+
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
|
|
310
351
|
return cipher.update(plainText, "utf8", "base64url") + cipher.final("base64url");
|
|
311
352
|
}
|
|
312
353
|
function defaultSignature(buffer, privateKey, cert, version) {
|
|
313
|
-
const sig = createSign("RSA-SHA256").update(buffer).sign(createPrivateKey(privateKey), "base64");
|
|
354
|
+
const sig = crypto.createSign("RSA-SHA256").update(buffer).sign(crypto.createPrivateKey(privateKey), "base64");
|
|
314
355
|
return aesEncrypt(`${sig}%${version}`, hashBuffer(cert, 32), hashBuffer(buffer, 16));
|
|
315
356
|
}
|
|
316
357
|
function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
317
|
-
const privateKeyDir = dirname(privateKeyPath);
|
|
318
|
-
if (!existsSync(privateKeyDir)) {
|
|
319
|
-
mkdirSync(privateKeyDir, { recursive: true });
|
|
358
|
+
const privateKeyDir = path5.dirname(privateKeyPath);
|
|
359
|
+
if (!fs3.existsSync(privateKeyDir)) {
|
|
360
|
+
fs3.mkdirSync(privateKeyDir, { recursive: true });
|
|
320
361
|
}
|
|
321
|
-
const certDir = dirname(certPath);
|
|
322
|
-
if (!existsSync(certDir)) {
|
|
323
|
-
mkdirSync(certDir, { recursive: true });
|
|
362
|
+
const certDir = path5.dirname(certPath);
|
|
363
|
+
if (!fs3.existsSync(certDir)) {
|
|
364
|
+
fs3.mkdirSync(certDir, { recursive: true });
|
|
324
365
|
}
|
|
325
366
|
const { cert, private: privateKey } = generate(subject, {
|
|
326
367
|
keySize: keyLength,
|
|
327
368
|
algorithm: "sha256",
|
|
328
369
|
days
|
|
329
370
|
});
|
|
330
|
-
writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
|
|
331
|
-
writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
|
|
371
|
+
fs3.writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
|
|
372
|
+
fs3.writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
|
|
332
373
|
}
|
|
333
374
|
function parseKeys({
|
|
334
375
|
keyLength,
|
|
@@ -337,22 +378,22 @@ function parseKeys({
|
|
|
337
378
|
subject,
|
|
338
379
|
days
|
|
339
380
|
}) {
|
|
340
|
-
const keysDir = dirname(privateKeyPath);
|
|
381
|
+
const keysDir = path5.dirname(privateKeyPath);
|
|
341
382
|
let privateKey = process.env.UPDATER_PK;
|
|
342
383
|
let cert = process.env.UPDATER_CERT;
|
|
343
384
|
if (privateKey && cert) {
|
|
344
385
|
log.info("use UPDATER_PK and UPDATER_CERT from environment variables", { timestamp: true });
|
|
345
386
|
return { privateKey, cert };
|
|
346
387
|
}
|
|
347
|
-
if (!existsSync(keysDir)) {
|
|
348
|
-
mkdirSync(keysDir);
|
|
388
|
+
if (!fs3.existsSync(keysDir)) {
|
|
389
|
+
fs3.mkdirSync(keysDir);
|
|
349
390
|
}
|
|
350
|
-
if (!existsSync(privateKeyPath) || !existsSync(certPath)) {
|
|
391
|
+
if (!fs3.existsSync(privateKeyPath) || !fs3.existsSync(certPath)) {
|
|
351
392
|
log.info("no key pair found, generate new key pair", { timestamp: true });
|
|
352
393
|
generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
|
|
353
394
|
}
|
|
354
|
-
privateKey = readFileSync(privateKeyPath, "utf-8");
|
|
355
|
-
cert = readFileSync(certPath, "utf-8");
|
|
395
|
+
privateKey = fs3.readFileSync(privateKeyPath, "utf-8");
|
|
396
|
+
cert = fs3.readFileSync(certPath, "utf-8");
|
|
356
397
|
return { privateKey, cert };
|
|
357
398
|
}
|
|
358
399
|
function parseSubjects(subject) {
|
|
@@ -431,15 +472,16 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
431
472
|
};
|
|
432
473
|
return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert };
|
|
433
474
|
}
|
|
434
|
-
function bytecodePlugin(
|
|
435
|
-
if (!isBuild) {
|
|
436
|
-
return null;
|
|
437
|
-
}
|
|
475
|
+
function bytecodePlugin(env, options) {
|
|
438
476
|
const {
|
|
439
|
-
|
|
440
|
-
|
|
477
|
+
enable,
|
|
478
|
+
preload = false,
|
|
479
|
+
beforeCompile
|
|
441
480
|
} = options;
|
|
442
|
-
if (!
|
|
481
|
+
if (!enable) {
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
if (!preload && env === "preload") {
|
|
443
485
|
bytecodeLog.warn('bytecodePlugin is skiped in preload. To enable in preload, please manually set the "enablePreload" option to true and set `sandbox: false` when creating the window', { timestamp: true });
|
|
444
486
|
return null;
|
|
445
487
|
}
|
|
@@ -455,10 +497,9 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
455
497
|
config = resolvedConfig;
|
|
456
498
|
},
|
|
457
499
|
transform(code, id2) {
|
|
458
|
-
if (
|
|
459
|
-
return;
|
|
500
|
+
if (!filter(id2)) {
|
|
501
|
+
return convertLiteral(code, !!config.build.sourcemap);
|
|
460
502
|
}
|
|
461
|
-
return convertString(code, protectedStrings, !!config.build.sourcemap);
|
|
462
503
|
},
|
|
463
504
|
generateBundle(options2) {
|
|
464
505
|
if (options2.format !== "es" && bytecodeRequired) {
|
|
@@ -495,7 +536,7 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
495
536
|
(chunk) => chunk.type === "chunk" && chunk.fileName !== bytecodeModuleLoader
|
|
496
537
|
);
|
|
497
538
|
const bytecodeChunks = chunks.map((chunk) => chunk.fileName);
|
|
498
|
-
const nonEntryChunks = chunks.filter((chunk) => !chunk.isEntry).map((chunk) =>
|
|
539
|
+
const nonEntryChunks = chunks.filter((chunk) => !chunk.isEntry).map((chunk) => path5.basename(chunk.fileName));
|
|
499
540
|
const pattern = nonEntryChunks.map((chunk) => `(${chunk})`).join("|");
|
|
500
541
|
const bytecodeRE = pattern ? new RegExp(`require\\(\\S*(?=(${pattern})\\S*\\))`, "g") : null;
|
|
501
542
|
const getBytecodeLoaderBlock = (chunkFileName) => {
|
|
@@ -506,6 +547,12 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
506
547
|
const chunk = output[name];
|
|
507
548
|
if (chunk.type === "chunk") {
|
|
508
549
|
let _code = chunk.code;
|
|
550
|
+
if (beforeCompile) {
|
|
551
|
+
const cbResult = await beforeCompile(_code, chunk.fileName);
|
|
552
|
+
if (cbResult) {
|
|
553
|
+
_code = cbResult;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
509
556
|
if (bytecodeRE && _code.match(bytecodeRE)) {
|
|
510
557
|
let match;
|
|
511
558
|
const s = new MagicString(_code);
|
|
@@ -518,20 +565,20 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
518
565
|
}
|
|
519
566
|
_code = s.toString();
|
|
520
567
|
}
|
|
521
|
-
const chunkFilePath =
|
|
568
|
+
const chunkFilePath = path5.resolve(outDir, name);
|
|
522
569
|
if (bytecodeChunks.includes(name)) {
|
|
523
570
|
const bytecodeBuffer = await compileToBytecode(_code);
|
|
524
|
-
|
|
571
|
+
fs3.writeFileSync(chunkFilePath + "c", bytecodeBuffer);
|
|
525
572
|
if (chunk.isEntry) {
|
|
526
573
|
const bytecodeLoaderBlock = getBytecodeLoaderBlock(chunk.fileName);
|
|
527
|
-
const bytecodeModuleBlock = `require("./${
|
|
574
|
+
const bytecodeModuleBlock = `require("./${path5.basename(name) + "c"}");`;
|
|
528
575
|
const code = `${useStrict}
|
|
529
576
|
${bytecodeLoaderBlock}
|
|
530
577
|
module.exports=${bytecodeModuleBlock}
|
|
531
578
|
`;
|
|
532
|
-
|
|
579
|
+
fs3.writeFileSync(chunkFilePath, code);
|
|
533
580
|
} else {
|
|
534
|
-
|
|
581
|
+
fs3.unlinkSync(chunkFilePath);
|
|
535
582
|
}
|
|
536
583
|
bytecodeFiles.push({ name: name + "c", size: bytecodeBuffer.length });
|
|
537
584
|
} else {
|
|
@@ -558,14 +605,14 @@ module.exports=${bytecodeModuleBlock}
|
|
|
558
605
|
_code = hasBytecodeMoudle ? _code.replace(useStrict, `${useStrict}
|
|
559
606
|
${bytecodeLoaderBlock}`) : _code;
|
|
560
607
|
}
|
|
561
|
-
|
|
608
|
+
fs3.writeFileSync(chunkFilePath, _code);
|
|
562
609
|
}
|
|
563
610
|
}
|
|
564
611
|
})
|
|
565
612
|
);
|
|
566
613
|
},
|
|
567
614
|
closeBundle() {
|
|
568
|
-
const outDir = `${normalizePath(
|
|
615
|
+
const outDir = `${normalizePath(path5.relative(config.root, path5.resolve(config.root, config.build.outDir)))}/`;
|
|
569
616
|
bytecodeFiles.forEach((file) => {
|
|
570
617
|
bytecodeLog.info(
|
|
571
618
|
`${outDir}${file.name} [${readableSize(file.size)}]`,
|
|
@@ -577,8 +624,6 @@ ${bytecodeLoaderBlock}`) : _code;
|
|
|
577
624
|
}
|
|
578
625
|
};
|
|
579
626
|
}
|
|
580
|
-
|
|
581
|
-
// src/vite.ts
|
|
582
627
|
function debugStartup(args) {
|
|
583
628
|
if (process.env.VSCODE_DEBUG) {
|
|
584
629
|
console.log("[startup] Electron App");
|
|
@@ -589,9 +634,9 @@ function debugStartup(args) {
|
|
|
589
634
|
function getMainFilePath(options) {
|
|
590
635
|
let mainFilePath;
|
|
591
636
|
if (typeof options === "string") {
|
|
592
|
-
mainFilePath = basename(options);
|
|
637
|
+
mainFilePath = path5.basename(options);
|
|
593
638
|
} else if (Array.isArray(options)) {
|
|
594
|
-
mainFilePath = basename(options[0]);
|
|
639
|
+
mainFilePath = path5.basename(options[0]);
|
|
595
640
|
} else {
|
|
596
641
|
const name = options?.index ?? options?.main;
|
|
597
642
|
if (!name) {
|
|
@@ -616,7 +661,7 @@ async function electronWithUpdater(options) {
|
|
|
616
661
|
preload: _preload,
|
|
617
662
|
sourcemap = !isBuild,
|
|
618
663
|
minify = isBuild,
|
|
619
|
-
buildVersionJson
|
|
664
|
+
buildVersionJson,
|
|
620
665
|
updater,
|
|
621
666
|
bytecode,
|
|
622
667
|
useNotBundle = true,
|
|
@@ -631,21 +676,18 @@ async function electronWithUpdater(options) {
|
|
|
631
676
|
return void 0;
|
|
632
677
|
}
|
|
633
678
|
const _options = parseOptions(pkg, sourcemap, minify, updater);
|
|
634
|
-
const bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? {
|
|
635
|
-
if (bytecodeOptions) {
|
|
636
|
-
minify = false;
|
|
637
|
-
}
|
|
679
|
+
const bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? { enable: true } : void 0;
|
|
638
680
|
try {
|
|
639
|
-
rmSync(_options.buildAsarOption.electronDistPath, { recursive: true, force: true });
|
|
640
|
-
rmSync(_options.buildEntryOption.entryOutputDirPath, { recursive: true, force: true });
|
|
681
|
+
fs3.rmSync(_options.buildAsarOption.electronDistPath, { recursive: true, force: true });
|
|
682
|
+
fs3.rmSync(_options.buildEntryOption.entryOutputDirPath, { recursive: true, force: true });
|
|
641
683
|
} catch {
|
|
642
684
|
}
|
|
643
685
|
log.info(`remove old files`, { timestamp: true });
|
|
644
686
|
const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert } = _options;
|
|
645
687
|
const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
|
|
646
688
|
sourcemap ??= isBuild || !!process.env.VSCODE_DEBUG;
|
|
647
|
-
const _appPath = normalizePath(join(entryOutputDirPath, "entry.js"));
|
|
648
|
-
if (resolve(normalizePath(pkg.main)) !== resolve(_appPath)) {
|
|
689
|
+
const _appPath = normalizePath(path5.join(entryOutputDirPath, "entry.js"));
|
|
690
|
+
if (path5.resolve(normalizePath(pkg.main)) !== path5.resolve(_appPath)) {
|
|
649
691
|
throw new Error(`wrong "main" field in package.json: "${pkg.main}", it should be "${_appPath}"`);
|
|
650
692
|
}
|
|
651
693
|
const define = {
|
|
@@ -661,20 +703,20 @@ async function electronWithUpdater(options) {
|
|
|
661
703
|
await buildEntry(
|
|
662
704
|
buildEntryOption,
|
|
663
705
|
define,
|
|
664
|
-
|
|
706
|
+
bytecodeOptions
|
|
665
707
|
);
|
|
666
708
|
log.info(`vite build entry to '${entryOutputDirPath}'`, { timestamp: true });
|
|
667
709
|
};
|
|
668
710
|
const _postBuild = postBuild ? async () => await postBuild({
|
|
669
711
|
getPathFromEntryOutputDir(...paths) {
|
|
670
|
-
return join(entryOutputDirPath, ...paths);
|
|
712
|
+
return path5.join(entryOutputDirPath, ...paths);
|
|
671
713
|
},
|
|
672
714
|
copyToEntryOutputDir({ from, to, skipIfExist = true }) {
|
|
673
|
-
if (existsSync(from)) {
|
|
674
|
-
const target = join(entryOutputDirPath, to ?? basename(from));
|
|
675
|
-
if (!skipIfExist || !existsSync(target)) {
|
|
715
|
+
if (fs3.existsSync(from)) {
|
|
716
|
+
const target = path5.join(entryOutputDirPath, to ?? path5.basename(from));
|
|
717
|
+
if (!skipIfExist || !fs3.existsSync(target)) {
|
|
676
718
|
try {
|
|
677
|
-
cpSync(from, target);
|
|
719
|
+
fs3.cpSync(from, target);
|
|
678
720
|
} catch (error) {
|
|
679
721
|
log.warn(`copy failed: ${error}`);
|
|
680
722
|
}
|
|
@@ -685,7 +727,8 @@ async function electronWithUpdater(options) {
|
|
|
685
727
|
};
|
|
686
728
|
let isInit = false;
|
|
687
729
|
const rollupOptions = {
|
|
688
|
-
external: (src) => src.startsWith("node:") || Object.keys("dependencies" in pkg ? pkg.dependencies : {}).includes(src)
|
|
730
|
+
external: (src) => src.startsWith("node:") || Object.keys("dependencies" in pkg ? pkg.dependencies : {}).includes(src) || src === "original-fs",
|
|
731
|
+
treeshake: true
|
|
689
732
|
};
|
|
690
733
|
const electronPluginOptions = {
|
|
691
734
|
main: {
|
|
@@ -706,7 +749,7 @@ async function electronWithUpdater(options) {
|
|
|
706
749
|
{
|
|
707
750
|
plugins: [
|
|
708
751
|
!isBuild && useNotBundle ? notBundle() : void 0,
|
|
709
|
-
bytecodeOptions && bytecodePlugin(
|
|
752
|
+
bytecodeOptions && bytecodePlugin("main", bytecodeOptions)
|
|
710
753
|
],
|
|
711
754
|
build: {
|
|
712
755
|
sourcemap,
|
|
@@ -725,7 +768,7 @@ async function electronWithUpdater(options) {
|
|
|
725
768
|
vite: mergeConfig(
|
|
726
769
|
{
|
|
727
770
|
plugins: [
|
|
728
|
-
bytecodeOptions && bytecodePlugin(
|
|
771
|
+
bytecodeOptions && bytecodePlugin("preload", bytecodeOptions),
|
|
729
772
|
{
|
|
730
773
|
name: `${id}-build`,
|
|
731
774
|
enforce: "post",
|
|
@@ -736,7 +779,9 @@ async function electronWithUpdater(options) {
|
|
|
736
779
|
await _buildEntry();
|
|
737
780
|
await _postBuild();
|
|
738
781
|
const buffer = await buildAsar(buildAsarOption);
|
|
739
|
-
if (buildVersionJson) {
|
|
782
|
+
if (!buildVersionJson && !isCI) {
|
|
783
|
+
log.warn("no `buildVersionJson` setup, skip build version json. Will build in CI by default", { timestamp: true });
|
|
784
|
+
} else {
|
|
740
785
|
await buildVersion(buildVersionOption, buffer);
|
|
741
786
|
}
|
|
742
787
|
}
|
|
@@ -769,7 +814,10 @@ async function electronWithUpdater(options) {
|
|
|
769
814
|
}
|
|
770
815
|
let extraHmrPlugin;
|
|
771
816
|
if (nativeModuleEntryMap) {
|
|
772
|
-
const files = [
|
|
817
|
+
const files = [
|
|
818
|
+
...Object.values(nativeModuleEntryMap),
|
|
819
|
+
appEntryPath
|
|
820
|
+
].map((file) => path5.resolve(normalizePath(file)));
|
|
773
821
|
extraHmrPlugin = {
|
|
774
822
|
name: `${id}-dev`,
|
|
775
823
|
apply() {
|
|
@@ -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 defaultVerifySignature(buffer: Buffer, version: string, signature: string, cert: string): boolean;
|
|
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, defaultVerifySignature 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 defaultVerifySignature(buffer: Buffer, version: string, signature: string, cert: string): boolean;
|
|
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, defaultVerifySignature 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.8",
|
|
5
5
|
"description": "electron incremental update tools, powered by vite",
|
|
6
6
|
"author": "subframe7536",
|
|
7
7
|
"license": "MIT",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"build": "tsup && esno fix-module.cjs",
|
|
46
46
|
"release": "pnpm test && pnpm run build && bumpp --all && npm publish",
|
|
47
47
|
"test": "vitest --run",
|
|
48
|
+
"test:dev": "vitest",
|
|
48
49
|
"format": "eslint . --fix"
|
|
49
50
|
},
|
|
50
51
|
"publishConfig": {
|
|
@@ -53,27 +54,28 @@
|
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
56
|
"@electron/asar": "*",
|
|
56
|
-
"esbuild": "*"
|
|
57
|
-
"magic-string": "*"
|
|
57
|
+
"esbuild": "*"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@babel/core": "^7.24.
|
|
60
|
+
"@babel/core": "^7.24.9",
|
|
61
61
|
"@babel/plugin-transform-arrow-functions": "^7.24.7",
|
|
62
|
+
"@babel/plugin-transform-template-literals": "^7.24.7",
|
|
62
63
|
"@subframe7536/type-utils": "^0.1.6",
|
|
63
64
|
"ci-info": "^4.0.0",
|
|
64
65
|
"local-pkg": "^0.5.0",
|
|
66
|
+
"magic-string": "^0.30.10",
|
|
65
67
|
"selfsigned": "^2.4.1",
|
|
66
68
|
"vite-plugin-electron": "^0.28.7"
|
|
67
69
|
},
|
|
68
70
|
"devDependencies": {
|
|
69
|
-
"@subframe7536/eslint-config": "^0.7.
|
|
71
|
+
"@subframe7536/eslint-config": "^0.7.3",
|
|
70
72
|
"@types/babel__core": "^7.20.5",
|
|
71
73
|
"@types/node": "^20.14.11",
|
|
72
74
|
"bumpp": "^9.4.1",
|
|
73
75
|
"electron": "28.2.10",
|
|
74
76
|
"eslint": "^9.7.0",
|
|
75
77
|
"esno": "^4.7.0",
|
|
76
|
-
"tsup": "^8.1
|
|
78
|
+
"tsup": "^8.2.1",
|
|
77
79
|
"typescript": "^5.5.3",
|
|
78
80
|
"vite": "^5.3.4",
|
|
79
81
|
"vite-plugin-electron": "^0.28.7",
|