pake-cli 3.2.15 → 3.2.16

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 CHANGED
@@ -22,7 +22,7 @@ import sharp from 'sharp';
22
22
  import * as psl from 'psl';
23
23
 
24
24
  var name = "pake-cli";
25
- var version = "3.2.15";
25
+ var version = "3.2.16";
26
26
  var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
27
27
  var engines = {
28
28
  node: ">=16.0.0"
@@ -435,9 +435,19 @@ StartupNotify=true
435
435
  tauriConf.bundle.linux.deb.files = {
436
436
  [`/usr/share/applications/${desktopFileName}`]: `assets/${desktopFileName}`,
437
437
  };
438
- const validTargets = ['deb', 'appimage', 'rpm'];
438
+ const validTargets = [
439
+ 'deb',
440
+ 'appimage',
441
+ 'rpm',
442
+ 'deb-arm64',
443
+ 'appimage-arm64',
444
+ 'rpm-arm64',
445
+ ];
446
+ const baseTarget = options.targets.includes('-arm64')
447
+ ? options.targets.replace('-arm64', '')
448
+ : options.targets;
439
449
  if (validTargets.includes(options.targets)) {
440
- tauriConf.bundle.targets = [options.targets];
450
+ tauriConf.bundle.targets = [baseTarget];
441
451
  }
442
452
  else {
443
453
  logger.warn(`✼ The target must be one of ${validTargets.join(', ')}, the default 'deb' will be used.`);
@@ -709,33 +719,46 @@ class BaseBuilder {
709
719
  class MacBuilder extends BaseBuilder {
710
720
  constructor(options) {
711
721
  super(options);
722
+ // Store the original targets value for architecture selection
723
+ this.buildArch = options.targets || 'auto';
712
724
  // Use DMG by default for distribution
713
725
  // Only create app bundles for testing to avoid user interaction
714
726
  if (process.env.PAKE_CREATE_APP === '1') {
715
- this.options.targets = 'app';
727
+ this.buildFormat = 'app';
716
728
  }
717
729
  else {
718
- this.options.targets = 'dmg';
730
+ this.buildFormat = 'dmg';
719
731
  }
732
+ // Set targets to format for Tauri
733
+ this.options.targets = this.buildFormat;
720
734
  }
721
735
  getFileName() {
722
736
  const { name } = this.options;
723
737
  // For app bundles, use simple name without version/arch
724
- if (this.options.targets === 'app') {
738
+ if (this.buildFormat === 'app') {
725
739
  return name;
726
740
  }
727
741
  // For DMG files, use versioned filename
728
742
  let arch;
729
- if (this.options.multiArch) {
743
+ if (this.buildArch === 'universal' || this.options.multiArch) {
730
744
  arch = 'universal';
731
745
  }
746
+ else if (this.buildArch === 'apple') {
747
+ arch = 'aarch64';
748
+ }
749
+ else if (this.buildArch === 'intel') {
750
+ arch = 'x64';
751
+ }
732
752
  else {
753
+ // Auto-detect based on current architecture
733
754
  arch = process.arch === 'arm64' ? 'aarch64' : process.arch;
734
755
  }
735
756
  return `${name}_${tauriConfig.version}_${arch}`;
736
757
  }
737
758
  getBuildCommand() {
738
- if (this.options.multiArch) {
759
+ // Determine if we need universal build
760
+ const needsUniversal = this.buildArch === 'universal' || this.options.multiArch;
761
+ if (needsUniversal) {
739
762
  const baseCommand = this.options.debug
740
763
  ? 'npm run tauri build -- --debug'
741
764
  : 'npm run tauri build --';
@@ -754,38 +777,171 @@ class MacBuilder extends BaseBuilder {
754
777
  }
755
778
  return fullCommand;
756
779
  }
780
+ else if (this.buildArch === 'apple') {
781
+ // Build for Apple Silicon only
782
+ const baseCommand = this.options.debug
783
+ ? 'npm run tauri build -- --debug'
784
+ : 'npm run tauri build --';
785
+ const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
786
+ let fullCommand = `${baseCommand} --target aarch64-apple-darwin -c "${configPath}"`;
787
+ // Add features
788
+ const features = ['cli-build'];
789
+ const macOSVersion = this.getMacOSMajorVersion();
790
+ if (macOSVersion >= 23) {
791
+ features.push('macos-proxy');
792
+ }
793
+ if (features.length > 0) {
794
+ fullCommand += ` --features ${features.join(',')}`;
795
+ }
796
+ return fullCommand;
797
+ }
798
+ else if (this.buildArch === 'intel') {
799
+ // Build for Intel only
800
+ const baseCommand = this.options.debug
801
+ ? 'npm run tauri build -- --debug'
802
+ : 'npm run tauri build --';
803
+ const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
804
+ let fullCommand = `${baseCommand} --target x86_64-apple-darwin -c "${configPath}"`;
805
+ // Add features
806
+ const features = ['cli-build'];
807
+ const macOSVersion = this.getMacOSMajorVersion();
808
+ if (macOSVersion >= 23) {
809
+ features.push('macos-proxy');
810
+ }
811
+ if (features.length > 0) {
812
+ fullCommand += ` --features ${features.join(',')}`;
813
+ }
814
+ return fullCommand;
815
+ }
757
816
  return super.getBuildCommand();
758
817
  }
759
818
  getBasePath() {
760
- return this.options.multiArch
761
- ? 'src-tauri/target/universal-apple-darwin/release/bundle'
762
- : super.getBasePath();
819
+ const needsUniversal = this.buildArch === 'universal' || this.options.multiArch;
820
+ const basePath = this.options.debug ? 'debug' : 'release';
821
+ if (needsUniversal) {
822
+ return `src-tauri/target/universal-apple-darwin/${basePath}/bundle`;
823
+ }
824
+ else if (this.buildArch === 'apple') {
825
+ return `src-tauri/target/aarch64-apple-darwin/${basePath}/bundle`;
826
+ }
827
+ else if (this.buildArch === 'intel') {
828
+ return `src-tauri/target/x86_64-apple-darwin/${basePath}/bundle`;
829
+ }
830
+ return super.getBasePath();
763
831
  }
764
832
  }
765
833
 
766
834
  class WinBuilder extends BaseBuilder {
767
835
  constructor(options) {
768
836
  super(options);
769
- this.options.targets = 'msi';
837
+ this.buildFormat = 'msi';
838
+ // Store the original targets value for architecture selection
839
+ this.buildArch = options.targets || 'auto';
840
+ // Set targets to msi format for Tauri
841
+ this.options.targets = this.buildFormat;
770
842
  }
771
843
  getFileName() {
772
844
  const { name } = this.options;
773
- const { arch } = process;
774
845
  const language = tauriConfig.bundle.windows.wix.language[0];
775
- return `${name}_${tauriConfig.version}_${arch}_${language}`;
846
+ // Determine architecture name based on explicit targets option or auto-detect
847
+ let targetArch;
848
+ if (this.buildArch === 'arm64') {
849
+ targetArch = 'aarch64';
850
+ }
851
+ else if (this.buildArch === 'x64') {
852
+ targetArch = 'x64';
853
+ }
854
+ else {
855
+ // Auto-detect based on current architecture if no explicit target
856
+ const archMap = {
857
+ x64: 'x64',
858
+ arm64: 'aarch64',
859
+ };
860
+ targetArch = archMap[process.arch] || process.arch;
861
+ }
862
+ return `${name}_${tauriConfig.version}_${targetArch}_${language}`;
863
+ }
864
+ getBuildCommand() {
865
+ const baseCommand = this.options.debug
866
+ ? 'npm run build:debug'
867
+ : 'npm run build';
868
+ // Use temporary config directory to avoid modifying source files
869
+ const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
870
+ let fullCommand = `${baseCommand} -- -c "${configPath}"`;
871
+ // Determine build target based on explicit targets option or auto-detect
872
+ let buildTarget;
873
+ if (this.buildArch === 'arm64') {
874
+ buildTarget = 'aarch64-pc-windows-msvc';
875
+ }
876
+ else if (this.buildArch === 'x64') {
877
+ buildTarget = 'x86_64-pc-windows-msvc';
878
+ }
879
+ else {
880
+ // Auto-detect based on current architecture if no explicit target
881
+ buildTarget =
882
+ process.arch === 'arm64'
883
+ ? 'aarch64-pc-windows-msvc'
884
+ : 'x86_64-pc-windows-msvc';
885
+ }
886
+ fullCommand += ` --target ${buildTarget}`;
887
+ // Add features
888
+ const features = ['cli-build'];
889
+ if (features.length > 0) {
890
+ fullCommand += ` --features ${features.join(',')}`;
891
+ }
892
+ return fullCommand;
893
+ }
894
+ getBasePath() {
895
+ const basePath = this.options.debug ? 'debug' : 'release';
896
+ // Determine target based on explicit targets option or auto-detect
897
+ let target;
898
+ if (this.buildArch === 'arm64') {
899
+ target = 'aarch64-pc-windows-msvc';
900
+ }
901
+ else if (this.buildArch === 'x64') {
902
+ target = 'x86_64-pc-windows-msvc';
903
+ }
904
+ else {
905
+ // Auto-detect based on current architecture if no explicit target
906
+ target =
907
+ process.arch === 'arm64'
908
+ ? 'aarch64-pc-windows-msvc'
909
+ : 'x86_64-pc-windows-msvc';
910
+ }
911
+ return `src-tauri/target/${target}/${basePath}/bundle/`;
776
912
  }
777
913
  }
778
914
 
779
915
  class LinuxBuilder extends BaseBuilder {
780
916
  constructor(options) {
781
917
  super(options);
918
+ // Parse target format and architecture
919
+ const target = options.targets || 'deb';
920
+ if (target.includes('-arm64')) {
921
+ this.buildFormat = target.replace('-arm64', '');
922
+ this.buildArch = 'arm64';
923
+ }
924
+ else {
925
+ this.buildFormat = target;
926
+ this.buildArch = 'auto';
927
+ }
928
+ // Set targets to format for Tauri
929
+ this.options.targets = this.buildFormat;
782
930
  }
783
931
  getFileName() {
784
932
  const { name, targets } = this.options;
785
933
  const version = tauriConfig.version;
786
- let arch = process.arch === 'x64' ? 'amd64' : process.arch;
787
- if (arch === 'arm64' && (targets === 'rpm' || targets === 'appimage')) {
788
- arch = 'aarch64';
934
+ // Determine architecture based on explicit target or auto-detect
935
+ let arch;
936
+ if (this.buildArch === 'arm64') {
937
+ arch = targets === 'rpm' || targets === 'appimage' ? 'aarch64' : 'arm64';
938
+ }
939
+ else {
940
+ // Auto-detect or default to current architecture
941
+ arch = process.arch === 'x64' ? 'amd64' : process.arch;
942
+ if (arch === 'arm64' && (targets === 'rpm' || targets === 'appimage')) {
943
+ arch = 'aarch64';
944
+ }
789
945
  }
790
946
  // The RPM format uses different separators and version number formats
791
947
  if (targets === 'rpm') {
@@ -802,6 +958,31 @@ class LinuxBuilder extends BaseBuilder {
802
958
  }
803
959
  }
804
960
  }
961
+ getBuildCommand() {
962
+ const baseCommand = this.options.debug
963
+ ? 'npm run build:debug'
964
+ : 'npm run build';
965
+ // Use temporary config directory to avoid modifying source files
966
+ const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
967
+ let fullCommand = `${baseCommand} -- -c "${configPath}"`;
968
+ // Add ARM64 target if explicitly specified
969
+ if (this.buildArch === 'arm64') {
970
+ fullCommand += ' --target aarch64-unknown-linux-gnu';
971
+ }
972
+ // Add features
973
+ const features = ['cli-build'];
974
+ if (features.length > 0) {
975
+ fullCommand += ` --features ${features.join(',')}`;
976
+ }
977
+ return fullCommand;
978
+ }
979
+ getBasePath() {
980
+ const basePath = this.options.debug ? 'debug' : 'release';
981
+ if (this.buildArch === 'arm64') {
982
+ return `src-tauri/target/aarch64-unknown-linux-gnu/${basePath}/bundle/`;
983
+ }
984
+ return super.getBasePath();
985
+ }
805
986
  getFileType(target) {
806
987
  if (target === 'appimage') {
807
988
  return 'AppImage';
@@ -1068,7 +1249,7 @@ async function tryGetFavicon(url, appName) {
1068
1249
  continue;
1069
1250
  }
1070
1251
  }
1071
- spinner.warn(`✼ No favicon found for ${domain}. Using default.`);
1252
+ spinner.warn(`No favicon found for ${domain}. Using default.`);
1072
1253
  return null;
1073
1254
  }
1074
1255
  catch (error) {
@@ -1271,9 +1452,7 @@ program
1271
1452
  .addOption(new Option('--user-agent <string>', 'Custom user agent')
1272
1453
  .default(DEFAULT_PAKE_OPTIONS.userAgent)
1273
1454
  .hideHelp())
1274
- .addOption(new Option('--targets <string>', 'For Linux, option "deb" or "appimage"')
1275
- .default(DEFAULT_PAKE_OPTIONS.targets)
1276
- .hideHelp())
1455
+ .addOption(new Option('--targets <string>', 'Build target: Linux: "deb", "rpm", "appimage", "deb-arm64", "rpm-arm64", "appimage-arm64"; Windows: "x64", "arm64"; macOS: "intel", "apple", "universal"').default(DEFAULT_PAKE_OPTIONS.targets))
1277
1456
  .addOption(new Option('--app-version <string>', 'App version, the same as package.json version')
1278
1457
  .default(DEFAULT_PAKE_OPTIONS.appVersion)
1279
1458
  .hideHelp())
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pake-cli",
3
- "version": "3.2.15",
3
+ "version": "3.2.16",
4
4
  "description": "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。",
5
5
  "engines": {
6
6
  "node": ">=16.0.0"
@@ -19,6 +19,7 @@
19
19
  "notification:allow-get-active",
20
20
  "notification:allow-register-listener",
21
21
  "notification:allow-register-action-types",
22
- "notification:default"
22
+ "notification:default",
23
+ "core:path:default"
23
24
  ]
24
25
  }
@@ -1,4 +1,4 @@
1
- use crate::util::{check_file_or_append, get_download_message, show_toast, MessageType};
1
+ use crate::util::{check_file_or_append, get_download_message_with_lang, show_toast, MessageType};
2
2
  use std::fs::{self, File};
3
3
  use std::io::Write;
4
4
  use std::str::FromStr;
@@ -10,12 +10,14 @@ use tauri_plugin_http::reqwest::{ClientBuilder, Request};
10
10
  pub struct DownloadFileParams {
11
11
  url: String,
12
12
  filename: String,
13
+ language: Option<String>,
13
14
  }
14
15
 
15
16
  #[derive(serde::Deserialize)]
16
17
  pub struct BinaryDownloadParams {
17
18
  filename: String,
18
19
  binary: Vec<u8>,
20
+ language: Option<String>,
19
21
  }
20
22
 
21
23
  #[derive(serde::Deserialize)]
@@ -28,7 +30,10 @@ pub struct NotificationParams {
28
30
  #[command]
29
31
  pub async fn download_file(app: AppHandle, params: DownloadFileParams) -> Result<(), String> {
30
32
  let window: WebviewWindow = app.get_webview_window("pake").unwrap();
31
- show_toast(&window, &get_download_message(MessageType::Start));
33
+ show_toast(
34
+ &window,
35
+ &get_download_message_with_lang(MessageType::Start, params.language.clone()),
36
+ );
32
37
 
33
38
  let output_path = app.path().download_dir().unwrap().join(params.filename);
34
39
  let file_path = check_file_or_append(output_path.to_str().unwrap());
@@ -47,11 +52,17 @@ pub async fn download_file(app: AppHandle, params: DownloadFileParams) -> Result
47
52
 
48
53
  let mut file = File::create(file_path).unwrap();
49
54
  file.write_all(&bytes).unwrap();
50
- show_toast(&window, &get_download_message(MessageType::Success));
55
+ show_toast(
56
+ &window,
57
+ &get_download_message_with_lang(MessageType::Success, params.language.clone()),
58
+ );
51
59
  Ok(())
52
60
  }
53
61
  Err(e) => {
54
- show_toast(&window, &get_download_message(MessageType::Failure));
62
+ show_toast(
63
+ &window,
64
+ &get_download_message_with_lang(MessageType::Failure, params.language),
65
+ );
55
66
  Err(e.to_string())
56
67
  }
57
68
  }
@@ -63,17 +74,26 @@ pub async fn download_file_by_binary(
63
74
  params: BinaryDownloadParams,
64
75
  ) -> Result<(), String> {
65
76
  let window: WebviewWindow = app.get_webview_window("pake").unwrap();
66
- show_toast(&window, &get_download_message(MessageType::Start));
77
+ show_toast(
78
+ &window,
79
+ &get_download_message_with_lang(MessageType::Start, params.language.clone()),
80
+ );
67
81
  let output_path = app.path().download_dir().unwrap().join(params.filename);
68
82
  let file_path = check_file_or_append(output_path.to_str().unwrap());
69
83
  let download_file_result = fs::write(file_path, &params.binary);
70
84
  match download_file_result {
71
85
  Ok(_) => {
72
- show_toast(&window, &get_download_message(MessageType::Success));
86
+ show_toast(
87
+ &window,
88
+ &get_download_message_with_lang(MessageType::Success, params.language.clone()),
89
+ );
73
90
  Ok(())
74
91
  }
75
92
  Err(e) => {
76
- show_toast(&window, &get_download_message(MessageType::Failure));
93
+ show_toast(
94
+ &window,
95
+ &get_download_message_with_lang(MessageType::Failure, params.language),
96
+ );
77
97
  Err(e.to_string())
78
98
  }
79
99
  }