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 +55 -9
- package/package.json +1 -1
- package/src-tauri/src/app/setup.rs +11 -3
- package/src-tauri/src/app/window.rs +74 -11
- package/src-tauri/src/lib.rs +6 -1
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.
|
|
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
|
-
(
|
|
228
|
-
|
|
229
|
-
|
|
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
|
|
820
|
-
|
|
821
|
-
...(
|
|
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
|
-
|
|
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' &&
|
|
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
|
@@ -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(
|
|
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()
|
|
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()
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
.
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src-tauri/src/lib.rs
CHANGED
|
@@ -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(
|
|
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
|