pake-cli 3.15.6 โ†’ 3.15.7

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
@@ -14,16 +14,14 @@ import fs from 'fs';
14
14
  import fs$1 from 'fs/promises';
15
15
  import { dir } from 'tmp-promise';
16
16
  import { fileTypeFromBuffer } from 'file-type';
17
- import icongen from 'icon-gen';
18
- import sharp from 'sharp';
19
17
  import * as psl from 'psl';
20
18
  import { InvalidArgumentError, program as program$1, Option } from 'commander';
21
19
 
22
20
  var name = "pake-cli";
23
- var version = "3.15.6";
21
+ var version = "3.15.7";
24
22
  var description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚";
25
23
  var engines = {
26
- node: ">=20.0.0"
24
+ node: ">=20.9.0"
27
25
  };
28
26
  var packageManager = "pnpm@10.26.2";
29
27
  var bin = {
@@ -80,7 +78,6 @@ var dependencies = {
80
78
  execa: "^9.6.1",
81
79
  "file-type": "^21.3.4",
82
80
  "fs-extra": "^11.3.3",
83
- "icon-gen": "^5.0.0",
84
81
  loglevel: "^1.9.2",
85
82
  ora: "^9.3.0",
86
83
  prompts: "^2.4.2",
@@ -2114,6 +2111,9 @@ function getIconSourcePriority(url, appName) {
2114
2111
  : ['domain', 'dashboard'];
2115
2112
  }
2116
2113
 
2114
+ async function loadSharp$1() {
2115
+ return (await import('sharp')).default;
2116
+ }
2117
2117
  const ICO_HEADER_SIZE = 6;
2118
2118
  const ICO_DIR_ENTRY_SIZE = 16;
2119
2119
  const ICO_TYPE_ICON = 1;
@@ -2247,6 +2247,7 @@ async function pickLargestFrameAsPng(buffer, entries) {
2247
2247
  // Fallback: let sharp render directly from the ICO buffer. sharp picks the
2248
2248
  // largest embedded frame on its own.
2249
2249
  try {
2250
+ const sharp = await loadSharp$1();
2250
2251
  return await sharp(buffer).png().toBuffer();
2251
2252
  }
2252
2253
  catch {
@@ -2268,6 +2269,7 @@ async function ensureMultiResolutionIco(sourcePath, outputPath, preferredSize =
2268
2269
  if (!sourcePng) {
2269
2270
  return await writeIcoWithPreferredSize(sourcePath, outputPath, preferredSize);
2270
2271
  }
2272
+ const sharp = await loadSharp$1();
2271
2273
  const frames = await Promise.all(desiredSizes.map(async (size) => {
2272
2274
  // Reuse an existing exact-size PNG frame when possible to keep any
2273
2275
  // hand-tuned small icon (e.g. a 16x16 with deliberate pixel hinting).
@@ -2334,6 +2336,9 @@ function buildIcoFromPngBuffers(frames) {
2334
2336
  return output;
2335
2337
  }
2336
2338
 
2339
+ async function loadSharp() {
2340
+ return (await import('sharp')).default;
2341
+ }
2337
2342
  const ICON_CONFIG = {
2338
2343
  minFileSize: 100,
2339
2344
  supportedFormats: [
@@ -2354,8 +2359,20 @@ const ICON_CONFIG = {
2354
2359
  const PLATFORM_CONFIG = {
2355
2360
  win: { format: '.ico', sizes: [...WIN_STANDARD_ICO_SIZES] },
2356
2361
  linux: { format: '.png', size: 512 },
2357
- macos: { format: '.icns', sizes: [16, 32, 64, 128, 256, 512, 1024] },
2362
+ macos: { format: '.icns' },
2358
2363
  };
2364
+ const MACOS_ICONSET_FILES = [
2365
+ ['icon_16x16.png', 16],
2366
+ ['icon_16x16@2x.png', 32],
2367
+ ['icon_32x32.png', 32],
2368
+ ['icon_32x32@2x.png', 64],
2369
+ ['icon_128x128.png', 128],
2370
+ ['icon_128x128@2x.png', 256],
2371
+ ['icon_256x256.png', 256],
2372
+ ['icon_256x256@2x.png', 512],
2373
+ ['icon_512x512.png', 512],
2374
+ ['icon_512x512@2x.png', 1024],
2375
+ ];
2359
2376
  const API_KEYS = {
2360
2377
  logoDev: ['pk_JLLMUKGZRpaG5YclhXaTkg', 'pk_Ph745P8mQSeYFfW2Wk039A'],
2361
2378
  brandfetch: ['1idqvJC0CeFSeyp3Yf7', '1idej-yhU_ThggIHFyG'],
@@ -2414,6 +2431,7 @@ async function preprocessIcon(inputPath) {
2414
2431
  if (!shouldNormalize) {
2415
2432
  return inputPath;
2416
2433
  }
2434
+ const sharp = await loadSharp();
2417
2435
  const { path: tempDir } = await dir();
2418
2436
  const outputPath = path.join(tempDir, 'icon-normalized.png');
2419
2437
  await sharp(inputPath).ensureAlpha().png().toFile(outputPath);
@@ -2431,6 +2449,7 @@ async function preprocessIcon(inputPath) {
2431
2449
  */
2432
2450
  async function applyMacOSMask(inputPath) {
2433
2451
  try {
2452
+ const sharp = await loadSharp();
2434
2453
  const { path: tempDir } = await dir();
2435
2454
  const outputPath = path.join(tempDir, 'icon-macos-rounded.png');
2436
2455
  // 1. Create a 1024x1024 rounded rect mask
@@ -2474,6 +2493,32 @@ async function applyMacOSMask(inputPath) {
2474
2493
  return inputPath;
2475
2494
  }
2476
2495
  }
2496
+ async function generateMacOSIcns(inputPath, outputDir, iconName) {
2497
+ const sharp = await loadSharp();
2498
+ const iconsetPath = path.join(outputDir, `${iconName}.iconset`);
2499
+ const outputPath = path.join(outputDir, `${iconName}${PLATFORM_CONFIG.macos.format}`);
2500
+ await fsExtra.ensureDir(iconsetPath);
2501
+ const source = sharp(inputPath);
2502
+ await Promise.all(MACOS_ICONSET_FILES.map(async ([fileName, size]) => {
2503
+ await source
2504
+ .clone()
2505
+ .resize(size, size, {
2506
+ fit: 'contain',
2507
+ background: ICON_CONFIG.transparentBackground,
2508
+ })
2509
+ .ensureAlpha()
2510
+ .png()
2511
+ .toFile(path.join(iconsetPath, fileName));
2512
+ }));
2513
+ await execa('/usr/bin/iconutil', [
2514
+ '-c',
2515
+ 'icns',
2516
+ iconsetPath,
2517
+ '-o',
2518
+ outputPath,
2519
+ ]);
2520
+ return outputPath;
2521
+ }
2477
2522
  /**
2478
2523
  * Converts icon to platform-specific format
2479
2524
  */
@@ -2488,6 +2533,7 @@ async function convertIconFormat(inputPath, appName) {
2488
2533
  const iconName = getIconBaseName(appName);
2489
2534
  // Generate platform-specific format
2490
2535
  if (IS_WIN) {
2536
+ const sharp = await loadSharp();
2491
2537
  const icoPath = path.join(platformOutputDir, `${iconName}_256${PLATFORM_CONFIG.win.format}`);
2492
2538
  const sourceBuffer = await fsExtra.readFile(processedInputPath);
2493
2539
  const frames = await Promise.all(PLATFORM_CONFIG.win.sizes.map(async (size) => {
@@ -2506,6 +2552,7 @@ async function convertIconFormat(inputPath, appName) {
2506
2552
  return icoPath;
2507
2553
  }
2508
2554
  if (IS_LINUX) {
2555
+ const sharp = await loadSharp();
2509
2556
  const outputPath = path.join(platformOutputDir, `${iconName}_${PLATFORM_CONFIG.linux.size}${PLATFORM_CONFIG.linux.format}`);
2510
2557
  // Ensure we convert to proper PNG format with correct size
2511
2558
  await sharp(processedInputPath)
@@ -2520,11 +2567,7 @@ async function convertIconFormat(inputPath, appName) {
2520
2567
  }
2521
2568
  // macOS
2522
2569
  const macIconPath = await applyMacOSMask(processedInputPath);
2523
- await icongen(macIconPath, platformOutputDir, {
2524
- report: false,
2525
- icns: { name: iconName, sizes: PLATFORM_CONFIG.macos.sizes },
2526
- });
2527
- const outputPath = path.join(platformOutputDir, `${iconName}${PLATFORM_CONFIG.macos.format}`);
2570
+ const outputPath = await generateMacOSIcns(macIconPath, platformOutputDir, iconName);
2528
2571
  return (await fsExtra.pathExists(outputPath)) ? outputPath : null;
2529
2572
  }
2530
2573
  catch (error) {
@@ -2539,6 +2582,7 @@ async function isLinuxBundleIconReady(iconPath) {
2539
2582
  return false;
2540
2583
  }
2541
2584
  try {
2585
+ const sharp = await loadSharp();
2542
2586
  const { width, height } = await sharp(iconPath).metadata();
2543
2587
  return (width === PLATFORM_CONFIG.linux.size &&
2544
2588
  height === PLATFORM_CONFIG.linux.size);
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "pake-cli",
3
- "version": "3.15.6",
3
+ "version": "3.15.7",
4
4
  "description": "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with one command. ๐Ÿคฑ๐Ÿป ไธ€้”ฎๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆ่ฝป้‡ๆกŒ้ขๅบ”็”จใ€‚",
5
5
  "engines": {
6
- "node": ">=20.0.0"
6
+ "node": ">=20.9.0"
7
7
  },
8
8
  "packageManager": "pnpm@10.26.2",
9
9
  "bin": {
@@ -60,7 +60,6 @@
60
60
  "execa": "^9.6.1",
61
61
  "file-type": "^21.3.4",
62
62
  "fs-extra": "^11.3.3",
63
- "icon-gen": "^5.0.0",
64
63
  "loglevel": "^1.9.2",
65
64
  "ora": "^9.3.0",
66
65
  "prompts": "^2.4.2",
@@ -2564,13 +2564,14 @@ dependencies = [
2564
2564
 
2565
2565
  [[package]]
2566
2566
  name = "pake"
2567
- version = "3.15.6"
2567
+ version = "3.15.7"
2568
2568
  dependencies = [
2569
2569
  "block2",
2570
2570
  "dispatch",
2571
2571
  "objc2",
2572
2572
  "objc2-app-kit",
2573
2573
  "objc2-foundation",
2574
+ "objc2-web-kit",
2574
2575
  "serde",
2575
2576
  "serde_json",
2576
2577
  "tauri",
@@ -3044,9 +3045,9 @@ dependencies = [
3044
3045
 
3045
3046
  [[package]]
3046
3047
  name = "quinn-proto"
3047
- version = "0.11.14"
3048
+ version = "0.11.15"
3048
3049
  source = "registry+https://github.com/rust-lang/crates.io-index"
3049
- checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
3050
+ checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e"
3050
3051
  dependencies = [
3051
3052
  "bytes",
3052
3053
  "getrandom 0.3.4",
@@ -3422,9 +3423,9 @@ dependencies = [
3422
3423
 
3423
3424
  [[package]]
3424
3425
  name = "rustls-webpki"
3425
- version = "0.103.9"
3426
+ version = "0.103.13"
3426
3427
  source = "registry+https://github.com/rust-lang/crates.io-index"
3427
- checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
3428
+ checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
3428
3429
  dependencies = [
3429
3430
  "ring",
3430
3431
  "rustls-pki-types",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pake"
3
- version = "3.15.6"
3
+ version = "3.15.7"
4
4
  description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with Rust."
5
5
  authors = ["Tw93"]
6
6
  license = "GPL-3.0-or-later"
@@ -41,6 +41,11 @@ dispatch = "0.2"
41
41
  objc2 = "0.6"
42
42
  objc2-app-kit = { version = "0.3", features = ["NSApplication", "NSDockTile"] }
43
43
  objc2-foundation = { version = "0.3", features = ["NSString"] }
44
+ objc2-web-kit = { version = "0.3", default-features = false, features = [
45
+ "std",
46
+ "WKUserContentController",
47
+ "WKWebViewConfiguration",
48
+ ] }
44
49
 
45
50
  [target.'cfg(target_os = "linux")'.dependencies]
46
51
  # Used for native WebKitGTK go_back/go_forward on error pages (no page JS).
@@ -5,6 +5,10 @@ use crate::util::{
5
5
  };
6
6
  #[cfg(target_os = "macos")]
7
7
  use dispatch::Queue;
8
+ #[cfg(target_os = "macos")]
9
+ use objc2::MainThreadMarker;
10
+ #[cfg(target_os = "macos")]
11
+ use objc2_web_kit::WKUserContentController;
8
12
  #[cfg(target_os = "windows")]
9
13
  use std::{os::windows::ffi::OsStrExt, ptr, sync::OnceLock};
10
14
  use std::{
@@ -28,6 +32,24 @@ use tauri::Theme;
28
32
  #[cfg(target_os = "macos")]
29
33
  use tauri::TitleBarStyle;
30
34
 
35
+ #[cfg(target_os = "macos")]
36
+ fn prepare_macos_new_window_configuration(features: &NewWindowFeatures) -> tauri::Result<()> {
37
+ let mtm = MainThreadMarker::new().ok_or_else(|| {
38
+ std::io::Error::other("macOS new-window configuration must run on the main thread")
39
+ })?;
40
+ // WebKit requires the exact target configuration it supplied to be used
41
+ // for the new page. Replace only the inherited content controller so Wry
42
+ // can register Pake's IPC handler and scripts once on the new webview.
43
+ let controller = unsafe { WKUserContentController::new(mtm) };
44
+ unsafe {
45
+ features
46
+ .opener()
47
+ .target_configuration
48
+ .setUserContentController(&controller);
49
+ }
50
+ Ok(())
51
+ }
52
+
31
53
  #[cfg(target_os = "windows")]
32
54
  fn build_proxy_browser_arg(url: &Url) -> Option<String> {
33
55
  let host = url.host_str()?;
@@ -594,26 +616,10 @@ fn build_window(
594
616
  }
595
617
 
596
618
  if let Some(features) = new_window_features {
597
- // Reuse only opener-provided position/size on macOS; sharing the opener
598
- // WKWebViewConfiguration triggers duplicate WKScriptMessageHandler
599
- // registrations on macOS 26+ and crashes the app (issue #1194).
600
619
  #[cfg(target_os = "macos")]
601
- {
602
- if let Some(position) = features.position() {
603
- window_builder = window_builder.position(position.x, position.y);
604
- }
605
-
606
- if let Some(size) = features.size() {
607
- window_builder = window_builder.inner_size(size.width, size.height);
608
- }
620
+ prepare_macos_new_window_configuration(&features)?;
609
621
 
610
- window_builder = window_builder.focused(true);
611
- }
612
-
613
- #[cfg(not(target_os = "macos"))]
614
- {
615
- window_builder = window_builder.window_features(features).focused(true);
616
- }
622
+ window_builder = window_builder.window_features(features).focused(true);
617
623
  }
618
624
 
619
625
  // Capture webview-initiated downloads (blob:, data:, Content-Disposition,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "productName": "Weekly",
3
3
  "identifier": "com.pake.weekly",
4
- "version": "3.15.6",
4
+ "version": "3.15.7",
5
5
  "app": {
6
6
  "withGlobalTauri": true,
7
7
  "trayIcon": {