electron-incremental-update 1.3.0 → 2.0.0-beta.10

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