pake-cli 3.6.0 โ 3.6.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/dist/cli.js +402 -308
- package/dist/dev.js +1100 -215
- package/dist/dev.js.map +1 -1
- package/package.json +4 -3
- package/src-tauri/.pake/pake.json +43 -0
- package/src-tauri/.pake/tauri.conf.json +27 -0
- package/src-tauri/.pake/tauri.linux.conf.json +13 -0
- package/src-tauri/.pake/tauri.macos.conf.json +14 -0
- package/src-tauri/.pake/tauri.windows.conf.json +15 -0
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/icons/icon.icns +0 -0
- package/src-tauri/icons/icon.png +0 -0
- package/src-tauri/src/app/invoke.rs +10 -5
- package/src-tauri/src/app/menu.rs +281 -0
- package/src-tauri/src/app/mod.rs +1 -0
- package/src-tauri/src/lib.rs +2 -231
- package/src-tauri/assets/com-tw93-weekly.desktop +0 -10
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { InvalidArgumentError, program, Option } from 'commander';
|
|
4
2
|
import log from 'loglevel';
|
|
5
3
|
import path from 'path';
|
|
6
4
|
import fsExtra from 'fs-extra';
|
|
7
5
|
import { fileURLToPath } from 'url';
|
|
6
|
+
import chalk from 'chalk';
|
|
8
7
|
import prompts from 'prompts';
|
|
9
8
|
import os from 'os';
|
|
10
9
|
import { execa, execaSync } from 'execa';
|
|
@@ -21,113 +20,7 @@ import { fileTypeFromBuffer } from 'file-type';
|
|
|
21
20
|
import icongen from 'icon-gen';
|
|
22
21
|
import sharp from 'sharp';
|
|
23
22
|
import * as psl from 'psl';
|
|
24
|
-
|
|
25
|
-
var name = "pake-cli";
|
|
26
|
-
var version = "3.6.0";
|
|
27
|
-
var description = "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ";
|
|
28
|
-
var engines = {
|
|
29
|
-
node: ">=18.0.0"
|
|
30
|
-
};
|
|
31
|
-
var packageManager = "pnpm@10.15.0";
|
|
32
|
-
var bin = {
|
|
33
|
-
pake: "./dist/cli.js"
|
|
34
|
-
};
|
|
35
|
-
var repository = {
|
|
36
|
-
type: "git",
|
|
37
|
-
url: "https://github.com/tw93/pake.git"
|
|
38
|
-
};
|
|
39
|
-
var author = {
|
|
40
|
-
name: "Tw93",
|
|
41
|
-
email: "tw93@qq.com"
|
|
42
|
-
};
|
|
43
|
-
var keywords = [
|
|
44
|
-
"pake",
|
|
45
|
-
"pake-cli",
|
|
46
|
-
"rust",
|
|
47
|
-
"tauri",
|
|
48
|
-
"no-electron",
|
|
49
|
-
"productivity"
|
|
50
|
-
];
|
|
51
|
-
var files = [
|
|
52
|
-
"dist",
|
|
53
|
-
"src-tauri"
|
|
54
|
-
];
|
|
55
|
-
var scripts = {
|
|
56
|
-
start: "pnpm run dev",
|
|
57
|
-
dev: "pnpm run tauri dev",
|
|
58
|
-
build: "tauri build",
|
|
59
|
-
"build:debug": "tauri build --debug",
|
|
60
|
-
"build:mac": "tauri build --target universal-apple-darwin",
|
|
61
|
-
"build:config": "chmod +x scripts/configure-tauri.mjs && node scripts/configure-tauri.mjs",
|
|
62
|
-
analyze: "cd src-tauri && cargo bloat --release --crates",
|
|
63
|
-
tauri: "tauri",
|
|
64
|
-
cli: "cross-env NODE_ENV=development rollup -c -w",
|
|
65
|
-
"cli:build": "cross-env NODE_ENV=production rollup -c",
|
|
66
|
-
test: "pnpm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
|
|
67
|
-
format: "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
|
|
68
|
-
"format:check": "prettier --check . --ignore-unknown",
|
|
69
|
-
update: "pnpm update --verbose && cd src-tauri && cargo update",
|
|
70
|
-
prepublishOnly: "pnpm run cli:build"
|
|
71
|
-
};
|
|
72
|
-
var type = "module";
|
|
73
|
-
var exports = "./dist/cli.js";
|
|
74
|
-
var license = "MIT";
|
|
75
|
-
var dependencies = {
|
|
76
|
-
"@tauri-apps/api": "^2.9.0",
|
|
77
|
-
"@tauri-apps/cli": "^2.9.0",
|
|
78
|
-
axios: "^1.12.2",
|
|
79
|
-
chalk: "^5.6.2",
|
|
80
|
-
commander: "^12.1.0",
|
|
81
|
-
execa: "^9.6.0",
|
|
82
|
-
"file-type": "^18.7.0",
|
|
83
|
-
"fs-extra": "^11.3.2",
|
|
84
|
-
"icon-gen": "^5.0.0",
|
|
85
|
-
loglevel: "^1.9.2",
|
|
86
|
-
ora: "^8.2.0",
|
|
87
|
-
prompts: "^2.4.2",
|
|
88
|
-
psl: "^1.15.0",
|
|
89
|
-
sharp: "^0.33.5",
|
|
90
|
-
"tmp-promise": "^3.0.3",
|
|
91
|
-
"update-notifier": "^7.3.1"
|
|
92
|
-
};
|
|
93
|
-
var devDependencies = {
|
|
94
|
-
"@rollup/plugin-alias": "^5.1.1",
|
|
95
|
-
"@rollup/plugin-commonjs": "^28.0.8",
|
|
96
|
-
"@rollup/plugin-json": "^6.1.0",
|
|
97
|
-
"@rollup/plugin-replace": "^6.0.2",
|
|
98
|
-
"@rollup/plugin-terser": "^0.4.4",
|
|
99
|
-
"@types/fs-extra": "^11.0.4",
|
|
100
|
-
"@types/node": "^20.19.23",
|
|
101
|
-
"@types/page-icon": "^0.3.6",
|
|
102
|
-
"@types/prompts": "^2.4.9",
|
|
103
|
-
"@types/tmp": "^0.2.6",
|
|
104
|
-
"@types/update-notifier": "^6.0.8",
|
|
105
|
-
"app-root-path": "^3.1.0",
|
|
106
|
-
"cross-env": "^7.0.3",
|
|
107
|
-
prettier: "^3.6.2",
|
|
108
|
-
rollup: "^4.52.5",
|
|
109
|
-
"rollup-plugin-typescript2": "^0.36.0",
|
|
110
|
-
tslib: "^2.8.1",
|
|
111
|
-
typescript: "^5.9.3"
|
|
112
|
-
};
|
|
113
|
-
var packageJson = {
|
|
114
|
-
name: name,
|
|
115
|
-
version: version,
|
|
116
|
-
description: description,
|
|
117
|
-
engines: engines,
|
|
118
|
-
packageManager: packageManager,
|
|
119
|
-
bin: bin,
|
|
120
|
-
repository: repository,
|
|
121
|
-
author: author,
|
|
122
|
-
keywords: keywords,
|
|
123
|
-
files: files,
|
|
124
|
-
scripts: scripts,
|
|
125
|
-
type: type,
|
|
126
|
-
exports: exports,
|
|
127
|
-
license: license,
|
|
128
|
-
dependencies: dependencies,
|
|
129
|
-
devDependencies: devDependencies
|
|
130
|
-
};
|
|
23
|
+
import { InvalidArgumentError, program as program$1, Option } from 'commander';
|
|
131
24
|
|
|
132
25
|
// Convert the current module URL to a file path
|
|
133
26
|
const currentModulePath = fileURLToPath(import.meta.url);
|
|
@@ -379,7 +272,12 @@ async function installRust() {
|
|
|
379
272
|
}
|
|
380
273
|
catch (error) {
|
|
381
274
|
spinner.fail(chalk.red('โ Rust installation failed!'));
|
|
382
|
-
|
|
275
|
+
if (error instanceof Error) {
|
|
276
|
+
console.error(error.message);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
console.error(error);
|
|
280
|
+
}
|
|
383
281
|
process.exit(1);
|
|
384
282
|
}
|
|
385
283
|
}
|
|
@@ -421,6 +319,9 @@ function generateSafeFilename(name) {
|
|
|
421
319
|
.replace(/\.+$/g, '')
|
|
422
320
|
.slice(0, 255);
|
|
423
321
|
}
|
|
322
|
+
function getSafeAppName(name) {
|
|
323
|
+
return generateSafeFilename(name).toLowerCase();
|
|
324
|
+
}
|
|
424
325
|
function generateLinuxPackageName(name) {
|
|
425
326
|
return name
|
|
426
327
|
.toLowerCase()
|
|
@@ -448,12 +349,6 @@ function generateIdentifierSafeName(name) {
|
|
|
448
349
|
return cleaned;
|
|
449
350
|
}
|
|
450
351
|
|
|
451
|
-
/**
|
|
452
|
-
* Helper function to generate safe lowercase app name for file paths
|
|
453
|
-
*/
|
|
454
|
-
function getSafeAppName(name) {
|
|
455
|
-
return generateSafeFilename(name).toLowerCase();
|
|
456
|
-
}
|
|
457
352
|
async function mergeConfig(url, options, tauriConf) {
|
|
458
353
|
// Ensure .pake directory exists and copy source templates if needed
|
|
459
354
|
const srcTauriDir = path.join(npmDirectory, 'src-tauri');
|
|
@@ -474,7 +369,7 @@ async function mergeConfig(url, options, tauriConf) {
|
|
|
474
369
|
await fsExtra.copy(sourcePath, destPath);
|
|
475
370
|
}
|
|
476
371
|
}));
|
|
477
|
-
const { width, height, fullscreen, maximize, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, enableDragDrop, multiInstance, startToTray, forceInternalNavigation, zoom, minWidth, minHeight, ignoreCertificateErrors, } = options;
|
|
372
|
+
const { width, height, fullscreen, maximize, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name = 'pake-app', resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, enableDragDrop, multiInstance, startToTray, forceInternalNavigation, zoom, minWidth, minHeight, ignoreCertificateErrors, } = options;
|
|
478
373
|
const { platform } = process;
|
|
479
374
|
const platformHideOnClose = hideOnClose ?? platform === 'darwin';
|
|
480
375
|
const tauriConfWindowOptions = {
|
|
@@ -555,10 +450,13 @@ async function mergeConfig(url, options, tauriConf) {
|
|
|
555
450
|
const identifier = `com.pake.${appNameSafe}`;
|
|
556
451
|
const desktopFileName = `${identifier}.desktop`;
|
|
557
452
|
// Create desktop file content
|
|
453
|
+
// Determine if title contains Chinese characters for Name[zh_CN]
|
|
454
|
+
const chineseName = title && /[\u4e00-\u9fa5]/.test(title) ? title : null;
|
|
558
455
|
const desktopContent = `[Desktop Entry]
|
|
559
456
|
Version=1.0
|
|
560
457
|
Type=Application
|
|
561
458
|
Name=${name}
|
|
459
|
+
${chineseName ? `Name[zh_CN]=${chineseName}` : ''}
|
|
562
460
|
Comment=${name}
|
|
563
461
|
Exec=pake-${appNameSafe}
|
|
564
462
|
Icon=${appNameSafe}_512
|
|
@@ -822,7 +720,9 @@ class BaseBuilder {
|
|
|
822
720
|
}
|
|
823
721
|
catch (error) {
|
|
824
722
|
// If installation times out and we haven't tried the mirror yet, retry with mirror
|
|
825
|
-
if (error
|
|
723
|
+
if (error instanceof Error &&
|
|
724
|
+
error.message.includes('timed out') &&
|
|
725
|
+
!usedMirror) {
|
|
826
726
|
spinner.fail(chalk.yellow('Installation timed out, retrying with CN mirror...'));
|
|
827
727
|
logger.info('โบ Retrying installation with CN mirror for better speed...');
|
|
828
728
|
const retrySpinner = getSpinner('Retrying installation...');
|
|
@@ -851,10 +751,18 @@ class BaseBuilder {
|
|
|
851
751
|
await this.buildAndCopy(url, this.options.targets);
|
|
852
752
|
}
|
|
853
753
|
async start(url) {
|
|
754
|
+
logger.info('Pake dev server starting...');
|
|
854
755
|
await mergeConfig(url, this.options, tauriConfig);
|
|
756
|
+
const packageManager = await this.detectPackageManager();
|
|
757
|
+
const configPath = path.join(npmDirectory, 'src-tauri', '.pake', 'tauri.conf.json');
|
|
758
|
+
const features = this.getBuildFeatures();
|
|
759
|
+
const featureArgs = features.length > 0 ? `--features ${features.join(',')}` : '';
|
|
760
|
+
const argSeparator = packageManager === 'npm' ? ' --' : '';
|
|
761
|
+
const command = `cd "${npmDirectory}" && ${packageManager} run tauri${argSeparator} dev --config "${configPath}" ${featureArgs}`;
|
|
762
|
+
await shellExec(command);
|
|
855
763
|
}
|
|
856
764
|
async buildAndCopy(url, target) {
|
|
857
|
-
const { name } = this.options;
|
|
765
|
+
const { name = 'pake-app' } = this.options;
|
|
858
766
|
await mergeConfig(url, this.options, tauriConfig);
|
|
859
767
|
// Detect available package manager
|
|
860
768
|
const packageManager = await this.detectPackageManager();
|
|
@@ -1121,7 +1029,7 @@ class MacBuilder extends BaseBuilder {
|
|
|
1121
1029
|
this.buildArch = validArchs.includes(options.targets || '')
|
|
1122
1030
|
? options.targets
|
|
1123
1031
|
: 'auto';
|
|
1124
|
-
if (process.env.PAKE_CREATE_APP === '1') {
|
|
1032
|
+
if (options.iterativeBuild || process.env.PAKE_CREATE_APP === '1') {
|
|
1125
1033
|
this.buildFormat = 'app';
|
|
1126
1034
|
}
|
|
1127
1035
|
else {
|
|
@@ -1130,7 +1038,7 @@ class MacBuilder extends BaseBuilder {
|
|
|
1130
1038
|
this.options.targets = this.buildFormat;
|
|
1131
1039
|
}
|
|
1132
1040
|
getFileName() {
|
|
1133
|
-
const { name } = this.options;
|
|
1041
|
+
const { name = 'pake-app' } = this.options;
|
|
1134
1042
|
if (this.buildFormat === 'app') {
|
|
1135
1043
|
return name;
|
|
1136
1044
|
}
|
|
@@ -1249,7 +1157,7 @@ class LinuxBuilder extends BaseBuilder {
|
|
|
1249
1157
|
this.options.targets = this.buildFormat;
|
|
1250
1158
|
}
|
|
1251
1159
|
getFileName() {
|
|
1252
|
-
const { name, targets } = this.options;
|
|
1160
|
+
const { name = 'pake-app', targets } = this.options;
|
|
1253
1161
|
const version = tauriConfig.version;
|
|
1254
1162
|
let arch;
|
|
1255
1163
|
if (this.buildArch === 'arm64') {
|
|
@@ -1283,7 +1191,7 @@ class LinuxBuilder extends BaseBuilder {
|
|
|
1283
1191
|
getBuildCommand(packageManager = 'pnpm') {
|
|
1284
1192
|
const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
|
|
1285
1193
|
const buildTarget = this.buildArch === 'arm64'
|
|
1286
|
-
? this.getTauriTarget(this.buildArch, 'linux')
|
|
1194
|
+
? (this.getTauriTarget(this.buildArch, 'linux') ?? undefined)
|
|
1287
1195
|
: undefined;
|
|
1288
1196
|
let fullCommand = this.buildBaseCommand(packageManager, configPath, buildTarget);
|
|
1289
1197
|
const features = this.getBuildFeatures();
|
|
@@ -1341,40 +1249,112 @@ class BuilderProvider {
|
|
|
1341
1249
|
}
|
|
1342
1250
|
}
|
|
1343
1251
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1252
|
+
var name = "pake-cli";
|
|
1253
|
+
var version = "3.6.2";
|
|
1254
|
+
var description = "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ";
|
|
1255
|
+
var engines = {
|
|
1256
|
+
node: ">=18.0.0"
|
|
1257
|
+
};
|
|
1258
|
+
var packageManager = "pnpm@10.15.0";
|
|
1259
|
+
var bin = {
|
|
1260
|
+
pake: "./dist/cli.js"
|
|
1261
|
+
};
|
|
1262
|
+
var repository = {
|
|
1263
|
+
type: "git",
|
|
1264
|
+
url: "https://github.com/tw93/pake.git"
|
|
1265
|
+
};
|
|
1266
|
+
var author = {
|
|
1267
|
+
name: "Tw93",
|
|
1268
|
+
email: "tw93@qq.com"
|
|
1269
|
+
};
|
|
1270
|
+
var keywords = [
|
|
1271
|
+
"pake",
|
|
1272
|
+
"pake-cli",
|
|
1273
|
+
"rust",
|
|
1274
|
+
"tauri",
|
|
1275
|
+
"no-electron",
|
|
1276
|
+
"productivity"
|
|
1277
|
+
];
|
|
1278
|
+
var files = [
|
|
1279
|
+
"dist",
|
|
1280
|
+
"src-tauri"
|
|
1281
|
+
];
|
|
1282
|
+
var scripts = {
|
|
1283
|
+
start: "pnpm run dev",
|
|
1284
|
+
dev: "pnpm run tauri dev",
|
|
1285
|
+
build: "tauri build",
|
|
1286
|
+
"build:debug": "tauri build --debug",
|
|
1287
|
+
"build:mac": "tauri build --target universal-apple-darwin",
|
|
1288
|
+
analyze: "cd src-tauri && cargo bloat --release --crates",
|
|
1289
|
+
tauri: "tauri",
|
|
1290
|
+
cli: "cross-env NODE_ENV=development rollup -c -w",
|
|
1291
|
+
"cli:dev": "cross-env NODE_ENV=development rollup -c -w",
|
|
1292
|
+
"cli:build": "cross-env NODE_ENV=production rollup -c",
|
|
1293
|
+
test: "pnpm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
|
|
1294
|
+
format: "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
|
|
1295
|
+
"format:check": "prettier --check . --ignore-unknown",
|
|
1296
|
+
update: "pnpm update --verbose && cd src-tauri && cargo update",
|
|
1297
|
+
prepublishOnly: "pnpm run cli:build"
|
|
1298
|
+
};
|
|
1299
|
+
var type = "module";
|
|
1300
|
+
var exports = "./dist/cli.js";
|
|
1301
|
+
var license = "MIT";
|
|
1302
|
+
var dependencies = {
|
|
1303
|
+
"@tauri-apps/api": "^2.9.0",
|
|
1304
|
+
"@tauri-apps/cli": "^2.9.0",
|
|
1305
|
+
axios: "^1.12.2",
|
|
1306
|
+
chalk: "^5.6.2",
|
|
1307
|
+
commander: "^12.1.0",
|
|
1308
|
+
execa: "^9.6.0",
|
|
1309
|
+
"file-type": "^18.7.0",
|
|
1310
|
+
"fs-extra": "^11.3.2",
|
|
1311
|
+
"icon-gen": "^5.0.0",
|
|
1312
|
+
loglevel: "^1.9.2",
|
|
1313
|
+
ora: "^8.2.0",
|
|
1314
|
+
prompts: "^2.4.2",
|
|
1315
|
+
psl: "^1.15.0",
|
|
1316
|
+
sharp: "^0.33.5",
|
|
1317
|
+
"tmp-promise": "^3.0.3",
|
|
1318
|
+
"update-notifier": "^7.3.1"
|
|
1319
|
+
};
|
|
1320
|
+
var devDependencies = {
|
|
1321
|
+
"@rollup/plugin-alias": "^5.1.1",
|
|
1322
|
+
"@rollup/plugin-commonjs": "^28.0.8",
|
|
1323
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
1324
|
+
"@rollup/plugin-replace": "^6.0.2",
|
|
1325
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
1326
|
+
"@types/fs-extra": "^11.0.4",
|
|
1327
|
+
"@types/node": "^20.19.23",
|
|
1328
|
+
"@types/page-icon": "^0.3.6",
|
|
1329
|
+
"@types/prompts": "^2.4.9",
|
|
1330
|
+
"@types/tmp": "^0.2.6",
|
|
1331
|
+
"@types/update-notifier": "^6.0.8",
|
|
1332
|
+
"app-root-path": "^3.1.0",
|
|
1333
|
+
"cross-env": "^7.0.3",
|
|
1334
|
+
prettier: "^3.6.2",
|
|
1335
|
+
rollup: "^4.52.5",
|
|
1336
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
1337
|
+
tslib: "^2.8.1",
|
|
1338
|
+
typescript: "^5.9.3",
|
|
1339
|
+
vitest: "^4.0.15"
|
|
1340
|
+
};
|
|
1341
|
+
var packageJson = {
|
|
1342
|
+
name: name,
|
|
1343
|
+
version: version,
|
|
1344
|
+
description: description,
|
|
1345
|
+
engines: engines,
|
|
1346
|
+
packageManager: packageManager,
|
|
1347
|
+
bin: bin,
|
|
1348
|
+
repository: repository,
|
|
1349
|
+
author: author,
|
|
1350
|
+
keywords: keywords,
|
|
1351
|
+
files: files,
|
|
1352
|
+
scripts: scripts,
|
|
1353
|
+
type: type,
|
|
1354
|
+
exports: exports,
|
|
1355
|
+
license: license,
|
|
1356
|
+
dependencies: dependencies,
|
|
1357
|
+
devDependencies: devDependencies
|
|
1378
1358
|
};
|
|
1379
1359
|
|
|
1380
1360
|
async function checkUpdateTips() {
|
|
@@ -1444,8 +1424,8 @@ async function preprocessIcon(inputPath) {
|
|
|
1444
1424
|
create: {
|
|
1445
1425
|
width: metadata.width || 512,
|
|
1446
1426
|
height: metadata.height || 512,
|
|
1447
|
-
channels:
|
|
1448
|
-
background: ICON_CONFIG.whiteBackground,
|
|
1427
|
+
channels: 4,
|
|
1428
|
+
background: { ...ICON_CONFIG.whiteBackground, alpha: 1 },
|
|
1449
1429
|
},
|
|
1450
1430
|
})
|
|
1451
1431
|
.composite([{ input: inputPath }])
|
|
@@ -1454,7 +1434,57 @@ async function preprocessIcon(inputPath) {
|
|
|
1454
1434
|
return outputPath;
|
|
1455
1435
|
}
|
|
1456
1436
|
catch (error) {
|
|
1457
|
-
|
|
1437
|
+
if (error instanceof Error) {
|
|
1438
|
+
logger.warn(`Failed to add background to icon: ${error.message}`);
|
|
1439
|
+
}
|
|
1440
|
+
return inputPath;
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Applies macOS squircle mask to icon
|
|
1445
|
+
*/
|
|
1446
|
+
async function applyMacOSMask(inputPath) {
|
|
1447
|
+
try {
|
|
1448
|
+
const { path: tempDir } = await dir();
|
|
1449
|
+
const outputPath = path.join(tempDir, 'icon-macos-rounded.png');
|
|
1450
|
+
// 1. Create a 1024x1024 rounded rect mask
|
|
1451
|
+
// rx="224" is closer to the smooth Apple squircle look for 1024px
|
|
1452
|
+
const mask = Buffer.from('<svg width="1024" height="1024"><rect x="0" y="0" width="1024" height="1024" rx="224" ry="224" fill="white"/></svg>');
|
|
1453
|
+
// 2. Load input, resize to 1024, apply mask
|
|
1454
|
+
const maskedBuffer = await sharp(inputPath)
|
|
1455
|
+
.resize(1024, 1024, {
|
|
1456
|
+
fit: 'contain',
|
|
1457
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
1458
|
+
})
|
|
1459
|
+
.composite([
|
|
1460
|
+
{
|
|
1461
|
+
input: mask,
|
|
1462
|
+
blend: 'dest-in',
|
|
1463
|
+
},
|
|
1464
|
+
])
|
|
1465
|
+
.png()
|
|
1466
|
+
.toBuffer();
|
|
1467
|
+
// 3. Resize to 840x840 (~18% padding) to solve "too big" visual issue
|
|
1468
|
+
// Native MacOS icons often leave some breathing room
|
|
1469
|
+
await sharp(maskedBuffer)
|
|
1470
|
+
.resize(840, 840, {
|
|
1471
|
+
fit: 'contain',
|
|
1472
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
1473
|
+
})
|
|
1474
|
+
.extend({
|
|
1475
|
+
top: 92,
|
|
1476
|
+
bottom: 92,
|
|
1477
|
+
left: 92,
|
|
1478
|
+
right: 92,
|
|
1479
|
+
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
|
1480
|
+
})
|
|
1481
|
+
.toFile(outputPath);
|
|
1482
|
+
return outputPath;
|
|
1483
|
+
}
|
|
1484
|
+
catch (error) {
|
|
1485
|
+
if (error instanceof Error) {
|
|
1486
|
+
logger.warn(`Failed to apply macOS mask: ${error.message}`);
|
|
1487
|
+
}
|
|
1458
1488
|
return inputPath;
|
|
1459
1489
|
}
|
|
1460
1490
|
}
|
|
@@ -1490,12 +1520,14 @@ async function convertIconFormat(inputPath, appName) {
|
|
|
1490
1520
|
fit: 'contain',
|
|
1491
1521
|
background: ICON_CONFIG.transparentBackground,
|
|
1492
1522
|
})
|
|
1523
|
+
.ensureAlpha()
|
|
1493
1524
|
.png()
|
|
1494
1525
|
.toFile(outputPath);
|
|
1495
1526
|
return outputPath;
|
|
1496
1527
|
}
|
|
1497
1528
|
// macOS
|
|
1498
|
-
await
|
|
1529
|
+
const macIconPath = await applyMacOSMask(processedInputPath);
|
|
1530
|
+
await icongen(macIconPath, platformOutputDir, {
|
|
1499
1531
|
report: false,
|
|
1500
1532
|
icns: { name: iconName, sizes: PLATFORM_CONFIG.macos.sizes },
|
|
1501
1533
|
});
|
|
@@ -1503,7 +1535,9 @@ async function convertIconFormat(inputPath, appName) {
|
|
|
1503
1535
|
return (await fsExtra.pathExists(outputPath)) ? outputPath : null;
|
|
1504
1536
|
}
|
|
1505
1537
|
catch (error) {
|
|
1506
|
-
|
|
1538
|
+
if (error instanceof Error) {
|
|
1539
|
+
logger.warn(`Icon format conversion failed: ${error.message}`);
|
|
1540
|
+
}
|
|
1507
1541
|
return null;
|
|
1508
1542
|
}
|
|
1509
1543
|
}
|
|
@@ -1641,14 +1675,18 @@ async function tryGetFavicon(url, appName) {
|
|
|
1641
1675
|
}
|
|
1642
1676
|
}
|
|
1643
1677
|
catch (error) {
|
|
1644
|
-
|
|
1645
|
-
|
|
1678
|
+
if (error instanceof Error) {
|
|
1679
|
+
logger.debug(`Icon service ${serviceUrl} failed: ${error.message}`);
|
|
1680
|
+
}
|
|
1681
|
+
// Network error handling
|
|
1646
1682
|
if ((IS_LINUX || IS_WIN) && error.code === 'ENOTFOUND') {
|
|
1647
|
-
|
|
1683
|
+
return null;
|
|
1648
1684
|
}
|
|
1649
|
-
//
|
|
1650
|
-
if (IS_WIN &&
|
|
1651
|
-
|
|
1685
|
+
// Icon generation error on Windows
|
|
1686
|
+
if (IS_WIN &&
|
|
1687
|
+
error instanceof Error &&
|
|
1688
|
+
error.message.includes('icongen')) {
|
|
1689
|
+
return null;
|
|
1652
1690
|
}
|
|
1653
1691
|
continue;
|
|
1654
1692
|
}
|
|
@@ -1657,7 +1695,9 @@ async function tryGetFavicon(url, appName) {
|
|
|
1657
1695
|
return null;
|
|
1658
1696
|
}
|
|
1659
1697
|
catch (error) {
|
|
1660
|
-
|
|
1698
|
+
if (error instanceof Error) {
|
|
1699
|
+
logger.warn(`Failed to fetch favicon: ${error.message}`);
|
|
1700
|
+
}
|
|
1661
1701
|
return null;
|
|
1662
1702
|
}
|
|
1663
1703
|
}
|
|
@@ -1682,7 +1722,7 @@ async function downloadIcon(iconUrl, showSpinner = true, customTimeout) {
|
|
|
1682
1722
|
}
|
|
1683
1723
|
catch (error) {
|
|
1684
1724
|
if (showSpinner && !(error.response?.status === 404)) {
|
|
1685
|
-
|
|
1725
|
+
logger.error('Icon download failed!', error);
|
|
1686
1726
|
}
|
|
1687
1727
|
return null;
|
|
1688
1728
|
}
|
|
@@ -1765,7 +1805,7 @@ async function handleOptions(options, url) {
|
|
|
1765
1805
|
if (name && platform === 'linux') {
|
|
1766
1806
|
name = generateLinuxPackageName(name);
|
|
1767
1807
|
}
|
|
1768
|
-
if (!isValidName(name, platform)) {
|
|
1808
|
+
if (name && !isValidName(name, platform)) {
|
|
1769
1809
|
const LINUX_NAME_ERROR = `โ Name should only include lowercase letters, numbers, and dashes (not leading dashes). Examples: com-123-xxx, 123pan, pan123, weread, we-read, 123.`;
|
|
1770
1810
|
const DEFAULT_NAME_ERROR = `โ Name should only include letters, numbers, dashes, and spaces (not leading dashes and spaces). Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead, we-read, We Read, 123.`;
|
|
1771
1811
|
const errorMsg = platform === 'linux' ? LINUX_NAME_ERROR : DEFAULT_NAME_ERROR;
|
|
@@ -1784,10 +1824,58 @@ async function handleOptions(options, url) {
|
|
|
1784
1824
|
identifier: getIdentifier(url),
|
|
1785
1825
|
};
|
|
1786
1826
|
const iconPath = await handleIcon(appOptions, url);
|
|
1787
|
-
appOptions.icon = iconPath ||
|
|
1827
|
+
appOptions.icon = iconPath || '';
|
|
1788
1828
|
return appOptions;
|
|
1789
1829
|
}
|
|
1790
1830
|
|
|
1831
|
+
const DEFAULT_PAKE_OPTIONS = {
|
|
1832
|
+
icon: '',
|
|
1833
|
+
height: 780,
|
|
1834
|
+
width: 1200,
|
|
1835
|
+
fullscreen: false,
|
|
1836
|
+
maximize: false,
|
|
1837
|
+
hideTitleBar: false,
|
|
1838
|
+
alwaysOnTop: false,
|
|
1839
|
+
appVersion: '1.0.0',
|
|
1840
|
+
darkMode: false,
|
|
1841
|
+
disabledWebShortcuts: false,
|
|
1842
|
+
activationShortcut: '',
|
|
1843
|
+
userAgent: '',
|
|
1844
|
+
showSystemTray: false,
|
|
1845
|
+
multiArch: false,
|
|
1846
|
+
targets: (() => {
|
|
1847
|
+
switch (process.platform) {
|
|
1848
|
+
case 'linux':
|
|
1849
|
+
return 'deb';
|
|
1850
|
+
case 'darwin':
|
|
1851
|
+
return 'dmg';
|
|
1852
|
+
case 'win32':
|
|
1853
|
+
return 'msi';
|
|
1854
|
+
default:
|
|
1855
|
+
return 'deb';
|
|
1856
|
+
}
|
|
1857
|
+
})(),
|
|
1858
|
+
useLocalFile: false,
|
|
1859
|
+
systemTrayIcon: '',
|
|
1860
|
+
proxyUrl: '',
|
|
1861
|
+
debug: false,
|
|
1862
|
+
inject: [],
|
|
1863
|
+
installerLanguage: 'en-US',
|
|
1864
|
+
hideOnClose: undefined, // Platform-specific: true for macOS, false for others
|
|
1865
|
+
incognito: false,
|
|
1866
|
+
wasm: false,
|
|
1867
|
+
enableDragDrop: false,
|
|
1868
|
+
keepBinary: false,
|
|
1869
|
+
multiInstance: false,
|
|
1870
|
+
startToTray: false,
|
|
1871
|
+
forceInternalNavigation: false,
|
|
1872
|
+
iterativeBuild: false,
|
|
1873
|
+
zoom: 100,
|
|
1874
|
+
minWidth: 0,
|
|
1875
|
+
minHeight: 0,
|
|
1876
|
+
ignoreCertificateErrors: false,
|
|
1877
|
+
};
|
|
1878
|
+
|
|
1791
1879
|
function validateNumberInput(value) {
|
|
1792
1880
|
const parsedValue = Number(value);
|
|
1793
1881
|
if (isNaN(parsedValue)) {
|
|
@@ -1802,152 +1890,158 @@ function validateUrlInput(url) {
|
|
|
1802
1890
|
return normalizeUrl(url);
|
|
1803
1891
|
}
|
|
1804
1892
|
catch (error) {
|
|
1805
|
-
|
|
1893
|
+
if (error instanceof Error) {
|
|
1894
|
+
throw new InvalidArgumentError(error.message);
|
|
1895
|
+
}
|
|
1896
|
+
throw error;
|
|
1806
1897
|
}
|
|
1807
1898
|
}
|
|
1808
1899
|
return url;
|
|
1809
1900
|
}
|
|
1810
1901
|
|
|
1811
|
-
|
|
1812
|
-
const
|
|
1902
|
+
function getCliProgram() {
|
|
1903
|
+
const { green, yellow } = chalk;
|
|
1904
|
+
const logo = `${chalk.green(' ____ _')}
|
|
1813
1905
|
${green('| _ \\ __ _| | _____')}
|
|
1814
1906
|
${green('| |_) / _` | |/ / _ \\')}
|
|
1815
1907
|
${green('| __/ (_| | < __/')} ${yellow('https://github.com/tw93/pake')}
|
|
1816
1908
|
${green('|_| \\__,_|_|\\_\\___| can turn any webpage into a desktop app with Rust.')}
|
|
1817
1909
|
`;
|
|
1818
|
-
program
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
.
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
return
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
return
|
|
1947
|
-
|
|
1948
|
-
}
|
|
1949
|
-
}
|
|
1950
|
-
|
|
1910
|
+
return program$1
|
|
1911
|
+
.addHelpText('beforeAll', logo)
|
|
1912
|
+
.usage(`[url] [options]`)
|
|
1913
|
+
.showHelpAfterError()
|
|
1914
|
+
.argument('[url]', 'The web URL you want to package', validateUrlInput)
|
|
1915
|
+
.option('--name <string>', 'Application name')
|
|
1916
|
+
.option('--icon <string>', 'Application icon', DEFAULT_PAKE_OPTIONS.icon)
|
|
1917
|
+
.option('--width <number>', 'Window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width)
|
|
1918
|
+
.option('--height <number>', 'Window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height)
|
|
1919
|
+
.option('--use-local-file', 'Use local file packaging', DEFAULT_PAKE_OPTIONS.useLocalFile)
|
|
1920
|
+
.option('--fullscreen', 'Start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen)
|
|
1921
|
+
.option('--hide-title-bar', 'For Mac, hide title bar', DEFAULT_PAKE_OPTIONS.hideTitleBar)
|
|
1922
|
+
.option('--multi-arch', 'For Mac, both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch)
|
|
1923
|
+
.option('--inject <files>', 'Inject local CSS/JS files into the page', (val, previous) => {
|
|
1924
|
+
if (!val)
|
|
1925
|
+
return DEFAULT_PAKE_OPTIONS.inject;
|
|
1926
|
+
// Split by comma and trim whitespace, filter out empty strings
|
|
1927
|
+
const files = val
|
|
1928
|
+
.split(',')
|
|
1929
|
+
.map((item) => item.trim())
|
|
1930
|
+
.filter((item) => item.length > 0);
|
|
1931
|
+
// If previous values exist (from multiple --inject options), merge them
|
|
1932
|
+
return previous ? [...previous, ...files] : files;
|
|
1933
|
+
}, DEFAULT_PAKE_OPTIONS.inject)
|
|
1934
|
+
.option('--debug', 'Debug build and more output', DEFAULT_PAKE_OPTIONS.debug)
|
|
1935
|
+
.addOption(new Option('--proxy-url <url>', 'Proxy URL for all network requests (http://, https://, socks5://)')
|
|
1936
|
+
.default(DEFAULT_PAKE_OPTIONS.proxyUrl)
|
|
1937
|
+
.hideHelp())
|
|
1938
|
+
.addOption(new Option('--user-agent <string>', 'Custom user agent')
|
|
1939
|
+
.default(DEFAULT_PAKE_OPTIONS.userAgent)
|
|
1940
|
+
.hideHelp())
|
|
1941
|
+
.addOption(new Option('--targets <string>', 'Build target format for your system').default(DEFAULT_PAKE_OPTIONS.targets))
|
|
1942
|
+
.addOption(new Option('--app-version <string>', 'App version, the same as package.json version')
|
|
1943
|
+
.default(DEFAULT_PAKE_OPTIONS.appVersion)
|
|
1944
|
+
.hideHelp())
|
|
1945
|
+
.addOption(new Option('--always-on-top', 'Always on the top level')
|
|
1946
|
+
.default(DEFAULT_PAKE_OPTIONS.alwaysOnTop)
|
|
1947
|
+
.hideHelp())
|
|
1948
|
+
.addOption(new Option('--maximize', 'Start window maximized')
|
|
1949
|
+
.default(DEFAULT_PAKE_OPTIONS.maximize)
|
|
1950
|
+
.hideHelp())
|
|
1951
|
+
.addOption(new Option('--dark-mode', 'Force Mac app to use dark mode')
|
|
1952
|
+
.default(DEFAULT_PAKE_OPTIONS.darkMode)
|
|
1953
|
+
.hideHelp())
|
|
1954
|
+
.addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts')
|
|
1955
|
+
.default(DEFAULT_PAKE_OPTIONS.disabledWebShortcuts)
|
|
1956
|
+
.hideHelp())
|
|
1957
|
+
.addOption(new Option('--activation-shortcut <string>', 'Shortcut key to active App')
|
|
1958
|
+
.default(DEFAULT_PAKE_OPTIONS.activationShortcut)
|
|
1959
|
+
.hideHelp())
|
|
1960
|
+
.addOption(new Option('--show-system-tray', 'Show system tray in app')
|
|
1961
|
+
.default(DEFAULT_PAKE_OPTIONS.showSystemTray)
|
|
1962
|
+
.hideHelp())
|
|
1963
|
+
.addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon')
|
|
1964
|
+
.default(DEFAULT_PAKE_OPTIONS.systemTrayIcon)
|
|
1965
|
+
.hideHelp())
|
|
1966
|
+
.addOption(new Option('--hide-on-close [boolean]', 'Hide window on close instead of exiting (default: true for macOS, false for others)')
|
|
1967
|
+
.default(DEFAULT_PAKE_OPTIONS.hideOnClose)
|
|
1968
|
+
.argParser((value) => {
|
|
1969
|
+
if (value === undefined)
|
|
1970
|
+
return true; // --hide-on-close without value
|
|
1971
|
+
if (value === 'true')
|
|
1972
|
+
return true;
|
|
1973
|
+
if (value === 'false')
|
|
1974
|
+
return false;
|
|
1975
|
+
throw new Error('--hide-on-close must be true or false');
|
|
1976
|
+
})
|
|
1977
|
+
.hideHelp())
|
|
1978
|
+
.addOption(new Option('--title <string>', 'Window title').hideHelp())
|
|
1979
|
+
.addOption(new Option('--incognito', 'Launch app in incognito/private mode')
|
|
1980
|
+
.default(DEFAULT_PAKE_OPTIONS.incognito)
|
|
1981
|
+
.hideHelp())
|
|
1982
|
+
.addOption(new Option('--wasm', 'Enable WebAssembly support (Flutter Web, etc.)')
|
|
1983
|
+
.default(DEFAULT_PAKE_OPTIONS.wasm)
|
|
1984
|
+
.hideHelp())
|
|
1985
|
+
.addOption(new Option('--enable-drag-drop', 'Enable drag and drop functionality')
|
|
1986
|
+
.default(DEFAULT_PAKE_OPTIONS.enableDragDrop)
|
|
1987
|
+
.hideHelp())
|
|
1988
|
+
.addOption(new Option('--keep-binary', 'Keep raw binary file alongside installer')
|
|
1989
|
+
.default(DEFAULT_PAKE_OPTIONS.keepBinary)
|
|
1990
|
+
.hideHelp())
|
|
1991
|
+
.addOption(new Option('--multi-instance', 'Allow multiple app instances')
|
|
1992
|
+
.default(DEFAULT_PAKE_OPTIONS.multiInstance)
|
|
1993
|
+
.hideHelp())
|
|
1994
|
+
.addOption(new Option('--start-to-tray', 'Start app minimized to tray')
|
|
1995
|
+
.default(DEFAULT_PAKE_OPTIONS.startToTray)
|
|
1996
|
+
.hideHelp())
|
|
1997
|
+
.addOption(new Option('--force-internal-navigation', 'Keep every link inside the Pake window instead of opening external handlers')
|
|
1998
|
+
.default(DEFAULT_PAKE_OPTIONS.forceInternalNavigation)
|
|
1999
|
+
.hideHelp())
|
|
2000
|
+
.addOption(new Option('--installer-language <string>', 'Installer language')
|
|
2001
|
+
.default(DEFAULT_PAKE_OPTIONS.installerLanguage)
|
|
2002
|
+
.hideHelp())
|
|
2003
|
+
.addOption(new Option('--zoom <number>', 'Initial page zoom level (50-200)')
|
|
2004
|
+
.default(DEFAULT_PAKE_OPTIONS.zoom)
|
|
2005
|
+
.argParser((value) => {
|
|
2006
|
+
const zoom = parseInt(value);
|
|
2007
|
+
if (isNaN(zoom) || zoom < 50 || zoom > 200) {
|
|
2008
|
+
throw new Error('--zoom must be a number between 50 and 200');
|
|
2009
|
+
}
|
|
2010
|
+
return zoom;
|
|
2011
|
+
})
|
|
2012
|
+
.hideHelp())
|
|
2013
|
+
.addOption(new Option('--min-width <number>', 'Minimum window width')
|
|
2014
|
+
.default(DEFAULT_PAKE_OPTIONS.minWidth)
|
|
2015
|
+
.argParser(validateNumberInput)
|
|
2016
|
+
.hideHelp())
|
|
2017
|
+
.addOption(new Option('--min-height <number>', 'Minimum window height')
|
|
2018
|
+
.default(DEFAULT_PAKE_OPTIONS.minHeight)
|
|
2019
|
+
.argParser(validateNumberInput)
|
|
2020
|
+
.hideHelp())
|
|
2021
|
+
.addOption(new Option('--ignore-certificate-errors', 'Ignore certificate errors (for self-signed certificates)')
|
|
2022
|
+
.default(DEFAULT_PAKE_OPTIONS.ignoreCertificateErrors)
|
|
2023
|
+
.hideHelp())
|
|
2024
|
+
.addOption(new Option('--iterative-build', 'Turn on rapid build mode (app only, no dmg/deb/msi), good for debugging')
|
|
2025
|
+
.default(DEFAULT_PAKE_OPTIONS.iterativeBuild)
|
|
2026
|
+
.hideHelp())
|
|
2027
|
+
.version(packageJson.version, '-v, --version')
|
|
2028
|
+
.configureHelp({
|
|
2029
|
+
sortSubcommands: true,
|
|
2030
|
+
optionTerm: (option) => {
|
|
2031
|
+
if (option.flags === '-v, --version' || option.flags === '-h, --help')
|
|
2032
|
+
return '';
|
|
2033
|
+
return option.flags;
|
|
2034
|
+
},
|
|
2035
|
+
optionDescription: (option) => {
|
|
2036
|
+
if (option.flags === '-v, --version' || option.flags === '-h, --help')
|
|
2037
|
+
return '';
|
|
2038
|
+
return option.description;
|
|
2039
|
+
},
|
|
2040
|
+
});
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
const program = getCliProgram();
|
|
2044
|
+
program.action(async (url, options) => {
|
|
1951
2045
|
await checkUpdateTips();
|
|
1952
2046
|
if (!url) {
|
|
1953
2047
|
program.help({
|