pake-cli 3.1.1 → 3.2.0-beta

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.
Files changed (82) hide show
  1. package/README.md +82 -25
  2. package/dist/cli.js +145 -81
  3. package/dist/dev.js +39 -20
  4. package/dist/dev.js.map +1 -1
  5. package/package.json +15 -17
  6. package/src-tauri/.cargo/config.toml +5 -0
  7. package/src-tauri/Cargo.lock +1337 -1111
  8. package/src-tauri/Cargo.toml +12 -12
  9. package/src-tauri/assets/{com-tw93-weread.desktop → com-tw93-weekly.desktop} +4 -4
  10. package/src-tauri/gen/schemas/acl-manifests.json +1 -1
  11. package/src-tauri/gen/schemas/desktop-schema.json +906 -421
  12. package/src-tauri/gen/schemas/macOS-schema.json +906 -421
  13. package/src-tauri/icons/deepseek.icns +0 -0
  14. package/src-tauri/icons/grok.icns +0 -0
  15. package/src-tauri/icons/weekly.icns +0 -0
  16. package/src-tauri/pake.json +3 -2
  17. package/src-tauri/png/chatgpt_256.ico +0 -0
  18. package/src-tauri/png/chatgpt_32.ico +0 -0
  19. package/src-tauri/png/chatgpt_512.png +0 -0
  20. package/src-tauri/png/deepseek_256.ico +0 -0
  21. package/src-tauri/png/deepseek_32.ico +0 -0
  22. package/src-tauri/png/deepseek_512.png +0 -0
  23. package/src-tauri/png/excalidraw_256.ico +0 -0
  24. package/src-tauri/png/excalidraw_32.ico +0 -0
  25. package/src-tauri/png/excalidraw_512.png +0 -0
  26. package/src-tauri/png/flomo_256.ico +0 -0
  27. package/src-tauri/png/flomo_32.ico +0 -0
  28. package/src-tauri/png/flomo_512.png +0 -0
  29. package/src-tauri/png/gemini_256.ico +0 -0
  30. package/src-tauri/png/gemini_32.ico +0 -0
  31. package/src-tauri/png/gemini_512.png +0 -0
  32. package/src-tauri/png/grok_256.ico +0 -0
  33. package/src-tauri/png/grok_32.ico +0 -0
  34. package/src-tauri/png/grok_512.png +0 -0
  35. package/src-tauri/png/icon_256.ico +0 -0
  36. package/src-tauri/png/icon_32.ico +0 -0
  37. package/src-tauri/png/icon_512.png +0 -0
  38. package/src-tauri/png/lizhi_256.ico +0 -0
  39. package/src-tauri/png/lizhi_32.ico +0 -0
  40. package/src-tauri/png/lizhi_512.png +0 -0
  41. package/src-tauri/png/programmusic_256.ico +0 -0
  42. package/src-tauri/png/programmusic_32.ico +0 -0
  43. package/src-tauri/png/programmusic_512.png +0 -0
  44. package/src-tauri/png/qwerty_256.ico +0 -0
  45. package/src-tauri/png/qwerty_32.ico +0 -0
  46. package/src-tauri/png/qwerty_512.png +0 -0
  47. package/src-tauri/png/twitter_256.ico +0 -0
  48. package/src-tauri/png/twitter_32.ico +0 -0
  49. package/src-tauri/png/twitter_512.png +0 -0
  50. package/src-tauri/png/wechat_256.ico +0 -0
  51. package/src-tauri/png/wechat_32.ico +0 -0
  52. package/src-tauri/png/wechat_512.png +0 -0
  53. package/src-tauri/png/weekly_256.ico +0 -0
  54. package/src-tauri/png/weekly_32.ico +0 -0
  55. package/src-tauri/png/weekly_512.png +0 -0
  56. package/src-tauri/png/weread_256.ico +0 -0
  57. package/src-tauri/png/weread_32.ico +0 -0
  58. package/src-tauri/png/weread_512.png +0 -0
  59. package/src-tauri/png/xiaohongshu_256.ico +0 -0
  60. package/src-tauri/png/xiaohongshu_32.ico +0 -0
  61. package/src-tauri/png/xiaohongshu_512.png +0 -0
  62. package/src-tauri/png/youtube_256.ico +0 -0
  63. package/src-tauri/png/youtube_32.ico +0 -0
  64. package/src-tauri/png/youtube_512.png +0 -0
  65. package/src-tauri/png/youtubemusic_256.ico +0 -0
  66. package/src-tauri/png/youtubemusic_32.ico +0 -0
  67. package/src-tauri/png/youtubemusic_512.png +0 -0
  68. package/src-tauri/src/app/config.rs +1 -0
  69. package/src-tauri/src/app/setup.rs +3 -1
  70. package/src-tauri/src/app/window.rs +25 -3
  71. package/src-tauri/src/inject/component.js +6 -5
  72. package/src-tauri/src/inject/event.js +143 -62
  73. package/src-tauri/src/inject/style.js +29 -8
  74. package/src-tauri/src/lib.rs +18 -12
  75. package/src-tauri/src/util.rs +4 -4
  76. package/src-tauri/tauri.conf.json +3 -3
  77. package/src-tauri/tauri.linux.conf.json +4 -2
  78. package/src-tauri/tauri.macos.conf.json +1 -1
  79. package/src-tauri/tauri.windows.conf.json +2 -2
  80. package/src-tauri/.pake/pake.json +0 -30
  81. package/src-tauri/.pake/tauri.conf.json +0 -24
  82. package/src-tauri/.pake/tauri.macos.conf.json +0 -15
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import log from 'loglevel';
4
4
  import path from 'path';
5
5
  import fsExtra from 'fs-extra';
6
6
  import prompts from 'prompts';
7
- import shelljs from 'shelljs';
7
+ import { execa, execaSync } from 'execa';
8
8
  import crypto from 'crypto';
9
9
  import ora from 'ora';
10
10
  import { fileURLToPath } from 'url';
@@ -17,10 +17,9 @@ import axios from 'axios';
17
17
  import { dir } from 'tmp-promise';
18
18
  import { fileTypeFromBuffer } from 'file-type';
19
19
  import * as psl from 'psl';
20
- import isUrl from 'is-url';
21
20
 
22
21
  var name = "pake-cli";
23
- var version$1 = "3.1.1";
22
+ var version$1 = "3.2.0-beta";
24
23
  var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
25
24
  var engines = {
26
25
  node: ">=16.0.0"
@@ -61,49 +60,47 @@ var scripts = {
61
60
  cli: "rollup -c rollup.config.js --watch",
62
61
  "cli:dev": "cross-env NODE_ENV=development rollup -c rollup.config.js -w",
63
62
  "cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
63
+ format: "npx prettier --write . --ignore-unknown && cd src-tauri && cargo fmt --verbose",
64
64
  prepublishOnly: "npm run cli:build"
65
65
  };
66
66
  var type = "module";
67
67
  var exports = "./dist/pake.js";
68
68
  var license = "MIT";
69
69
  var dependencies = {
70
- "@tauri-apps/api": "^1.6.0",
71
- "@tauri-apps/cli": "^2.1.0",
72
- axios: "^1.7.9",
73
- chalk: "^5.4.1",
70
+ "@tauri-apps/api": "^2.7.0",
71
+ "@tauri-apps/cli": "^2.7.1",
72
+ axios: "^1.11.0",
73
+ chalk: "^5.5.0",
74
74
  commander: "^11.1.0",
75
+ execa: "^9.6.0",
75
76
  "file-type": "^18.7.0",
76
- "fs-extra": "^11.2.0",
77
- "is-url": "^1.2.4",
77
+ "fs-extra": "^11.3.1",
78
78
  loglevel: "^1.9.2",
79
- ora: "^7.0.1",
79
+ ora: "^8.2.0",
80
80
  prompts: "^2.4.2",
81
81
  psl: "^1.15.0",
82
- shelljs: "^0.8.5",
83
82
  "tmp-promise": "^3.0.3",
84
83
  "update-notifier": "^7.3.1"
85
84
  };
86
85
  var devDependencies = {
87
86
  "@rollup/plugin-alias": "^5.1.1",
88
- "@rollup/plugin-commonjs": "^25.0.8",
87
+ "@rollup/plugin-commonjs": "^28.0.6",
89
88
  "@rollup/plugin-json": "^6.1.0",
90
- "@rollup/plugin-replace": "^5.0.7",
89
+ "@rollup/plugin-replace": "^6.0.2",
91
90
  "@rollup/plugin-terser": "^0.4.4",
92
91
  "@types/fs-extra": "^11.0.4",
93
- "@types/is-url": "^1.2.32",
94
- "@types/node": "^20.17.10",
92
+ "@types/node": "^20.19.10",
95
93
  "@types/page-icon": "^0.3.6",
96
94
  "@types/prompts": "^2.4.9",
97
- "@types/psl": "^1.1.3",
98
- "@types/shelljs": "^0.8.15",
95
+ "@types/psl": "^1.11.0",
99
96
  "@types/tmp": "^0.2.6",
100
97
  "@types/update-notifier": "^6.0.8",
101
98
  "app-root-path": "^3.1.0",
102
99
  "cross-env": "^7.0.3",
103
- rollup: "^4.29.1",
100
+ rollup: "^4.46.2",
104
101
  "rollup-plugin-typescript2": "^0.36.0",
105
102
  tslib: "^2.8.1",
106
- typescript: "^5.7.2"
103
+ typescript: "^5.9.2"
107
104
  };
108
105
  var packageJson = {
109
106
  name: name,
@@ -125,7 +122,7 @@ var packageJson = {
125
122
 
126
123
  var windows = [
127
124
  {
128
- url: "https://weread.qq.com",
125
+ url: "https://weekly.tw93.fun/",
129
126
  url_type: "web",
130
127
  hide_title_bar: true,
131
128
  fullscreen: false,
@@ -135,7 +132,8 @@ var windows = [
135
132
  always_on_top: false,
136
133
  dark_mode: false,
137
134
  activation_shortcut: "",
138
- disabled_web_shortcuts: false
135
+ disabled_web_shortcuts: false,
136
+ hide_on_close: true
139
137
  }
140
138
  ];
141
139
  var user_agent = {
@@ -161,13 +159,13 @@ var pakeConf = {
161
159
  proxy_url: proxy_url
162
160
  };
163
161
 
164
- var productName$1 = "WeRead";
165
- var identifier = "com.pake.weread";
162
+ var productName$1 = "Weekly";
163
+ var identifier = "com.pake.weekly";
166
164
  var version = "1.0.0";
167
165
  var app = {
168
166
  withGlobalTauri: true,
169
167
  trayIcon: {
170
- iconPath: "png/weread_512.png",
168
+ iconPath: "png/weekly_512.png",
171
169
  iconAsTemplate: false,
172
170
  id: "pake-tray"
173
171
  }
@@ -185,12 +183,12 @@ var CommonConf = {
185
183
 
186
184
  var bundle$2 = {
187
185
  icon: [
188
- "png/weread_256.ico",
189
- "png/weread_32.ico"
186
+ "png/weekly_256.ico",
187
+ "png/weekly_32.ico"
190
188
  ],
191
189
  active: true,
192
190
  resources: [
193
- "png/weread_32.ico"
191
+ "png/weekly_32.ico"
194
192
  ],
195
193
  targets: [
196
194
  "msi"
@@ -211,7 +209,7 @@ var WinConf = {
211
209
 
212
210
  var bundle$1 = {
213
211
  icon: [
214
- "icons/weread.icns"
212
+ "icons/weekly.icns"
215
213
  ],
216
214
  active: true,
217
215
  macOS: {
@@ -227,7 +225,7 @@ var MacConf = {
227
225
  var productName = "we-read";
228
226
  var bundle = {
229
227
  icon: [
230
- "png/weread_512.png"
228
+ "png/weekly.png"
231
229
  ],
232
230
  active: true,
233
231
  linux: {
@@ -237,7 +235,7 @@ var bundle = {
237
235
  "wget"
238
236
  ],
239
237
  files: {
240
- "/usr/share/applications/com-pake-weread.desktop": "assets/com-pake-weread.desktop"
238
+ "/usr/share/applications/com-pake-weekly.desktop": "assets/com-pake-weekly.desktop"
241
239
  }
242
240
  }
243
241
  },
@@ -274,7 +272,11 @@ let tauriConfig = {
274
272
 
275
273
  // Generates an identifier based on the given URL.
276
274
  function getIdentifier(url) {
277
- const postFixHash = crypto.createHash('md5').update(url).digest('hex').substring(0, 6);
275
+ const postFixHash = crypto
276
+ .createHash('md5')
277
+ .update(url)
278
+ .digest('hex')
279
+ .substring(0, 6);
278
280
  return `com.pake.${postFixHash}`;
279
281
  }
280
282
  async function promptText(message, initial) {
@@ -312,34 +314,34 @@ const currentModulePath = fileURLToPath(import.meta.url);
312
314
  const npmDirectory = path.join(path.dirname(currentModulePath), '..');
313
315
  const tauriConfigDirectory = path.join(npmDirectory, 'src-tauri');
314
316
 
315
- function shellExec(command) {
316
- return new Promise((resolve, reject) => {
317
- shelljs.exec(command, { async: true, silent: false, cwd: npmDirectory }, code => {
318
- if (code === 0) {
319
- resolve(0);
320
- }
321
- else {
322
- reject(new Error(`Error occurred while executing command "${command}". Exit code: ${code}`));
323
- }
317
+ async function shellExec(command) {
318
+ try {
319
+ const { exitCode } = await execa(command, {
320
+ cwd: npmDirectory,
321
+ stdio: 'inherit',
324
322
  });
325
- });
323
+ return exitCode;
324
+ }
325
+ catch (error) {
326
+ throw new Error(`Error occurred while executing command "${command}". Exit code: ${error.exitCode}`);
327
+ }
326
328
  }
327
329
 
328
330
  const logger = {
329
331
  info(...msg) {
330
- log.info(...msg.map(m => chalk.white(m)));
332
+ log.info(...msg.map((m) => chalk.white(m)));
331
333
  },
332
334
  debug(...msg) {
333
335
  log.debug(...msg);
334
336
  },
335
337
  error(...msg) {
336
- log.error(...msg.map(m => chalk.red(m)));
338
+ log.error(...msg.map((m) => chalk.red(m)));
337
339
  },
338
340
  warn(...msg) {
339
- log.info(...msg.map(m => chalk.yellow(m)));
341
+ log.info(...msg.map((m) => chalk.yellow(m)));
340
342
  },
341
343
  success(...msg) {
342
- log.info(...msg.map(m => chalk.green(m)));
344
+ log.info(...msg.map((m) => chalk.green(m)));
343
345
  },
344
346
  };
345
347
 
@@ -350,12 +352,12 @@ const ping = async (host) => {
350
352
  const start = new Date();
351
353
  // Prevent timeouts from affecting user experience.
352
354
  const requestPromise = new Promise((resolve, reject) => {
353
- const req = http.get(`http://${ip.address}`, res => {
355
+ const req = http.get(`http://${ip.address}`, (res) => {
354
356
  const delay = new Date().getTime() - start.getTime();
355
357
  res.resume();
356
358
  resolve(delay);
357
359
  });
358
- req.on('error', err => {
360
+ req.on('error', (err) => {
359
361
  reject(err);
360
362
  });
361
363
  });
@@ -407,25 +409,33 @@ async function installRust() {
407
409
  }
408
410
  }
409
411
  function checkRustInstalled() {
410
- return shelljs.exec('rustc --version', { silent: true }).code === 0;
412
+ try {
413
+ execaSync('rustc', ['--version']);
414
+ return true;
415
+ }
416
+ catch {
417
+ return false;
418
+ }
411
419
  }
412
420
 
413
421
  async function combineFiles(files, output) {
414
- const contents = files.map(file => {
422
+ const contents = files.map((file) => {
415
423
  const fileContent = fs.readFileSync(file);
416
424
  if (file.endsWith('.css')) {
417
425
  return ("window.addEventListener('DOMContentLoaded', (_event) => { const css = `" +
418
426
  fileContent +
419
427
  "`; const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); });");
420
428
  }
421
- return "window.addEventListener('DOMContentLoaded', (_event) => { " + fileContent + ' });';
429
+ return ("window.addEventListener('DOMContentLoaded', (_event) => { " +
430
+ fileContent +
431
+ ' });');
422
432
  });
423
433
  fs.writeFileSync(output, contents.join('\n'));
424
434
  return files;
425
435
  }
426
436
 
427
437
  async function mergeConfig(url, options, tauriConf) {
428
- const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, } = options;
438
+ const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, } = options;
429
439
  const { platform } = process;
430
440
  // Set Windows parameters.
431
441
  const tauriConfWindowOptions = {
@@ -438,6 +448,7 @@ async function mergeConfig(url, options, tauriConf) {
438
448
  always_on_top: alwaysOnTop,
439
449
  dark_mode: darkMode,
440
450
  disabled_web_shortcuts: disabledWebShortcuts,
451
+ hide_on_close: hideOnClose,
441
452
  };
442
453
  Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });
443
454
  tauriConf.productName = name;
@@ -465,7 +476,7 @@ async function mergeConfig(url, options, tauriConf) {
465
476
  // ignore it, because about_pake.html have be erased.
466
477
  // const filesToCopyBack = ['cli.js', 'about_pake.html'];
467
478
  const filesToCopyBack = ['cli.js'];
468
- await Promise.all(filesToCopyBack.map(file => fsExtra.copy(path.join(distBakDir, file), path.join(distDir, file))));
479
+ await Promise.all(filesToCopyBack.map((file) => fsExtra.copy(path.join(distBakDir, file), path.join(distDir, file))));
469
480
  }
470
481
  tauriConf.pake.windows[0].url = fileName;
471
482
  tauriConf.pake.windows[0].url_type = 'local';
@@ -569,11 +580,11 @@ async function mergeConfig(url, options, tauriConf) {
569
580
  const injectFilePath = path.join(npmDirectory, `src-tauri/src/inject/custom.js`);
570
581
  // inject js or css files
571
582
  if (inject?.length > 0) {
572
- if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) {
583
+ if (!inject.every((item) => item.endsWith('.css') || item.endsWith('.js'))) {
573
584
  logger.error('The injected file must be in either CSS or JS format.');
574
585
  return;
575
586
  }
576
- const files = inject.map(filepath => (path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath)));
587
+ const files = inject.map((filepath) => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath));
577
588
  tauriConf.pake.inject = files;
578
589
  await combineFiles(files, injectFilePath);
579
590
  }
@@ -701,7 +712,9 @@ class MacBuilder extends BaseBuilder {
701
712
  return `${name}_${tauriConfig.version}_${arch}`;
702
713
  }
703
714
  getBuildCommand() {
704
- return this.options.multiArch ? 'npm run build:mac' : super.getBuildCommand();
715
+ return this.options.multiArch
716
+ ? 'npm run build:mac'
717
+ : super.getBuildCommand();
705
718
  }
706
719
  getBasePath() {
707
720
  return this.options.multiArch
@@ -778,7 +791,6 @@ const DEFAULT_PAKE_OPTIONS = {
778
791
  height: 780,
779
792
  width: 1200,
780
793
  fullscreen: false,
781
- resizable: true,
782
794
  hideTitleBar: false,
783
795
  alwaysOnTop: false,
784
796
  appVersion: '1.0.0',
@@ -791,14 +803,17 @@ const DEFAULT_PAKE_OPTIONS = {
791
803
  targets: 'deb',
792
804
  useLocalFile: false,
793
805
  systemTrayIcon: '',
794
- proxyUrl: "",
806
+ proxyUrl: '',
795
807
  debug: false,
796
808
  inject: [],
797
809
  installerLanguage: 'en-US',
810
+ hideOnClose: true,
798
811
  };
799
812
 
800
813
  async function checkUpdateTips() {
801
- updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 }).notify({ isGlobal: true });
814
+ updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 }).notify({
815
+ isGlobal: true,
816
+ });
802
817
  }
803
818
 
804
819
  async function handleIcon(options) {
@@ -823,7 +838,9 @@ async function handleIcon(options) {
823
838
  async function downloadIcon(iconUrl) {
824
839
  const spinner = getSpinner('Downloading icon...');
825
840
  try {
826
- const iconResponse = await axios.get(iconUrl, { responseType: 'arraybuffer' });
841
+ const iconResponse = await axios.get(iconUrl, {
842
+ responseType: 'arraybuffer',
843
+ });
827
844
  const iconData = await iconResponse.data;
828
845
  if (!iconData) {
829
846
  return null;
@@ -886,11 +903,12 @@ function appendProtocol(inputUrl) {
886
903
  // Normalizes the URL by ensuring it has a protocol and is valid.
887
904
  function normalizeUrl(urlToNormalize) {
888
905
  const urlWithProtocol = appendProtocol(urlToNormalize);
889
- if (isUrl(urlWithProtocol)) {
906
+ try {
907
+ new URL(urlWithProtocol);
890
908
  return urlWithProtocol;
891
909
  }
892
- else {
893
- throw new Error(`Your url "${urlWithProtocol}" is invalid`);
910
+ catch (err) {
911
+ throw new Error(`Your url "${urlWithProtocol}" is invalid: ${err.message}`);
894
912
  }
895
913
  }
896
914
 
@@ -900,8 +918,8 @@ function resolveAppName(name, platform) {
900
918
  }
901
919
  function isValidName(name, platform) {
902
920
  const platformRegexMapping = {
903
- linux: /^[a-z0-9]+(-[a-z0-9]+)*$/,
904
- default: /^[a-zA-Z0-9]+([-a-zA-Z0-9])*$/,
921
+ linux: /^[a-z0-9][a-z0-9-]*$/,
922
+ default: /^[a-zA-Z0-9][a-zA-Z0-9- ]*$/,
905
923
  };
906
924
  const reg = platformRegexMapping[platform] || platformRegexMapping.default;
907
925
  return !!name && reg.test(name);
@@ -917,9 +935,14 @@ async function handleOptions(options, url) {
917
935
  const namePrompt = await promptText(promptMessage, defaultName);
918
936
  name = namePrompt || defaultName;
919
937
  }
938
+ // Handle platform-specific name formatting
939
+ if (name && platform === 'linux') {
940
+ // Convert to lowercase and replace spaces with dashes for Linux
941
+ name = name.toLowerCase().replace(/\s+/g, '-');
942
+ }
920
943
  if (!isValidName(name, platform)) {
921
- const LINUX_NAME_ERROR = `✕ name should only include lowercase letters, numbers, and dashes, and must contain at least one lowercase letter. Examples: com-123-xxx, 123pan, pan123, weread, we-read.`;
922
- const DEFAULT_NAME_ERROR = `✕ Name should only include letters and numbers, and dashes (dashes must not at the beginning), and must contain at least one letter. Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead, we-read.`;
944
+ 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.`;
945
+ 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.`;
923
946
  const errorMsg = platform === 'linux' ? LINUX_NAME_ERROR : DEFAULT_NAME_ERROR;
924
947
  logger.error(errorMsg);
925
948
  if (isActions) {
@@ -966,9 +989,15 @@ ${green('| |_) / _` | |/ / _ \\')}
966
989
  ${green('| __/ (_| | < __/')} ${yellow('https://github.com/tw93/pake')}
967
990
  ${green('|_| \\__,_|_|\\_\\___| can turn any webpage into a desktop app with Rust.')}
968
991
  `;
969
- program.addHelpText('beforeAll', logo).usage(`[url] [options]`).showHelpAfterError();
992
+ program
993
+ .addHelpText('beforeAll', logo)
994
+ .usage(`[url] [options]`)
995
+ .showHelpAfterError();
970
996
  program
971
997
  .argument('[url]', 'The web URL you want to package', validateUrlInput)
998
+ // Refer to https://github.com/tj/commander.js#custom-option-processing, turn string array into a string connected with custom connectors.
999
+ // If the platform is Linux, use `-` as the connector, and convert all characters to lowercase.
1000
+ // For example, Google Translate will become google-translate.
972
1001
  .option('--name <string>', 'Application name')
973
1002
  .option('--icon <string>', 'Application icon', DEFAULT_PAKE_OPTIONS.icon)
974
1003
  .option('--width <number>', 'Window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width)
@@ -977,27 +1006,62 @@ program
977
1006
  .option('--fullscreen', 'Start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen)
978
1007
  .option('--hide-title-bar', 'For Mac, hide title bar', DEFAULT_PAKE_OPTIONS.hideTitleBar)
979
1008
  .option('--multi-arch', 'For Mac, both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch)
980
- .option('--inject <url>', 'Injection of .js or .css files', DEFAULT_PAKE_OPTIONS.inject)
1009
+ .option('--inject <./style.css,./script.js,...>', 'Injection of .js or .css files', (val, previous) => {
1010
+ if (!val)
1011
+ return DEFAULT_PAKE_OPTIONS.inject;
1012
+ // Split by comma and trim whitespace, filter out empty strings
1013
+ const files = val
1014
+ .split(',')
1015
+ .map((item) => item.trim())
1016
+ .filter((item) => item.length > 0);
1017
+ // If previous values exist (from multiple --inject options), merge them
1018
+ return previous ? [...previous, ...files] : files;
1019
+ }, DEFAULT_PAKE_OPTIONS.inject)
981
1020
  .option('--debug', 'Debug build and more output', DEFAULT_PAKE_OPTIONS.debug)
982
- .addOption(new Option('--proxy-url <url>', 'Proxy URL for all network requests').default(DEFAULT_PAKE_OPTIONS.proxyUrl).hideHelp())
983
- .addOption(new Option('--user-agent <string>', 'Custom user agent').default(DEFAULT_PAKE_OPTIONS.userAgent).hideHelp())
984
- .addOption(new Option('--targets <string>', 'For Linux, option "deb" or "appimage"').default(DEFAULT_PAKE_OPTIONS.targets).hideHelp())
985
- .addOption(new Option('--app-version <string>', 'App version, the same as package.json version').default(DEFAULT_PAKE_OPTIONS.appVersion).hideHelp())
986
- .addOption(new Option('--always-on-top', 'Always on the top level').default(DEFAULT_PAKE_OPTIONS.alwaysOnTop).hideHelp())
987
- .addOption(new Option('--dark-mode', 'Force Mac app to use dark mode').default(DEFAULT_PAKE_OPTIONS.darkMode).hideHelp())
988
- .addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts').default(DEFAULT_PAKE_OPTIONS.disabledWebShortcuts).hideHelp())
989
- .addOption(new Option('--activation-shortcut <string>', 'Shortcut key to active App').default(DEFAULT_PAKE_OPTIONS.activationShortcut).hideHelp())
990
- .addOption(new Option('--show-system-tray', 'Show system tray in app').default(DEFAULT_PAKE_OPTIONS.showSystemTray).hideHelp())
991
- .addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon').default(DEFAULT_PAKE_OPTIONS.systemTrayIcon).hideHelp())
992
- .addOption(new Option('--installer-language <string>', 'Installer language').default(DEFAULT_PAKE_OPTIONS.installerLanguage).hideHelp())
1021
+ .addOption(new Option('--proxy-url <url>', 'Proxy URL for all network requests (http://, https://, socks5://)')
1022
+ .default(DEFAULT_PAKE_OPTIONS.proxyUrl)
1023
+ .hideHelp())
1024
+ .addOption(new Option('--user-agent <string>', 'Custom user agent')
1025
+ .default(DEFAULT_PAKE_OPTIONS.userAgent)
1026
+ .hideHelp())
1027
+ .addOption(new Option('--targets <string>', 'For Linux, option "deb" or "appimage"')
1028
+ .default(DEFAULT_PAKE_OPTIONS.targets)
1029
+ .hideHelp())
1030
+ .addOption(new Option('--app-version <string>', 'App version, the same as package.json version')
1031
+ .default(DEFAULT_PAKE_OPTIONS.appVersion)
1032
+ .hideHelp())
1033
+ .addOption(new Option('--always-on-top', 'Always on the top level')
1034
+ .default(DEFAULT_PAKE_OPTIONS.alwaysOnTop)
1035
+ .hideHelp())
1036
+ .addOption(new Option('--dark-mode', 'Force Mac app to use dark mode')
1037
+ .default(DEFAULT_PAKE_OPTIONS.darkMode)
1038
+ .hideHelp())
1039
+ .addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts')
1040
+ .default(DEFAULT_PAKE_OPTIONS.disabledWebShortcuts)
1041
+ .hideHelp())
1042
+ .addOption(new Option('--activation-shortcut <string>', 'Shortcut key to active App')
1043
+ .default(DEFAULT_PAKE_OPTIONS.activationShortcut)
1044
+ .hideHelp())
1045
+ .addOption(new Option('--show-system-tray', 'Show system tray in app')
1046
+ .default(DEFAULT_PAKE_OPTIONS.showSystemTray)
1047
+ .hideHelp())
1048
+ .addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon')
1049
+ .default(DEFAULT_PAKE_OPTIONS.systemTrayIcon)
1050
+ .hideHelp())
1051
+ .addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting')
1052
+ .default(DEFAULT_PAKE_OPTIONS.hideOnClose)
1053
+ .hideHelp())
1054
+ .addOption(new Option('--installer-language <string>', 'Installer language')
1055
+ .default(DEFAULT_PAKE_OPTIONS.installerLanguage)
1056
+ .hideHelp())
993
1057
  .version(packageJson.version, '-v, --version', 'Output the current version')
994
1058
  .action(async (url, options) => {
995
1059
  await checkUpdateTips();
996
1060
  if (!url) {
997
- program.outputHelp(str => {
1061
+ program.outputHelp((str) => {
998
1062
  return str
999
1063
  .split('\n')
1000
- .filter(line => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line))
1064
+ .filter((line) => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line))
1001
1065
  .join('\n');
1002
1066
  });
1003
1067
  process.exit(0);
package/dist/dev.js CHANGED
@@ -11,7 +11,7 @@ import ora from 'ora';
11
11
  import { fileTypeFromBuffer } from 'file-type';
12
12
  import * as psl from 'psl';
13
13
  import 'is-url';
14
- import shelljs from 'shelljs';
14
+ import { execa, execaSync } from 'execa';
15
15
  import dns from 'dns';
16
16
  import http from 'http';
17
17
  import { promisify } from 'util';
@@ -70,7 +70,8 @@ const logger = {
70
70
  const currentModulePath = fileURLToPath(import.meta.url);
71
71
  // Resolve the parent directory of the current module
72
72
  const npmDirectory = path.join(path.dirname(currentModulePath), '..');
73
- const tauriConfigDirectory = path.join(npmDirectory, 'src-tauri');
73
+ const tauriConfigDirectory = path.join(npmDirectory, 'src-tauri', '.pake')
74
+ ;
74
75
 
75
76
  const { platform: platform$2 } = process;
76
77
  const IS_MAC = platform$2 === 'darwin';
@@ -373,17 +374,17 @@ let tauriConfig = {
373
374
  pake: pakeConf,
374
375
  };
375
376
 
376
- function shellExec(command) {
377
- return new Promise((resolve, reject) => {
378
- shelljs.exec(command, { async: true, silent: false, cwd: npmDirectory }, code => {
379
- if (code === 0) {
380
- resolve(0);
381
- }
382
- else {
383
- reject(new Error(`Error occurred while executing command "${command}". Exit code: ${code}`));
384
- }
377
+ async function shellExec(command) {
378
+ try {
379
+ const { exitCode } = await execa(command, {
380
+ cwd: npmDirectory,
381
+ stdio: 'inherit'
385
382
  });
386
- });
383
+ return exitCode;
384
+ }
385
+ catch (error) {
386
+ throw new Error(`Error occurred while executing command "${command}". Exit code: ${error.exitCode}`);
387
+ }
387
388
  }
388
389
 
389
390
  const resolve = promisify(dns.resolve);
@@ -450,7 +451,13 @@ async function installRust() {
450
451
  }
451
452
  }
452
453
  function checkRustInstalled() {
453
- return shelljs.exec('rustc --version', { silent: true }).code === 0;
454
+ try {
455
+ execaSync('rustc', ['--version']);
456
+ return true;
457
+ }
458
+ catch {
459
+ return false;
460
+ }
454
461
  }
455
462
 
456
463
  async function combineFiles(files, output) {
@@ -529,9 +536,9 @@ async function mergeConfig(url, options, tauriConf) {
529
536
  // Processing targets are currently only open to Linux.
530
537
  if (platform === 'linux') {
531
538
  delete tauriConf.bundle.linux.deb.files;
532
- const validTargets = ['all', 'deb', 'appimage', 'rpm'];
539
+ const validTargets = ['deb', 'appimage', 'rpm'];
533
540
  if (validTargets.includes(options.targets)) {
534
- tauriConf.bundle.targets = options.targets === 'all' ? ['deb', 'appimage', 'rpm'] : [options.targets];
541
+ tauriConf.bundle.targets = [options.targets];
535
542
  }
536
543
  else {
537
544
  logger.warn(`✼ The target must be one of ${validTargets.join(', ')}, the default 'deb' will be used.`);
@@ -639,6 +646,10 @@ async function mergeConfig(url, options, tauriConf) {
639
646
  await fsExtra.outputJSON(pakeConfigPath, tauriConf.pake, { spaces: 4 });
640
647
  let tauriConf2 = JSON.parse(JSON.stringify(tauriConf));
641
648
  delete tauriConf2.pake;
649
+ // delete tauriConf2.bundle;
650
+ {
651
+ tauriConf2.bundle = bundleConf.bundle;
652
+ }
642
653
  const configJsonPath = path.join(tauriConfigDirectory, 'tauri.conf.json');
643
654
  await fsExtra.outputJSON(configJsonPath, tauriConf2, { spaces: 4 });
644
655
  }
@@ -771,15 +782,23 @@ class LinuxBuilder extends BaseBuilder {
771
782
  super(options);
772
783
  }
773
784
  getFileName() {
774
- const { name } = this.options;
775
- const arch = process.arch === 'x64' ? 'amd64' : process.arch;
776
- return `${name}_${tauriConfig.version}_${arch}`;
785
+ const { name, targets } = this.options;
786
+ const version = tauriConfig.version;
787
+ let arch = process.arch === 'x64' ? 'amd64' : process.arch;
788
+ if (arch === 'arm64' && (targets === 'rpm' || targets === 'appimage')) {
789
+ arch = 'aarch64';
790
+ }
791
+ // The RPM format uses different separators and version number formats
792
+ if (targets === 'rpm') {
793
+ return `${name}-${version}-1.${arch}`;
794
+ }
795
+ return `${name}_${version}_${arch}`;
777
796
  }
778
797
  // Customize it, considering that there are all targets.
779
798
  async build(url) {
780
- const targetTypes = ['deb', 'appimage'];
799
+ const targetTypes = ['deb', 'appimage', 'rpm'];
781
800
  for (const target of targetTypes) {
782
- if (this.options.targets === target || this.options.targets === 'all') {
801
+ if (this.options.targets === target) {
783
802
  await this.buildAndCopy(url, target);
784
803
  }
785
804
  }