pake-cli 3.7.2 โ 3.7.4
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 +20 -3
- package/package.json +6 -2
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/pake.json +2 -1
- package/src-tauri/src/app/config.rs +1 -0
- package/src-tauri/src/app/window.rs +12 -3
- package/src-tauri/src/inject/theme_refresh.js +22 -87
- package/src-tauri/tauri.macos.conf.json +4 -1
package/dist/cli.js
CHANGED
|
@@ -22,7 +22,7 @@ import * as psl from 'psl';
|
|
|
22
22
|
import { InvalidArgumentError, program as program$1, Option } from 'commander';
|
|
23
23
|
|
|
24
24
|
var name = "pake-cli";
|
|
25
|
-
var version = "3.7.
|
|
25
|
+
var version = "3.7.4";
|
|
26
26
|
var description = "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ";
|
|
27
27
|
var engines = {
|
|
28
28
|
node: ">=18.0.0"
|
|
@@ -111,7 +111,11 @@ var devDependencies = {
|
|
|
111
111
|
var pnpm = {
|
|
112
112
|
overrides: {
|
|
113
113
|
sharp: "^0.34.5"
|
|
114
|
-
}
|
|
114
|
+
},
|
|
115
|
+
onlyBuiltDependencies: [
|
|
116
|
+
"esbuild",
|
|
117
|
+
"sharp"
|
|
118
|
+
]
|
|
115
119
|
};
|
|
116
120
|
var packageJson = {
|
|
117
121
|
name: name,
|
|
@@ -480,7 +484,7 @@ async function mergeConfig(url, options, tauriConf) {
|
|
|
480
484
|
await fsExtra.copy(sourcePath, destPath);
|
|
481
485
|
}
|
|
482
486
|
}));
|
|
483
|
-
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;
|
|
487
|
+
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, newWindow, } = options;
|
|
484
488
|
const { platform } = process;
|
|
485
489
|
const platformHideOnClose = hideOnClose ?? platform === 'darwin';
|
|
486
490
|
const tauriConfWindowOptions = {
|
|
@@ -505,6 +509,7 @@ async function mergeConfig(url, options, tauriConf) {
|
|
|
505
509
|
min_width: minWidth,
|
|
506
510
|
min_height: minHeight,
|
|
507
511
|
ignore_certificate_errors: ignoreCertificateErrors,
|
|
512
|
+
new_window: newWindow,
|
|
508
513
|
};
|
|
509
514
|
Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });
|
|
510
515
|
tauriConf.productName = name;
|
|
@@ -1640,6 +1645,14 @@ async function handleIcon(options, url) {
|
|
|
1640
1645
|
const result = await processIcon(resolvedPath, options.name || '');
|
|
1641
1646
|
return result || resolvedPath;
|
|
1642
1647
|
}
|
|
1648
|
+
// Check for existing local icon before downloading
|
|
1649
|
+
if (options.name) {
|
|
1650
|
+
const localIconPath = generateIconPath(options.name);
|
|
1651
|
+
if (await fsExtra.pathExists(localIconPath)) {
|
|
1652
|
+
logger.info(`โผ Using existing local icon: ${localIconPath}`);
|
|
1653
|
+
return localIconPath;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1643
1656
|
// Try favicon from website
|
|
1644
1657
|
if (url && options.name) {
|
|
1645
1658
|
const faviconPath = await tryGetFavicon(url, options.name);
|
|
@@ -1913,6 +1926,7 @@ const DEFAULT_PAKE_OPTIONS = {
|
|
|
1913
1926
|
minWidth: 0,
|
|
1914
1927
|
minHeight: 0,
|
|
1915
1928
|
ignoreCertificateErrors: false,
|
|
1929
|
+
newWindow: false,
|
|
1916
1930
|
};
|
|
1917
1931
|
|
|
1918
1932
|
function validateNumberInput(value) {
|
|
@@ -2063,6 +2077,9 @@ ${green('|_| \\__,_|_|\\_\\___| can turn any webpage into a desktop app with
|
|
|
2063
2077
|
.addOption(new Option('--iterative-build', 'Turn on rapid build mode (app only, no dmg/deb/msi), good for debugging')
|
|
2064
2078
|
.default(DEFAULT_PAKE_OPTIONS.iterativeBuild)
|
|
2065
2079
|
.hideHelp())
|
|
2080
|
+
.addOption(new Option('--new-window', 'Allow new window for third-party login')
|
|
2081
|
+
.default(DEFAULT_PAKE_OPTIONS.newWindow)
|
|
2082
|
+
.hideHelp())
|
|
2066
2083
|
.version(packageJson.version, '-v, --version')
|
|
2067
2084
|
.configureHelp({
|
|
2068
2085
|
sortSubcommands: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pake-cli",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.4",
|
|
4
4
|
"description": "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
"pnpm": {
|
|
90
90
|
"overrides": {
|
|
91
91
|
"sharp": "^0.34.5"
|
|
92
|
-
}
|
|
92
|
+
},
|
|
93
|
+
"onlyBuiltDependencies": [
|
|
94
|
+
"esbuild",
|
|
95
|
+
"sharp"
|
|
96
|
+
]
|
|
93
97
|
}
|
|
94
98
|
}
|
package/src-tauri/Cargo.lock
CHANGED
package/src-tauri/Cargo.toml
CHANGED
package/src-tauri/pake.json
CHANGED
|
@@ -82,6 +82,11 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
82
82
|
window_builder = window_builder.disable_drag_drop_handler();
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
if window_config.new_window {
|
|
86
|
+
window_builder = window_builder
|
|
87
|
+
.on_new_window(move |_url, _features| tauri::webview::NewWindowResponse::Allow);
|
|
88
|
+
}
|
|
89
|
+
|
|
85
90
|
// Add initialization scripts
|
|
86
91
|
window_builder = window_builder
|
|
87
92
|
.initialization_script(&config_script)
|
|
@@ -148,9 +153,13 @@ pub fn set_window(app: &mut App, config: &PakeConfig, tauri_config: &Config) ->
|
|
|
148
153
|
};
|
|
149
154
|
window_builder = window_builder.title_bar_style(title_bar_style);
|
|
150
155
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
// Default to following system theme (None), only force dark when explicitly set
|
|
157
|
+
let theme = if window_config.dark_mode {
|
|
158
|
+
Some(Theme::Dark)
|
|
159
|
+
} else {
|
|
160
|
+
None // Follow system theme
|
|
161
|
+
};
|
|
162
|
+
window_builder = window_builder.theme(theme);
|
|
154
163
|
}
|
|
155
164
|
|
|
156
165
|
// Windows and Linux: set data_directory before proxy_url
|
|
@@ -1,124 +1,59 @@
|
|
|
1
1
|
document.addEventListener("DOMContentLoaded", () => {
|
|
2
|
-
// Helper: Calculate brightness from RGB color
|
|
3
|
-
const isDarkColor = (color) => {
|
|
4
|
-
if (!color) return false;
|
|
5
|
-
const match = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
6
|
-
if (!match) return false;
|
|
7
|
-
const r = parseInt(match[1]);
|
|
8
|
-
const g = parseInt(match[2]);
|
|
9
|
-
const b = parseInt(match[3]);
|
|
10
|
-
// Standard luminance formula
|
|
11
|
-
const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
12
|
-
return luminance < 128;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
// Debounce helper
|
|
16
2
|
const debounce = (func, wait) => {
|
|
17
3
|
let timeout;
|
|
18
|
-
return
|
|
19
|
-
const later = () => {
|
|
20
|
-
clearTimeout(timeout);
|
|
21
|
-
func(...args);
|
|
22
|
-
};
|
|
4
|
+
return (...args) => {
|
|
23
5
|
clearTimeout(timeout);
|
|
24
|
-
timeout = setTimeout(
|
|
6
|
+
timeout = setTimeout(() => func(...args), wait);
|
|
25
7
|
};
|
|
26
8
|
};
|
|
27
9
|
|
|
28
|
-
// Function to detect and send theme to Rust
|
|
29
10
|
const updateTheme = () => {
|
|
30
|
-
let mode = "light";
|
|
31
|
-
let detected = false;
|
|
32
|
-
|
|
33
|
-
// Strategy 1: Explicit DOM Class/Attribute (High Priority)
|
|
34
|
-
// Many apps use specific classes for hard-coded themes
|
|
35
11
|
const doc = document.documentElement;
|
|
36
12
|
const body = document.body;
|
|
13
|
+
let mode = null;
|
|
37
14
|
|
|
38
|
-
|
|
15
|
+
// Check for explicit theme classes or attributes
|
|
16
|
+
const isDark =
|
|
39
17
|
doc.classList.contains("dark") ||
|
|
40
18
|
body.classList.contains("dark") ||
|
|
41
19
|
doc.getAttribute("data-theme") === "dark" ||
|
|
42
20
|
body.getAttribute("data-theme") === "dark" ||
|
|
43
21
|
doc.style.colorScheme === "dark";
|
|
44
22
|
|
|
45
|
-
const
|
|
23
|
+
const isLight =
|
|
46
24
|
doc.classList.contains("light") ||
|
|
47
25
|
body.classList.contains("light") ||
|
|
48
26
|
doc.getAttribute("data-theme") === "light" ||
|
|
49
27
|
body.getAttribute("data-theme") === "light" ||
|
|
50
28
|
doc.style.colorScheme === "light";
|
|
51
29
|
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
detected = true;
|
|
55
|
-
} else if (isExplicitLight) {
|
|
56
|
-
mode = "light";
|
|
57
|
-
detected = true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Strategy 2: Computed Background Color (Fallback & Verification)
|
|
61
|
-
// If no explicit class is found, or to double-check, look at the actual background color.
|
|
62
|
-
// This is useful when the site relies purely on CSS media queries without classes.
|
|
63
|
-
if (!detected) {
|
|
64
|
-
const bodyBg = window.getComputedStyle(document.body).backgroundColor;
|
|
65
|
-
const htmlBg = window.getComputedStyle(
|
|
66
|
-
document.documentElement,
|
|
67
|
-
).backgroundColor;
|
|
30
|
+
if (isDark) mode = "dark";
|
|
31
|
+
else if (isLight) mode = "light";
|
|
68
32
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
mode = isDarkColor(bodyBg) ? "dark" : "light";
|
|
72
|
-
} else if (
|
|
73
|
-
htmlBg &&
|
|
74
|
-
htmlBg !== "rgba(0, 0, 0, 0)" &&
|
|
75
|
-
htmlBg !== "transparent"
|
|
76
|
-
) {
|
|
77
|
-
mode = isDarkColor(htmlBg) ? "dark" : "light";
|
|
78
|
-
} else {
|
|
79
|
-
// Strategy 3: System Preference (Last Resort)
|
|
80
|
-
if (
|
|
81
|
-
window.matchMedia &&
|
|
82
|
-
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
83
|
-
) {
|
|
84
|
-
mode = "dark";
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Send to Rust
|
|
90
|
-
if (window.__TAURI__ && window.__TAURI__.core) {
|
|
33
|
+
// Only invoke Rust command if an explicit theme override is detected
|
|
34
|
+
if (mode && window.__TAURI__?.core) {
|
|
91
35
|
window.__TAURI__.core.invoke("update_theme_mode", { mode });
|
|
92
36
|
}
|
|
93
37
|
};
|
|
94
38
|
|
|
95
|
-
// Debounced version of updateTheme
|
|
96
39
|
const debouncedUpdateTheme = debounce(updateTheme, 200);
|
|
97
40
|
|
|
98
|
-
// Initial check
|
|
99
|
-
|
|
100
|
-
setTimeout(updateTheme, 100);
|
|
101
|
-
|
|
102
|
-
// Watch for system theme changes
|
|
103
|
-
window
|
|
104
|
-
.matchMedia("(prefers-color-scheme: dark)")
|
|
105
|
-
.addEventListener("change", updateTheme);
|
|
41
|
+
// Initial check with delay to allow site to render
|
|
42
|
+
setTimeout(updateTheme, 500);
|
|
106
43
|
|
|
107
44
|
// Watch for DOM changes
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
debouncedUpdateTheme();
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
observer.observe(document.documentElement, {
|
|
45
|
+
const observer = new MutationObserver(debouncedUpdateTheme);
|
|
46
|
+
const config = {
|
|
114
47
|
attributes: true,
|
|
115
48
|
attributeFilter: ["class", "data-theme", "style"],
|
|
116
49
|
subtree: false,
|
|
117
|
-
}
|
|
50
|
+
};
|
|
118
51
|
|
|
119
|
-
observer.observe(document.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
52
|
+
observer.observe(document.documentElement, config);
|
|
53
|
+
observer.observe(document.body, config);
|
|
54
|
+
|
|
55
|
+
// Watch for system theme changes (though window should handle this natively now)
|
|
56
|
+
window
|
|
57
|
+
.matchMedia("(prefers-color-scheme: dark)")
|
|
58
|
+
.addEventListener("change", updateTheme);
|
|
124
59
|
});
|