pake-cli 3.11.9 โ 3.11.10
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/LICENSE-EXCEPTION +20 -0
- package/README.md +6 -1
- package/dist/cli.js +19 -5
- package/package.json +2 -1
- package/src-tauri/Cargo.lock +1 -1
- package/src-tauri/Cargo.toml +1 -1
- package/src-tauri/src/inject/event.js +37 -8
- package/src-tauri/src/lib.rs +136 -8
- package/src-tauri/tauri.conf.json +1 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Pake Output Exception
|
|
2
|
+
|
|
3
|
+
This is an exception to the GNU General Public License version 3 (GPLv3),
|
|
4
|
+
under which Pake is licensed (see the LICENSE file).
|
|
5
|
+
|
|
6
|
+
As an additional permission under section 7 of the GPLv3:
|
|
7
|
+
|
|
8
|
+
When you use Pake, or a build of Pake produced by the standard Pake build
|
|
9
|
+
and packaging process, to generate a target application ("Pake Output"),
|
|
10
|
+
the portions of Pake incorporated into that Pake Output do not by
|
|
11
|
+
themselves cause the Pake Output as a whole to be or become subject to the
|
|
12
|
+
GPLv3. You may distribute such Pake Output under license terms of your own
|
|
13
|
+
choosing, including proprietary terms.
|
|
14
|
+
|
|
15
|
+
This permission does NOT apply to Pake itself or to any modified version of
|
|
16
|
+
Pake's own source code: anyone who distributes Pake, or a work derived from
|
|
17
|
+
Pake's source code beyond the configuration and packaging performed by the
|
|
18
|
+
standard build process, remains fully bound by the GPLv3.
|
|
19
|
+
|
|
20
|
+
Copyright (c) 2024 Tw93 and the Pake contributors.
|
package/README.md
CHANGED
|
@@ -202,12 +202,17 @@ Pake's development can not be without these Hackers. They contributed a lot of c
|
|
|
202
202
|
|
|
203
203
|
## Support
|
|
204
204
|
|
|
205
|
+
- The most direct way to support me is getting [Mole for Mac](https://mole.fit), my paid Mac cleanup app.
|
|
205
206
|
- If Pake helped you, [share it](https://twitter.com/intent/tweet?url=https://github.com/tw93/Pake&text=Pake%20-%20Turn%20any%20webpage%20into%20a%20desktop%20app%20with%20one%20command.%20Nearly%2020x%20smaller%20than%20Electron%20packages,%20supports%20macOS%20Windows%20Linux) with friends or give it a star.
|
|
206
207
|
- Got ideas or bugs? Open an issue or PR, feel free to contribute your best AI model.
|
|
207
208
|
- I have two cats, TangYuan and Coke. If you think Pake delights your life, you can feed them <a href="https://cats.tw93.fun?name=Pake" target="_blank">canned food ๐ฅฉ</a>.
|
|
208
209
|
|
|
210
|
+
<details>
|
|
211
|
+
<summary>These lovely people already did ๐ฑ</summary>
|
|
212
|
+
<br/>
|
|
209
213
|
<a href="https://cats.tw93.fun?name=Pake"><img src="https://cdn.jsdelivr.net/gh/tw93/sponsors@main/assets/sponsors.svg" width="1000" loading="lazy" /></a>
|
|
214
|
+
</details>
|
|
210
215
|
|
|
211
216
|
## License
|
|
212
217
|
|
|
213
|
-
Pake is open source under GPL-3.0, see [LICENSE](./LICENSE); apps you build with Pake are entirely yours to use and distribute. If you fork Pake into your own product, to avoid confusion please give it a different name and credit Pake as the source.
|
|
218
|
+
Pake is open source under GPL-3.0, see [LICENSE](./LICENSE) and [Pake Output Exception](./LICENSE-EXCEPTION); apps you build with Pake are entirely yours to use and distribute. If you fork Pake into your own product, to avoid confusion please give it a different name and credit Pake as the source.
|
package/dist/cli.js
CHANGED
|
@@ -20,7 +20,7 @@ import { InvalidArgumentError, program as program$1, Option } from 'commander';
|
|
|
20
20
|
import fs$1 from 'fs';
|
|
21
21
|
|
|
22
22
|
var name = "pake-cli";
|
|
23
|
-
var version = "3.11.
|
|
23
|
+
var version = "3.11.10";
|
|
24
24
|
var description = "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ";
|
|
25
25
|
var engines = {
|
|
26
26
|
node: ">=18.0.0"
|
|
@@ -46,6 +46,7 @@ var keywords = [
|
|
|
46
46
|
"productivity"
|
|
47
47
|
];
|
|
48
48
|
var files = [
|
|
49
|
+
"LICENSE-EXCEPTION",
|
|
49
50
|
"dist",
|
|
50
51
|
"src-tauri"
|
|
51
52
|
];
|
|
@@ -417,6 +418,9 @@ function filterLinuxTargets(targets) {
|
|
|
417
418
|
const requested = targets.split(',').map((target) => target.trim());
|
|
418
419
|
return LINUX_TARGET_TYPES.filter((target) => requested.includes(target));
|
|
419
420
|
}
|
|
421
|
+
function needsTemporaryDebForZst(targets) {
|
|
422
|
+
return targets.includes('zst') && !targets.includes('deb');
|
|
423
|
+
}
|
|
420
424
|
|
|
421
425
|
/**
|
|
422
426
|
* Pure transform from CLI options to the window-config slice that gets
|
|
@@ -1407,11 +1411,16 @@ class LinuxBuilder extends BaseBuilder {
|
|
|
1407
1411
|
if (targets.length === 0) {
|
|
1408
1412
|
throw new Error(`No valid Linux target in "${this.options.targets}". Valid targets: ${LINUX_TARGET_TYPES.join(', ')}.`);
|
|
1409
1413
|
}
|
|
1414
|
+
const useTemporaryDebForZst = needsTemporaryDebForZst(targets);
|
|
1410
1415
|
for (const target of targets) {
|
|
1411
1416
|
this.currentBuildType = target;
|
|
1412
1417
|
if (target === 'zst') {
|
|
1413
|
-
|
|
1414
|
-
|
|
1418
|
+
if (useTemporaryDebForZst) {
|
|
1419
|
+
await this.buildAndCopy(url, 'deb', false);
|
|
1420
|
+
}
|
|
1421
|
+
await this.createArchPackageFromDeb({
|
|
1422
|
+
removeSourceDeb: useTemporaryDebForZst,
|
|
1423
|
+
});
|
|
1415
1424
|
}
|
|
1416
1425
|
else {
|
|
1417
1426
|
await this.buildAndCopy(url, target);
|
|
@@ -1432,7 +1441,7 @@ class LinuxBuilder extends BaseBuilder {
|
|
|
1432
1441
|
}
|
|
1433
1442
|
}
|
|
1434
1443
|
}
|
|
1435
|
-
async createArchPackageFromDeb() {
|
|
1444
|
+
async createArchPackageFromDeb({ removeSourceDeb, }) {
|
|
1436
1445
|
const { name = 'pake-app' } = this.options;
|
|
1437
1446
|
const packageName = generateLinuxPackageName(name);
|
|
1438
1447
|
const version = tauriConfig.version;
|
|
@@ -1493,11 +1502,13 @@ post_remove() {
|
|
|
1493
1502
|
}
|
|
1494
1503
|
`);
|
|
1495
1504
|
await shellExec(`bsdtar --zstd -cf "${packagePath}" -C "${dataDir}" .PKGINFO .INSTALL usr`);
|
|
1496
|
-
await fsExtra.remove(debPath);
|
|
1497
1505
|
logger.success('โ Build success!');
|
|
1498
1506
|
logger.success('โ App installer located in', packagePath);
|
|
1499
1507
|
}
|
|
1500
1508
|
finally {
|
|
1509
|
+
if (removeSourceDeb) {
|
|
1510
|
+
await fsExtra.remove(debPath);
|
|
1511
|
+
}
|
|
1501
1512
|
await fsExtra.remove(workDir);
|
|
1502
1513
|
}
|
|
1503
1514
|
}
|
|
@@ -2540,6 +2551,9 @@ const DEFAULT_PAKE_OPTIONS = {
|
|
|
2540
2551
|
};
|
|
2541
2552
|
|
|
2542
2553
|
function validateNumberInput(value) {
|
|
2554
|
+
if (value.trim() === '') {
|
|
2555
|
+
throw new InvalidArgumentError('Not a number.');
|
|
2556
|
+
}
|
|
2543
2557
|
const parsedValue = Number(value);
|
|
2544
2558
|
if (!Number.isFinite(parsedValue)) {
|
|
2545
2559
|
throw new InvalidArgumentError('Not a number.');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pake-cli",
|
|
3
|
-
"version": "3.11.
|
|
3
|
+
"version": "3.11.10",
|
|
4
4
|
"description": "๐คฑ๐ป Turn any webpage into a desktop app with one command. ๐คฑ๐ป ไธ้ฎๆๅ
็ฝ้กต็ๆ่ฝป้ๆก้ขๅบ็จใ",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"productivity"
|
|
27
27
|
],
|
|
28
28
|
"files": [
|
|
29
|
+
"LICENSE-EXCEPTION",
|
|
29
30
|
"dist",
|
|
30
31
|
"src-tauri"
|
|
31
32
|
],
|
package/src-tauri/Cargo.lock
CHANGED
package/src-tauri/Cargo.toml
CHANGED
|
@@ -272,6 +272,33 @@ function shouldBypassPakeLinkHandling(rawHref) {
|
|
|
272
272
|
);
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
function shouldNavigateAuthInCurrentWindow() {
|
|
276
|
+
return /macintosh|mac os x/i.test(navigator.userAgent);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function canNavigateAuthUrl(url) {
|
|
280
|
+
const normalizedUrl = normalizeAnchorHref(url).toLowerCase();
|
|
281
|
+
return normalizedUrl !== "" && normalizedUrl !== "about:blank";
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function navigateInCurrentWindow(url) {
|
|
285
|
+
window.location.href = url;
|
|
286
|
+
return window;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function openAuthNavigation(originalWindowOpen, url, name, specs) {
|
|
290
|
+
if (shouldNavigateAuthInCurrentWindow() && canNavigateAuthUrl(url)) {
|
|
291
|
+
return navigateInCurrentWindow(url);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const authWindow = originalWindowOpen.call(window, url, name, specs);
|
|
295
|
+
if (!authWindow) {
|
|
296
|
+
return navigateInCurrentWindow(url);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return authWindow;
|
|
300
|
+
}
|
|
301
|
+
|
|
275
302
|
document.addEventListener("DOMContentLoaded", () => {
|
|
276
303
|
const tauri = window.__TAURI__;
|
|
277
304
|
const appWindow = tauri.window.getCurrentWindow();
|
|
@@ -440,16 +467,12 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
440
467
|
e.preventDefault();
|
|
441
468
|
e.stopImmediatePropagation();
|
|
442
469
|
|
|
443
|
-
|
|
444
|
-
|
|
470
|
+
openAuthNavigation(
|
|
471
|
+
originalWindowOpen,
|
|
445
472
|
absoluteUrl,
|
|
446
473
|
"_blank",
|
|
447
474
|
"width=1200,height=800,scrollbars=yes,resizable=yes",
|
|
448
475
|
);
|
|
449
|
-
|
|
450
|
-
if (!authWindow) {
|
|
451
|
-
window.location.href = absoluteUrl;
|
|
452
|
-
}
|
|
453
476
|
}
|
|
454
477
|
|
|
455
478
|
return;
|
|
@@ -544,9 +567,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
544
567
|
return originalWindowOpen.call(window, url, name, specs);
|
|
545
568
|
}
|
|
546
569
|
|
|
547
|
-
//
|
|
570
|
+
// Avoid macOS WebKit auth-popup crashes by navigating auth URLs in-place.
|
|
548
571
|
if (window.isAuthPopup(url, name)) {
|
|
549
|
-
|
|
572
|
+
try {
|
|
573
|
+
const baseUrl = window.location.origin + window.location.pathname;
|
|
574
|
+
const absoluteUrl = new URL(url, baseUrl).href;
|
|
575
|
+
return openAuthNavigation(originalWindowOpen, absoluteUrl, name, specs);
|
|
576
|
+
} catch (error) {
|
|
577
|
+
return openAuthNavigation(originalWindowOpen, url, name, specs);
|
|
578
|
+
}
|
|
550
579
|
}
|
|
551
580
|
|
|
552
581
|
try {
|
package/src-tauri/src/lib.rs
CHANGED
|
@@ -10,6 +10,12 @@ use tauri_plugin_window_state::StateFlags;
|
|
|
10
10
|
use std::time::Duration;
|
|
11
11
|
|
|
12
12
|
const WINDOW_SHOW_DELAY: u64 = 50;
|
|
13
|
+
#[cfg(target_os = "linux")]
|
|
14
|
+
const PAKE_LINUX_WEBKIT_SAFE_MODE: &str = "PAKE_LINUX_WEBKIT_SAFE_MODE";
|
|
15
|
+
#[cfg(target_os = "linux")]
|
|
16
|
+
const WEBKIT_DISABLE_DMABUF_RENDERER: &str = "WEBKIT_DISABLE_DMABUF_RENDERER";
|
|
17
|
+
#[cfg(target_os = "linux")]
|
|
18
|
+
const WEBKIT_DISABLE_COMPOSITING_MODE: &str = "WEBKIT_DISABLE_COMPOSITING_MODE";
|
|
13
19
|
|
|
14
20
|
use app::{
|
|
15
21
|
invoke::{
|
|
@@ -21,16 +27,83 @@ use app::{
|
|
|
21
27
|
};
|
|
22
28
|
use util::get_pake_config;
|
|
23
29
|
|
|
30
|
+
#[cfg(any(target_os = "linux", test))]
|
|
31
|
+
fn is_disabled_env_value(value: &str) -> bool {
|
|
32
|
+
matches!(
|
|
33
|
+
value.trim().to_ascii_lowercase().as_str(),
|
|
34
|
+
"0" | "false" | "off" | "no" | "native" | "disabled"
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
#[cfg(any(target_os = "linux", test))]
|
|
39
|
+
fn is_non_empty_env_value(value: Option<&str>) -> bool {
|
|
40
|
+
value.map(|value| !value.trim().is_empty()).unwrap_or(false)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
#[cfg(any(target_os = "linux", test))]
|
|
44
|
+
fn contains_niri(value: &str) -> bool {
|
|
45
|
+
value
|
|
46
|
+
.split([':', ';', ',', ' '])
|
|
47
|
+
.any(|part| part.eq_ignore_ascii_case("niri"))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#[cfg(any(target_os = "linux", test))]
|
|
51
|
+
fn should_enable_linux_webkit_safe_mode_from_values(
|
|
52
|
+
safe_mode: Option<&str>,
|
|
53
|
+
niri_socket: Option<&str>,
|
|
54
|
+
desktop_values: &[Option<&str>],
|
|
55
|
+
) -> bool {
|
|
56
|
+
if let Some(value) = safe_mode.filter(|value| !value.trim().is_empty()) {
|
|
57
|
+
return !is_disabled_env_value(value);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let is_niri_session = is_non_empty_env_value(niri_socket)
|
|
61
|
+
|| desktop_values
|
|
62
|
+
.iter()
|
|
63
|
+
.flatten()
|
|
64
|
+
.any(|value| contains_niri(value));
|
|
65
|
+
|
|
66
|
+
!is_niri_session
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#[cfg(target_os = "linux")]
|
|
70
|
+
fn apply_linux_webkit_runtime_flags() {
|
|
71
|
+
let safe_mode = std::env::var(PAKE_LINUX_WEBKIT_SAFE_MODE).ok();
|
|
72
|
+
if safe_mode.as_deref().is_some_and(is_disabled_env_value) {
|
|
73
|
+
std::env::remove_var(WEBKIT_DISABLE_DMABUF_RENDERER);
|
|
74
|
+
std::env::remove_var(WEBKIT_DISABLE_COMPOSITING_MODE);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let desktop_values = [
|
|
79
|
+
std::env::var("XDG_CURRENT_DESKTOP").ok(),
|
|
80
|
+
std::env::var("XDG_SESSION_DESKTOP").ok(),
|
|
81
|
+
std::env::var("DESKTOP_SESSION").ok(),
|
|
82
|
+
];
|
|
83
|
+
let desktop_refs = desktop_values
|
|
84
|
+
.iter()
|
|
85
|
+
.map(|value| value.as_deref())
|
|
86
|
+
.collect::<Vec<_>>();
|
|
87
|
+
|
|
88
|
+
if !should_enable_linux_webkit_safe_mode_from_values(
|
|
89
|
+
safe_mode.as_deref(),
|
|
90
|
+
std::env::var("NIRI_SOCKET").ok().as_deref(),
|
|
91
|
+
&desktop_refs,
|
|
92
|
+
) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if std::env::var(WEBKIT_DISABLE_DMABUF_RENDERER).is_err() {
|
|
97
|
+
std::env::set_var(WEBKIT_DISABLE_DMABUF_RENDERER, "1");
|
|
98
|
+
}
|
|
99
|
+
if std::env::var(WEBKIT_DISABLE_COMPOSITING_MODE).is_err() {
|
|
100
|
+
std::env::set_var(WEBKIT_DISABLE_COMPOSITING_MODE, "1");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
24
104
|
pub fn run_app() {
|
|
25
105
|
#[cfg(target_os = "linux")]
|
|
26
|
-
|
|
27
|
-
if std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() {
|
|
28
|
-
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
|
|
29
|
-
}
|
|
30
|
-
if std::env::var("WEBKIT_DISABLE_COMPOSITING_MODE").is_err() {
|
|
31
|
-
std::env::set_var("WEBKIT_DISABLE_COMPOSITING_MODE", "1");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
106
|
+
apply_linux_webkit_runtime_flags();
|
|
34
107
|
|
|
35
108
|
let (pake_config, tauri_config) = get_pake_config();
|
|
36
109
|
let tauri_app = tauri::Builder::default();
|
|
@@ -202,3 +275,58 @@ pub fn run_app() {
|
|
|
202
275
|
pub fn run() {
|
|
203
276
|
run_app()
|
|
204
277
|
}
|
|
278
|
+
|
|
279
|
+
#[cfg(test)]
|
|
280
|
+
mod tests {
|
|
281
|
+
use super::*;
|
|
282
|
+
|
|
283
|
+
#[test]
|
|
284
|
+
fn linux_webkit_safe_mode_stays_on_by_default() {
|
|
285
|
+
assert!(should_enable_linux_webkit_safe_mode_from_values(
|
|
286
|
+
None,
|
|
287
|
+
None,
|
|
288
|
+
&[None, None, None]
|
|
289
|
+
));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
#[test]
|
|
293
|
+
fn linux_webkit_safe_mode_is_disabled_for_niri_socket() {
|
|
294
|
+
assert!(!should_enable_linux_webkit_safe_mode_from_values(
|
|
295
|
+
None,
|
|
296
|
+
Some("/run/user/501/niri.sock"),
|
|
297
|
+
&[None, None, None]
|
|
298
|
+
));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
#[test]
|
|
302
|
+
fn linux_webkit_safe_mode_is_disabled_for_niri_desktop() {
|
|
303
|
+
assert!(!should_enable_linux_webkit_safe_mode_from_values(
|
|
304
|
+
None,
|
|
305
|
+
None,
|
|
306
|
+
&[Some("niri"), None, None]
|
|
307
|
+
));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
#[test]
|
|
311
|
+
fn linux_webkit_safe_mode_can_be_forced_on_for_niri() {
|
|
312
|
+
assert!(should_enable_linux_webkit_safe_mode_from_values(
|
|
313
|
+
Some("1"),
|
|
314
|
+
Some("/run/user/501/niri.sock"),
|
|
315
|
+
&[Some("niri"), None, None]
|
|
316
|
+
));
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#[test]
|
|
320
|
+
fn linux_webkit_safe_mode_can_be_disabled_explicitly() {
|
|
321
|
+
for value in ["0", "false", "off", "no", "native", "disabled"] {
|
|
322
|
+
assert!(
|
|
323
|
+
!should_enable_linux_webkit_safe_mode_from_values(
|
|
324
|
+
Some(value),
|
|
325
|
+
None,
|
|
326
|
+
&[None, None, None]
|
|
327
|
+
),
|
|
328
|
+
"expected {value} to disable safe mode"
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|