pake-cli 3.4.1 โ†’ 3.4.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 CHANGED
@@ -23,7 +23,7 @@ import sharp from 'sharp';
23
23
  import * as psl from 'psl';
24
24
 
25
25
  var name = "pake-cli";
26
- var version = "3.4.1";
26
+ var version = "3.4.2";
27
27
  var description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚";
28
28
  var engines = {
29
29
  node: ">=18.0.0"
@@ -223,10 +223,11 @@ async function shellExec(command, timeout = 300000, env) {
223
223
  let errorMsg = `Error occurred while executing command "${command}". Exit code: ${exitCode}. Details: ${errorMessage}`;
224
224
  // Provide helpful guidance for common Linux AppImage build failures
225
225
  // caused by strip tool incompatibility with modern glibc (2.38+)
226
+ const lowerError = errorMessage.toLowerCase();
226
227
  if (process.platform === 'linux' &&
227
- (errorMessage.includes('linuxdeploy') ||
228
- errorMessage.includes('appimage') ||
229
- errorMessage.includes('strip'))) {
228
+ (lowerError.includes('linuxdeploy') ||
229
+ lowerError.includes('appimage') ||
230
+ lowerError.includes('strip'))) {
230
231
  errorMsg +=
231
232
  '\n\nโ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”\n' +
232
233
  'Linux AppImage Build Failed\n' +
@@ -240,6 +241,15 @@ async function shellExec(command, timeout = 300000, env) {
240
241
  ' โ€ข Update binutils: sudo apt install binutils (or pacman -S binutils)\n' +
241
242
  ' โ€ข Detailed guide: https://github.com/tw93/Pake/blob/main/docs/faq.md\n' +
242
243
  'โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”';
244
+ if (lowerError.includes('fuse') ||
245
+ lowerError.includes('operation not permitted') ||
246
+ lowerError.includes('/dev/fuse')) {
247
+ errorMsg +=
248
+ '\n\nDocker / Container hint:\n' +
249
+ ' AppImage tooling needs access to /dev/fuse. When running inside Docker, add:\n' +
250
+ ' --privileged --device /dev/fuse --security-opt apparmor=unconfined\n' +
251
+ ' or run on the host directly.';
252
+ }
243
253
  }
244
254
  throw new Error(errorMsg);
245
255
  }
@@ -816,10 +826,12 @@ class BaseBuilder {
816
826
  buildSpinner.stop();
817
827
  // Show static message to keep the status visible
818
828
  logger.warn('โœธ Building app...');
819
- const buildEnv = {
820
- ...this.getBuildEnvironment(),
821
- ...(process.env.NO_STRIP && { NO_STRIP: process.env.NO_STRIP }),
829
+ const baseEnv = this.getBuildEnvironment();
830
+ let buildEnv = {
831
+ ...(baseEnv ?? {}),
832
+ ...(process.env.NO_STRIP ? { NO_STRIP: process.env.NO_STRIP } : {}),
822
833
  };
834
+ const resolveExecEnv = () => Object.keys(buildEnv).length > 0 ? buildEnv : undefined;
823
835
  // Warn users about potential AppImage build failures on modern Linux systems.
824
836
  // The linuxdeploy tool bundled in Tauri uses an older strip tool that doesn't
825
837
  // recognize the .relr.dyn section introduced in glibc 2.38+.
@@ -829,7 +841,28 @@ class BaseBuilder {
829
841
  logger.warn('โš  If build fails, retry with: NO_STRIP=1 pake <url> --targets appimage');
830
842
  }
831
843
  }
832
- await shellExec(`cd "${npmDirectory}" && ${this.getBuildCommand(packageManager)}`, this.getBuildTimeout(), buildEnv);
844
+ const buildCommand = `cd "${npmDirectory}" && ${this.getBuildCommand(packageManager)}`;
845
+ const buildTimeout = this.getBuildTimeout();
846
+ try {
847
+ await shellExec(buildCommand, buildTimeout, resolveExecEnv());
848
+ }
849
+ catch (error) {
850
+ const shouldRetryWithoutStrip = process.platform === 'linux' &&
851
+ this.options.targets === 'appimage' &&
852
+ !buildEnv.NO_STRIP &&
853
+ this.isLinuxDeployStripError(error);
854
+ if (shouldRetryWithoutStrip) {
855
+ logger.warn('โš  AppImage build failed during linuxdeploy strip step, retrying with NO_STRIP=1 automatically.');
856
+ buildEnv = {
857
+ ...buildEnv,
858
+ NO_STRIP: '1',
859
+ };
860
+ await shellExec(buildCommand, buildTimeout, resolveExecEnv());
861
+ }
862
+ else {
863
+ throw error;
864
+ }
865
+ }
833
866
  // Copy app
834
867
  const fileName = this.getFileName();
835
868
  const fileType = this.getFileType(target);
@@ -852,6 +885,18 @@ class BaseBuilder {
852
885
  getFileType(target) {
853
886
  return target;
854
887
  }
888
+ isLinuxDeployStripError(error) {
889
+ if (!(error instanceof Error) || !error.message) {
890
+ return false;
891
+ }
892
+ const message = error.message.toLowerCase();
893
+ return (message.includes('linuxdeploy') ||
894
+ message.includes('failed to run linuxdeploy') ||
895
+ message.includes('strip:') ||
896
+ message.includes('unable to recognise the format of the input file') ||
897
+ message.includes('appimage tool failed') ||
898
+ message.includes('strip tool'));
899
+ }
855
900
  /**
856
901
  * ่งฃๆž็›ฎๆ ‡ๆžถๆž„
857
902
  */
@@ -1209,7 +1254,8 @@ class LinuxBuilder extends BaseBuilder {
1209
1254
  // Enable verbose output for AppImage builds when debugging or PAKE_VERBOSE is set.
1210
1255
  // AppImage builds often fail with minimal error messages from linuxdeploy,
1211
1256
  // so verbose mode helps diagnose issues like strip failures and missing dependencies.
1212
- if (this.options.targets === 'appimage' && (this.options.debug || process.env.PAKE_VERBOSE)) {
1257
+ if (this.options.targets === 'appimage' &&
1258
+ (this.options.debug || process.env.PAKE_VERBOSE)) {
1213
1259
  fullCommand += ' --verbose';
1214
1260
  }
1215
1261
  return fullCommand;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pake-cli",
3
- "version": "3.4.1",
3
+ "version": "3.4.2",
4
4
  "description": "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -9,7 +9,11 @@ use tauri::{
9
9
  use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut};
10
10
  use tauri_plugin_window_state::{AppHandleExt, StateFlags};
11
11
 
12
- pub fn set_system_tray(app: &AppHandle, show_system_tray: bool, tray_icon_path: &str) -> tauri::Result<()> {
12
+ pub fn set_system_tray(
13
+ app: &AppHandle,
14
+ show_system_tray: bool,
15
+ tray_icon_path: &str,
16
+ ) -> tauri::Result<()> {
13
17
  if !show_system_tray {
14
18
  app.remove_tray_by_id("pake-tray");
15
19
  return Ok(());
@@ -61,11 +65,15 @@ pub fn set_system_tray(app: &AppHandle, show_system_tray: bool, tray_icon_path:
61
65
  _ => {}
62
66
  })
63
67
  .icon(if tray_icon_path.is_empty() {
64
- app.default_window_icon().unwrap_or_else(|| panic!("Failed to get default window icon")).clone()
68
+ app.default_window_icon()
69
+ .unwrap_or_else(|| panic!("Failed to get default window icon"))
70
+ .clone()
65
71
  } else {
66
72
  tauri::image::Image::from_path(tray_icon_path).unwrap_or_else(|_| {
67
73
  // If custom tray icon fails to load, fallback to default
68
- app.default_window_icon().unwrap_or_else(|| panic!("Failed to get default window icon")).clone()
74
+ app.default_window_icon()
75
+ .unwrap_or_else(|| panic!("Failed to get default window icon"))
76
+ .clone()
69
77
  })
70
78
  })
71
79
  .build(app)?;
@@ -6,6 +6,22 @@ use tauri::{App, Config, Url, WebviewUrl, WebviewWindow, WebviewWindowBuilder};
6
6
  #[cfg(target_os = "macos")]
7
7
  use tauri::{Theme, TitleBarStyle};
8
8
 
9
+ #[cfg(target_os = "windows")]
10
+ fn build_proxy_browser_arg(url: &Url) -> Option<String> {
11
+ let host = url.host_str()?;
12
+ let scheme = url.scheme();
13
+ let port = url.port().or_else(|| match scheme {
14
+ "http" => Some(80),
15
+ "socks5" => Some(1080),
16
+ _ => None,
17
+ })?;
18
+
19
+ match scheme {
20
+ "http" | "socks5" => Some(format!("--proxy-server={scheme}://{host}:{port}")),
21
+ _ => None,
22
+ }
23
+ }
24
+
9
25
  pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) -> WebviewWindow {
10
26
  let package_name = tauri_config.clone().product_name.unwrap();
11
27
  let _data_dir = get_data_dir(app.handle(), package_name);
@@ -60,12 +76,35 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
60
76
  .initialization_script(include_str!("../inject/style.js"))
61
77
  .initialization_script(include_str!("../inject/custom.js"));
62
78
 
79
+ #[cfg(target_os = "windows")]
80
+ let mut windows_browser_args = String::from("--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection --disable-blink-features=AutomationControlled");
81
+
82
+ #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
83
+ let mut linux_browser_args = String::from("--disable-blink-features=AutomationControlled");
84
+
63
85
  if window_config.enable_wasm {
64
- window_builder = window_builder
65
- .additional_browser_args("--enable-features=SharedArrayBuffer")
66
- .additional_browser_args("--enable-unsafe-webgpu");
86
+ #[cfg(target_os = "windows")]
87
+ {
88
+ windows_browser_args.push_str(" --enable-features=SharedArrayBuffer");
89
+ windows_browser_args.push_str(" --enable-unsafe-webgpu");
90
+ }
91
+
92
+ #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
93
+ {
94
+ linux_browser_args.push_str(" --enable-features=SharedArrayBuffer");
95
+ linux_browser_args.push_str(" --enable-unsafe-webgpu");
96
+ }
97
+
98
+ #[cfg(target_os = "macos")]
99
+ {
100
+ window_builder = window_builder
101
+ .additional_browser_args("--enable-features=SharedArrayBuffer")
102
+ .additional_browser_args("--enable-unsafe-webgpu");
103
+ }
67
104
  }
68
105
 
106
+ let mut parsed_proxy_url: Option<Url> = None;
107
+
69
108
  // Platform-specific configuration must be set before proxy on Windows/Linux
70
109
  #[cfg(target_os = "macos")]
71
110
  {
@@ -84,20 +123,44 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
84
123
  // Windows and Linux: set data_directory before proxy_url
85
124
  #[cfg(not(target_os = "macos"))]
86
125
  {
87
- window_builder = window_builder
88
- .data_directory(_data_dir)
89
- .additional_browser_args("--disable-blink-features=AutomationControlled")
90
- .theme(None);
126
+ window_builder = window_builder.data_directory(_data_dir).theme(None);
127
+
128
+ if !config.proxy_url.is_empty() {
129
+ if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
130
+ parsed_proxy_url = Some(proxy_url.clone());
131
+ #[cfg(target_os = "windows")]
132
+ {
133
+ if let Some(arg) = build_proxy_browser_arg(&proxy_url) {
134
+ windows_browser_args.push(' ');
135
+ windows_browser_args.push_str(&arg);
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ #[cfg(target_os = "windows")]
142
+ {
143
+ window_builder = window_builder.additional_browser_args(&windows_browser_args);
144
+ }
145
+
146
+ #[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
147
+ {
148
+ window_builder = window_builder.additional_browser_args(&linux_browser_args);
149
+ }
91
150
  }
92
151
 
93
152
  // Set proxy after platform-specific configs (required for Windows/Linux)
94
- if !config.proxy_url.is_empty() {
153
+ if parsed_proxy_url.is_none() && !config.proxy_url.is_empty() {
95
154
  if let Ok(proxy_url) = Url::from_str(&config.proxy_url) {
96
- window_builder = window_builder.proxy_url(proxy_url);
97
- #[cfg(debug_assertions)]
98
- println!("Proxy configured: {}", config.proxy_url);
155
+ parsed_proxy_url = Some(proxy_url);
99
156
  }
100
157
  }
101
158
 
159
+ if let Some(proxy_url) = parsed_proxy_url {
160
+ window_builder = window_builder.proxy_url(proxy_url);
161
+ #[cfg(debug_assertions)]
162
+ println!("Proxy configured: {}", config.proxy_url);
163
+ }
164
+
102
165
  window_builder.build().expect("Failed to build window")
103
166
  }
@@ -63,7 +63,12 @@ pub fn run_app() {
63
63
  ])
64
64
  .setup(move |app| {
65
65
  let window = set_window(app, &pake_config, &tauri_config);
66
- set_system_tray(app.app_handle(), show_system_tray, &pake_config.system_tray_path).unwrap();
66
+ set_system_tray(
67
+ app.app_handle(),
68
+ show_system_tray,
69
+ &pake_config.system_tray_path,
70
+ )
71
+ .unwrap();
67
72
  set_global_shortcut(app.app_handle(), activation_shortcut).unwrap();
68
73
 
69
74
  // Show window after state restoration to prevent position flashing