electron-incremental-update 2.4.0 → 2.4.2

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 CHANGED
@@ -127,6 +127,35 @@ export default defineConfig(async ({ command }) => {
127
127
  })
128
128
  ```
129
129
 
130
+ Or use the helper function
131
+
132
+ ```ts
133
+ import { defineElectronConfig } from 'electron-incremental-update/vite'
134
+
135
+ export default defineElectronConfig({
136
+ main: {
137
+ files: ['./electron/main/index.ts', './electron/main/worker.ts'],
138
+ // see https://github.com/electron-vite/electron-vite-vue/blob/85ed267c4851bf59f32888d766c0071661d4b94c/vite.config.ts#L22-L28
139
+ onstart: debugStartup,
140
+ },
141
+ preload: {
142
+ files: './electron/preload/index.ts',
143
+ },
144
+ updater: {
145
+ // options
146
+ },
147
+ renderer: {
148
+ server: process.env.VSCODE_DEBUG && (() => {
149
+ const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL)
150
+ return {
151
+ host: url.hostname,
152
+ port: +url.port,
153
+ }
154
+ })(),
155
+ }
156
+ })
157
+ ```
158
+
130
159
  ### Modify package.json
131
160
 
132
161
  ```json
@@ -838,10 +867,10 @@ export interface ElectronWithUpdaterOptions {
838
867
  /**
839
868
  * Updater options
840
869
  */
841
- updater?: ElectronUpdaterOptions
870
+ updater?: UpdaterOptions
842
871
  }
843
872
 
844
- export interface ElectronUpdaterOptions {
873
+ export interface UpdaterOptions {
845
874
  /**
846
875
  * Minimum version of entry
847
876
  * @default '0.0.0'
package/dist/vite.d.ts CHANGED
@@ -1,26 +1,20 @@
1
1
  import { Promisable, AnyFunction } from '@subframe7536/type-utils';
2
- import { InlineConfig, PluginOption } from 'vite';
2
+ import { InlineConfig, PluginOption, UserConfig, UserConfigFn } from 'vite';
3
+ import { ElectronOptions } from 'vite-plugin-electron';
3
4
  import { ElectronSimpleOptions } from 'vite-plugin-electron/simple';
4
5
  export { isCI } from 'ci-info';
5
6
  export { getPackageInfo, getPackageInfoSync, loadPackageJSON, resolveModule } from 'local-pkg';
6
7
 
7
- interface BytecodeOptions {
8
- enable: boolean;
9
- /**
10
- * Enable in preload script. Remember to set `sandbox: false` when creating window
11
- */
12
- preload?: boolean;
13
- /**
14
- * Custom electron binary path
15
- */
16
- electronPath?: string;
17
- /**
18
- * Before transformed code compile function. If return `Falsy` value, it will be ignored
19
- * @param code transformed code
20
- * @param id file path
21
- */
22
- beforeCompile?: (code: string, id: string) => Promisable<string | null | undefined | void>;
23
- }
8
+ /**
9
+ * Obfuscate string
10
+ * @param code source code
11
+ * @param sourcemap whether to generate sourcemap
12
+ * @param offset custom offset
13
+ */
14
+ declare function convertLiteral(code: string, sourcemap?: boolean, offset?: number): {
15
+ code: string;
16
+ map?: any;
17
+ };
24
18
 
25
19
  /**
26
20
  * Update info json
@@ -49,6 +43,24 @@ type UpdateJSON = UpdateInfo & {
49
43
  beta: UpdateInfo;
50
44
  };
51
45
 
46
+ interface BytecodeOptions {
47
+ enable: boolean;
48
+ /**
49
+ * Enable in preload script. Remember to set `sandbox: false` when creating window
50
+ */
51
+ preload?: boolean;
52
+ /**
53
+ * Custom electron binary path
54
+ */
55
+ electronPath?: string;
56
+ /**
57
+ * Before transformed code compile function. If return `Falsy` value, it will be ignored
58
+ * @param code transformed code
59
+ * @param id file path
60
+ */
61
+ beforeCompile?: (code: string, id: string) => Promisable<string | null | undefined | void>;
62
+ }
63
+
52
64
  interface DistinguishedName {
53
65
  countryName?: string;
54
66
  stateOrProvinceName?: string;
@@ -69,6 +81,105 @@ interface PKG {
69
81
  main: string;
70
82
  type: 'commonjs' | 'module';
71
83
  }
84
+ interface ViteOverride {
85
+ /**
86
+ * Override vite options
87
+ */
88
+ vite?: ElectronOptions['vite'] & {
89
+ build?: {
90
+ outDir: never;
91
+ rollupOptions?: {
92
+ output?: {
93
+ dir: never;
94
+ };
95
+ };
96
+ };
97
+ };
98
+ }
99
+ interface ElectronWithUpdaterOptions {
100
+ /**
101
+ * Whether is in build mode
102
+ * ```ts
103
+ * export default defineConfig(({ command }) => {
104
+ * const isBuild = command === 'build'
105
+ * })
106
+ * ```
107
+ */
108
+ isBuild: boolean;
109
+ /**
110
+ * Manually setup package.json, read name, version and main,
111
+ * use `local-pkg` of `loadPackageJSON()` to load package.json by default
112
+ * ```ts
113
+ * import pkg from './package.json'
114
+ * ```
115
+ */
116
+ pkg?: PKG;
117
+ /**
118
+ * Whether to generate sourcemap
119
+ * @default !isBuild
120
+ */
121
+ sourcemap?: boolean;
122
+ /**
123
+ * Whether to minify the code
124
+ * @default isBuild
125
+ */
126
+ minify?: boolean;
127
+ /**
128
+ * Whether to generate bytecode
129
+ *
130
+ * **Only support CommonJS**
131
+ *
132
+ * Only main process by default, if you want to use in preload script, please use `electronWithUpdater({ bytecode: { enablePreload: true } })` and set `sandbox: false` when creating window
133
+ */
134
+ bytecode?: boolean | BytecodeOptions;
135
+ /**
136
+ * Use `NotBundle()` plugin in main
137
+ * @default true
138
+ */
139
+ useNotBundle?: boolean;
140
+ /**
141
+ * Whether to generate version json
142
+ * @default isCI
143
+ */
144
+ buildVersionJson?: boolean;
145
+ /**
146
+ * Main process options
147
+ *
148
+ * To change output directories, use `options.updater.paths.electronDistPath` instead
149
+ */
150
+ main: {
151
+ /**
152
+ * Shortcut of `build.rollupOptions.input`
153
+ */
154
+ files: NonNullable<ElectronOptions['entry']>;
155
+ /**
156
+ * Electron App startup function.
157
+ *
158
+ * It will mount the Electron App child-process to `process.electronApp`.
159
+ * @param argv default value `['.', '--no-sandbox']`
160
+ * @param options options for `child_process.spawn`
161
+ * @param customElectronPkg custom electron package name (default: 'electron')
162
+ */
163
+ onstart?: ElectronOptions['onstart'];
164
+ } & ViteOverride;
165
+ /**
166
+ * Preload process options
167
+ *
168
+ * To change output directories, use `options.updater.paths.electronDistPath` instead
169
+ */
170
+ preload: {
171
+ /**
172
+ * Shortcut of `build.rollupOptions.input`.
173
+ *
174
+ * Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
175
+ */
176
+ files: NonNullable<ElectronOptions['entry']>;
177
+ } & ViteOverride;
178
+ /**
179
+ * Updater options
180
+ */
181
+ updater?: UpdaterOptions;
182
+ }
72
183
  interface BuildEntryOption {
73
184
  /**
74
185
  * Override to minify on entry
@@ -197,7 +308,7 @@ interface GeneratorOverrideFunctions {
197
308
  */
198
309
  generateGzipFile?: (buffer: Buffer) => Promisable<Buffer>;
199
310
  }
200
- interface ElectronUpdaterOptions {
311
+ interface UpdaterOptions {
201
312
  /**
202
313
  * Minimum version of entry
203
314
  * @default '0.0.0'
@@ -285,24 +396,6 @@ interface ElectronUpdaterOptions {
285
396
  overrideGenerator?: GeneratorOverrideFunctions;
286
397
  }
287
398
 
288
- /**
289
- * Obfuscate string
290
- * @param code source code
291
- * @param sourcemap whether to generate sourcemap
292
- * @param offset custom offset
293
- */
294
- declare function convertLiteral(code: string, sourcemap?: boolean, offset?: number): {
295
- code: string;
296
- map?: any;
297
- };
298
-
299
- type MakeRequired<T, K extends keyof T> = NonNullable<T> & {
300
- [P in K]-?: T[P];
301
- };
302
- type ReplaceKey<T, Key extends keyof T, NewKey extends string> = Omit<T, Key> & {
303
- [P in NewKey]: T[Key];
304
- };
305
- type MakeRequiredAndReplaceKey<T, K extends keyof T, NewKey extends string> = MakeRequired<ReplaceKey<T, K, NewKey>, NewKey>;
306
399
  type StartupFn = NonNullable<NonNullable<ElectronSimpleOptions['main']>['onstart']>;
307
400
  /**
308
401
  * Startup function for debug
@@ -349,81 +442,6 @@ declare function filterErrorMessageStartup(args: Parameters<StartupFn>[0], filte
349
442
  * })
350
443
  */
351
444
  declare function fixWinCharEncoding<T extends AnyFunction>(fn: T): T;
352
- type ExcludeOutputDirOptions = {
353
- vite?: {
354
- build?: {
355
- outDir: never;
356
- rollupOptions?: {
357
- output?: {
358
- dir: never;
359
- };
360
- };
361
- };
362
- };
363
- };
364
- interface ElectronWithUpdaterOptions {
365
- /**
366
- * Whether is in build mode
367
- * ```ts
368
- * export default defineConfig(({ command }) => {
369
- * const isBuild = command === 'build'
370
- * })
371
- * ```
372
- */
373
- isBuild: boolean;
374
- /**
375
- * Manually setup package.json, read name, version and main,
376
- * use `local-pkg` of `loadPackageJSON()` to load package.json by default
377
- * ```ts
378
- * import pkg from './package.json'
379
- * ```
380
- */
381
- pkg?: PKG;
382
- /**
383
- * Whether to generate sourcemap
384
- * @default !isBuild
385
- */
386
- sourcemap?: boolean;
387
- /**
388
- * Whether to minify the code
389
- * @default isBuild
390
- */
391
- minify?: boolean;
392
- /**
393
- * Whether to generate bytecode
394
- *
395
- * **Only support CommonJS**
396
- *
397
- * Only main process by default, if you want to use in preload script, please use `electronWithUpdater({ bytecode: { enablePreload: true } })` and set `sandbox: false` when creating window
398
- */
399
- bytecode?: boolean | BytecodeOptions;
400
- /**
401
- * Use `NotBundle()` plugin in main
402
- * @default true
403
- */
404
- useNotBundle?: boolean;
405
- /**
406
- * Whether to generate version json
407
- * @default isCI
408
- */
409
- buildVersionJson?: boolean;
410
- /**
411
- * Main process options
412
- *
413
- * To change output directories, use `options.updater.paths.electronDistPath` instead
414
- */
415
- main: MakeRequiredAndReplaceKey<ElectronSimpleOptions['main'], 'entry', 'files'> & ExcludeOutputDirOptions;
416
- /**
417
- * Preload process options
418
- *
419
- * To change output directories, use `options.updater.paths.electronDistPath` instead
420
- */
421
- preload: MakeRequiredAndReplaceKey<Exclude<ElectronSimpleOptions['preload'], undefined>, 'input', 'files'> & ExcludeOutputDirOptions;
422
- /**
423
- * Updater options
424
- */
425
- updater?: ElectronUpdaterOptions;
426
- }
427
445
  /**
428
446
  * Base on `vite-plugin-electron/simple`
429
447
  * - integrate with updater
@@ -472,4 +490,44 @@ interface ElectronWithUpdaterOptions {
472
490
  */
473
491
  declare function electronWithUpdater(options: ElectronWithUpdaterOptions): Promise<PluginOption[] | undefined>;
474
492
 
475
- export { type ElectronWithUpdaterOptions, convertLiteral, debugStartup, electronWithUpdater as default, electronWithUpdater, filterErrorMessageStartup, fixWinCharEncoding };
493
+ type MakeOptional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>;
494
+ interface ElectronViteHelperOptions extends MakeOptional<ElectronWithUpdaterOptions, 'isBuild'> {
495
+ /**
496
+ * Config for renderer process
497
+ */
498
+ renderer?: UserConfig;
499
+ }
500
+ /**
501
+ * Vite config helper
502
+ * @see {@link electronWithUpdater}
503
+ * @example
504
+ * ```ts
505
+ * import { defineElectronConfig } from 'electron-incremental-update/vite'
506
+ *
507
+ * export default defineElectronConfig({
508
+ * main: {
509
+ * files: ['./electron/main/index.ts', './electron/main/worker.ts'],
510
+ * // see https://github.com/electron-vite/electron-vite-vue/blob/85ed267c4851bf59f32888d766c0071661d4b94c/vite.config.ts#L22-L28
511
+ * onstart: debugStartup,
512
+ * },
513
+ * preload: {
514
+ * files: './electron/preload/index.ts',
515
+ * },
516
+ * updater: {
517
+ * // options
518
+ * },
519
+ * renderer: {
520
+ * server: process.env.VSCODE_DEBUG && (() => {
521
+ * const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL)
522
+ * return {
523
+ * host: url.hostname,
524
+ * port: +url.port,
525
+ * }
526
+ * })(),
527
+ * }
528
+ * })
529
+ * ```
530
+ */
531
+ declare function defineElectronConfig(options: ElectronViteHelperOptions): UserConfigFn;
532
+
533
+ export { type ElectronViteHelperOptions, type ElectronWithUpdaterOptions, convertLiteral, debugStartup, electronWithUpdater as default, defineElectronConfig, electronWithUpdater, filterErrorMessageStartup, fixWinCharEncoding };
package/dist/vite.js CHANGED
@@ -1,23 +1,23 @@
1
+ import cp from 'child_process';
1
2
  import fs5 from 'fs';
2
3
  import path5 from 'path';
3
- import { isCI } from 'ci-info';
4
- export { isCI } from 'ci-info';
4
+ import * as babel from '@babel/core';
5
5
  import { getPackageInfoSync, loadPackageJSON } from 'local-pkg';
6
6
  export { getPackageInfo, getPackageInfoSync, loadPackageJSON, resolveModule } from 'local-pkg';
7
+ import MagicString from 'magic-string';
7
8
  import { createLogger, normalizePath, mergeConfig, createFilter } from 'vite';
9
+ import { isCI } from 'ci-info';
10
+ export { isCI } from 'ci-info';
8
11
  import { startup, build } from 'vite-plugin-electron';
9
12
  import { notBundle } from 'vite-plugin-electron/plugin';
10
13
  import ElectronSimple from 'vite-plugin-electron/simple';
11
14
  import Asar from '@electron/asar';
12
- import MagicString from 'magic-string';
13
- import cp from 'child_process';
14
- import * as babel from '@babel/core';
15
15
  import { builtinModules } from 'module';
16
16
  import crypto from 'crypto';
17
17
  import zlib from 'zlib';
18
18
  import { generate } from 'selfsigned';
19
19
 
20
- // src/vite/index.ts
20
+ // src/vite/bytecode/utils.ts
21
21
 
22
22
  // src/utils/version.ts
23
23
  function parseVersion(version) {
@@ -65,28 +65,12 @@ var bytecodeId = `${id}-bytecode`;
65
65
  var esmId = `${id}-esm`;
66
66
  var log = createLogger("info", { prefix: `[${id}]` });
67
67
  var bytecodeLog = createLogger("info", { prefix: `[${bytecodeId}]` });
68
- function readableSize(size) {
69
- const units = ["B", "KB", "MB", "GB"];
70
- let i = 0;
71
- while (size >= 1024 && i < units.length - 1) {
72
- size /= 1024;
73
- i++;
74
- }
75
- return `${size.toFixed(2)} ${units[i]}`;
76
- }
77
- function copyAndSkipIfExist(from, to, skipIfExist) {
78
- if (!skipIfExist || !fs5.existsSync(to)) {
79
- try {
80
- fs5.cpSync(from, to, { recursive: true });
81
- } catch (error) {
82
- log.warn(`Copy failed: ${error}`, { timestamp: true });
83
- }
84
- }
85
- }
86
68
 
87
69
  // src/vite/bytecode/code.ts
88
70
  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";
89
71
  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';
72
+
73
+ // src/vite/bytecode/utils.ts
90
74
  var electronModule = getPackageInfoSync("electron");
91
75
  var electronMajorVersion = parseVersion(electronModule.version).major;
92
76
  var useStrict = "'use strict';";
@@ -222,6 +206,24 @@ function convertLiteral(code, sourcemap, offset) {
222
206
  map: sourcemap ? s.generateMap({ hires: true }) : void 0
223
207
  };
224
208
  }
209
+ function readableSize(size) {
210
+ const units = ["B", "KB", "MB", "GB"];
211
+ let i = 0;
212
+ while (size >= 1024 && i < units.length - 1) {
213
+ size /= 1024;
214
+ i++;
215
+ }
216
+ return `${size.toFixed(2)} ${units[i]}`;
217
+ }
218
+ function copyAndSkipIfExist(from, to, skipIfExist) {
219
+ if (!skipIfExist || !fs5.existsSync(to)) {
220
+ try {
221
+ fs5.cpSync(from, to, { recursive: true });
222
+ } catch (error) {
223
+ log.warn(`Copy failed: ${error}`, { timestamp: true });
224
+ }
225
+ }
226
+ }
225
227
 
226
228
  // src/vite/bytecode/index.ts
227
229
  function getBytecodeLoaderBlock(chunkFileName) {
@@ -672,7 +674,8 @@ function parseOptions(isBuild, pkg, sourcemap = false, minify = false, options =
672
674
  };
673
675
  return { buildAsarOption, buildEntryOption, buildVersionOption, postBuild, cert };
674
676
  }
675
- var vite_default = electronWithUpdater;
677
+
678
+ // src/vite/core.ts
676
679
  var debugStartup = async (args) => {
677
680
  if (process.env.VSCODE_DEBUG) {
678
681
  console.log("[startup] Electron App");
@@ -851,7 +854,6 @@ async function electronWithUpdater(options) {
851
854
  },
852
855
  preload: {
853
856
  input: _preload.files,
854
- onstart: _preload.onstart,
855
857
  vite: mergeConfig(
856
858
  {
857
859
  plugins: [
@@ -928,4 +930,16 @@ async function electronWithUpdater(options) {
928
930
  return result;
929
931
  }
930
932
 
931
- export { convertLiteral, debugStartup, vite_default as default, electronWithUpdater, filterErrorMessageStartup, fixWinCharEncoding };
933
+ // src/vite/define.ts
934
+ function defineElectronConfig(options) {
935
+ return ({ command }) => {
936
+ options.isBuild ??= command === "build";
937
+ const electronPlugin = electronWithUpdater(options);
938
+ const result = options.renderer ?? {};
939
+ result.plugins ??= [];
940
+ result.plugins.push(electronPlugin);
941
+ return result;
942
+ };
943
+ }
944
+
945
+ export { convertLiteral, debugStartup, electronWithUpdater as default, defineElectronConfig, electronWithUpdater, filterErrorMessageStartup, fixWinCharEncoding };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
3
  "type": "module",
4
- "version": "2.4.0",
4
+ "version": "2.4.2",
5
5
  "description": "Electron incremental update tools with Vite plugin, support bytecode protection",
6
6
  "author": "subframe7536",
7
7
  "license": "MIT",