electron-incremental-update 2.0.0-beta.7 → 2.0.0-beta.9
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/index.cjs +43 -52
- package/dist/index.d.cts +130 -9
- package/dist/index.d.ts +130 -9
- package/dist/index.js +36 -51
- package/dist/provider.cjs +25 -9
- package/dist/provider.d.cts +17 -1
- package/dist/provider.d.ts +17 -1
- package/dist/provider.js +17 -6
- package/dist/{types-CItP6bL-.d.ts → types-D7OK98ln.d.ts} +3 -28
- package/dist/{types-CItP6bL-.d.cts → types-mEfMjnlV.d.cts} +3 -28
- package/dist/utils.cjs +24 -25
- package/dist/utils.d.cts +3 -11
- package/dist/utils.d.ts +3 -11
- package/dist/utils.js +2 -11
- package/dist/version-DgfjJQUx.d.cts +27 -0
- package/dist/version-DgfjJQUx.d.ts +27 -0
- package/dist/vite.d.ts +7 -4
- package/dist/vite.js +164 -125
- package/package.json +8 -6
- package/dist/core-DJdvtwvU.d.ts +0 -134
- package/dist/core-ZUlLHadf.d.cts +0 -134
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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';
|
|
@@ -9,14 +9,14 @@ import { isCI } from 'ci-info';
|
|
|
9
9
|
export { isCI } from 'ci-info';
|
|
10
10
|
import Asar from '@electron/asar';
|
|
11
11
|
import { build } from 'esbuild';
|
|
12
|
-
import
|
|
12
|
+
import cp from 'node:child_process';
|
|
13
13
|
import * as babel from '@babel/core';
|
|
14
14
|
import MagicString from 'magic-string';
|
|
15
|
-
import
|
|
16
|
-
import
|
|
15
|
+
import zlib from 'node:zlib';
|
|
16
|
+
import crypto from 'node:crypto';
|
|
17
17
|
import { generate } from 'selfsigned';
|
|
18
18
|
|
|
19
|
-
// src/vite.ts
|
|
19
|
+
// src/vite/index.ts
|
|
20
20
|
|
|
21
21
|
// src/utils/version.ts
|
|
22
22
|
function parseVersion(version) {
|
|
@@ -64,7 +64,7 @@ var bytecodeId = `${id}-bytecode`;
|
|
|
64
64
|
var log = createLogger("info", { prefix: `[${id}]` });
|
|
65
65
|
var bytecodeLog = createLogger("info", { prefix: `[${bytecodeId}]` });
|
|
66
66
|
|
|
67
|
-
// src/
|
|
67
|
+
// src/vite/bytecode/code.ts
|
|
68
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";
|
|
69
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';
|
|
70
70
|
var electronModulePath = getPackageInfoSync("electron")?.rootPath;
|
|
@@ -76,13 +76,13 @@ function getElectronPath() {
|
|
|
76
76
|
if (!electronModulePath) {
|
|
77
77
|
throw new Error("Electron is not installed");
|
|
78
78
|
}
|
|
79
|
-
const pathFile =
|
|
79
|
+
const pathFile = path5.join(electronModulePath, "path.txt");
|
|
80
80
|
let executablePath;
|
|
81
|
-
if (
|
|
82
|
-
executablePath =
|
|
81
|
+
if (fs3.existsSync(pathFile)) {
|
|
82
|
+
executablePath = fs3.readFileSync(pathFile, "utf-8");
|
|
83
83
|
}
|
|
84
84
|
if (executablePath) {
|
|
85
|
-
electronExecPath =
|
|
85
|
+
electronExecPath = path5.join(electronModulePath, "dist", executablePath);
|
|
86
86
|
process.env.ELECTRON_EXEC_PATH = electronExecPath;
|
|
87
87
|
} else {
|
|
88
88
|
throw new Error("Electron executable file is not existed");
|
|
@@ -91,14 +91,14 @@ function getElectronPath() {
|
|
|
91
91
|
return electronExecPath;
|
|
92
92
|
}
|
|
93
93
|
function getBytecodeCompilerPath() {
|
|
94
|
-
const scriptPath =
|
|
95
|
-
if (!
|
|
96
|
-
|
|
94
|
+
const scriptPath = path5.join(electronModulePath, "bytenode.cjs");
|
|
95
|
+
if (!fs3.existsSync(scriptPath)) {
|
|
96
|
+
fs3.writeFileSync(scriptPath, bytecodeGeneratorScript);
|
|
97
97
|
}
|
|
98
98
|
return scriptPath;
|
|
99
99
|
}
|
|
100
100
|
function toRelativePath(filename, importer) {
|
|
101
|
-
const relPath =
|
|
101
|
+
const relPath = path5.posix.relative(path5.dirname(importer), filename);
|
|
102
102
|
return relPath.startsWith(".") ? relPath : `./${relPath}`;
|
|
103
103
|
}
|
|
104
104
|
function compileToBytecode(code) {
|
|
@@ -106,8 +106,8 @@ function compileToBytecode(code) {
|
|
|
106
106
|
const logErr = (...args) => bytecodeLog.error(args.join(" "), { timestamp: true });
|
|
107
107
|
const electronPath = getElectronPath();
|
|
108
108
|
const bytecodePath = getBytecodeCompilerPath();
|
|
109
|
-
return new Promise((
|
|
110
|
-
const proc = spawn(electronPath, [bytecodePath], {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const proc = cp.spawn(electronPath, [bytecodePath], {
|
|
111
111
|
env: { ELECTRON_RUN_AS_NODE: "1" },
|
|
112
112
|
stdio: ["pipe", "pipe", "pipe", "ipc"]
|
|
113
113
|
});
|
|
@@ -118,7 +118,7 @@ function compileToBytecode(code) {
|
|
|
118
118
|
if (proc.stdout) {
|
|
119
119
|
proc.stdout.on("data", (chunk) => data = Buffer.concat([data, chunk]));
|
|
120
120
|
proc.stdout.on("error", (err) => logErr(err));
|
|
121
|
-
proc.stdout.on("end", () =>
|
|
121
|
+
proc.stdout.on("end", () => resolve(data));
|
|
122
122
|
}
|
|
123
123
|
if (proc.stderr) {
|
|
124
124
|
proc.stderr.on("data", (chunk) => logErr("Error: ", chunk.toString()));
|
|
@@ -126,40 +126,80 @@ function compileToBytecode(code) {
|
|
|
126
126
|
}
|
|
127
127
|
proc.addListener("error", (err) => logErr(err));
|
|
128
128
|
proc.on("error", (err) => reject(err));
|
|
129
|
-
proc.on("exit", () =>
|
|
129
|
+
proc.on("exit", () => resolve(data));
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
|
-
function
|
|
132
|
+
function convertArrowFunctionAndTemplate(code) {
|
|
133
133
|
const result = babel.transform(code, {
|
|
134
|
-
plugins: ["@babel/plugin-transform-arrow-functions"]
|
|
134
|
+
plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-template-literals"]
|
|
135
135
|
});
|
|
136
136
|
return {
|
|
137
137
|
code: result?.code || code,
|
|
138
138
|
map: result?.map
|
|
139
139
|
};
|
|
140
140
|
}
|
|
141
|
-
function
|
|
142
|
-
|
|
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})`;
|
|
143
145
|
}
|
|
144
|
-
function
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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");
|
|
152
|
+
}
|
|
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);
|
|
149
195
|
}
|
|
150
|
-
return
|
|
196
|
+
return {
|
|
151
197
|
code: s.toString(),
|
|
152
|
-
map: sourcemap ? s.generateMap({ hires:
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
var decodeFn = "function(a,b){return String.fromCharCode.apply(0,a.map(function(x){return x-b}))}";
|
|
156
|
-
function obfuscateString(input) {
|
|
157
|
-
const offset = Math.random() << 4 | 0;
|
|
158
|
-
const hexArray = input.split("").map((c) => "0x" + (c.charCodeAt(0) + offset).toString(16));
|
|
159
|
-
return `(${decodeFn})(${JSON.stringify(hexArray)},${offset})`;
|
|
198
|
+
map: sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
199
|
+
};
|
|
160
200
|
}
|
|
161
201
|
|
|
162
|
-
// src/
|
|
202
|
+
// src/vite/utils.ts
|
|
163
203
|
function readableSize(size) {
|
|
164
204
|
const units = ["B", "KB", "MB", "GB"];
|
|
165
205
|
let i = 0;
|
|
@@ -170,7 +210,7 @@ function readableSize(size) {
|
|
|
170
210
|
return `${size.toFixed(2)} ${units[i]}`;
|
|
171
211
|
}
|
|
172
212
|
|
|
173
|
-
// src/
|
|
213
|
+
// src/vite/build.ts
|
|
174
214
|
async function buildAsar({
|
|
175
215
|
version,
|
|
176
216
|
asarOutputPath,
|
|
@@ -179,11 +219,11 @@ async function buildAsar({
|
|
|
179
219
|
rendererDistPath,
|
|
180
220
|
generateGzipFile
|
|
181
221
|
}) {
|
|
182
|
-
renameSync(rendererDistPath, join(electronDistPath, "renderer"));
|
|
183
|
-
writeFileSync(join(electronDistPath, "version"), version);
|
|
222
|
+
fs3.renameSync(rendererDistPath, path5.join(electronDistPath, "renderer"));
|
|
223
|
+
fs3.writeFileSync(path5.join(electronDistPath, "version"), version);
|
|
184
224
|
await Asar.createPackage(electronDistPath, asarOutputPath);
|
|
185
|
-
const buf = await generateGzipFile(readFileSync(asarOutputPath));
|
|
186
|
-
writeFileSync(gzipPath, buf);
|
|
225
|
+
const buf = await generateGzipFile(fs3.readFileSync(asarOutputPath));
|
|
226
|
+
fs3.writeFileSync(gzipPath, buf);
|
|
187
227
|
log.info(`build update asar to '${gzipPath}' [${readableSize(buf.length)}]`, { timestamp: true });
|
|
188
228
|
return buf;
|
|
189
229
|
}
|
|
@@ -206,9 +246,9 @@ async function buildVersion({
|
|
|
206
246
|
signature: "",
|
|
207
247
|
version
|
|
208
248
|
};
|
|
209
|
-
if (existsSync(versionPath)) {
|
|
249
|
+
if (fs3.existsSync(versionPath)) {
|
|
210
250
|
try {
|
|
211
|
-
const oldVersionJson = JSON.parse(readFileSync(versionPath, "utf-8"));
|
|
251
|
+
const oldVersionJson = JSON.parse(fs3.readFileSync(versionPath, "utf-8"));
|
|
212
252
|
if (isUpdateJSON(oldVersionJson)) {
|
|
213
253
|
_json = oldVersionJson;
|
|
214
254
|
} else {
|
|
@@ -222,7 +262,7 @@ async function buildVersion({
|
|
|
222
262
|
if (!isUpdateJSON(_json)) {
|
|
223
263
|
throw new Error("invalid version info");
|
|
224
264
|
}
|
|
225
|
-
writeFileSync(versionPath, JSON.stringify(_json, null, 2));
|
|
265
|
+
fs3.writeFileSync(versionPath, JSON.stringify(_json, null, 2));
|
|
226
266
|
log.info(`build version info to '${versionPath}'`, { timestamp: true });
|
|
227
267
|
}
|
|
228
268
|
async function buildEntry({
|
|
@@ -232,7 +272,7 @@ async function buildEntry({
|
|
|
232
272
|
entryOutputDirPath,
|
|
233
273
|
nativeModuleEntryMap,
|
|
234
274
|
overrideEsbuildOptions
|
|
235
|
-
}, define,
|
|
275
|
+
}, define, bytecodeOptions) {
|
|
236
276
|
const option = mergeConfig(
|
|
237
277
|
{
|
|
238
278
|
entryPoints: {
|
|
@@ -257,30 +297,27 @@ async function buildEntry({
|
|
|
257
297
|
overrideEsbuildOptions ?? {}
|
|
258
298
|
);
|
|
259
299
|
const { metafile } = await build(option);
|
|
260
|
-
if (
|
|
300
|
+
if (!bytecodeOptions?.enable) {
|
|
261
301
|
return;
|
|
262
302
|
}
|
|
263
|
-
const filePaths = Object.keys(metafile?.outputs ?? []);
|
|
303
|
+
const filePaths = Object.keys(metafile?.outputs ?? []).filter((filePath) => filePath.endsWith("js"));
|
|
264
304
|
for (const filePath of filePaths) {
|
|
265
|
-
let code = readFileSync(filePath, "utf-8");
|
|
266
|
-
const fileName = basename(filePath);
|
|
305
|
+
let code = fs3.readFileSync(filePath, "utf-8");
|
|
306
|
+
const fileName = path5.basename(filePath);
|
|
267
307
|
const isEntry = fileName.endsWith("entry.js");
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
308
|
+
let transformedCode = convertLiteral(convertArrowFunctionAndTemplate(code).code).code;
|
|
309
|
+
if (bytecodeOptions.beforeCompile) {
|
|
310
|
+
const result = await bytecodeOptions.beforeCompile(transformedCode, filePath);
|
|
311
|
+
if (result) {
|
|
312
|
+
transformedCode = result;
|
|
313
|
+
}
|
|
273
314
|
}
|
|
274
|
-
const transformedCode = convertString(
|
|
275
|
-
convertArrowToFunction(code).code,
|
|
276
|
-
[...protectedStrings, ...isEntry ? getCert(code) : []]
|
|
277
|
-
).code;
|
|
278
315
|
const buffer = await compileToBytecode(transformedCode);
|
|
279
|
-
writeFileSync(
|
|
280
|
-
writeFileSync(
|
|
316
|
+
fs3.writeFileSync(
|
|
281
317
|
filePath,
|
|
282
318
|
`${isEntry ? bytecodeModuleLoaderCode : useStrict}${isEntry ? "" : "module.exports = "}require("./${fileName}c")`
|
|
283
319
|
);
|
|
320
|
+
fs3.writeFileSync(`${filePath}c`, buffer);
|
|
284
321
|
bytecodeLog.info(
|
|
285
322
|
`${filePath} [${(buffer.byteLength / 1e3).toFixed(2)} kB]`,
|
|
286
323
|
{ timestamp: true }
|
|
@@ -288,49 +325,45 @@ async function buildEntry({
|
|
|
288
325
|
}
|
|
289
326
|
bytecodeLog.info(`${filePaths.length} file${filePaths.length > 1 ? "s" : ""} compiled into bytecode`, { timestamp: true });
|
|
290
327
|
}
|
|
291
|
-
function getCert(code) {
|
|
292
|
-
const cert = code.match(/-----BEGIN CERTIFICATE-----[\s\S]*-----END CERTIFICATE-----\\n/)?.[0];
|
|
293
|
-
return cert ? [cert] : [];
|
|
294
|
-
}
|
|
295
328
|
async function defaultZipFile(buffer) {
|
|
296
|
-
return new Promise((
|
|
297
|
-
brotliCompress(buffer, (err, buffer2) => {
|
|
329
|
+
return new Promise((resolve, reject) => {
|
|
330
|
+
zlib.brotliCompress(buffer, (err, buffer2) => {
|
|
298
331
|
if (err) {
|
|
299
332
|
reject(err);
|
|
300
333
|
} else {
|
|
301
|
-
|
|
334
|
+
resolve(buffer2);
|
|
302
335
|
}
|
|
303
336
|
});
|
|
304
337
|
});
|
|
305
338
|
}
|
|
306
339
|
function hashBuffer(data, length) {
|
|
307
|
-
const hash = createHash("SHA256").update(data).digest("binary");
|
|
340
|
+
const hash = crypto.createHash("SHA256").update(data).digest("binary");
|
|
308
341
|
return Buffer.from(hash).subarray(0, length);
|
|
309
342
|
}
|
|
310
343
|
function aesEncrypt(plainText, key, iv) {
|
|
311
|
-
const cipher = createCipheriv("aes-256-cbc", key, iv);
|
|
344
|
+
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
|
|
312
345
|
return cipher.update(plainText, "utf8", "base64url") + cipher.final("base64url");
|
|
313
346
|
}
|
|
314
347
|
function defaultSignature(buffer, privateKey, cert, version) {
|
|
315
|
-
const sig = createSign("RSA-SHA256").update(buffer).sign(createPrivateKey(privateKey), "base64");
|
|
348
|
+
const sig = crypto.createSign("RSA-SHA256").update(buffer).sign(crypto.createPrivateKey(privateKey), "base64");
|
|
316
349
|
return aesEncrypt(`${sig}%${version}`, hashBuffer(cert, 32), hashBuffer(buffer, 16));
|
|
317
350
|
}
|
|
318
351
|
function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
319
|
-
const privateKeyDir = dirname(privateKeyPath);
|
|
320
|
-
if (!existsSync(privateKeyDir)) {
|
|
321
|
-
mkdirSync(privateKeyDir, { recursive: true });
|
|
352
|
+
const privateKeyDir = path5.dirname(privateKeyPath);
|
|
353
|
+
if (!fs3.existsSync(privateKeyDir)) {
|
|
354
|
+
fs3.mkdirSync(privateKeyDir, { recursive: true });
|
|
322
355
|
}
|
|
323
|
-
const certDir = dirname(certPath);
|
|
324
|
-
if (!existsSync(certDir)) {
|
|
325
|
-
mkdirSync(certDir, { recursive: true });
|
|
356
|
+
const certDir = path5.dirname(certPath);
|
|
357
|
+
if (!fs3.existsSync(certDir)) {
|
|
358
|
+
fs3.mkdirSync(certDir, { recursive: true });
|
|
326
359
|
}
|
|
327
360
|
const { cert, private: privateKey } = generate(subject, {
|
|
328
361
|
keySize: keyLength,
|
|
329
362
|
algorithm: "sha256",
|
|
330
363
|
days
|
|
331
364
|
});
|
|
332
|
-
writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
|
|
333
|
-
writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
|
|
365
|
+
fs3.writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
|
|
366
|
+
fs3.writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
|
|
334
367
|
}
|
|
335
368
|
function parseKeys({
|
|
336
369
|
keyLength,
|
|
@@ -339,29 +372,29 @@ function parseKeys({
|
|
|
339
372
|
subject,
|
|
340
373
|
days
|
|
341
374
|
}) {
|
|
342
|
-
const keysDir = dirname(privateKeyPath);
|
|
375
|
+
const keysDir = path5.dirname(privateKeyPath);
|
|
343
376
|
let privateKey = process.env.UPDATER_PK;
|
|
344
377
|
let cert = process.env.UPDATER_CERT;
|
|
345
378
|
if (privateKey && cert) {
|
|
346
379
|
log.info("use UPDATER_PK and UPDATER_CERT from environment variables", { timestamp: true });
|
|
347
380
|
return { privateKey, cert };
|
|
348
381
|
}
|
|
349
|
-
if (!existsSync(keysDir)) {
|
|
350
|
-
mkdirSync(keysDir);
|
|
382
|
+
if (!fs3.existsSync(keysDir)) {
|
|
383
|
+
fs3.mkdirSync(keysDir);
|
|
351
384
|
}
|
|
352
|
-
if (!existsSync(privateKeyPath) || !existsSync(certPath)) {
|
|
385
|
+
if (!fs3.existsSync(privateKeyPath) || !fs3.existsSync(certPath)) {
|
|
353
386
|
log.info("no key pair found, generate new key pair", { timestamp: true });
|
|
354
387
|
generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
|
|
355
388
|
}
|
|
356
|
-
privateKey = readFileSync(privateKeyPath, "utf-8");
|
|
357
|
-
cert = readFileSync(certPath, "utf-8");
|
|
389
|
+
privateKey = fs3.readFileSync(privateKeyPath, "utf-8");
|
|
390
|
+
cert = fs3.readFileSync(certPath, "utf-8");
|
|
358
391
|
return { privateKey, cert };
|
|
359
392
|
}
|
|
360
393
|
function parseSubjects(subject) {
|
|
361
394
|
return Object.entries(subject).filter(([_, value]) => !!value).map(([name, value]) => ({ name, value }));
|
|
362
395
|
}
|
|
363
396
|
|
|
364
|
-
// src/
|
|
397
|
+
// src/vite/option.ts
|
|
365
398
|
function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
366
399
|
const {
|
|
367
400
|
minimumVersion = "0.0.0",
|
|
@@ -433,15 +466,16 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
433
466
|
};
|
|
434
467
|
return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert };
|
|
435
468
|
}
|
|
436
|
-
function bytecodePlugin(
|
|
469
|
+
function bytecodePlugin(env, options) {
|
|
470
|
+
const {
|
|
471
|
+
enable,
|
|
472
|
+
preload = false,
|
|
473
|
+
beforeCompile
|
|
474
|
+
} = options;
|
|
437
475
|
if (!enable) {
|
|
438
476
|
return null;
|
|
439
477
|
}
|
|
440
|
-
|
|
441
|
-
protectedStrings = [],
|
|
442
|
-
enablePreload = false
|
|
443
|
-
} = options;
|
|
444
|
-
if (!enablePreload && env === "preload") {
|
|
478
|
+
if (!preload && env === "preload") {
|
|
445
479
|
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 });
|
|
446
480
|
return null;
|
|
447
481
|
}
|
|
@@ -457,10 +491,9 @@ function bytecodePlugin(enable, env, options = {}) {
|
|
|
457
491
|
config = resolvedConfig;
|
|
458
492
|
},
|
|
459
493
|
transform(code, id2) {
|
|
460
|
-
if (
|
|
461
|
-
return;
|
|
494
|
+
if (!filter(id2)) {
|
|
495
|
+
return convertLiteral(code, !!config.build.sourcemap);
|
|
462
496
|
}
|
|
463
|
-
return convertString(code, protectedStrings, !!config.build.sourcemap);
|
|
464
497
|
},
|
|
465
498
|
generateBundle(options2) {
|
|
466
499
|
if (options2.format !== "es" && bytecodeRequired) {
|
|
@@ -482,7 +515,7 @@ function bytecodePlugin(enable, env, options = {}) {
|
|
|
482
515
|
}
|
|
483
516
|
if (chunk.type === "chunk") {
|
|
484
517
|
bytecodeRequired = true;
|
|
485
|
-
return
|
|
518
|
+
return convertArrowFunctionAndTemplate(code);
|
|
486
519
|
}
|
|
487
520
|
return null;
|
|
488
521
|
},
|
|
@@ -497,7 +530,7 @@ function bytecodePlugin(enable, env, options = {}) {
|
|
|
497
530
|
(chunk) => chunk.type === "chunk" && chunk.fileName !== bytecodeModuleLoader
|
|
498
531
|
);
|
|
499
532
|
const bytecodeChunks = chunks.map((chunk) => chunk.fileName);
|
|
500
|
-
const nonEntryChunks = chunks.filter((chunk) => !chunk.isEntry).map((chunk) =>
|
|
533
|
+
const nonEntryChunks = chunks.filter((chunk) => !chunk.isEntry).map((chunk) => path5.basename(chunk.fileName));
|
|
501
534
|
const pattern = nonEntryChunks.map((chunk) => `(${chunk})`).join("|");
|
|
502
535
|
const bytecodeRE = pattern ? new RegExp(`require\\(\\S*(?=(${pattern})\\S*\\))`, "g") : null;
|
|
503
536
|
const getBytecodeLoaderBlock = (chunkFileName) => {
|
|
@@ -508,6 +541,12 @@ function bytecodePlugin(enable, env, options = {}) {
|
|
|
508
541
|
const chunk = output[name];
|
|
509
542
|
if (chunk.type === "chunk") {
|
|
510
543
|
let _code = chunk.code;
|
|
544
|
+
if (beforeCompile) {
|
|
545
|
+
const cbResult = await beforeCompile(_code, chunk.fileName);
|
|
546
|
+
if (cbResult) {
|
|
547
|
+
_code = cbResult;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
511
550
|
if (bytecodeRE && _code.match(bytecodeRE)) {
|
|
512
551
|
let match;
|
|
513
552
|
const s = new MagicString(_code);
|
|
@@ -520,20 +559,20 @@ function bytecodePlugin(enable, env, options = {}) {
|
|
|
520
559
|
}
|
|
521
560
|
_code = s.toString();
|
|
522
561
|
}
|
|
523
|
-
const chunkFilePath =
|
|
562
|
+
const chunkFilePath = path5.resolve(outDir, name);
|
|
524
563
|
if (bytecodeChunks.includes(name)) {
|
|
525
564
|
const bytecodeBuffer = await compileToBytecode(_code);
|
|
526
|
-
|
|
565
|
+
fs3.writeFileSync(chunkFilePath + "c", bytecodeBuffer);
|
|
527
566
|
if (chunk.isEntry) {
|
|
528
567
|
const bytecodeLoaderBlock = getBytecodeLoaderBlock(chunk.fileName);
|
|
529
|
-
const bytecodeModuleBlock = `require("./${
|
|
568
|
+
const bytecodeModuleBlock = `require("./${path5.basename(name) + "c"}");`;
|
|
530
569
|
const code = `${useStrict}
|
|
531
570
|
${bytecodeLoaderBlock}
|
|
532
571
|
module.exports=${bytecodeModuleBlock}
|
|
533
572
|
`;
|
|
534
|
-
|
|
573
|
+
fs3.writeFileSync(chunkFilePath, code);
|
|
535
574
|
} else {
|
|
536
|
-
|
|
575
|
+
fs3.unlinkSync(chunkFilePath);
|
|
537
576
|
}
|
|
538
577
|
bytecodeFiles.push({ name: name + "c", size: bytecodeBuffer.length });
|
|
539
578
|
} else {
|
|
@@ -560,14 +599,14 @@ module.exports=${bytecodeModuleBlock}
|
|
|
560
599
|
_code = hasBytecodeMoudle ? _code.replace(useStrict, `${useStrict}
|
|
561
600
|
${bytecodeLoaderBlock}`) : _code;
|
|
562
601
|
}
|
|
563
|
-
|
|
602
|
+
fs3.writeFileSync(chunkFilePath, _code);
|
|
564
603
|
}
|
|
565
604
|
}
|
|
566
605
|
})
|
|
567
606
|
);
|
|
568
607
|
},
|
|
569
608
|
closeBundle() {
|
|
570
|
-
const outDir = `${normalizePath(
|
|
609
|
+
const outDir = `${normalizePath(path5.relative(config.root, path5.resolve(config.root, config.build.outDir)))}/`;
|
|
571
610
|
bytecodeFiles.forEach((file) => {
|
|
572
611
|
bytecodeLog.info(
|
|
573
612
|
`${outDir}${file.name} [${readableSize(file.size)}]`,
|
|
@@ -589,9 +628,9 @@ function debugStartup(args) {
|
|
|
589
628
|
function getMainFilePath(options) {
|
|
590
629
|
let mainFilePath;
|
|
591
630
|
if (typeof options === "string") {
|
|
592
|
-
mainFilePath = basename(options);
|
|
631
|
+
mainFilePath = path5.basename(options);
|
|
593
632
|
} else if (Array.isArray(options)) {
|
|
594
|
-
mainFilePath = basename(options[0]);
|
|
633
|
+
mainFilePath = path5.basename(options[0]);
|
|
595
634
|
} else {
|
|
596
635
|
const name = options?.index ?? options?.main;
|
|
597
636
|
if (!name) {
|
|
@@ -631,21 +670,18 @@ async function electronWithUpdater(options) {
|
|
|
631
670
|
return void 0;
|
|
632
671
|
}
|
|
633
672
|
const _options = parseOptions(pkg, sourcemap, minify, updater);
|
|
634
|
-
const bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? {
|
|
635
|
-
if (bytecodeOptions) {
|
|
636
|
-
minify = false;
|
|
637
|
-
}
|
|
673
|
+
const bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? { enable: true } : void 0;
|
|
638
674
|
try {
|
|
639
|
-
rmSync(_options.buildAsarOption.electronDistPath, { recursive: true, force: true });
|
|
640
|
-
rmSync(_options.buildEntryOption.entryOutputDirPath, { recursive: true, force: true });
|
|
675
|
+
fs3.rmSync(_options.buildAsarOption.electronDistPath, { recursive: true, force: true });
|
|
676
|
+
fs3.rmSync(_options.buildEntryOption.entryOutputDirPath, { recursive: true, force: true });
|
|
641
677
|
} catch {
|
|
642
678
|
}
|
|
643
679
|
log.info(`remove old files`, { timestamp: true });
|
|
644
680
|
const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert } = _options;
|
|
645
681
|
const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
|
|
646
682
|
sourcemap ??= isBuild || !!process.env.VSCODE_DEBUG;
|
|
647
|
-
const _appPath = normalizePath(join(entryOutputDirPath, "entry.js"));
|
|
648
|
-
if (resolve(normalizePath(pkg.main)) !== resolve(_appPath)) {
|
|
683
|
+
const _appPath = normalizePath(path5.join(entryOutputDirPath, "entry.js"));
|
|
684
|
+
if (path5.resolve(normalizePath(pkg.main)) !== path5.resolve(_appPath)) {
|
|
649
685
|
throw new Error(`wrong "main" field in package.json: "${pkg.main}", it should be "${_appPath}"`);
|
|
650
686
|
}
|
|
651
687
|
const define = {
|
|
@@ -661,20 +697,20 @@ async function electronWithUpdater(options) {
|
|
|
661
697
|
await buildEntry(
|
|
662
698
|
buildEntryOption,
|
|
663
699
|
define,
|
|
664
|
-
|
|
700
|
+
bytecodeOptions
|
|
665
701
|
);
|
|
666
702
|
log.info(`vite build entry to '${entryOutputDirPath}'`, { timestamp: true });
|
|
667
703
|
};
|
|
668
704
|
const _postBuild = postBuild ? async () => await postBuild({
|
|
669
705
|
getPathFromEntryOutputDir(...paths) {
|
|
670
|
-
return join(entryOutputDirPath, ...paths);
|
|
706
|
+
return path5.join(entryOutputDirPath, ...paths);
|
|
671
707
|
},
|
|
672
708
|
copyToEntryOutputDir({ from, to, skipIfExist = true }) {
|
|
673
|
-
if (existsSync(from)) {
|
|
674
|
-
const target = join(entryOutputDirPath, to ?? basename(from));
|
|
675
|
-
if (!skipIfExist || !existsSync(target)) {
|
|
709
|
+
if (fs3.existsSync(from)) {
|
|
710
|
+
const target = path5.join(entryOutputDirPath, to ?? path5.basename(from));
|
|
711
|
+
if (!skipIfExist || !fs3.existsSync(target)) {
|
|
676
712
|
try {
|
|
677
|
-
cpSync(from, target);
|
|
713
|
+
fs3.cpSync(from, target);
|
|
678
714
|
} catch (error) {
|
|
679
715
|
log.warn(`copy failed: ${error}`);
|
|
680
716
|
}
|
|
@@ -685,7 +721,7 @@ async function electronWithUpdater(options) {
|
|
|
685
721
|
};
|
|
686
722
|
let isInit = false;
|
|
687
723
|
const rollupOptions = {
|
|
688
|
-
external: (src) => src.startsWith("node:") || Object.keys("dependencies" in pkg ? pkg.dependencies : {}).includes(src),
|
|
724
|
+
external: (src) => src.startsWith("node:") || Object.keys("dependencies" in pkg ? pkg.dependencies : {}).includes(src) || src === "original-fs",
|
|
689
725
|
treeshake: true
|
|
690
726
|
};
|
|
691
727
|
const electronPluginOptions = {
|
|
@@ -707,7 +743,7 @@ async function electronWithUpdater(options) {
|
|
|
707
743
|
{
|
|
708
744
|
plugins: [
|
|
709
745
|
!isBuild && useNotBundle ? notBundle() : void 0,
|
|
710
|
-
bytecodeOptions && bytecodePlugin(
|
|
746
|
+
bytecodeOptions && bytecodePlugin("main", bytecodeOptions)
|
|
711
747
|
],
|
|
712
748
|
build: {
|
|
713
749
|
sourcemap,
|
|
@@ -726,7 +762,7 @@ async function electronWithUpdater(options) {
|
|
|
726
762
|
vite: mergeConfig(
|
|
727
763
|
{
|
|
728
764
|
plugins: [
|
|
729
|
-
bytecodeOptions && bytecodePlugin(
|
|
765
|
+
bytecodeOptions && bytecodePlugin("preload", bytecodeOptions),
|
|
730
766
|
{
|
|
731
767
|
name: `${id}-build`,
|
|
732
768
|
enforce: "post",
|
|
@@ -772,7 +808,10 @@ async function electronWithUpdater(options) {
|
|
|
772
808
|
}
|
|
773
809
|
let extraHmrPlugin;
|
|
774
810
|
if (nativeModuleEntryMap) {
|
|
775
|
-
const files = [
|
|
811
|
+
const files = [
|
|
812
|
+
...Object.values(nativeModuleEntryMap),
|
|
813
|
+
appEntryPath
|
|
814
|
+
].map((file) => path5.resolve(normalizePath(file)));
|
|
776
815
|
extraHmrPlugin = {
|
|
777
816
|
name: `${id}-dev`,
|
|
778
817
|
apply() {
|
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.9",
|
|
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",
|