electron-incremental-update 1.0.3 → 1.1.0

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.mjs DELETED
@@ -1,404 +0,0 @@
1
- import {
2
- signature
3
- } from "./chunk-GXZSAUBR.mjs";
4
- import {
5
- isUpdateJSON,
6
- parseVersion,
7
- zipFile
8
- } from "./chunk-GB6VLKJZ.mjs";
9
-
10
- // src/vite.ts
11
- import { basename, join as join2, resolve } from "node:path";
12
- import { cpSync, existsSync as existsSync3, rmSync } from "node:fs";
13
- import { createLogger, mergeConfig, normalizePath } from "vite";
14
- import ElectronSimple from "vite-plugin-electron/simple";
15
- import { startup } from "vite-plugin-electron";
16
- import { notBundle } from "vite-plugin-electron/plugin";
17
-
18
- // src/build-plugins/build.ts
19
- import { readFile, rename, writeFile } from "node:fs/promises";
20
- import { existsSync } from "node:fs";
21
- import { join } from "node:path";
22
- import Asar from "@electron/asar";
23
- import { build } from "esbuild";
24
- async function buildAsar({
25
- version,
26
- asarOutputPath,
27
- gzipPath,
28
- electronDistPath,
29
- rendererDistPath
30
- }) {
31
- await rename(rendererDistPath, join(electronDistPath, "renderer"));
32
- await writeFile(join(electronDistPath, "version"), version);
33
- await Asar.createPackage(electronDistPath, asarOutputPath);
34
- await zipFile(asarOutputPath, gzipPath);
35
- }
36
- async function buildVersion({
37
- gzipPath,
38
- versionPath,
39
- privateKey,
40
- cert,
41
- version,
42
- minimumVersion,
43
- generateSignature,
44
- generateVersionJson
45
- }) {
46
- let _json = {
47
- beta: {
48
- minimumVersion: version,
49
- signature: "",
50
- size: 0,
51
- version
52
- },
53
- minimumVersion: version,
54
- signature: "",
55
- size: 0,
56
- version
57
- };
58
- if (existsSync(versionPath)) {
59
- try {
60
- const oldVersionJson = JSON.parse(await readFile(versionPath, "utf-8"));
61
- if (isUpdateJSON(oldVersionJson)) {
62
- _json = oldVersionJson;
63
- } else {
64
- log.warn("old version json is invalid, ignore it");
65
- }
66
- } catch (error) {
67
- }
68
- }
69
- const buffer = await readFile(gzipPath);
70
- const sig = await (generateSignature ?? signature)(buffer, privateKey, cert, version);
71
- if (generateVersionJson) {
72
- _json = await generateVersionJson(_json, buffer, sig, version, minimumVersion);
73
- if (!isUpdateJSON(_json)) {
74
- throw new Error("invalid version info");
75
- }
76
- } else {
77
- _json.beta = {
78
- version,
79
- minimumVersion,
80
- signature: sig,
81
- size: buffer.length
82
- };
83
- if (!parseVersion(version).stage) {
84
- _json.version = version;
85
- _json.minimumVersion = minimumVersion;
86
- _json.signature = sig;
87
- _json.size = buffer.length;
88
- }
89
- }
90
- await writeFile(versionPath, JSON.stringify(_json, null, 2));
91
- }
92
- async function buildEntry({
93
- sourcemap,
94
- minify,
95
- appEntryPath,
96
- entryOutputDirPath,
97
- nativeModuleEntryMap,
98
- overrideEsbuildOptions
99
- }) {
100
- await build({
101
- entryPoints: {
102
- entry: appEntryPath,
103
- ...nativeModuleEntryMap
104
- },
105
- bundle: true,
106
- platform: "node",
107
- outdir: entryOutputDirPath,
108
- minify,
109
- sourcemap,
110
- entryNames: "[dir]/[name]",
111
- assetNames: "[dir]/[name]",
112
- external: ["electron", "original-fs"],
113
- loader: {
114
- ".node": "empty"
115
- },
116
- ...overrideEsbuildOptions
117
- });
118
- }
119
-
120
- // src/build-plugins/key.ts
121
- import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "node:fs";
122
- import { dirname } from "node:path";
123
- import { generate } from "selfsigned";
124
- function generateKeyPair(keyLength, subject, days, privateKeyPath, certPath) {
125
- const privateKeyDir = dirname(privateKeyPath);
126
- if (!existsSync2(privateKeyDir)) {
127
- mkdirSync(privateKeyDir, { recursive: true });
128
- }
129
- const certDir = dirname(certPath);
130
- if (!existsSync2(certDir)) {
131
- mkdirSync(certDir, { recursive: true });
132
- }
133
- const { cert, private: privateKey } = generate(subject, {
134
- keySize: keyLength,
135
- algorithm: "sha256",
136
- days
137
- });
138
- writeFileSync(privateKeyPath, privateKey.replace(/\r\n?/g, "\n"));
139
- writeFileSync(certPath, cert.replace(/\r\n?/g, "\n"));
140
- }
141
- var noCertRegex = /(?<=const SIGNATURE_CERT\s*=\s*)['"]{2}/m;
142
- var existCertRegex = /(?<=const SIGNATURE_CERT\s*=\s*)(['"]-----BEGIN CERTIFICATE-----[\s\S]*-----END CERTIFICATE-----\\n['"])/m;
143
- function writeCertToEntry(entryPath, cert) {
144
- if (!existsSync2(entryPath)) {
145
- throw new Error(`entry not exist: ${entryPath}`);
146
- }
147
- const file = readFileSync(entryPath, "utf-8");
148
- const replacement = cert.split("\n").filter(Boolean).map((s) => `'${s}\\n'`).join("\n + ");
149
- let replaced = file;
150
- if (noCertRegex.test(file)) {
151
- replaced = file.replace(noCertRegex, replacement);
152
- } else if (existCertRegex.test(file)) {
153
- replaced = file.replace(existCertRegex, replacement);
154
- } else {
155
- throw new Error("no `SIGNATURE_CERT` found in entry");
156
- }
157
- writeFileSync(entryPath, replaced);
158
- }
159
- function parseKeys({
160
- keyLength,
161
- privateKeyPath,
162
- certPath,
163
- appEntryPath,
164
- subject,
165
- days
166
- }) {
167
- const keysDir = dirname(privateKeyPath);
168
- !existsSync2(keysDir) && mkdirSync(keysDir);
169
- if (!existsSync2(privateKeyPath) || !existsSync2(certPath)) {
170
- log.warn("no key pair found, generate new key pair");
171
- generateKeyPair(keyLength, parseSubjects(subject), days, privateKeyPath, certPath);
172
- }
173
- const privateKey = process.env.UPDATER_PK || readFileSync(privateKeyPath, "utf-8");
174
- const cert = process.env.UPDATER_CERT || readFileSync(certPath, "utf-8");
175
- writeCertToEntry(appEntryPath, cert);
176
- return { privateKey, cert };
177
- }
178
- function parseSubjects(subject) {
179
- return Object.entries(subject).filter(([_, value]) => !!value).map(([name, value]) => ({ name, value }));
180
- }
181
-
182
- // src/build-plugins/option.ts
183
- function parseOptions(isBuild, pkg, options = {}) {
184
- const {
185
- minimumVersion = "0.0.0",
186
- entry: {
187
- minify = isBuild,
188
- sourcemap = isBuild,
189
- entryOutputDirPath = "dist-entry",
190
- appEntryPath = "electron/entry.ts",
191
- nativeModuleEntryMap = {},
192
- postBuild,
193
- overrideEsbuildOptions = {}
194
- } = {},
195
- paths: {
196
- asarOutputPath = `release/${pkg.name}.asar`,
197
- gzipPath = `release/${pkg.name}-${pkg.version}.asar.gz`,
198
- electronDistPath = "dist-electron",
199
- rendererDistPath = "dist",
200
- versionPath = "version.json"
201
- } = {},
202
- keys: {
203
- privateKeyPath = "keys/private.pem",
204
- certPath = "keys/cert.pem",
205
- keyLength = 2048,
206
- certInfo = {},
207
- overrideGenerator = {}
208
- } = {}
209
- } = options;
210
- const { generateSignature, generateVersionJson } = overrideGenerator;
211
- let {
212
- subject = {
213
- commonName: pkg.name,
214
- organizationName: `org.${pkg.name}`
215
- },
216
- days = 3650
217
- } = certInfo;
218
- const buildAsarOption = {
219
- version: pkg.version,
220
- asarOutputPath,
221
- gzipPath,
222
- electronDistPath,
223
- rendererDistPath
224
- };
225
- const buildEntryOption = {
226
- minify,
227
- sourcemap,
228
- entryOutputDirPath,
229
- appEntryPath,
230
- nativeModuleEntryMap,
231
- overrideEsbuildOptions
232
- };
233
- const { privateKey, cert } = parseKeys({
234
- keyLength,
235
- privateKeyPath,
236
- certPath,
237
- appEntryPath,
238
- subject,
239
- days
240
- });
241
- const buildVersionOption = {
242
- version: pkg.version,
243
- minimumVersion,
244
- gzipPath,
245
- privateKey,
246
- cert,
247
- versionPath,
248
- generateSignature,
249
- generateVersionJson
250
- };
251
- return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild };
252
- }
253
-
254
- // src/vite.ts
255
- function debugStartup(args) {
256
- process.env.VSCODE_DEBUG ? console.log("[startup] Electron App") : args.startup();
257
- }
258
- var id = "electron-incremental-updater";
259
- var log = createLogger("info", { prefix: `[${id}]` });
260
- function electronWithUpdater(options) {
261
- const {
262
- isBuild,
263
- pkg,
264
- main: _main,
265
- preload: _preload,
266
- updater,
267
- useNotBundle = true,
268
- logParsedOptions
269
- } = options;
270
- const _options = parseOptions(isBuild, pkg, updater);
271
- try {
272
- rmSync(_options.buildAsarOption.electronDistPath, { recursive: true, force: true });
273
- rmSync(_options.buildEntryOption.entryOutputDirPath, { recursive: true, force: true });
274
- } catch (ignore) {
275
- }
276
- log.info(`remove old files`, { timestamp: true });
277
- const { buildAsarOption, buildEntryOption, buildVersionOption, postBuild } = _options;
278
- const { entryOutputDirPath, nativeModuleEntryMap, appEntryPath } = buildEntryOption;
279
- const sourcemap = isBuild || !!process.env.VSCODE_DEBUG;
280
- const _appPath = join2(entryOutputDirPath, "entry.js");
281
- if (resolve(normalizePath(pkg.main)) !== resolve(normalizePath(_appPath))) {
282
- throw new Error(`wrong "main" field in package.json: "${pkg.main}", it should be "${normalizePath(_appPath)}"`);
283
- }
284
- let isInit = false;
285
- const _buildEntry = async () => {
286
- await buildEntry(buildEntryOption);
287
- log.info(`build entry to '${entryOutputDirPath}'`, { timestamp: true });
288
- };
289
- const _postBuild = postBuild ? async () => postBuild({
290
- getPathFromEntryOutputDir(...paths) {
291
- return join2(entryOutputDirPath, ...paths);
292
- },
293
- existsAndCopyToEntryOutputDir({ from, to, skipIfExist = true }) {
294
- if (existsSync3(from)) {
295
- const target = join2(entryOutputDirPath, to ?? basename(from));
296
- if (!skipIfExist || !existsSync3(target)) {
297
- try {
298
- cpSync(from, target);
299
- } catch (ignore) {
300
- log.warn(`copy failed: ${ignore}`);
301
- }
302
- }
303
- }
304
- }
305
- }) : async () => {
306
- };
307
- const electronPluginOptions = {
308
- main: {
309
- entry: _main.files,
310
- onstart: async (args) => {
311
- if (!isInit) {
312
- isInit = true;
313
- await _buildEntry();
314
- await _postBuild();
315
- }
316
- _main.onstart ? _main.onstart(args) : args.startup();
317
- },
318
- vite: mergeConfig(
319
- {
320
- plugins: !isBuild && useNotBundle ? [notBundle()] : void 0,
321
- build: {
322
- sourcemap,
323
- minify: isBuild,
324
- outDir: `${buildAsarOption.electronDistPath}/main`,
325
- rollupOptions: {
326
- external: Object.keys("dependencies" in pkg ? pkg.dependencies : {})
327
- }
328
- }
329
- },
330
- _main.vite ?? {}
331
- )
332
- },
333
- preload: {
334
- input: _preload.files,
335
- onstart: _preload.onstart,
336
- vite: mergeConfig(
337
- {
338
- plugins: [
339
- {
340
- name: `${id}-build`,
341
- enforce: "post",
342
- apply() {
343
- return isBuild;
344
- },
345
- async closeBundle() {
346
- await _buildEntry();
347
- await buildAsar(buildAsarOption);
348
- log.info(`build asar to '${buildAsarOption.asarOutputPath}'`, { timestamp: true });
349
- await buildVersion(buildVersionOption);
350
- log.info(`build version info to '${buildVersionOption.versionPath}'`, { timestamp: true });
351
- }
352
- }
353
- ],
354
- build: {
355
- sourcemap: sourcemap ? "inline" : void 0,
356
- minify: isBuild,
357
- outDir: `${buildAsarOption.electronDistPath}/preload`,
358
- rollupOptions: {
359
- external: Object.keys("dependencies" in pkg ? pkg.dependencies : {})
360
- }
361
- }
362
- },
363
- _preload.vite ?? {}
364
- )
365
- }
366
- };
367
- logParsedOptions && log.info(
368
- JSON.stringify(
369
- {
370
- ...electronPluginOptions,
371
- updater: { buildAsarOption, buildEntryOption, buildVersionOption }
372
- },
373
- (key, value) => key === "privateKey" || key === "cert" ? "***" : value,
374
- 2
375
- ),
376
- { timestamp: true }
377
- );
378
- let extraHmrPlugin;
379
- if (nativeModuleEntryMap) {
380
- const files = [...Object.values(nativeModuleEntryMap), appEntryPath].map((file) => resolve(normalizePath(file)));
381
- extraHmrPlugin = {
382
- name: `${id}-dev`,
383
- apply() {
384
- return !isBuild;
385
- },
386
- configureServer: (server) => {
387
- server.watcher.add(files).on(
388
- "change",
389
- (p) => files.includes(p) && _buildEntry().then(async () => {
390
- await startup.exit();
391
- await _postBuild();
392
- await startup();
393
- })
394
- );
395
- }
396
- };
397
- }
398
- return [ElectronSimple(electronPluginOptions), extraHmrPlugin];
399
- }
400
- export {
401
- debugStartup,
402
- electronWithUpdater,
403
- log
404
- };