electron-incremental-update 2.0.0-beta.1 → 2.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/chunk-IABBXJFB.js +87 -0
- package/dist/chunk-KZSYEXLO.js +55 -0
- package/dist/chunk-RCRKUKFX.js +70 -0
- package/dist/index.cjs +193 -233
- package/dist/index.d.cts +89 -117
- package/dist/index.d.ts +89 -117
- package/dist/index.js +166 -169
- package/dist/provider.cjs +165 -146
- package/dist/provider.d.cts +94 -22
- package/dist/provider.d.ts +94 -22
- package/dist/provider.js +125 -71
- package/dist/types-C8JhnJjU.d.ts +80 -0
- package/dist/types-CGSkHX4Y.d.cts +80 -0
- package/dist/utils.cjs +142 -191
- package/dist/utils.d.cts +42 -30
- package/dist/utils.d.ts +42 -30
- package/dist/utils.js +3 -62
- package/dist/version-BYVQ367i.d.cts +62 -0
- package/dist/version-BYVQ367i.d.ts +62 -0
- package/dist/vite.d.ts +372 -0
- package/dist/vite.js +326 -274
- package/dist/zip-rm9ED9nU.d.cts +33 -0
- package/dist/zip-rm9ED9nU.d.ts +33 -0
- package/package.json +21 -15
- package/dist/chunk-RSLOPAIZ.js +0 -247
- package/dist/decrypt-BNBcodiO.d.cts +0 -4
- package/dist/decrypt-BNBcodiO.d.ts +0 -4
- package/dist/types-DxPmQmaq.d.cts +0 -61
- package/dist/types-seJf3Wbc.d.ts +0 -61
- package/dist/version-CffZWDhZ.d.cts +0 -32
- package/dist/version-CffZWDhZ.d.ts +0 -32
package/dist/vite.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import path5 from 'node:path';
|
|
2
|
+
import fs3 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 { isCI } from 'ci-info';
|
|
9
|
+
export { isCI } from 'ci-info';
|
|
10
|
+
import Asar from '@electron/asar';
|
|
11
|
+
import { build } from 'esbuild';
|
|
12
|
+
import cp from 'node:child_process';
|
|
13
|
+
import * as babel from '@babel/core';
|
|
14
|
+
import MagicString from 'magic-string';
|
|
15
|
+
import zlib from 'node:zlib';
|
|
16
|
+
import crypto from 'node:crypto';
|
|
17
|
+
import { generate } from 'selfsigned';
|
|
9
18
|
|
|
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";
|
|
19
|
+
// src/vite/index.ts
|
|
16
20
|
|
|
17
21
|
// src/utils/version.ts
|
|
18
22
|
function parseVersion(version) {
|
|
@@ -34,72 +38,35 @@ function parseVersion(version) {
|
|
|
34
38
|
ret.stageVersion = Number(_v) || -1;
|
|
35
39
|
}
|
|
36
40
|
if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch) || Number.isNaN(ret.stageVersion)) {
|
|
37
|
-
throw new TypeError(`
|
|
41
|
+
throw new TypeError(`Invalid version: ${version}`);
|
|
38
42
|
}
|
|
39
43
|
return ret;
|
|
40
44
|
}
|
|
41
45
|
function isUpdateJSON(json) {
|
|
42
|
-
const is = (j) => !!(j && j.minimumVersion && j.signature && j.
|
|
46
|
+
const is = (j) => !!(j && j.minimumVersion && j.signature && j.version);
|
|
43
47
|
return is(json) && is(json?.beta);
|
|
44
48
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
function defaultVersionJsonGenerator(existingJson, signature, version, minimumVersion) {
|
|
50
|
+
existingJson.beta = {
|
|
51
|
+
version,
|
|
52
|
+
minimumVersion,
|
|
53
|
+
signature
|
|
54
|
+
};
|
|
55
|
+
if (!parseVersion(version).stage) {
|
|
56
|
+
existingJson.version = version;
|
|
57
|
+
existingJson.minimumVersion = minimumVersion;
|
|
58
|
+
existingJson.signature = signature;
|
|
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(null);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
}
|
|
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);
|
|
60
|
+
return existingJson;
|
|
70
61
|
}
|
|
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}]` });
|
|
90
65
|
var bytecodeLog = createLogger("info", { prefix: `[${bytecodeId}]` });
|
|
91
66
|
|
|
92
|
-
// src/
|
|
67
|
+
// src/vite/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 = path5.join(electronModulePath, "path.txt");
|
|
113
80
|
let executablePath;
|
|
114
|
-
if (
|
|
115
|
-
executablePath =
|
|
81
|
+
if (fs3.existsSync(pathFile)) {
|
|
82
|
+
executablePath = fs3.readFileSync(pathFile, "utf-8");
|
|
116
83
|
}
|
|
117
84
|
if (executablePath) {
|
|
118
|
-
electronExecPath =
|
|
85
|
+
electronExecPath = path5.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,23 +91,23 @@ function getElectronPath() {
|
|
|
124
91
|
return electronExecPath;
|
|
125
92
|
}
|
|
126
93
|
function getBytecodeCompilerPath() {
|
|
127
|
-
const scriptPath =
|
|
128
|
-
if (!
|
|
129
|
-
|
|
94
|
+
const scriptPath = path5.join(electronModulePath, "EIU_bytenode.cjs");
|
|
95
|
+
if (!fs3.existsSync(scriptPath)) {
|
|
96
|
+
fs3.writeFileSync(scriptPath, bytecodeGeneratorScript);
|
|
130
97
|
}
|
|
131
98
|
return scriptPath;
|
|
132
99
|
}
|
|
133
100
|
function toRelativePath(filename, importer) {
|
|
134
|
-
const relPath =
|
|
101
|
+
const relPath = path5.posix.relative(path5.dirname(importer), filename);
|
|
135
102
|
return relPath.startsWith(".") ? relPath : `./${relPath}`;
|
|
136
103
|
}
|
|
137
104
|
function compileToBytecode(code) {
|
|
138
105
|
let data = Buffer.from([]);
|
|
139
|
-
const logErr = (...args) =>
|
|
106
|
+
const logErr = (...args) => bytecodeLog.error(args.join(" "), { timestamp: true });
|
|
140
107
|
const electronPath = getElectronPath();
|
|
141
108
|
const bytecodePath = getBytecodeCompilerPath();
|
|
142
|
-
return new Promise((
|
|
143
|
-
const proc = spawn(electronPath, [bytecodePath], {
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const proc = cp.spawn(electronPath, [bytecodePath], {
|
|
144
111
|
env: { ELECTRON_RUN_AS_NODE: "1" },
|
|
145
112
|
stdio: ["pipe", "pipe", "pipe", "ipc"]
|
|
146
113
|
});
|
|
@@ -151,7 +118,7 @@ function compileToBytecode(code) {
|
|
|
151
118
|
if (proc.stdout) {
|
|
152
119
|
proc.stdout.on("data", (chunk) => data = Buffer.concat([data, chunk]));
|
|
153
120
|
proc.stdout.on("error", (err) => logErr(err));
|
|
154
|
-
proc.stdout.on("end", () =>
|
|
121
|
+
proc.stdout.on("end", () => resolve(data));
|
|
155
122
|
}
|
|
156
123
|
if (proc.stderr) {
|
|
157
124
|
proc.stderr.on("data", (chunk) => logErr("Error: ", chunk.toString()));
|
|
@@ -159,54 +126,111 @@ function compileToBytecode(code) {
|
|
|
159
126
|
}
|
|
160
127
|
proc.addListener("error", (err) => logErr(err));
|
|
161
128
|
proc.on("error", (err) => reject(err));
|
|
162
|
-
proc.on("exit", () =>
|
|
129
|
+
proc.on("exit", () => resolve(data));
|
|
163
130
|
});
|
|
164
131
|
}
|
|
165
|
-
function
|
|
132
|
+
function convertArrowFunctionAndTemplate(code) {
|
|
166
133
|
const result = babel.transform(code, {
|
|
167
|
-
plugins: ["@babel/plugin-transform-arrow-functions"]
|
|
134
|
+
plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-template-literals"]
|
|
168
135
|
});
|
|
169
136
|
return {
|
|
170
137
|
code: result?.code || code,
|
|
171
138
|
map: result?.map
|
|
172
139
|
};
|
|
173
140
|
}
|
|
174
|
-
function
|
|
175
|
-
|
|
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})`;
|
|
176
145
|
}
|
|
177
|
-
function
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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 === "ObjectMethod" && parent.key === node) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
if (parent.type === "ObjectProperty" && parent.key === node) {
|
|
175
|
+
const result2 = `[${obfuscateString(node.value, offset)}]`;
|
|
176
|
+
const start2 = node.start;
|
|
177
|
+
const end2 = node.end;
|
|
178
|
+
if (start2 && end2) {
|
|
179
|
+
s.overwrite(start2, end2, result2);
|
|
180
|
+
hasTransformed = true;
|
|
181
|
+
}
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (!node.value.trim()) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const result = obfuscateString(node.value, offset);
|
|
188
|
+
const start = node.start;
|
|
189
|
+
const end = node.end;
|
|
190
|
+
if (start && end) {
|
|
191
|
+
s.overwrite(start, end, result);
|
|
192
|
+
hasTransformed = true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
if (hasTransformed) {
|
|
197
|
+
s.append("\n").append(decodeFn);
|
|
182
198
|
}
|
|
183
|
-
return
|
|
199
|
+
return {
|
|
184
200
|
code: s.toString(),
|
|
185
|
-
map: sourcemap ? s.generateMap({ hires:
|
|
186
|
-
}
|
|
201
|
+
map: sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
202
|
+
};
|
|
187
203
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
204
|
+
|
|
205
|
+
// src/vite/utils.ts
|
|
206
|
+
function readableSize(size) {
|
|
207
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
208
|
+
let i = 0;
|
|
209
|
+
while (size >= 1024 && i < units.length - 1) {
|
|
210
|
+
size /= 1024;
|
|
211
|
+
i++;
|
|
212
|
+
}
|
|
213
|
+
return `${size.toFixed(2)} ${units[i]}`;
|
|
193
214
|
}
|
|
194
215
|
|
|
195
|
-
// src/
|
|
216
|
+
// src/vite/build.ts
|
|
196
217
|
async function buildAsar({
|
|
197
218
|
version,
|
|
198
219
|
asarOutputPath,
|
|
199
220
|
gzipPath,
|
|
200
221
|
electronDistPath,
|
|
201
|
-
rendererDistPath
|
|
222
|
+
rendererDistPath,
|
|
223
|
+
generateGzipFile
|
|
202
224
|
}) {
|
|
203
|
-
renameSync(rendererDistPath, join(electronDistPath, "renderer"));
|
|
204
|
-
|
|
225
|
+
fs3.renameSync(rendererDistPath, path5.join(electronDistPath, "renderer"));
|
|
226
|
+
fs3.writeFileSync(path5.join(electronDistPath, "version"), version);
|
|
205
227
|
await Asar.createPackage(electronDistPath, asarOutputPath);
|
|
206
|
-
await
|
|
228
|
+
const buf = await generateGzipFile(fs3.readFileSync(asarOutputPath));
|
|
229
|
+
fs3.writeFileSync(gzipPath, buf);
|
|
230
|
+
log.info(`Build update asar to '${gzipPath}' [${readableSize(buf.length)}]`, { timestamp: true });
|
|
231
|
+
return buf;
|
|
207
232
|
}
|
|
208
233
|
async function buildVersion({
|
|
209
|
-
gzipPath,
|
|
210
234
|
versionPath,
|
|
211
235
|
privateKey,
|
|
212
236
|
cert,
|
|
@@ -214,52 +238,35 @@ async function buildVersion({
|
|
|
214
238
|
minimumVersion,
|
|
215
239
|
generateSignature,
|
|
216
240
|
generateVersionJson
|
|
217
|
-
}) {
|
|
241
|
+
}, asarBuffer) {
|
|
218
242
|
let _json = {
|
|
219
243
|
beta: {
|
|
220
244
|
minimumVersion: version,
|
|
221
245
|
signature: "",
|
|
222
|
-
size: 0,
|
|
223
246
|
version
|
|
224
247
|
},
|
|
225
248
|
minimumVersion: version,
|
|
226
249
|
signature: "",
|
|
227
|
-
size: 0,
|
|
228
250
|
version
|
|
229
251
|
};
|
|
230
|
-
if (
|
|
252
|
+
if (fs3.existsSync(versionPath)) {
|
|
231
253
|
try {
|
|
232
|
-
const oldVersionJson = JSON.parse(
|
|
254
|
+
const oldVersionJson = JSON.parse(fs3.readFileSync(versionPath, "utf-8"));
|
|
233
255
|
if (isUpdateJSON(oldVersionJson)) {
|
|
234
256
|
_json = oldVersionJson;
|
|
235
257
|
} else {
|
|
236
|
-
log.warn("
|
|
258
|
+
log.warn("Old version json is invalid, ignore it", { timestamp: true });
|
|
237
259
|
}
|
|
238
|
-
} catch
|
|
260
|
+
} catch {
|
|
239
261
|
}
|
|
240
262
|
}
|
|
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
|
-
}
|
|
263
|
+
const sig = await generateSignature(asarBuffer, privateKey, cert, version);
|
|
264
|
+
_json = await generateVersionJson(_json, sig, version, minimumVersion);
|
|
265
|
+
if (!isUpdateJSON(_json)) {
|
|
266
|
+
throw new Error("Invalid version info");
|
|
261
267
|
}
|
|
262
|
-
|
|
268
|
+
fs3.writeFileSync(versionPath, JSON.stringify(_json, null, 2));
|
|
269
|
+
log.info(`build version info to '${versionPath}'`, { timestamp: true });
|
|
263
270
|
}
|
|
264
271
|
async function buildEntry({
|
|
265
272
|
sourcemap,
|
|
@@ -268,7 +275,7 @@ async function buildEntry({
|
|
|
268
275
|
entryOutputDirPath,
|
|
269
276
|
nativeModuleEntryMap,
|
|
270
277
|
overrideEsbuildOptions
|
|
271
|
-
}, define,
|
|
278
|
+
}, isESM, define, bytecodeOptions) {
|
|
272
279
|
const option = mergeConfig(
|
|
273
280
|
{
|
|
274
281
|
entryPoints: {
|
|
@@ -284,70 +291,83 @@ async function buildEntry({
|
|
|
284
291
|
entryNames: "[dir]/[name]",
|
|
285
292
|
assetNames: "[dir]/[name]",
|
|
286
293
|
external: ["electron", "original-fs"],
|
|
294
|
+
treeShaking: true,
|
|
287
295
|
loader: {
|
|
288
296
|
".node": "empty"
|
|
289
297
|
},
|
|
290
|
-
define
|
|
298
|
+
define,
|
|
299
|
+
format: isESM ? "esm" : "cjs"
|
|
291
300
|
},
|
|
292
301
|
overrideEsbuildOptions ?? {}
|
|
293
302
|
);
|
|
294
303
|
const { metafile } = await build(option);
|
|
295
|
-
if (
|
|
304
|
+
if (!bytecodeOptions?.enable) {
|
|
296
305
|
return;
|
|
297
306
|
}
|
|
298
|
-
const filePaths = Object.keys(metafile?.outputs ?? []);
|
|
307
|
+
const filePaths = Object.keys(metafile?.outputs ?? []).filter((filePath) => filePath.endsWith("js"));
|
|
299
308
|
for (const filePath of filePaths) {
|
|
300
|
-
let code =
|
|
301
|
-
const fileName = basename(filePath);
|
|
309
|
+
let code = fs3.readFileSync(filePath, "utf-8");
|
|
310
|
+
const fileName = path5.basename(filePath);
|
|
302
311
|
const isEntry = fileName.endsWith("entry.js");
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
312
|
+
let transformedCode = convertLiteral(convertArrowFunctionAndTemplate(code).code).code;
|
|
313
|
+
if (bytecodeOptions.beforeCompile) {
|
|
314
|
+
const result = await bytecodeOptions.beforeCompile(transformedCode, filePath);
|
|
315
|
+
if (result) {
|
|
316
|
+
transformedCode = result;
|
|
317
|
+
}
|
|
308
318
|
}
|
|
309
|
-
const transformedCode = convertString(
|
|
310
|
-
convertArrowToFunction(code).code,
|
|
311
|
-
[...protectedStrings, ...isEntry ? getCert(code) : []]
|
|
312
|
-
).code;
|
|
313
319
|
const buffer = await compileToBytecode(transformedCode);
|
|
314
|
-
|
|
315
|
-
writeFileSync2(
|
|
320
|
+
fs3.writeFileSync(
|
|
316
321
|
filePath,
|
|
317
322
|
`${isEntry ? bytecodeModuleLoaderCode : useStrict}${isEntry ? "" : "module.exports = "}require("./${fileName}c")`
|
|
318
323
|
);
|
|
324
|
+
fs3.writeFileSync(`${filePath}c`, buffer);
|
|
319
325
|
bytecodeLog.info(
|
|
320
|
-
`${filePath}
|
|
326
|
+
`${filePath} [${(buffer.byteLength / 1e3).toFixed(2)} kB]`,
|
|
321
327
|
{ timestamp: true }
|
|
322
328
|
);
|
|
323
329
|
}
|
|
324
|
-
bytecodeLog.info(`${filePaths.length}
|
|
330
|
+
bytecodeLog.info(`${filePaths.length} file${filePaths.length > 1 ? "s" : ""} compiled into bytecode`, { timestamp: true });
|
|
325
331
|
}
|
|
326
|
-
function
|
|
327
|
-
|
|
328
|
-
|
|
332
|
+
async function defaultZipFile(buffer) {
|
|
333
|
+
return new Promise((resolve, reject) => {
|
|
334
|
+
zlib.brotliCompress(buffer, (err, buffer2) => {
|
|
335
|
+
if (err) {
|
|
336
|
+
reject(err);
|
|
337
|
+
} else {
|
|
338
|
+
resolve(buffer2);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
function hashBuffer(data, length) {
|
|
344
|
+
const hash = crypto.createHash("SHA256").update(data).digest("binary");
|
|
345
|
+
return Buffer.from(hash).subarray(0, length);
|
|
346
|
+
}
|
|
347
|
+
function aesEncrypt(plainText, key, iv) {
|
|
348
|
+
const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
|
|
349
|
+
return cipher.update(plainText, "utf8", "base64url") + cipher.final("base64url");
|
|
350
|
+
}
|
|
351
|
+
function defaultSignature(buffer, privateKey, cert, version) {
|
|
352
|
+
const sig = crypto.createSign("RSA-SHA256").update(buffer).sign(crypto.createPrivateKey(privateKey), "base64");
|
|
353
|
+
return aesEncrypt(`${sig}%${version}`, hashBuffer(cert, 32), hashBuffer(buffer, 16));
|
|
329
354
|
}
|
|
330
|
-
|
|
331
|
-
// src/build-plugins/key.ts
|
|
332
|
-
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
333
|
-
import { dirname } from "node:path";
|
|
334
|
-
import { generate } from "selfsigned";
|
|
335
355
|
function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
|
|
336
|
-
const privateKeyDir = dirname(privateKeyPath);
|
|
337
|
-
if (!
|
|
338
|
-
mkdirSync(privateKeyDir, { recursive: true });
|
|
356
|
+
const privateKeyDir = path5.dirname(privateKeyPath);
|
|
357
|
+
if (!fs3.existsSync(privateKeyDir)) {
|
|
358
|
+
fs3.mkdirSync(privateKeyDir, { recursive: true });
|
|
339
359
|
}
|
|
340
|
-
const certDir = dirname(certPath);
|
|
341
|
-
if (!
|
|
342
|
-
mkdirSync(certDir, { recursive: true });
|
|
360
|
+
const certDir = path5.dirname(certPath);
|
|
361
|
+
if (!fs3.existsSync(certDir)) {
|
|
362
|
+
fs3.mkdirSync(certDir, { recursive: true });
|
|
343
363
|
}
|
|
344
364
|
const { cert, private: privateKey } = generate(subject, {
|
|
345
365
|
keySize: keyLength,
|
|
346
366
|
algorithm: "sha256",
|
|
347
367
|
days
|
|
348
368
|
});
|
|
349
|
-
|
|
350
|
-
|
|
369
|
+
fs3.writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
|
|
370
|
+
fs3.writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
|
|
351
371
|
}
|
|
352
372
|
function parseKeys({
|
|
353
373
|
keyLength,
|
|
@@ -356,21 +376,29 @@ function parseKeys({
|
|
|
356
376
|
subject,
|
|
357
377
|
days
|
|
358
378
|
}) {
|
|
359
|
-
const keysDir = dirname(privateKeyPath);
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
379
|
+
const keysDir = path5.dirname(privateKeyPath);
|
|
380
|
+
let privateKey = process.env.UPDATER_PK;
|
|
381
|
+
let cert = process.env.UPDATER_CERT;
|
|
382
|
+
if (privateKey && cert) {
|
|
383
|
+
log.info("Use `UPDATER_PK` and `UPDATER_CERT` from environment variables", { timestamp: true });
|
|
384
|
+
return { privateKey, cert };
|
|
385
|
+
}
|
|
386
|
+
if (!fs3.existsSync(keysDir)) {
|
|
387
|
+
fs3.mkdirSync(keysDir);
|
|
388
|
+
}
|
|
389
|
+
if (!fs3.existsSync(privateKeyPath) || !fs3.existsSync(certPath)) {
|
|
390
|
+
log.info("No key pair found, generate new key pair", { timestamp: true });
|
|
363
391
|
generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
|
|
364
392
|
}
|
|
365
|
-
|
|
366
|
-
|
|
393
|
+
privateKey = fs3.readFileSync(privateKeyPath, "utf-8");
|
|
394
|
+
cert = fs3.readFileSync(certPath, "utf-8");
|
|
367
395
|
return { privateKey, cert };
|
|
368
396
|
}
|
|
369
397
|
function parseSubjects(subject) {
|
|
370
398
|
return Object.entries(subject).filter(([_, value]) => !!value).map(([name, value]) => ({ name, value }));
|
|
371
399
|
}
|
|
372
400
|
|
|
373
|
-
// src/
|
|
401
|
+
// src/vite/option.ts
|
|
374
402
|
function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
375
403
|
const {
|
|
376
404
|
minimumVersion = "0.0.0",
|
|
@@ -394,24 +422,27 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
394
422
|
privateKeyPath = "keys/private.pem",
|
|
395
423
|
certPath = "keys/cert.pem",
|
|
396
424
|
keyLength = 2048,
|
|
397
|
-
certInfo
|
|
398
|
-
|
|
425
|
+
certInfo: {
|
|
426
|
+
subject = {
|
|
427
|
+
commonName: pkg.name,
|
|
428
|
+
organizationName: `org.${pkg.name}`
|
|
429
|
+
},
|
|
430
|
+
days = 3650
|
|
431
|
+
} = {}
|
|
432
|
+
} = {},
|
|
433
|
+
overrideGenerator: {
|
|
434
|
+
generateGzipFile = defaultZipFile,
|
|
435
|
+
generateSignature = defaultSignature,
|
|
436
|
+
generateVersionJson = defaultVersionJsonGenerator
|
|
399
437
|
} = {}
|
|
400
438
|
} = options;
|
|
401
|
-
const { generateSignature, generateVersionJson } = overrideGenerator;
|
|
402
|
-
let {
|
|
403
|
-
subject = {
|
|
404
|
-
commonName: pkg.name,
|
|
405
|
-
organizationName: `org.${pkg.name}`
|
|
406
|
-
},
|
|
407
|
-
days = 3650
|
|
408
|
-
} = certInfo;
|
|
409
439
|
const buildAsarOption = {
|
|
410
440
|
version: pkg.version,
|
|
411
441
|
asarOutputPath,
|
|
412
442
|
gzipPath,
|
|
413
443
|
electronDistPath,
|
|
414
|
-
rendererDistPath
|
|
444
|
+
rendererDistPath,
|
|
445
|
+
generateGzipFile
|
|
415
446
|
};
|
|
416
447
|
const buildEntryOption = {
|
|
417
448
|
minify: entryMinify ?? minify,
|
|
@@ -431,7 +462,6 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
431
462
|
const buildVersionOption = {
|
|
432
463
|
version: pkg.version,
|
|
433
464
|
minimumVersion,
|
|
434
|
-
gzipPath,
|
|
435
465
|
privateKey,
|
|
436
466
|
cert,
|
|
437
467
|
versionPath,
|
|
@@ -440,22 +470,17 @@ function parseOptions(pkg, sourcemap = false, minify = false, options = {}) {
|
|
|
440
470
|
};
|
|
441
471
|
return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert };
|
|
442
472
|
}
|
|
443
|
-
|
|
444
|
-
// src/build-plugins/bytecode/index.ts
|
|
445
|
-
import path2 from "node:path";
|
|
446
|
-
import fs2 from "node:fs";
|
|
447
|
-
import { createFilter, normalizePath } from "vite";
|
|
448
|
-
import MagicString2 from "magic-string";
|
|
449
|
-
function bytecodePlugin(isBuild, env, options = {}) {
|
|
450
|
-
if (!isBuild) {
|
|
451
|
-
return null;
|
|
452
|
-
}
|
|
473
|
+
function bytecodePlugin(env, options) {
|
|
453
474
|
const {
|
|
454
|
-
|
|
455
|
-
|
|
475
|
+
enable,
|
|
476
|
+
preload = false,
|
|
477
|
+
beforeCompile
|
|
456
478
|
} = options;
|
|
457
|
-
if (!
|
|
458
|
-
|
|
479
|
+
if (!enable) {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
if (!preload && env === "preload") {
|
|
483
|
+
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 });
|
|
459
484
|
return null;
|
|
460
485
|
}
|
|
461
486
|
const filter = createFilter(/\.(m?[jt]s|[jt]sx)$/);
|
|
@@ -470,10 +495,9 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
470
495
|
config = resolvedConfig;
|
|
471
496
|
},
|
|
472
497
|
transform(code, id2) {
|
|
473
|
-
if (
|
|
474
|
-
return;
|
|
498
|
+
if (!filter(id2)) {
|
|
499
|
+
return convertLiteral(code, !!config.build.sourcemap);
|
|
475
500
|
}
|
|
476
|
-
return convertString(code, protectedStrings, !!config.build.sourcemap);
|
|
477
501
|
},
|
|
478
502
|
generateBundle(options2) {
|
|
479
503
|
if (options2.format !== "es" && bytecodeRequired) {
|
|
@@ -488,14 +512,14 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
488
512
|
renderChunk(code, chunk, options2) {
|
|
489
513
|
if (options2.format === "es") {
|
|
490
514
|
bytecodeLog.warn(
|
|
491
|
-
'bytecodePlugin does not support ES module, please
|
|
515
|
+
'`bytecodePlugin` does not support ES module, please set "build.rollupOptions.output.format" option to "cjs"',
|
|
492
516
|
{ timestamp: true }
|
|
493
517
|
);
|
|
494
518
|
return null;
|
|
495
519
|
}
|
|
496
520
|
if (chunk.type === "chunk") {
|
|
497
521
|
bytecodeRequired = true;
|
|
498
|
-
return
|
|
522
|
+
return convertArrowFunctionAndTemplate(code);
|
|
499
523
|
}
|
|
500
524
|
return null;
|
|
501
525
|
},
|
|
@@ -510,7 +534,7 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
510
534
|
(chunk) => chunk.type === "chunk" && chunk.fileName !== bytecodeModuleLoader
|
|
511
535
|
);
|
|
512
536
|
const bytecodeChunks = chunks.map((chunk) => chunk.fileName);
|
|
513
|
-
const nonEntryChunks = chunks.filter((chunk) => !chunk.isEntry).map((chunk) =>
|
|
537
|
+
const nonEntryChunks = chunks.filter((chunk) => !chunk.isEntry).map((chunk) => path5.basename(chunk.fileName));
|
|
514
538
|
const pattern = nonEntryChunks.map((chunk) => `(${chunk})`).join("|");
|
|
515
539
|
const bytecodeRE = pattern ? new RegExp(`require\\(\\S*(?=(${pattern})\\S*\\))`, "g") : null;
|
|
516
540
|
const getBytecodeLoaderBlock = (chunkFileName) => {
|
|
@@ -521,9 +545,16 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
521
545
|
const chunk = output[name];
|
|
522
546
|
if (chunk.type === "chunk") {
|
|
523
547
|
let _code = chunk.code;
|
|
548
|
+
const chunkFilePath = path5.resolve(outDir, name);
|
|
549
|
+
if (beforeCompile) {
|
|
550
|
+
const cbResult = await beforeCompile(_code, chunkFilePath);
|
|
551
|
+
if (cbResult) {
|
|
552
|
+
_code = cbResult;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
524
555
|
if (bytecodeRE && _code.match(bytecodeRE)) {
|
|
525
556
|
let match;
|
|
526
|
-
const s = new
|
|
557
|
+
const s = new MagicString(_code);
|
|
527
558
|
while (match = bytecodeRE.exec(_code)) {
|
|
528
559
|
const [prefix, chunkName] = match;
|
|
529
560
|
const len = prefix.length + chunkName.length;
|
|
@@ -533,20 +564,19 @@ function bytecodePlugin(isBuild, env, options = {}) {
|
|
|
533
564
|
}
|
|
534
565
|
_code = s.toString();
|
|
535
566
|
}
|
|
536
|
-
const chunkFilePath = path2.resolve(outDir, name);
|
|
537
567
|
if (bytecodeChunks.includes(name)) {
|
|
538
568
|
const bytecodeBuffer = await compileToBytecode(_code);
|
|
539
|
-
|
|
569
|
+
fs3.writeFileSync(chunkFilePath + "c", bytecodeBuffer);
|
|
540
570
|
if (chunk.isEntry) {
|
|
541
571
|
const bytecodeLoaderBlock = getBytecodeLoaderBlock(chunk.fileName);
|
|
542
|
-
const bytecodeModuleBlock = `require("./${
|
|
572
|
+
const bytecodeModuleBlock = `require("./${path5.basename(name) + "c"}");`;
|
|
543
573
|
const code = `${useStrict}
|
|
544
574
|
${bytecodeLoaderBlock}
|
|
545
575
|
module.exports=${bytecodeModuleBlock}
|
|
546
576
|
`;
|
|
547
|
-
|
|
577
|
+
fs3.writeFileSync(chunkFilePath, code);
|
|
548
578
|
} else {
|
|
549
|
-
|
|
579
|
+
fs3.unlinkSync(chunkFilePath);
|
|
550
580
|
}
|
|
551
581
|
bytecodeFiles.push({ name: name + "c", size: bytecodeBuffer.length });
|
|
552
582
|
} else {
|
|
@@ -573,18 +603,17 @@ module.exports=${bytecodeModuleBlock}
|
|
|
573
603
|
_code = hasBytecodeMoudle ? _code.replace(useStrict, `${useStrict}
|
|
574
604
|
${bytecodeLoaderBlock}`) : _code;
|
|
575
605
|
}
|
|
576
|
-
|
|
606
|
+
fs3.writeFileSync(chunkFilePath, _code);
|
|
577
607
|
}
|
|
578
608
|
}
|
|
579
609
|
})
|
|
580
610
|
);
|
|
581
611
|
},
|
|
582
612
|
closeBundle() {
|
|
583
|
-
const outDir = `${normalizePath(
|
|
613
|
+
const outDir = `${normalizePath(path5.relative(config.root, path5.resolve(config.root, config.build.outDir)))}/`;
|
|
584
614
|
bytecodeFiles.forEach((file) => {
|
|
585
|
-
const kbs = file.size / 1e3;
|
|
586
615
|
bytecodeLog.info(
|
|
587
|
-
`${outDir}${file.name}
|
|
616
|
+
`${outDir}${file.name} [${readableSize(file.size)}]`,
|
|
588
617
|
{ timestamp: true }
|
|
589
618
|
);
|
|
590
619
|
});
|
|
@@ -593,17 +622,19 @@ ${bytecodeLoaderBlock}`) : _code;
|
|
|
593
622
|
}
|
|
594
623
|
};
|
|
595
624
|
}
|
|
596
|
-
|
|
597
|
-
// src/vite.ts
|
|
598
625
|
function debugStartup(args) {
|
|
599
|
-
process.env.VSCODE_DEBUG
|
|
626
|
+
if (process.env.VSCODE_DEBUG) {
|
|
627
|
+
console.log("[startup] Electron App");
|
|
628
|
+
} else {
|
|
629
|
+
args.startup();
|
|
630
|
+
}
|
|
600
631
|
}
|
|
601
632
|
function getMainFilePath(options) {
|
|
602
633
|
let mainFilePath;
|
|
603
634
|
if (typeof options === "string") {
|
|
604
|
-
mainFilePath =
|
|
635
|
+
mainFilePath = path5.basename(options);
|
|
605
636
|
} else if (Array.isArray(options)) {
|
|
606
|
-
mainFilePath =
|
|
637
|
+
mainFilePath = path5.basename(options[0]);
|
|
607
638
|
} else {
|
|
608
639
|
const name = options?.index ?? options?.main;
|
|
609
640
|
if (!name) {
|
|
@@ -611,10 +642,11 @@ function getMainFilePath(options) {
|
|
|
611
642
|
}
|
|
612
643
|
mainFilePath = options?.index ? "index.js" : "main.js";
|
|
613
644
|
}
|
|
645
|
+
log.info(`Using "${mainFilePath}" as main file`, { timestamp: true });
|
|
614
646
|
return mainFilePath.replace(/\.[cm]?ts$/, ".js");
|
|
615
647
|
}
|
|
616
648
|
function parseVersionPath(versionPath) {
|
|
617
|
-
versionPath =
|
|
649
|
+
versionPath = normalizePath(versionPath);
|
|
618
650
|
if (!versionPath.startsWith("./")) {
|
|
619
651
|
versionPath = "./" + versionPath;
|
|
620
652
|
}
|
|
@@ -628,66 +660,75 @@ async function electronWithUpdater(options) {
|
|
|
628
660
|
preload: _preload,
|
|
629
661
|
sourcemap = !isBuild,
|
|
630
662
|
minify = isBuild,
|
|
663
|
+
buildVersionJson,
|
|
631
664
|
updater,
|
|
632
665
|
bytecode,
|
|
633
666
|
useNotBundle = true,
|
|
634
667
|
logParsedOptions
|
|
635
668
|
} = options;
|
|
636
|
-
if (!pkg) {
|
|
637
|
-
log.error(
|
|
638
|
-
return
|
|
669
|
+
if (!pkg || !pkg.version || !pkg.name || !pkg.main) {
|
|
670
|
+
log.error("package.json not found or invalid", { timestamp: true });
|
|
671
|
+
return void 0;
|
|
639
672
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
673
|
+
const isESM = pkg.type === "module";
|
|
674
|
+
let bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? { enable: true } : void 0;
|
|
675
|
+
if (isESM && bytecodeOptions?.enable) {
|
|
676
|
+
bytecodeLog.warn(
|
|
677
|
+
'`bytecodePlugin` does not support ES module, please remove "type": "module" in package.json',
|
|
678
|
+
{ timestamp: true }
|
|
679
|
+
);
|
|
680
|
+
bytecodeOptions = void 0;
|
|
648
681
|
}
|
|
682
|
+
const {
|
|
683
|
+
buildAsarOption,
|
|
684
|
+
buildEntryOption,
|
|
685
|
+
buildVersionOption,
|
|
686
|
+
postBuild,
|
|
687
|
+
cert
|
|
688
|
+
} = parseOptions(pkg, sourcemap, minify, updater);
|
|
689
|
+
const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
|
|
649
690
|
try {
|
|
650
|
-
rmSync(
|
|
651
|
-
rmSync(
|
|
652
|
-
} catch
|
|
691
|
+
fs3.rmSync(buildAsarOption.electronDistPath, { recursive: true, force: true });
|
|
692
|
+
fs3.rmSync(entryOutputDirPath, { recursive: true, force: true });
|
|
693
|
+
} catch {
|
|
653
694
|
}
|
|
654
|
-
log.info(`
|
|
655
|
-
const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert } = _options;
|
|
656
|
-
const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
|
|
695
|
+
log.info(`Clear cache files`, { timestamp: true });
|
|
657
696
|
sourcemap ??= isBuild || !!process.env.VSCODE_DEBUG;
|
|
658
|
-
const _appPath =
|
|
659
|
-
if (resolve(
|
|
660
|
-
throw new Error(`
|
|
697
|
+
const _appPath = normalizePath(path5.join(entryOutputDirPath, "entry.js"));
|
|
698
|
+
if (path5.resolve(normalizePath(pkg.main)) !== path5.resolve(_appPath)) {
|
|
699
|
+
throw new Error(`Wrong "main" field in package.json: "${pkg.main}", it should be "${_appPath}"`);
|
|
661
700
|
}
|
|
662
701
|
const define = {
|
|
663
702
|
__EIU_ELECTRON_DIST_PATH__: JSON.stringify(buildAsarOption.electronDistPath),
|
|
664
703
|
__EIU_ENTRY_DIST_PATH__: JSON.stringify(buildEntryOption.entryOutputDirPath),
|
|
665
704
|
__EIU_IS_DEV__: JSON.stringify(!isBuild),
|
|
705
|
+
__EIU_IS_ESM__: JSON.stringify(isESM),
|
|
666
706
|
__EIU_MAIN_DEV_DIR__: JSON.stringify(buildAsarOption.electronDistPath),
|
|
667
707
|
__EIU_MAIN_FILE__: JSON.stringify(getMainFilePath(_main.files)),
|
|
668
708
|
__EIU_SIGNATURE_CERT__: JSON.stringify(cert),
|
|
669
|
-
|
|
709
|
+
__EIU_VERSION_PATH__: JSON.stringify(parseVersionPath(buildVersionOption.versionPath))
|
|
670
710
|
};
|
|
671
711
|
const _buildEntry = async () => {
|
|
672
712
|
await buildEntry(
|
|
673
713
|
buildEntryOption,
|
|
714
|
+
isESM,
|
|
674
715
|
define,
|
|
675
|
-
|
|
716
|
+
bytecodeOptions
|
|
676
717
|
);
|
|
677
|
-
log.info(`
|
|
718
|
+
log.info(`Build entry to '${entryOutputDirPath}'`, { timestamp: true });
|
|
678
719
|
};
|
|
679
720
|
const _postBuild = postBuild ? async () => await postBuild({
|
|
680
721
|
getPathFromEntryOutputDir(...paths) {
|
|
681
|
-
return
|
|
722
|
+
return path5.join(entryOutputDirPath, ...paths);
|
|
682
723
|
},
|
|
683
724
|
copyToEntryOutputDir({ from, to, skipIfExist = true }) {
|
|
684
|
-
if (
|
|
685
|
-
const target =
|
|
686
|
-
if (!skipIfExist || !
|
|
725
|
+
if (fs3.existsSync(from)) {
|
|
726
|
+
const target = path5.join(entryOutputDirPath, to ?? path5.basename(from));
|
|
727
|
+
if (!skipIfExist || !fs3.existsSync(target)) {
|
|
687
728
|
try {
|
|
688
|
-
cpSync(from, target);
|
|
729
|
+
fs3.cpSync(from, target);
|
|
689
730
|
} catch (error) {
|
|
690
|
-
log.warn(`
|
|
731
|
+
log.warn(`Copy failed: ${error}`, { timestamp: true });
|
|
691
732
|
}
|
|
692
733
|
}
|
|
693
734
|
}
|
|
@@ -696,7 +737,8 @@ async function electronWithUpdater(options) {
|
|
|
696
737
|
};
|
|
697
738
|
let isInit = false;
|
|
698
739
|
const rollupOptions = {
|
|
699
|
-
external: (src) => src.startsWith("node:") || Object.keys("dependencies" in pkg ? pkg.dependencies : {}).includes(src)
|
|
740
|
+
external: (src) => src.startsWith("node:") || Object.keys("dependencies" in pkg ? pkg.dependencies : {}).includes(src) || src === "original-fs",
|
|
741
|
+
treeshake: true
|
|
700
742
|
};
|
|
701
743
|
const electronPluginOptions = {
|
|
702
744
|
main: {
|
|
@@ -707,13 +749,17 @@ async function electronWithUpdater(options) {
|
|
|
707
749
|
await _buildEntry();
|
|
708
750
|
await _postBuild();
|
|
709
751
|
}
|
|
710
|
-
|
|
752
|
+
if (_main.onstart) {
|
|
753
|
+
_main.onstart(args);
|
|
754
|
+
} else {
|
|
755
|
+
args.startup();
|
|
756
|
+
}
|
|
711
757
|
},
|
|
712
|
-
vite:
|
|
758
|
+
vite: mergeConfig(
|
|
713
759
|
{
|
|
714
760
|
plugins: [
|
|
715
761
|
!isBuild && useNotBundle ? notBundle() : void 0,
|
|
716
|
-
bytecodeOptions && bytecodePlugin(
|
|
762
|
+
bytecodeOptions && bytecodePlugin("main", bytecodeOptions)
|
|
717
763
|
],
|
|
718
764
|
build: {
|
|
719
765
|
sourcemap,
|
|
@@ -729,10 +775,10 @@ async function electronWithUpdater(options) {
|
|
|
729
775
|
preload: {
|
|
730
776
|
input: _preload.files,
|
|
731
777
|
onstart: _preload.onstart,
|
|
732
|
-
vite:
|
|
778
|
+
vite: mergeConfig(
|
|
733
779
|
{
|
|
734
780
|
plugins: [
|
|
735
|
-
bytecodeOptions && bytecodePlugin(
|
|
781
|
+
bytecodeOptions && bytecodePlugin("preload", bytecodeOptions),
|
|
736
782
|
{
|
|
737
783
|
name: `${id}-build`,
|
|
738
784
|
enforce: "post",
|
|
@@ -742,10 +788,12 @@ async function electronWithUpdater(options) {
|
|
|
742
788
|
async closeBundle() {
|
|
743
789
|
await _buildEntry();
|
|
744
790
|
await _postBuild();
|
|
745
|
-
await buildAsar(buildAsarOption);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
791
|
+
const buffer = await buildAsar(buildAsarOption);
|
|
792
|
+
if (!buildVersionJson && !isCI) {
|
|
793
|
+
log.warn("No `buildVersionJson` setup, skip build version json. Will build in CI by default", { timestamp: true });
|
|
794
|
+
} else {
|
|
795
|
+
await buildVersion(buildVersionOption, buffer);
|
|
796
|
+
}
|
|
749
797
|
}
|
|
750
798
|
}
|
|
751
799
|
],
|
|
@@ -761,20 +809,25 @@ async function electronWithUpdater(options) {
|
|
|
761
809
|
)
|
|
762
810
|
}
|
|
763
811
|
};
|
|
764
|
-
logParsedOptions
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
812
|
+
if (logParsedOptions) {
|
|
813
|
+
log.info(
|
|
814
|
+
JSON.stringify(
|
|
815
|
+
{
|
|
816
|
+
...electronPluginOptions,
|
|
817
|
+
updater: { buildAsarOption, buildEntryOption, buildVersionOption }
|
|
818
|
+
},
|
|
819
|
+
(key, value) => (key === "privateKey" || key === "cert") && !(typeof logParsedOptions === "object" && logParsedOptions.showKeys === true) ? "***" : value,
|
|
820
|
+
2
|
|
821
|
+
),
|
|
822
|
+
{ timestamp: true }
|
|
823
|
+
);
|
|
824
|
+
}
|
|
775
825
|
let extraHmrPlugin;
|
|
776
826
|
if (nativeModuleEntryMap) {
|
|
777
|
-
const files = [
|
|
827
|
+
const files = [
|
|
828
|
+
...Object.values(nativeModuleEntryMap),
|
|
829
|
+
appEntryPath
|
|
830
|
+
].map((file) => path5.resolve(normalizePath(file)));
|
|
778
831
|
extraHmrPlugin = {
|
|
779
832
|
name: `${id}-dev`,
|
|
780
833
|
apply() {
|
|
@@ -794,7 +847,6 @@ async function electronWithUpdater(options) {
|
|
|
794
847
|
}
|
|
795
848
|
return [ElectronSimple(electronPluginOptions), extraHmrPlugin];
|
|
796
849
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
};
|
|
850
|
+
var vite_default = electronWithUpdater;
|
|
851
|
+
|
|
852
|
+
export { debugStartup, vite_default as default, electronWithUpdater };
|