electron-incremental-update 0.5.1 → 0.6.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/index.mjs CHANGED
@@ -1,24 +1,33 @@
1
1
  import {
2
2
  __require,
3
3
  verify
4
- } from "./chunk-OBERMV66.mjs";
4
+ } from "./chunk-VADH6AZA.mjs";
5
5
 
6
6
  // src/index.ts
7
- import { resolve } from "node:path";
7
+ import { resolve as resolve2 } from "node:path";
8
8
  import { app as app3 } from "electron";
9
9
 
10
10
  // src/updater/index.ts
11
11
  import { EventEmitter } from "node:events";
12
+ import { Buffer as Buffer2 } from "node:buffer";
12
13
  import { createGunzip } from "node:zlib";
13
- import { createReadStream, createWriteStream, existsSync } from "node:fs";
14
- import { rm, writeFile } from "node:fs/promises";
14
+ import { createReadStream, createWriteStream, existsSync, rmSync } from "node:fs";
15
+ import { readFile, rename, rm, writeFile } from "node:fs/promises";
16
+ import { resolve } from "node:path";
15
17
  import { app as app2 } from "electron";
16
18
 
17
19
  // src/updater/defaultFunctions.ts
18
20
  import { Buffer } from "node:buffer";
19
21
  import https from "node:https";
22
+
23
+ // src/updater/types.ts
24
+ function isUpdateJSON(json) {
25
+ return "signature" in json && "version" in json && "size" in json;
26
+ }
27
+
28
+ // src/updater/defaultFunctions.ts
20
29
  function downloadJSONDefault(url, updater, headers) {
21
- return new Promise((resolve2, reject) => {
30
+ return new Promise((resolve3, reject) => {
22
31
  https.get(url, (res) => {
23
32
  let data = "";
24
33
  res.setEncoding("utf8");
@@ -27,8 +36,8 @@ function downloadJSONDefault(url, updater, headers) {
27
36
  res.on("end", () => {
28
37
  try {
29
38
  const json = JSON.parse(data);
30
- if ("signature" in json && "version" in json && "size" in json) {
31
- resolve2(json);
39
+ if (isUpdateJSON(json)) {
40
+ resolve3(json);
32
41
  } else {
33
42
  throw Error;
34
43
  }
@@ -43,7 +52,7 @@ function downloadJSONDefault(url, updater, headers) {
43
52
  }
44
53
  function downloadBufferDefault(url, updater, headers) {
45
54
  let progress = 0;
46
- return new Promise((resolve2, reject) => {
55
+ return new Promise((resolve3, reject) => {
47
56
  https.get(url, (res) => {
48
57
  let data = [];
49
58
  res.headers = headers;
@@ -53,7 +62,7 @@ function downloadBufferDefault(url, updater, headers) {
53
62
  data.push(chunk);
54
63
  });
55
64
  res.on("end", () => {
56
- resolve2(Buffer.concat(data));
65
+ resolve3(Buffer.concat(data));
57
66
  });
58
67
  }).on("error", (e) => {
59
68
  reject(e);
@@ -87,14 +96,14 @@ function compareVersionDefault(oldVersion, newVersion) {
87
96
  import { readFileSync } from "node:fs";
88
97
  import { dirname, join } from "node:path";
89
98
  import { app } from "electron";
90
- function getAppAsarPath(name) {
99
+ function getProductAsarPath(name) {
91
100
  return app.isPackaged ? join(dirname(app.getAppPath()), `${name}.asar`) : "dev";
92
101
  }
93
102
  function getEntryVersion() {
94
103
  return app.getVersion();
95
104
  }
96
- function getAppVersion(name) {
97
- return app.isPackaged ? readFileSync(join(getAppAsarPath(name), "version"), "utf-8") : getEntryVersion();
105
+ function getProductVersion(name) {
106
+ return app.isPackaged ? readFileSync(join(getProductAsarPath(name), "version"), "utf-8") : getEntryVersion();
98
107
  }
99
108
  function requireNative(packageName) {
100
109
  const path = app.isPackaged ? join(app.getAppPath(), "node_modules", packageName) : packageName;
@@ -134,7 +143,7 @@ function restartApp() {
134
143
 
135
144
  // src/updater/index.ts
136
145
  function createUpdater({
137
- SIGNATURE_PUB,
146
+ SIGNATURE_CERT,
138
147
  repository,
139
148
  productName,
140
149
  releaseAsarURL: _release,
@@ -145,94 +154,103 @@ function createUpdater({
145
154
  }) {
146
155
  const updater = new EventEmitter();
147
156
  let signature = "";
148
- let version = "";
149
- const gzipPath = `../${productName}.asar.gz`;
150
- const tmpFile = gzipPath.replace(".asar.gz", ".tmp.gz");
157
+ const asarPath = getProductAsarPath(productName);
158
+ const gzipPath = `${asarPath}.gz`;
159
+ const tmpFilePath = gzipPath.replace(".asar.gz", ".tmp.asar");
151
160
  const { downloadBuffer, downloadJSON, extraHeader, userAgent } = downloadConfig || {};
152
161
  function log(msg) {
153
162
  debug && updater.emit("debug", msg);
154
163
  }
155
- async function download(url, format) {
156
- const ua = userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
157
- const headers = {
158
- Accept: `application/${format === "json" ? "json" : "octet-stream"}`,
159
- UserAgent: ua,
160
- ...extraHeader
161
- };
162
- log(`download headers: ${JSON.stringify(headers, null, 2)}`);
163
- const downloadFn = format === "json" ? downloadJSON ?? downloadJSONDefault : downloadBuffer ?? downloadBufferDefault;
164
- log(`download ${format} from ${url}`);
165
- const ret = await downloadFn(url, updater, headers);
166
- log(`download ${format} success`);
167
- return ret;
168
- }
169
- async function extractFile(gzipFilePath) {
170
- if (!gzipFilePath.endsWith(".asar.gz") || !existsSync(gzipFilePath)) {
171
- log("update .asar.gz file not exist");
172
- return;
164
+ async function extractFile() {
165
+ if (!gzipPath.endsWith(".asar.gz") || !existsSync(gzipPath)) {
166
+ throw new Error(".asar.gz file not exist");
173
167
  }
174
- gzipFilePath = gzipFilePath.replace(".asar.gz", ".tmp.gz");
175
- return new Promise((resolve2, reject) => {
168
+ return new Promise((resolve3, reject) => {
176
169
  const gunzip = createGunzip();
177
- const input = createReadStream(gzipFilePath);
178
- const outputFilePath = gzipFilePath.replace(".tmp.gz", ".asar");
179
- const output = createWriteStream(outputFilePath);
180
- log(`outputFilePath: ${outputFilePath}`);
170
+ const input = createReadStream(gzipPath);
171
+ const output = createWriteStream(tmpFilePath);
172
+ log(`outputFilePath: ${tmpFilePath}`);
181
173
  input.pipe(gunzip).pipe(output).on("finish", async () => {
182
- await rm(gzipFilePath);
183
- log(`${gzipFilePath} unzipped`);
184
- resolve2(outputFilePath);
174
+ await rm(gzipPath);
175
+ log(`${gzipPath} unzipped`);
176
+ resolve3(null);
185
177
  }).on("error", async (err) => {
186
- await rm(gzipFilePath);
178
+ await rm(gzipPath);
187
179
  output.destroy(err);
188
180
  reject(err);
189
181
  });
190
182
  });
191
183
  }
192
- function needUpdate(version2) {
184
+ function needUpdate(version) {
193
185
  if (!app2.isPackaged) {
194
186
  log("in dev mode, no need to update");
195
187
  return false;
196
188
  }
197
189
  const currentVersion = getEntryVersion();
198
- log(`check update:
199
- current version is ${currentVersion},
200
- new version is ${version2}`);
190
+ log(`check update: current version is ${currentVersion}, new version is ${version}`);
201
191
  const _compare = compareVersion ?? compareVersionDefault;
202
- return _compare(currentVersion, version2);
192
+ return _compare(currentVersion, version);
203
193
  }
204
- updater.checkUpdate = async (url) => {
205
- try {
206
- url ??= _update;
207
- if (!url) {
208
- log("no updateJsonURL, fallback to use repository");
194
+ async function parseData(format, data) {
195
+ if (existsSync(tmpFilePath)) {
196
+ log(`remove tmp file: ${tmpFilePath}`);
197
+ await rm(tmpFilePath);
198
+ }
199
+ if (existsSync(gzipPath)) {
200
+ log(`remove .gz file: ${gzipPath}`);
201
+ await rm(gzipPath);
202
+ }
203
+ if (typeof data === "object") {
204
+ if (format === "json" && isUpdateJSON(data) || format === "buffer" && Buffer2.isBuffer(data)) {
205
+ return data;
206
+ } else {
207
+ throw new Error(`invalid type at format '${format}': ${data}`);
208
+ }
209
+ } else if (["string", "undefined"].includes(typeof data)) {
210
+ const ua = userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36";
211
+ const headers = {
212
+ Accept: `application/${format === "json" ? "json" : "octet-stream"}`,
213
+ UserAgent: ua,
214
+ ...extraHeader
215
+ };
216
+ log(`download headers: ${JSON.stringify(headers, null, 2)}`);
217
+ const info = format === "json" ? {
218
+ name: "updateJsonURL",
219
+ url: _update,
220
+ repoFallback: `${repository.replace("github.com", "raw.githubusercontent.com")}/master/version.json`,
221
+ fn: downloadJSON ?? downloadJSONDefault
222
+ } : {
223
+ name: "releaseAsarURL",
224
+ url: _release,
225
+ repoFallback: `${repository}/releases/download/latest/${productName}.asar.gz`,
226
+ fn: downloadBuffer ?? downloadBufferDefault
227
+ };
228
+ data ??= info.url;
229
+ if (!data) {
230
+ log(`no ${info.name}, fallback to use repository`);
209
231
  if (!repository) {
210
- throw new Error("updateJsonURL or repository are not set");
232
+ throw new Error(`${info.name} or repository are not set`);
211
233
  }
212
- url = `${repository.replace("github.com", "raw.githubusercontent.com")}/master/version.json`;
234
+ data = info.repoFallback;
213
235
  }
214
- if (existsSync(tmpFile)) {
215
- log(`remove tmp file: ${tmpFile}`);
216
- await rm(tmpFile);
217
- }
218
- if (existsSync(gzipPath)) {
219
- log(`remove .gz file: ${gzipPath}`);
220
- await rm(gzipPath);
221
- }
222
- const json = await download(url, "json");
223
- const {
224
- signature: _sig,
225
- version: _v,
226
- size
227
- } = json;
228
- log(`update info: ${JSON.stringify(json, null, 2)}`);
229
- if (!await needUpdate(_v)) {
230
- log(`update unavailable: ${_v}`);
236
+ log(`download ${format} from ${data}`);
237
+ const ret = await info.fn(data, updater, headers);
238
+ log(`download ${format} success`);
239
+ return ret;
240
+ } else {
241
+ throw new Error(`invalid type at format '${format}': ${data}`);
242
+ }
243
+ }
244
+ updater.checkUpdate = async (data) => {
245
+ try {
246
+ const { signature: _sig, size, version } = await parseData("json", data);
247
+ log(`checked version: ${version}, size: ${size}`);
248
+ if (!await needUpdate(version)) {
249
+ log(`update unavailable: ${version}`);
231
250
  return void 0;
232
251
  } else {
233
- log(`update available: ${_v}`);
252
+ log(`update available: ${version}`);
234
253
  signature = _sig;
235
- version = _v;
236
254
  return { size, version };
237
255
  }
238
256
  } catch (error) {
@@ -240,30 +258,35 @@ function createUpdater({
240
258
  return error;
241
259
  }
242
260
  };
243
- updater.downloadUpdate = async (src) => {
261
+ updater.downloadAndInstall = async (data, sig) => {
244
262
  try {
245
- if (typeof src !== "object") {
246
- let _url = src ?? _release;
247
- if (!_url) {
248
- log("no releaseAsarURL, fallback to use repository");
249
- if (!repository) {
250
- throw new Error("releaseAsarURL or repository are not set");
251
- }
252
- _url = `${repository}/releases/download/latest/${productName}.asar.gz`;
253
- }
254
- src = await download(_url, "buffer");
263
+ const _sig = sig ?? signature;
264
+ if (!_sig) {
265
+ throw new Error("signature are not set, please checkUpdate first or set the second parameter");
255
266
  }
267
+ const buffer = await parseData("buffer", data);
256
268
  log("verify start");
257
- if (!verify(src, signature, SIGNATURE_PUB)) {
258
- log("verify failed");
259
- throw new Error("invalid signature");
269
+ const version = verify(buffer, _sig, SIGNATURE_CERT);
270
+ if (!version) {
271
+ throw new Error("verify failed, invalid signature");
260
272
  }
261
273
  log("verify success");
274
+ if (!await needUpdate(version)) {
275
+ throw new Error(`update unavailable: ${version}`);
276
+ }
262
277
  log(`write file: ${gzipPath}`);
263
- await writeFile(gzipPath, src);
278
+ await writeFile(gzipPath, buffer);
264
279
  log(`extract file: ${gzipPath}`);
265
- await extractFile(gzipPath);
280
+ await extractFile();
281
+ const asarVersion = await readFile(resolve(tmpFilePath, "version"), "utf8");
282
+ if (asarVersion !== version) {
283
+ rmSync(tmpFilePath);
284
+ throw new Error(`update failed: asar version is ${asarVersion}, but it should be ${version}`);
285
+ } else {
286
+ await rename(tmpFilePath, asarPath);
287
+ }
266
288
  log(`update success, version: ${version}`);
289
+ signature = "";
267
290
  return true;
268
291
  } catch (error) {
269
292
  log(error);
@@ -281,7 +304,7 @@ function initApp(appOptions, updaterOptions) {
281
304
  mainPath = "main/index.js"
282
305
  } = appOptions ?? {};
283
306
  const mainDir = app3.isPackaged ? `../${productName}.asar` : electronDistPath;
284
- const entry = resolve(__dirname, mainDir, mainPath);
307
+ const entry = resolve2(__dirname, mainDir, mainPath);
285
308
  if (updaterOptions) {
286
309
  __require(entry)(
287
310
  createUpdater({ ...updaterOptions, productName })
@@ -296,11 +319,12 @@ function initApp(appOptions, updaterOptions) {
296
319
  }
297
320
  export {
298
321
  createUpdater,
299
- getAppAsarPath,
300
- getAppVersion,
301
322
  getEntryVersion,
302
323
  getGithubReleaseCdnGroup,
324
+ getProductAsarPath,
325
+ getProductVersion,
303
326
  initApp,
327
+ isUpdateJSON,
304
328
  parseGithubCdnURL,
305
329
  requireNative,
306
330
  restartApp
package/dist/vite.cjs CHANGED
@@ -11,9 +11,9 @@ var __export = (target, all) => {
11
11
  };
12
12
  var __copyProps = (to, from, except, desc) => {
13
13
  if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ for (let key2 of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key2) && key2 !== except)
16
+ __defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
17
17
  }
18
18
  return to;
19
19
  };
@@ -35,44 +35,36 @@ __export(vite_exports, {
35
35
  module.exports = __toCommonJS(vite_exports);
36
36
  var import_vite = require("vite");
37
37
 
38
- // src/build-plugins/asar.ts
38
+ // src/build-plugins/build.ts
39
39
  var import_node_fs = require("fs");
40
40
  var import_promises = require("fs/promises");
41
41
  var import_node_zlib = __toESM(require("zlib"), 1);
42
+ var import_esbuild = require("esbuild");
42
43
 
43
44
  // src/crypto.ts
44
45
  var import_node_crypto = require("crypto");
45
46
  var import_node_buffer = require("buffer");
46
47
  var aesEncode = "base64url";
47
- function generateRSA(length = 2048) {
48
- const pair = (0, import_node_crypto.generateKeyPairSync)("rsa", { modulusLength: length });
49
- const privateKey = pair.privateKey.export({ type: "pkcs1", format: "pem" });
50
- const publicKey = pair.publicKey.export({ type: "pkcs1", format: "pem" });
51
- return {
52
- privateKey,
53
- publicKey
54
- };
55
- }
56
- function encrypt(plainText, key, iv) {
57
- const cipher = (0, import_node_crypto.createCipheriv)("aes-256-cbc", key, iv);
48
+ function encrypt(plainText, key2, iv) {
49
+ const cipher = (0, import_node_crypto.createCipheriv)("aes-256-cbc", key2, iv);
58
50
  let encrypted = cipher.update(plainText, "utf8", aesEncode);
59
51
  encrypted += cipher.final(aesEncode);
60
52
  return encrypted;
61
53
  }
62
- function generateKey(data, length) {
54
+ function key(data, length) {
63
55
  const hash = (0, import_node_crypto.createHash)("SHA256").update(data).digest("binary");
64
56
  return import_node_buffer.Buffer.from(hash).subarray(0, length);
65
57
  }
66
- function signature(buffer, privateKey, publicKey) {
58
+ function signature(buffer, privateKey, cert, version) {
67
59
  const sig = (0, import_node_crypto.createSign)("RSA-SHA256").update(buffer).sign({
68
60
  key: privateKey,
69
61
  padding: import_node_crypto.constants.RSA_PKCS1_PADDING,
70
62
  saltLength: import_node_crypto.constants.RSA_PSS_SALTLEN_DIGEST
71
63
  }, "base64");
72
- return encrypt(sig, generateKey(publicKey, 32), generateKey(buffer, 16));
64
+ return encrypt(`${sig}%${version}`, key(cert, 32), key(buffer, 16));
73
65
  }
74
66
 
75
- // src/build-plugins/asar.ts
67
+ // src/build-plugins/build.ts
76
68
  function gzipFile(filePath) {
77
69
  return new Promise((resolve, reject) => {
78
70
  const gzip = import_node_zlib.default.createGzip();
@@ -109,23 +101,20 @@ async function buildAsar({
109
101
  await pack(electronDistPath, asarOutputPath);
110
102
  await gzipFile(asarOutputPath);
111
103
  }
112
- async function generateVersion({
104
+ async function buildVersion({
113
105
  asarOutputPath,
114
106
  versionPath,
115
107
  privateKey,
116
- publicKey,
108
+ cert,
117
109
  version
118
110
  }) {
119
111
  const buffer = await (0, import_promises.readFile)(`${asarOutputPath}.gz`);
120
112
  await (0, import_promises.writeFile)(versionPath, JSON.stringify({
121
- signature: signature(buffer, privateKey, publicKey),
113
+ signature: signature(buffer, privateKey, cert, version),
122
114
  version,
123
115
  size: buffer.length
124
116
  }, null, 2));
125
117
  }
126
-
127
- // src/build-plugins/entry.ts
128
- var import_esbuild = require("esbuild");
129
118
  async function buildEntry({
130
119
  entryPath,
131
120
  entryOutputPath: outfile,
@@ -145,16 +134,35 @@ async function buildEntry({
145
134
  var import_node_fs2 = require("fs");
146
135
  var import_node_path = require("path");
147
136
  var import_node_os = require("os");
148
- function generateKeyFile(privateKeyPath, publicKeyPath, length) {
149
- const ret = generateRSA(length);
150
- (0, import_node_fs2.writeFileSync)(privateKeyPath, ret.privateKey);
151
- (0, import_node_fs2.writeFileSync)(publicKeyPath, ret.publicKey);
152
- return ret;
137
+ var import_node_crypto2 = require("crypto");
138
+ var import_jscert = require("@cyyynthia/jscert");
139
+ function generateCert(privateKey) {
140
+ const dn = {
141
+ country: "zh-CN",
142
+ state: "zj",
143
+ locality: "hz",
144
+ organization: "test",
145
+ organizationalUnit: "test unit",
146
+ commonName: "test.test",
147
+ emailAddress: "test@example.com"
148
+ };
149
+ const csr = new import_jscert.CertificateSigningRequest(dn, privateKey, { digest: "sha256" });
150
+ const expiry = new Date(Date.now() + 365 * 864e5);
151
+ return csr.createSelfSignedCertificate(expiry).toPem();
152
+ }
153
+ function generateKeys(length = 2048) {
154
+ const { privateKey: _key } = (0, import_node_crypto2.generateKeyPairSync)("rsa", { modulusLength: length });
155
+ const cert = generateCert(_key);
156
+ const privateKey = _key.export({ type: "pkcs1", format: "pem" });
157
+ return {
158
+ privateKey,
159
+ cert
160
+ };
153
161
  }
154
- function writePublicKeyToMain(entryPath, publicKey) {
162
+ function writeCertToMain(entryPath, cert) {
155
163
  const file = (0, import_node_fs2.readFileSync)(entryPath, "utf-8");
156
- const regex = /const SIGNATURE_PUB = ['`][\s\S]*?['`]/;
157
- const replacement = `const SIGNATURE_PUB = \`${publicKey}\``;
164
+ const regex = /const SIGNATURE_CERT = ['`][\s\S]*?['`]/;
165
+ const replacement = `const SIGNATURE_CERT = \`${cert}\``;
158
166
  let replaced = file;
159
167
  const signaturePubExists = regex.test(file);
160
168
  if (signaturePubExists) {
@@ -179,24 +187,26 @@ function writePublicKeyToMain(entryPath, publicKey) {
179
187
  function getKeys({
180
188
  keyLength,
181
189
  privateKeyPath,
182
- publicKeyPath,
190
+ certPath,
183
191
  entryPath
184
192
  }) {
185
193
  const keysDir = (0, import_node_path.dirname)(privateKeyPath);
186
194
  !(0, import_node_fs2.existsSync)(keysDir) && (0, import_node_fs2.mkdirSync)(keysDir);
187
- let privateKey, publicKey;
188
- if (!(0, import_node_fs2.existsSync)(privateKeyPath)) {
189
- const keys = generateKeyFile(privateKeyPath, publicKeyPath, keyLength);
195
+ let privateKey, cert;
196
+ if (!(0, import_node_fs2.existsSync)(privateKeyPath) || !(0, import_node_fs2.existsSync)(certPath)) {
197
+ const keys = generateKeys(keyLength);
190
198
  privateKey = keys.privateKey;
191
- publicKey = keys.publicKey;
199
+ cert = keys.cert;
200
+ (0, import_node_fs2.writeFileSync)(privateKeyPath, privateKey);
201
+ (0, import_node_fs2.writeFileSync)(certPath, cert);
192
202
  } else {
193
203
  privateKey = (0, import_node_fs2.readFileSync)(privateKeyPath, "utf-8");
194
- publicKey = (0, import_node_fs2.readFileSync)(publicKeyPath, "utf-8");
204
+ cert = (0, import_node_fs2.readFileSync)(certPath, "utf-8");
195
205
  }
196
- writePublicKeyToMain(entryPath, publicKey);
206
+ writeCertToMain(entryPath, cert);
197
207
  return {
198
208
  privateKey,
199
- publicKey
209
+ cert
200
210
  };
201
211
  }
202
212
 
@@ -214,9 +224,17 @@ function parseOptions(options) {
214
224
  } = paths;
215
225
  const {
216
226
  privateKeyPath = "keys/private.pem",
217
- publicKeyPath = "keys/public.pem",
218
- keyLength = 2048
227
+ certPath = "keys/cert.pem",
228
+ keyLength = 2048,
229
+ certInfo
219
230
  } = keys;
231
+ let {
232
+ subject = {
233
+ commonName: productName,
234
+ organization: `org.${productName}`
235
+ },
236
+ expires = Date.now() + 365 * 864e5
237
+ } = certInfo || {};
220
238
  const buildAsarOption = {
221
239
  version,
222
240
  asarOutputPath,
@@ -230,17 +248,22 @@ function parseOptions(options) {
230
248
  };
231
249
  let buildVersionOption;
232
250
  if (!import_ci_info.isCI) {
233
- const { privateKey, publicKey } = getKeys({
251
+ if (typeof expires === "number") {
252
+ expires = new Date(Date.now() + expires);
253
+ }
254
+ const { privateKey, cert } = getKeys({
234
255
  keyLength,
235
256
  privateKeyPath,
236
- publicKeyPath,
237
- entryPath
257
+ certPath,
258
+ entryPath,
259
+ subject,
260
+ expires
238
261
  });
239
262
  buildVersionOption = {
240
263
  version,
241
264
  asarOutputPath,
242
265
  privateKey,
243
- publicKey,
266
+ cert,
244
267
  versionPath
245
268
  };
246
269
  }
@@ -266,7 +289,7 @@ function vite_default(options) {
266
289
  }
267
290
  log.info("build asar start");
268
291
  await buildAsar(buildAsarOption);
269
- buildVersionOption && await generateVersion(buildVersionOption);
292
+ buildVersionOption && await buildVersion(buildVersionOption);
270
293
  log.info(`build asar end, output to ${asarOutputPath}`);
271
294
  }
272
295
  };
package/dist/vite.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from 'vite';
2
+ import { DistinguishedName } from '@cyyynthia/jscert';
2
3
 
3
4
  type Options = {
4
5
  /**
@@ -69,14 +70,35 @@ type Options = {
69
70
  /**
70
71
  * Path to the pem file that contains public key
71
72
  * if not ended with .pem, it will be appended
72
- * @default 'keys/public.pem'
73
+ * @default 'keys/cert.pem'
73
74
  */
74
- publicKeyPath?: string;
75
+ certPath?: string;
75
76
  /**
76
77
  * Length of the key
77
78
  * @default 2048
78
79
  */
79
80
  keyLength?: number;
81
+ /**
82
+ * X509 certificate info
83
+ *
84
+ * only generate simple **self-signed** certificate **without extensions**
85
+ */
86
+ certInfo?: {
87
+ /**
88
+ * the subject of the certificate
89
+ *
90
+ * @default { commonName: productName, organization: `org.${productName}` }
91
+ */
92
+ subject?: DistinguishedName;
93
+ /**
94
+ * expires of the certificate
95
+ * - `Date`: expire date
96
+ * - `number`: expire duration in seconds
97
+ *
98
+ * @default Date.now() + 365 * 864e5 (1 year)
99
+ */
100
+ expires?: Date | number;
101
+ };
80
102
  };
81
103
  };
82
104