electron-incremental-update 0.6.2 → 0.6.3

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
@@ -82,14 +82,16 @@ To utilize the electron `net` module for requesting update information, the `che
82
82
 
83
83
  However, you have the option to customize the download function when creating the updater.
84
84
 
85
+ **NOTE: There can only be one function and should be default export in the entry file**
86
+
85
87
  ```ts
86
88
  // electron/main/index.ts
87
- import type { Updater } from 'electron-incremental-update'
89
+ import type { StartupWithUpdater, Updater } from 'electron-incremental-update'
88
90
  import { getEntryVersion, getProductAsarPath, getProductVersion } from 'electron-incremental-update'
89
91
  import { app } from 'electron'
90
92
  import { name } from '../../package.json'
91
93
 
92
- export default function (updater: Updater) {
94
+ const startup: StartupWithUpdater = (updater: Updater) => {
93
95
  await app.whenReady()
94
96
  console.log('\ncurrent:')
95
97
  console.log(`\tasar path: ${getProductAsarPath(name)}`)
@@ -117,6 +119,7 @@ export default function (updater: Updater) {
117
119
  }
118
120
  })
119
121
  }
122
+ export default startup
120
123
  ```
121
124
 
122
125
  ### use native modules
@@ -186,6 +189,15 @@ export default defineConfig(({ command }) => {
186
189
  })
187
190
  ```
188
191
 
192
+ ### modify package.json
193
+
194
+ ```json
195
+ {
196
+ // ...
197
+ "main": "app.js" // <- app entry file
198
+ }
199
+ ```
200
+
189
201
  ### electron-builder config
190
202
 
191
203
  ```js
@@ -3,7 +3,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
3
3
  }) : x)(function(x) {
4
4
  if (typeof require !== "undefined")
5
5
  return require.apply(this, arguments);
6
- throw new Error('Dynamic require of "' + x + '" is not supported');
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
7
  });
8
8
 
9
9
  // src/crypto.ts
@@ -0,0 +1,237 @@
1
+ import { Buffer } from 'node:buffer';
2
+
3
+ type CheckResultType = Omit<UpdateJSON, 'signature'> | undefined | Error;
4
+ type InstallResult = true | Error;
5
+ type UpdateEvents = {
6
+ downloading: [progress: number];
7
+ debug: [msg: string | Error];
8
+ };
9
+ type UpdateJSON = {
10
+ signature: string;
11
+ version: string;
12
+ size: number;
13
+ };
14
+ declare function isUpdateJSON(json: any): json is UpdateJSON;
15
+ type MaybeArray<T> = T extends undefined | null | never ? [] : T extends any[] ? T['length'] extends 1 ? [data: T[0]] : T : [data: T];
16
+ interface TypedUpdater<T extends Record<string | symbol, MaybeArray<any>>, Event extends Exclude<keyof T, number> = Exclude<keyof T, number>> {
17
+ removeAllListeners<E extends Event>(event?: E): this;
18
+ listeners<E extends Event>(eventName: E): Function[];
19
+ eventNames(): (Event)[];
20
+ on<E extends Event>(eventName: E, listener: (...data: MaybeArray<T[E]>) => void): this;
21
+ once<E extends Event>(eventName: E, listener: (...data: MaybeArray<T[E]>) => void): this;
22
+ emit<E extends Event>(eventName: E, ...args: MaybeArray<T[E]>): boolean;
23
+ off<E extends Event>(eventName: E, listener: (...args: MaybeArray<T[E]>) => void): this;
24
+ /**
25
+ * check update info
26
+ * @param data update json url
27
+ * @returns
28
+ * - `{size: number, version: string}`: available
29
+ * - `false`: unavailable
30
+ * - `Error`: fail
31
+ */
32
+ checkUpdate(data?: string | UpdateJSON): Promise<CheckResultType>;
33
+ /**
34
+ * download update and install
35
+ *
36
+ * if you want to update **offline**, you can set both `src` and `sig` to verify and install
37
+ * @param data asar download url or buffer
38
+ * @param sig signature
39
+ * @returns
40
+ * - `true`: success
41
+ * - `Error`: fail
42
+ */
43
+ downloadAndInstall(data?: string | Buffer, sig?: string): Promise<InstallResult>;
44
+ setDebug(debug: boolean): void;
45
+ }
46
+ type FunctionVerifySignature = (buffer: Buffer, signature: string, cert: string) => string | false;
47
+ type FunctionCompareVersion = (oldVersion: string, newVersion: string) => boolean;
48
+ type Updater = TypedUpdater<UpdateEvents>;
49
+ interface UpdaterOption {
50
+ /**
51
+ * public key of signature
52
+ *
53
+ * it will be auto generated by plugin
54
+ * @example
55
+ * ```ts
56
+ * // auto filled by plugin
57
+ * const SIGNATURE_CERT = ''
58
+ *
59
+ * const updater = createUpdater({
60
+ * SIGNATURE_CERT,
61
+ * ...
62
+ * })
63
+ * ```
64
+ */
65
+ SIGNATURE_CERT: string;
66
+ /**
67
+ * name of your application
68
+ *
69
+ * you can use the `name` in `package.json`
70
+ */
71
+ productName: string;
72
+ /**
73
+ * repository url, e.g. `https://github.com/electron/electron`
74
+ *
75
+ * you can use the `repository` in `package.json`
76
+ *
77
+ * if `updateJsonURL` or `releaseAsarURL` are absent,
78
+ * `repository` will be used to determine the url
79
+ */
80
+ repository?: string;
81
+ /**
82
+ * URL of version info json
83
+ * @default `${repository.replace('github.com', 'raw.githubusercontent.com')}/master/version.json`
84
+ * @throws if `updateJsonURL` and `repository` are all not set
85
+ */
86
+ updateJsonURL?: string;
87
+ /**
88
+ * URL of release asar.gz
89
+ * @default `${repository}/releases/download/latest/${productName}.asar.gz`
90
+ * @throws if `releaseAsarURL` and `repository` are all not set
91
+ */
92
+ releaseAsarURL?: string;
93
+ /**
94
+ * whether to enable debug listener
95
+ */
96
+ debug?: boolean;
97
+ overrideFunctions?: {
98
+ /**
99
+ * custom version compare function {@link FunctionCompareVersion}
100
+ * @param oldVersion old version string
101
+ * @param newVersion new version string
102
+ * @returns whether to update
103
+ */
104
+ compareVersion?: FunctionCompareVersion;
105
+ /**
106
+ * custom verify signature function {@link FunctionVerifySignature}
107
+ * @param buffer file buffer
108
+ * @param signature signature
109
+ * @param cert certificate
110
+ */
111
+ verifySignaure?: FunctionVerifySignature;
112
+ /**
113
+ * custom download JSON function
114
+ * @param url download url
115
+ * @param updater updater, to trigger events
116
+ * @param header download header
117
+ * @returns `UpdateJSON`
118
+ */
119
+ downloadJSON?: (url: string, updater: Updater, headers: Record<string, any>) => Promise<UpdateJSON>;
120
+ /**
121
+ * custom download buffer function
122
+ * @param url download url
123
+ * @param updater updater, to trigger events
124
+ * @param header download header
125
+ * @returns `Buffer`
126
+ */
127
+ downloadBuffer?: (url: string, updater: Updater, headers: Record<string, any>) => Promise<Buffer>;
128
+ };
129
+ downloadConfig?: {
130
+ /**
131
+ * download user agent
132
+ * @default 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36'
133
+ */
134
+ userAgent?: string;
135
+ /**
136
+ * extra download header, `accept` and `user-agent` is set by default
137
+ */
138
+ extraHeader?: Record<string, string>;
139
+ };
140
+ }
141
+
142
+ /**
143
+ * get the application asar absolute path
144
+ * @param name The name of the application
145
+ */
146
+ declare function getProductAsarPath(name: string): string;
147
+ /**
148
+ * get the version of entry (app.asar)
149
+ */
150
+ declare function getEntryVersion(): string;
151
+ /**
152
+ * get the version of application (name.asar)
153
+ * @param name - The name of the application
154
+ */
155
+ declare function getProductVersion(name: string): string;
156
+ /**
157
+ * require native package from app.asar
158
+ * @param packageName native package name
159
+ */
160
+ declare function requireNative<T = any>(packageName: string): T;
161
+ /**
162
+ * get github version.json CDN URL for accelerating the speed of downloading version info
163
+ */
164
+ declare function parseGithubCdnURL(repository: string, cdnPrefix: string, relativeFilePath: string): string;
165
+ /**
166
+ * get group of github release CDN prefix for accelerating the speed of downloading release
167
+ */
168
+ declare function getGithubReleaseCdnGroup(): {
169
+ cdnPrefix: string;
170
+ maintainer: string;
171
+ }[];
172
+ declare function restartApp(): void;
173
+ declare function waitAppReady(duration?: number): Promise<unknown>;
174
+
175
+ declare function createUpdater({ SIGNATURE_CERT, repository, productName, releaseAsarURL: _release, updateJsonURL: _update, debug, downloadConfig: { extraHeader, userAgent }, overrideFunctions: { compareVersion, verifySignaure, downloadBuffer, downloadJSON, }, }: UpdaterOption): Updater;
176
+
177
+ type AppOption = {
178
+ /**
179
+ * name of your application
180
+ *
181
+ * you can use the `name` in `package.json`
182
+ */
183
+ name: string;
184
+ /**
185
+ * path of electron output dist
186
+ * @default 'dist-electron'
187
+ */
188
+ electronDistPath?: string;
189
+ /**
190
+ * relative path of main entry in electron dist
191
+ * @default 'main/index.js'
192
+ */
193
+ mainPath?: string;
194
+ };
195
+ type OptionalProperty<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
196
+ type InitUpdaterOptions = OptionalProperty<UpdaterOption, 'productName'>;
197
+ type StartupWithUpdater = (updater: Updater) => void;
198
+ /**
199
+ * create updater manually
200
+ * @example
201
+ * ```ts
202
+ * import { createUpdater, getGithubReleaseCdnGroup, initApp, parseGithubCdnURL } from 'electron-incremental-update'
203
+ * import { name, repository } from '../package.json'
204
+ *
205
+ * const SIGNATURE_CERT = '' // auto generate
206
+ *
207
+ * const { cdnPrefix } = getGithubReleaseCdnGroup()[0]
208
+ * const updater = createUpdater({
209
+ * SIGNATURE_CERT,
210
+ * productName: name,
211
+ * repository,
212
+ * updateJsonURL: parseGithubCdnURL(repository, 'fastly.jsdelivr.net/gh', 'version.json'),
213
+ * releaseAsarURL: parseGithubCdnURL(repository, cdnPrefix, `download/latest/${name}.asar.gz`),
214
+ * debug: true,
215
+ * })
216
+ * initApp({ name }).setUpdater(updater)
217
+ * ```
218
+ */
219
+ declare function initApp(appOptions: AppOption): {
220
+ setUpdater: (updater: Updater) => void;
221
+ };
222
+ /**
223
+ * create updater when init, no need to set productName
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * import { initApp } from 'electron-incremental-update'
228
+ * import { name, repository } from '../package.json'
229
+ *
230
+ * const SIGNATURE_CERT = '' // auto generate
231
+ *
232
+ * initApp({ name }, { SIGNATURE_CERT, repository })
233
+ * ```
234
+ */
235
+ declare function initApp(appOptions: AppOption, updaterOptions: InitUpdaterOptions): undefined;
236
+
237
+ export { AppOption, CheckResultType, FunctionCompareVersion, FunctionVerifySignature, InitUpdaterOptions, InstallResult, StartupWithUpdater, UpdateJSON, Updater, UpdaterOption, createUpdater, getEntryVersion, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, initApp, isUpdateJSON, parseGithubCdnURL, requireNative, restartApp, waitAppReady };
package/dist/index.d.ts CHANGED
@@ -194,6 +194,7 @@ type AppOption = {
194
194
  };
195
195
  type OptionalProperty<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
196
196
  type InitUpdaterOptions = OptionalProperty<UpdaterOption, 'productName'>;
197
+ type StartupWithUpdater = (updater: Updater) => void;
197
198
  /**
198
199
  * create updater manually
199
200
  * @example
@@ -233,4 +234,4 @@ declare function initApp(appOptions: AppOption): {
233
234
  */
234
235
  declare function initApp(appOptions: AppOption, updaterOptions: InitUpdaterOptions): undefined;
235
236
 
236
- export { AppOption, CheckResultType, FunctionCompareVersion, FunctionVerifySignature, InitUpdaterOptions, InstallResult, UpdateJSON, Updater, UpdaterOption, createUpdater, getEntryVersion, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, initApp, isUpdateJSON, parseGithubCdnURL, requireNative, restartApp, waitAppReady };
237
+ export { AppOption, CheckResultType, FunctionCompareVersion, FunctionVerifySignature, InitUpdaterOptions, InstallResult, StartupWithUpdater, UpdateJSON, Updater, UpdaterOption, createUpdater, getEntryVersion, getGithubReleaseCdnGroup, getProductAsarPath, getProductVersion, initApp, isUpdateJSON, parseGithubCdnURL, requireNative, restartApp, waitAppReady };
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __require,
3
3
  verify
4
- } from "./chunk-KMBSE4OO.mjs";
4
+ } from "./chunk-XQ4Z2OVN.mjs";
5
5
 
6
6
  // src/index.ts
7
7
  import { resolve as resolve2 } from "node:path";
@@ -0,0 +1,129 @@
1
+ import { Plugin } from 'vite';
2
+ import { Buffer } from 'node:buffer';
3
+ import { DistinguishedName } from '@cyyynthia/jscert';
4
+
5
+ type FunctionGenerateKeyPair = (keyLength: number, subject: DistinguishedName, expires: Date) => {
6
+ privateKey: string;
7
+ cert: string;
8
+ };
9
+ type FunctionGenerateSignature = (buffer: Buffer, privateKey: string, cert: string, version: string) => string;
10
+ type Options = {
11
+ /**
12
+ * whether is in build mode
13
+ */
14
+ isBuild: boolean;
15
+ /**
16
+ * the name of you application
17
+ *
18
+ * you can set as 'name' in `package.json`
19
+ */
20
+ productName: string;
21
+ /**
22
+ * the version of you application
23
+ *
24
+ * you can set as 'version' in `package.json`
25
+ */
26
+ version: string;
27
+ /**
28
+ * Whether to minify entry file
29
+ */
30
+ minify?: boolean;
31
+ /**
32
+ * paths config
33
+ */
34
+ paths?: {
35
+ /**
36
+ * Path to app entry file
37
+ * @default 'electron/app.ts'
38
+ */
39
+ entryPath?: string;
40
+ /**
41
+ * Path to app entry output file
42
+ * @default 'app.js'
43
+ */
44
+ entryOutputPath?: string;
45
+ /**
46
+ * Path to asar file
47
+ * @default `release/${productName}.asar`
48
+ */
49
+ asarOutputPath?: string;
50
+ /**
51
+ * Path to electron build output
52
+ * @default `dist-electron`
53
+ */
54
+ electronDistPath?: string;
55
+ /**
56
+ * Path to renderer build output
57
+ * @default `dist`
58
+ */
59
+ rendererDistPath?: string;
60
+ /**
61
+ * Path to version info output
62
+ * @default `version.json`
63
+ */
64
+ versionPath?: string;
65
+ };
66
+ /**
67
+ * signature config
68
+ */
69
+ keys?: {
70
+ /**
71
+ * Path to the pem file that contains private key
72
+ * if not ended with .pem, it will be appended
73
+ * @default 'keys/private.pem'
74
+ */
75
+ privateKeyPath?: string;
76
+ /**
77
+ * Path to the pem file that contains public key
78
+ * if not ended with .pem, it will be appended
79
+ * @default 'keys/cert.pem'
80
+ */
81
+ certPath?: string;
82
+ /**
83
+ * Length of the key
84
+ * @default 2048
85
+ */
86
+ keyLength?: number;
87
+ /**
88
+ * X509 certificate info
89
+ *
90
+ * only generate simple **self-signed** certificate **without extensions**
91
+ */
92
+ certInfo?: {
93
+ /**
94
+ * the subject of the certificate
95
+ *
96
+ * @default { commonName: productName, organization: `org.${productName}` }
97
+ */
98
+ subject?: DistinguishedName;
99
+ /**
100
+ * expires of the certificate
101
+ * - `Date`: expire date
102
+ * - `number`: expire duration in seconds
103
+ *
104
+ * @default Date.now() + 365 * 864e5 (1 year)
105
+ */
106
+ expires?: Date | number;
107
+ };
108
+ overrideFunctions?: {
109
+ /**
110
+ * custom key pair generate function {@link FunctionGenerateKeyPair}
111
+ * @param keyLength key length
112
+ * @param subject subject info
113
+ * @param expires expire date
114
+ */
115
+ generateKeyPair?: FunctionGenerateKeyPair;
116
+ /**
117
+ * custom signature generate function {@link FunctionGenerateSignature}
118
+ * @param buffer file buffer
119
+ * @param privateKey private key
120
+ * @param cert certificate
121
+ */
122
+ generateSignature?: FunctionGenerateSignature;
123
+ };
124
+ };
125
+ };
126
+
127
+ declare function export_default(options: Options): Plugin;
128
+
129
+ export { export_default as default };
package/dist/vite.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  signature
3
- } from "./chunk-KMBSE4OO.mjs";
3
+ } from "./chunk-XQ4Z2OVN.mjs";
4
4
 
5
5
  // src/vite.ts
6
6
  import { createLogger } from "vite";
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
- "version": "0.6.2",
3
+ "author": "subframe7536",
4
+ "version": "0.6.3",
4
5
  "description": "electron incremental update tools, powered by vite",
5
6
  "scripts": {
6
7
  "build": "tsup",
7
- "release": "pnpm test && pnpm run build && bumpp && npm publish",
8
+ "release": "pnpm test && pnpm run build && bumpp --all && npm publish",
8
9
  "test": "vitest --run"
9
10
  },
10
11
  "publishConfig": {
@@ -22,22 +23,24 @@
22
23
  "types": "dist/index.d.ts",
23
24
  "exports": {
24
25
  ".": {
25
- "require": "./dist/index.cjs",
26
- "import": "./dist/index.mjs"
26
+ "import": {
27
+ "default": "./dist/index.mjs",
28
+ "types": "./dist/index.d.mts"
29
+ },
30
+ "require": {
31
+ "default": "./dist/index.cjs",
32
+ "types": "./dist/index.d.ts"
33
+ }
27
34
  },
28
35
  "./vite": {
29
- "require": "./dist/vite.cjs",
30
- "import": "./dist/vite.mjs"
31
- }
32
- },
33
- "typesVersions": {
34
- "*": {
35
- ".": [
36
- "dist/updater.d.ts"
37
- ],
38
- "vite": [
39
- "dist/vite.d.ts"
40
- ]
36
+ "import": {
37
+ "default": "./dist/index.mjs",
38
+ "types": "./dist/index.d.mts"
39
+ },
40
+ "require": {
41
+ "default": "./dist/index.cjs",
42
+ "types": "./dist/index.d.ts"
43
+ }
41
44
  }
42
45
  },
43
46
  "keywords": [
@@ -45,18 +48,17 @@
45
48
  "incremental update",
46
49
  "updater"
47
50
  ],
48
- "author": "",
49
51
  "devDependencies": {
50
52
  "@electron/asar": "^3.2.4",
51
53
  "@subframe7536/eslint-config": "^0.1.9",
52
- "@types/node": "^20.2.5",
54
+ "@types/node": "^20.3.2",
53
55
  "asar": "^3.2.0",
54
56
  "bumpp": "^9.1.1",
55
- "electron": "^25.0.1",
56
- "eslint": "^8.42.0",
57
+ "electron": "^25.2.0",
58
+ "eslint": "^8.43.0",
57
59
  "fs-jetpack": "^5.1.0",
58
- "tsup": "^6.7.0",
59
- "typescript": "^5.1.3",
60
+ "tsup": "^7.1.0",
61
+ "typescript": "^5.1.5",
60
62
  "vite": "^4.3.9",
61
63
  "vitest": "^0.32.2"
62
64
  },