pake-cli 3.11.3 → 3.11.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 CHANGED
@@ -10,9 +10,6 @@ import os from 'os';
10
10
  import { execa, execaSync } from 'execa';
11
11
  import crypto from 'crypto';
12
12
  import ora from 'ora';
13
- import dns from 'dns';
14
- import http from 'http';
15
- import { promisify } from 'util';
16
13
  import fs from 'fs/promises';
17
14
  import { dir } from 'tmp-promise';
18
15
  import { fileTypeFromBuffer } from 'file-type';
@@ -23,18 +20,18 @@ import { InvalidArgumentError, program as program$1, Option } from 'commander';
23
20
  import fs$1 from 'fs';
24
21
 
25
22
  var name = "pake-cli";
26
- var version = "3.11.3";
23
+ var version = "3.11.4";
27
24
  var description = "🤱🏻 Turn any webpage into a desktop app with one command. 🤱🏻 一键打包网页生成轻量桌面应用。";
28
25
  var engines = {
29
26
  node: ">=18.0.0"
30
27
  };
31
28
  var packageManager = "pnpm@10.26.2";
32
29
  var bin = {
33
- pake: "./dist/cli.js"
30
+ pake: "dist/cli.js"
34
31
  };
35
32
  var repository = {
36
33
  type: "git",
37
- url: "https://github.com/tw93/pake.git"
34
+ url: "git+https://github.com/tw93/pake.git"
38
35
  };
39
36
  var author = {
40
37
  name: "Tw93",
@@ -220,6 +217,12 @@ function getSpinner(text) {
220
217
  }).start();
221
218
  }
222
219
 
220
+ const TRUE_VALUES = new Set(['1', 'true', 'yes', 'on']);
221
+ const CN_MIRROR_ENV = 'PAKE_USE_CN_MIRROR';
222
+ function isCnMirrorEnabled(value = process.env[CN_MIRROR_ENV]) {
223
+ return TRUE_VALUES.has((value ?? '').trim().toLowerCase());
224
+ }
225
+
223
226
  const { platform: platform$1 } = process;
224
227
  const IS_MAC = platform$1 === 'darwin';
225
228
  const IS_WIN = platform$1 === 'win32';
@@ -279,69 +282,6 @@ async function shellExec(command, timeout = 300000, env) {
279
282
  }
280
283
  }
281
284
 
282
- const logger = {
283
- info(...msg) {
284
- log.info(...msg.map((m) => chalk.white(m)));
285
- },
286
- debug(...msg) {
287
- log.debug(...msg);
288
- },
289
- error(...msg) {
290
- log.error(...msg.map((m) => chalk.red(m)));
291
- },
292
- warn(...msg) {
293
- log.warn(...msg.map((m) => chalk.yellow(m)));
294
- },
295
- success(...msg) {
296
- log.info(...msg.map((m) => chalk.green(m)));
297
- },
298
- };
299
-
300
- const resolve = promisify(dns.resolve);
301
- const ping = async (host) => {
302
- const lookup = promisify(dns.lookup);
303
- const ip = await lookup(host);
304
- const start = new Date();
305
- // Prevent timeouts from affecting user experience.
306
- const requestPromise = new Promise((resolve, reject) => {
307
- const req = http.get(`http://${ip.address}`, (res) => {
308
- const delay = new Date().getTime() - start.getTime();
309
- res.resume();
310
- resolve(delay);
311
- });
312
- req.on('error', (err) => {
313
- reject(err);
314
- });
315
- });
316
- const timeoutPromise = new Promise((_, reject) => {
317
- setTimeout(() => {
318
- reject(new Error('Request timed out after 3 seconds'));
319
- }, 1000);
320
- });
321
- return Promise.race([requestPromise, timeoutPromise]);
322
- };
323
- async function isChinaDomain(domain) {
324
- try {
325
- const [ip] = await resolve(domain);
326
- return await isChinaIP(ip, domain);
327
- }
328
- catch (error) {
329
- logger.debug(`${domain} can't be parse!`);
330
- return true;
331
- }
332
- }
333
- async function isChinaIP(ip, domain) {
334
- try {
335
- const delay = await ping(ip);
336
- logger.debug(`${domain} latency is ${delay} ms`);
337
- return delay > 1000;
338
- }
339
- catch (error) {
340
- logger.debug(`ping ${domain} failed!`);
341
- return true;
342
- }
343
- }
344
-
345
285
  function normalizePathForComparison(targetPath) {
346
286
  const normalized = path.normalize(targetPath);
347
287
  return IS_WIN ? normalized.toLowerCase() : normalized;
@@ -389,15 +329,13 @@ function ensureRustEnv() {
389
329
  ensureCargoBinOnPath();
390
330
  }
391
331
  async function installRust() {
392
- const isActions = process.env.GITHUB_ACTIONS;
393
- const isInChina = await isChinaDomain('sh.rustup.rs');
394
- const rustInstallScriptForMac = isInChina && !isActions
332
+ const rustInstallScriptForUnix = isCnMirrorEnabled()
395
333
  ? 'export RUSTUP_DIST_SERVER="https://rsproxy.cn" && export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup" && curl --proto "=https" --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh'
396
334
  : "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y";
397
335
  const rustInstallScriptForWindows = 'winget install --id Rustlang.Rustup';
398
336
  const spinner = getSpinner('Downloading Rust...');
399
337
  try {
400
- await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForMac, 300000, undefined);
338
+ await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForUnix, 300000, undefined);
401
339
  spinner.succeed(chalk.green('✔ Rust installed successfully!'));
402
340
  ensureRustEnv();
403
341
  }
@@ -443,6 +381,24 @@ async function combineFiles(files, output) {
443
381
  return files;
444
382
  }
445
383
 
384
+ const logger = {
385
+ info(...msg) {
386
+ log.info(...msg.map((m) => chalk.white(m)));
387
+ },
388
+ debug(...msg) {
389
+ log.debug(...msg);
390
+ },
391
+ error(...msg) {
392
+ log.error(...msg.map((m) => chalk.red(m)));
393
+ },
394
+ warn(...msg) {
395
+ log.warn(...msg.map((m) => chalk.yellow(m)));
396
+ },
397
+ success(...msg) {
398
+ log.info(...msg.map((m) => chalk.green(m)));
399
+ },
400
+ };
401
+
446
402
  function generateSafeFilename(name) {
447
403
  return name
448
404
  .replace(/[<>:"/\\|?*]/g, '_')
@@ -873,6 +829,40 @@ class BaseBuilder {
873
829
  throw error;
874
830
  }
875
831
  }
832
+ getInstallCommand(packageManager, useCnMirror) {
833
+ const registryOption = useCnMirror
834
+ ? ' --registry=https://registry.npmmirror.com'
835
+ : '';
836
+ const peerDepsOption = packageManager === 'npm' ? ' --legacy-peer-deps' : '';
837
+ return `cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`;
838
+ }
839
+ isGeneratedCnMirrorConfig(projectConfig, cnMirrorConfig) {
840
+ return projectConfig.trim() === cnMirrorConfig.trim();
841
+ }
842
+ async configureCargoRegistry(tauriSrcPath, useCnMirror) {
843
+ const rustProjectDir = path.join(tauriSrcPath, '.cargo');
844
+ const projectConf = path.join(rustProjectDir, 'config.toml');
845
+ const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
846
+ if (useCnMirror) {
847
+ await fsExtra.ensureDir(rustProjectDir);
848
+ await this.copyFileWithSamePathGuard(projectCnConf, projectConf);
849
+ return;
850
+ }
851
+ if (!(await fsExtra.pathExists(projectConf))) {
852
+ return;
853
+ }
854
+ const [projectConfig, cnMirrorConfig] = await Promise.all([
855
+ fsExtra.readFile(projectConf, 'utf8'),
856
+ fsExtra.readFile(projectCnConf, 'utf8'),
857
+ ]);
858
+ if (this.isGeneratedCnMirrorConfig(projectConfig, cnMirrorConfig)) {
859
+ await fsExtra.remove(projectConf);
860
+ return;
861
+ }
862
+ if (projectConfig.includes('rsproxy.cn')) {
863
+ logger.warn(`✼ ${projectConf} still references rsproxy.cn. Remove it or set ${CN_MIRROR_ENV}=1 if you want to use the CN mirror.`);
864
+ }
865
+ }
876
866
  async prepare() {
877
867
  const tauriSrcPath = path.join(npmDirectory, 'src-tauri');
878
868
  const tauriTargetPath = path.join(tauriSrcPath, 'target');
@@ -896,15 +886,11 @@ class BaseBuilder {
896
886
  process.exit(1);
897
887
  }
898
888
  }
899
- const isChina = await isChinaDomain('www.npmjs.com');
900
889
  const spinner = getSpinner('Installing package...');
901
- const rustProjectDir = path.join(tauriSrcPath, '.cargo');
902
- const projectConf = path.join(rustProjectDir, 'config.toml');
903
- await fsExtra.ensureDir(rustProjectDir);
890
+ const useCnMirror = isCnMirrorEnabled();
891
+ await this.configureCargoRegistry(tauriSrcPath, useCnMirror);
904
892
  // Detect available package manager
905
893
  const packageManager = await this.detectPackageManager();
906
- const registryOption = ' --registry=https://registry.npmmirror.com';
907
- const peerDepsOption = packageManager === 'npm' ? ' --legacy-peer-deps' : '';
908
894
  const timeout = this.getInstallTimeout();
909
895
  const buildEnv = this.getBuildEnvironment();
910
896
  // Show helpful message for first-time users
@@ -913,43 +899,22 @@ class BaseBuilder {
913
899
  ? '✺ First-time setup may take 10-15 minutes on Windows (compiling dependencies)...'
914
900
  : '✺ First-time setup may take 5-10 minutes (installing dependencies)...');
915
901
  }
916
- let usedMirror = isChina;
902
+ if (useCnMirror) {
903
+ logger.info(`✺ ${CN_MIRROR_ENV}=1 detected, using ${packageManager}/rsProxy CN mirror.`);
904
+ }
917
905
  try {
918
- if (isChina) {
919
- logger.info(`✺ Located in China, using ${packageManager}/rsProxy CN mirror.`);
920
- const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
921
- await this.copyFileWithSamePathGuard(projectCnConf, projectConf);
922
- await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, { ...buildEnv, CI: 'true' });
923
- }
924
- else {
925
- await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption}`, timeout, { ...buildEnv, CI: 'true' });
926
- }
906
+ await shellExec(this.getInstallCommand(packageManager, useCnMirror), timeout, {
907
+ ...buildEnv,
908
+ CI: 'true',
909
+ });
927
910
  spinner.succeed(chalk.green('Package installed!'));
928
911
  }
929
912
  catch (error) {
930
- // If installation times out and we haven't tried the mirror yet, retry with mirror
931
- if (error instanceof Error &&
932
- error.message.includes('timed out') &&
933
- !usedMirror) {
934
- spinner.fail(chalk.yellow('Installation timed out, retrying with CN mirror...'));
935
- logger.info('✺ Retrying installation with CN mirror for better speed...');
936
- const retrySpinner = getSpinner('Retrying installation...');
937
- usedMirror = true;
938
- try {
939
- const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
940
- await this.copyFileWithSamePathGuard(projectCnConf, projectConf);
941
- await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption}`, timeout, { ...buildEnv, CI: 'true' });
942
- retrySpinner.succeed(chalk.green('Package installed with CN mirror!'));
943
- }
944
- catch (retryError) {
945
- retrySpinner.fail(chalk.red('Installation failed'));
946
- throw retryError;
947
- }
948
- }
949
- else {
950
- spinner.fail(chalk.red('Installation failed'));
951
- throw error;
913
+ spinner.fail(chalk.red('Installation failed'));
914
+ if (!useCnMirror) {
915
+ logger.info(`✺ If downloads are slow in China, retry with ${CN_MIRROR_ENV}=1 to use CN mirrors.`);
952
916
  }
917
+ throw error;
953
918
  }
954
919
  if (!tauriTargetPathExists) {
955
920
  logger.warn('✼ The first packaging may be slow, please be patient and wait, it will be faster afterwards.');
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "pake-cli",
3
- "version": "3.11.3",
3
+ "version": "3.11.4",
4
4
  "description": "🤱🏻 Turn any webpage into a desktop app with one command. 🤱🏻 一键打包网页生成轻量桌面应用。",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
7
7
  },
8
8
  "packageManager": "pnpm@10.26.2",
9
9
  "bin": {
10
- "pake": "./dist/cli.js"
10
+ "pake": "dist/cli.js"
11
11
  },
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "https://github.com/tw93/pake.git"
14
+ "url": "git+https://github.com/tw93/pake.git"
15
15
  },
16
16
  "author": {
17
17
  "name": "Tw93",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "pake"
3
- version = "3.11.3"
3
+ version = "3.11.4"
4
4
  description = "🤱🏻 Turn any webpage into a desktop app with Rust."
5
5
  authors = ["Tw93"]
6
6
  license = "MIT"
@@ -27,6 +27,9 @@ pub fn run_app() {
27
27
  if std::env::var("WEBKIT_DISABLE_DMABUF_RENDERER").is_err() {
28
28
  std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
29
29
  }
30
+ if std::env::var("WEBKIT_DISABLE_COMPOSITING_MODE").is_err() {
31
+ std::env::set_var("WEBKIT_DISABLE_COMPOSITING_MODE", "1");
32
+ }
30
33
  }
31
34
 
32
35
  let (pake_config, tauri_config) = get_pake_config();
@@ -1,6 +1,6 @@
1
1
  use crate::app::config::PakeConfig;
2
2
  use std::env;
3
- use std::path::PathBuf;
3
+ use std::path::{Path, PathBuf};
4
4
  use tauri::{AppHandle, Config, Manager, WebviewWindow};
5
5
 
6
6
  pub fn get_pake_config() -> (PakeConfig, Config) {
@@ -107,9 +107,14 @@ pub fn check_file_or_append(file_path: &str) -> String {
107
107
  let mut counter = 0;
108
108
 
109
109
  while new_path.exists() {
110
- let file_stem = new_path.file_stem().unwrap().to_string_lossy().to_string();
111
- let extension = new_path.extension().unwrap().to_string_lossy().to_string();
112
- let parent_dir = new_path.parent().unwrap();
110
+ let file_stem = new_path
111
+ .file_stem()
112
+ .map(|s| s.to_string_lossy().to_string())
113
+ .unwrap_or_default();
114
+ let extension = new_path
115
+ .extension()
116
+ .map(|e| e.to_string_lossy().to_string());
117
+ let parent_dir = new_path.parent().unwrap_or(Path::new(""));
113
118
 
114
119
  let new_file_stem = match file_stem.rfind('-') {
115
120
  Some(index) if file_stem[index + 1..].parse::<u32>().is_ok() => {
@@ -123,7 +128,10 @@ pub fn check_file_or_append(file_path: &str) -> String {
123
128
  }
124
129
  };
125
130
 
126
- new_path = parent_dir.join(format!("{new_file_stem}.{extension}"));
131
+ new_path = match &extension {
132
+ Some(ext) => parent_dir.join(format!("{new_file_stem}.{ext}")),
133
+ None => parent_dir.join(new_file_stem),
134
+ };
127
135
  }
128
136
 
129
137
  new_path.to_string_lossy().into_owned()
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "productName": "Weekly",
3
3
  "identifier": "com.pake.weekly",
4
- "version": "3.11.3",
4
+ "version": "3.11.4",
5
5
  "app": {
6
6
  "withGlobalTauri": true,
7
7
  "trayIcon": {
@@ -1 +0,0 @@
1
- <html><body><h1>Hello Pake</h1></body></html>
@@ -1,10 +0,0 @@
1
- [source.crates-io]
2
- replace-with = 'rsproxy-sparse'
3
- [source.rsproxy]
4
- registry = "https://rsproxy.cn/crates.io-index"
5
- [source.rsproxy-sparse]
6
- registry = "sparse+https://rsproxy.cn/index/"
7
- [registries.rsproxy]
8
- index = "https://rsproxy.cn/crates.io-index"
9
- [net]
10
- git-fetch-with-cli = true