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/README.md +7 -3
- package/dist/chunk-4MH6ZXCY.js +81 -0
- package/dist/chunk-72ZAJ7AF.js +70 -0
- package/dist/chunk-KZSYEXLO.js +55 -0
- package/dist/index.cjs +173 -386
- package/dist/index.d.cts +84 -213
- package/dist/index.d.ts +84 -213
- package/dist/index.js +142 -282
- package/dist/provider.cjs +232 -0
- package/dist/provider.d.cts +109 -0
- package/dist/provider.d.ts +109 -0
- package/dist/provider.js +139 -0
- package/dist/types-Bnc4jz6R.d.ts +78 -0
- package/dist/types-DEYw5VrL.d.cts +78 -0
- package/dist/utils.cjs +175 -208
- package/dist/utils.d.cts +47 -87
- package/dist/utils.d.ts +47 -87
- package/dist/utils.js +3 -38
- package/dist/version-C4tF_trh.d.cts +62 -0
- package/dist/version-C4tF_trh.d.ts +62 -0
- package/dist/vite.d.ts +93 -95
- package/dist/vite.js +342 -350
- package/dist/zip-rm9ED9nU.d.cts +33 -0
- package/dist/zip-rm9ED9nU.d.ts +33 -0
- package/package.json +28 -16
- package/provider.d.ts +1 -0
- package/provider.js +1 -0
- package/dist/chunk-7ET4GMTZ.js +0 -236
- package/dist/chunk-CXHA5TF7.js +0 -236
- package/dist/chunk-HWUYTDEF.js +0 -236
- package/dist/chunk-RQCTJY4L.js +0 -236
- package/dist/chunk-SBPTSLG7.js +0 -235
- package/dist/pure-GoN_3MEj.d.cts +0 -31
- package/dist/pure-GoN_3MEj.d.ts +0 -31
package/dist/vite.js
CHANGED
|
@@ -1,40 +1,24 @@
|
|
|
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
|
-
// src/
|
|
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.
|
|
46
|
+
const is = (j) => !!(j && j.minimumVersion && j.signature && j.version);
|
|
63
47
|
return is(json) && is(json?.beta);
|
|
64
48
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
|
|
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/
|
|
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 =
|
|
79
|
+
const pathFile = path5.join(electronModulePath, "path.txt");
|
|
191
80
|
let executablePath;
|
|
192
|
-
if (
|
|
193
|
-
executablePath =
|
|
81
|
+
if (fs3.existsSync(pathFile)) {
|
|
82
|
+
executablePath = fs3.readFileSync(pathFile, "utf-8");
|
|
194
83
|
}
|
|
195
84
|
if (executablePath) {
|
|
196
|
-
electronExecPath =
|
|
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 =
|
|
206
|
-
if (!
|
|
207
|
-
|
|
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 =
|
|
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) =>
|
|
106
|
+
const logErr = (...args) => bytecodeLog.error(args.join(" "), { timestamp: true });
|
|
218
107
|
const electronPath = getElectronPath();
|
|
219
108
|
const bytecodePath = getBytecodeCompilerPath();
|
|
220
|
-
return new Promise((
|
|
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", () =>
|
|
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", () =>
|
|
129
|
+
proc.on("exit", () => resolve(data));
|
|
241
130
|
});
|
|
242
131
|
}
|
|
243
|
-
function
|
|
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
|
|
253
|
-
|
|
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
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
199
|
+
return {
|
|
262
200
|
code: s.toString(),
|
|
263
|
-
map: sourcemap ? s.generateMap({ hires:
|
|
264
|
-
}
|
|
201
|
+
map: sourcemap ? s.generateMap({ hires: true }) : void 0
|
|
202
|
+
};
|
|
265
203
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
|
|
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/
|
|
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
|
-
|
|
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
|
|
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 (
|
|
252
|
+
if (fs3.existsSync(versionPath)) {
|
|
309
253
|
try {
|
|
310
|
-
const oldVersionJson = JSON.parse(
|
|
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("
|
|
258
|
+
log.warn("Old version json is invalid, ignore it", { timestamp: true });
|
|
315
259
|
}
|
|
316
|
-
} catch
|
|
260
|
+
} catch {
|
|
317
261
|
}
|
|
318
262
|
}
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
if (
|
|
322
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
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 (
|
|
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 =
|
|
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
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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
|
-
|
|
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}
|
|
325
|
+
`${filePath} [${(buffer.byteLength / 1e3).toFixed(2)} kB]`,
|
|
401
326
|
{ timestamp: true }
|
|
402
327
|
);
|
|
403
328
|
}
|
|
404
|
-
bytecodeLog.info(`${filePaths.length}
|
|
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
|
|
407
|
-
const
|
|
408
|
-
return
|
|
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 (!
|
|
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 (!
|
|
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
|
-
|
|
430
|
-
|
|
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
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
-
|
|
446
|
-
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
535
|
-
|
|
474
|
+
enable,
|
|
475
|
+
preload = false,
|
|
476
|
+
beforeCompile
|
|
536
477
|
} = options;
|
|
537
|
-
if (!
|
|
538
|
-
|
|
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 (
|
|
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
|
|
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) =>
|
|
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
|
|
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 =
|
|
565
|
+
const chunkFilePath = path5.resolve(outDir, name);
|
|
617
566
|
if (bytecodeChunks.includes(name)) {
|
|
618
567
|
const bytecodeBuffer = await compileToBytecode(_code);
|
|
619
|
-
|
|
568
|
+
fs3.writeFileSync(chunkFilePath + "c", bytecodeBuffer);
|
|
620
569
|
if (chunk.isEntry) {
|
|
621
570
|
const bytecodeLoaderBlock = getBytecodeLoaderBlock(chunk.fileName);
|
|
622
|
-
const bytecodeModuleBlock = `require("./${
|
|
571
|
+
const bytecodeModuleBlock = `require("./${path5.basename(name) + "c"}");`;
|
|
623
572
|
const code = `${useStrict}
|
|
624
573
|
${bytecodeLoaderBlock}
|
|
625
574
|
module.exports=${bytecodeModuleBlock}
|
|
626
575
|
`;
|
|
627
|
-
|
|
576
|
+
fs3.writeFileSync(chunkFilePath, code);
|
|
628
577
|
} else {
|
|
629
|
-
|
|
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
|
-
|
|
605
|
+
fs3.writeFileSync(chunkFilePath, _code);
|
|
657
606
|
}
|
|
658
607
|
}
|
|
659
608
|
})
|
|
660
609
|
);
|
|
661
610
|
},
|
|
662
611
|
closeBundle() {
|
|
663
|
-
const outDir = `${normalizePath(
|
|
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}
|
|
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
|
|
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
|
|
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
|
|
673
|
+
return void 0;
|
|
701
674
|
}
|
|
702
675
|
const _options = parseOptions(pkg, sourcemap, minify, updater);
|
|
703
|
-
const bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? {
|
|
704
|
-
if (bytecodeOptions) {
|
|
705
|
-
minify = false;
|
|
706
|
-
}
|
|
676
|
+
const bytecodeOptions = typeof bytecode === "object" ? bytecode : bytecode === true ? { enable: true } : void 0;
|
|
707
677
|
try {
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
} catch
|
|
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(`
|
|
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 =
|
|
717
|
-
if (resolve(
|
|
718
|
-
throw new Error(`
|
|
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(
|
|
722
|
-
|
|
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
|
|
709
|
+
return path5.join(entryOutputDirPath, ...paths);
|
|
727
710
|
},
|
|
728
711
|
copyToEntryOutputDir({ from, to, skipIfExist = true }) {
|
|
729
|
-
if (
|
|
730
|
-
const target =
|
|
731
|
-
if (!skipIfExist || !
|
|
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(`
|
|
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
|
-
|
|
745
|
-
|
|
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
|
-
|
|
739
|
+
if (_main.onstart) {
|
|
740
|
+
_main.onstart(args);
|
|
741
|
+
} else {
|
|
742
|
+
args.startup();
|
|
743
|
+
}
|
|
760
744
|
},
|
|
761
|
-
vite:
|
|
745
|
+
vite: mergeConfig(
|
|
762
746
|
{
|
|
763
747
|
plugins: [
|
|
764
748
|
!isBuild && useNotBundle ? notBundle() : void 0,
|
|
765
|
-
bytecodeOptions && bytecodePlugin(
|
|
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:
|
|
765
|
+
vite: mergeConfig(
|
|
781
766
|
{
|
|
782
767
|
plugins: [
|
|
783
|
-
bytecodeOptions && bytecodePlugin(
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
|
|
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
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
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 = [
|
|
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
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
};
|
|
837
|
+
var vite_default = electronWithUpdater;
|
|
838
|
+
|
|
839
|
+
export { debugStartup, vite_default as default, electronWithUpdater };
|