pake-cli 3.2.16 → 3.2.18

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
@@ -22,11 +22,12 @@ import sharp from 'sharp';
22
22
  import * as psl from 'psl';
23
23
 
24
24
  var name = "pake-cli";
25
- var version = "3.2.16";
25
+ var version = "3.2.18";
26
26
  var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 利用 Rust 轻松构建轻量级多端桌面应用。";
27
27
  var engines = {
28
- node: ">=16.0.0"
28
+ node: ">=18.0.0"
29
29
  };
30
+ var packageManager = "pnpm@10.15.0";
30
31
  var bin = {
31
32
  pake: "./dist/cli.js"
32
33
  };
@@ -51,29 +52,31 @@ var files = [
51
52
  "src-tauri"
52
53
  ];
53
54
  var scripts = {
54
- start: "npm run dev",
55
- dev: "npm run tauri dev",
56
- build: "npm run tauri build --",
57
- "build:debug": "npm run tauri build -- --debug",
58
- "build:mac": "npm run tauri build -- --target universal-apple-darwin",
55
+ start: "pnpm run dev",
56
+ dev: "pnpm run tauri dev",
57
+ build: "tauri build",
58
+ "build:debug": "tauri build --debug",
59
+ "build:mac": "tauri build --target universal-apple-darwin",
59
60
  "build:config": "chmod +x scripts/configure-tauri.mjs && node scripts/configure-tauri.mjs",
60
61
  analyze: "cd src-tauri && cargo bloat --release --crates",
61
62
  tauri: "tauri",
62
63
  cli: "cross-env NODE_ENV=development rollup -c -w",
63
64
  "cli:build": "cross-env NODE_ENV=production rollup -c",
64
- test: "npm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
65
+ test: "pnpm run cli:build && cross-env PAKE_CREATE_APP=1 node tests/index.js",
65
66
  format: "prettier --write . --ignore-unknown && find tests -name '*.js' -exec sed -i '' 's/[[:space:]]*$//' {} \\; && cd src-tauri && cargo fmt --verbose",
66
- prepublishOnly: "npm run cli:build"
67
+ "format:check": "prettier --check . --ignore-unknown",
68
+ update: "pnpm update --verbose && cd src-tauri && cargo update",
69
+ prepublishOnly: "pnpm run cli:build"
67
70
  };
68
71
  var type = "module";
69
72
  var exports = "./dist/cli.js";
70
73
  var license = "MIT";
71
74
  var dependencies = {
72
75
  "@tauri-apps/api": "^2.8.0",
73
- "@tauri-apps/cli": "^2.8.1",
76
+ "@tauri-apps/cli": "^2.8.3",
74
77
  axios: "^1.11.0",
75
78
  chalk: "^5.6.0",
76
- commander: "^11.1.0",
79
+ commander: "^12.1.0",
77
80
  execa: "^9.6.0",
78
81
  "file-type": "^18.7.0",
79
82
  "fs-extra": "^11.3.1",
@@ -82,7 +85,7 @@ var dependencies = {
82
85
  ora: "^8.2.0",
83
86
  prompts: "^2.4.2",
84
87
  psl: "^1.15.0",
85
- sharp: "^0.33.5",
88
+ sharp: "^0.34.3",
86
89
  "tmp-promise": "^3.0.3",
87
90
  "update-notifier": "^7.3.1"
88
91
  };
@@ -101,7 +104,7 @@ var devDependencies = {
101
104
  "app-root-path": "^3.1.0",
102
105
  "cross-env": "^7.0.3",
103
106
  prettier: "^3.6.2",
104
- rollup: "^4.46.3",
107
+ rollup: "^4.49.0",
105
108
  "rollup-plugin-typescript2": "^0.36.0",
106
109
  tslib: "^2.8.1",
107
110
  typescript: "^5.9.2"
@@ -111,6 +114,7 @@ var packageJson = {
111
114
  version: version,
112
115
  description: description,
113
116
  engines: engines,
117
+ packageManager: packageManager,
114
118
  bin: bin,
115
119
  repository: repository,
116
120
  author: author,
@@ -344,8 +348,10 @@ async function mergeConfig(url, options, tauriConf) {
344
348
  await fsExtra.copy(sourcePath, destPath);
345
349
  }
346
350
  }));
347
- const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, } = options;
351
+ const { width, height, fullscreen, hideTitleBar, alwaysOnTop, appVersion, darkMode, disabledWebShortcuts, activationShortcut, userAgent, showSystemTray, systemTrayIcon, useLocalFile, identifier, name, resizable = true, inject, proxyUrl, installerLanguage, hideOnClose, incognito, title, wasm, enableDragDrop, } = options;
348
352
  const { platform } = process;
353
+ // Platform-specific hide_on_close behavior: macOS keeps true, others default to false
354
+ const platformHideOnClose = hideOnClose ?? platform === 'darwin';
349
355
  // Set Windows parameters.
350
356
  const tauriConfWindowOptions = {
351
357
  width,
@@ -357,9 +363,11 @@ async function mergeConfig(url, options, tauriConf) {
357
363
  always_on_top: alwaysOnTop,
358
364
  dark_mode: darkMode,
359
365
  disabled_web_shortcuts: disabledWebShortcuts,
360
- hide_on_close: hideOnClose,
366
+ hide_on_close: platformHideOnClose,
361
367
  incognito: incognito,
362
368
  title: title || null,
369
+ enable_wasm: wasm,
370
+ enable_drag_drop: enableDragDrop,
363
371
  };
364
372
  Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });
365
373
  tauriConf.productName = name;
@@ -540,11 +548,13 @@ StartupNotify=true
540
548
  const injectFilePath = path.join(npmDirectory, `src-tauri/src/inject/custom.js`);
541
549
  // inject js or css files
542
550
  if (inject?.length > 0) {
543
- if (!inject.every((item) => item.endsWith('.css') || item.endsWith('.js'))) {
551
+ // Ensure inject is an array before calling .every()
552
+ const injectArray = Array.isArray(inject) ? inject : [inject];
553
+ if (!injectArray.every((item) => item.endsWith('.css') || item.endsWith('.js'))) {
544
554
  logger.error('The injected file must be in either CSS or JS format.');
545
555
  return;
546
556
  }
547
- const files = inject.map((filepath) => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath));
557
+ const files = injectArray.map((filepath) => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath));
548
558
  tauriConf.pake.inject = files;
549
559
  await combineFiles(files, injectFilePath);
550
560
  }
@@ -553,6 +563,15 @@ StartupNotify=true
553
563
  await fsExtra.writeFile(injectFilePath, '');
554
564
  }
555
565
  tauriConf.pake.proxy_url = proxyUrl || '';
566
+ // Configure WASM support with required HTTP headers
567
+ if (wasm) {
568
+ tauriConf.app.security = {
569
+ headers: {
570
+ 'Cross-Origin-Opener-Policy': 'same-origin',
571
+ 'Cross-Origin-Embedder-Policy': 'require-corp',
572
+ },
573
+ };
574
+ }
556
575
  // Save config file.
557
576
  const platformConfigPaths = {
558
577
  win32: 'tauri.windows.conf.json',
@@ -589,6 +608,32 @@ class BaseBuilder {
589
608
  getBuildTimeout() {
590
609
  return 900000; // 15 minutes for all builds
591
610
  }
611
+ async detectPackageManager() {
612
+ // 使用缓存避免重复检测
613
+ if (BaseBuilder.packageManagerCache) {
614
+ return BaseBuilder.packageManagerCache;
615
+ }
616
+ const { execa } = await import('execa');
617
+ // 优先使用pnpm(如果可用)
618
+ try {
619
+ await execa('pnpm', ['--version'], { stdio: 'ignore' });
620
+ logger.info('✺ Using pnpm for package management.');
621
+ BaseBuilder.packageManagerCache = 'pnpm';
622
+ return 'pnpm';
623
+ }
624
+ catch {
625
+ // pnpm不可用,回退到npm
626
+ try {
627
+ await execa('npm', ['--version'], { stdio: 'ignore' });
628
+ logger.info('✺ pnpm not available, using npm for package management.');
629
+ BaseBuilder.packageManagerCache = 'npm';
630
+ return 'npm';
631
+ }
632
+ catch {
633
+ throw new Error('Neither pnpm nor npm is available. Please install a package manager.');
634
+ }
635
+ }
636
+ }
592
637
  async prepare() {
593
638
  const tauriSrcPath = path.join(npmDirectory, 'src-tauri');
594
639
  const tauriTargetPath = path.join(tauriSrcPath, 'target');
@@ -616,22 +661,23 @@ class BaseBuilder {
616
661
  const rustProjectDir = path.join(tauriSrcPath, '.cargo');
617
662
  const projectConf = path.join(rustProjectDir, 'config.toml');
618
663
  await fsExtra.ensureDir(rustProjectDir);
619
- // 统一使用npm,简单可靠
620
- const packageManager = 'npm';
664
+ // 智能检测可用的包管理器
665
+ const packageManager = await this.detectPackageManager();
621
666
  const registryOption = isChina
622
667
  ? ' --registry=https://registry.npmmirror.com'
623
668
  : '';
624
- const legacyPeerDeps = ' --legacy-peer-deps'; // 解决dependency conflicts
669
+ // 根据包管理器类型设置依赖冲突解决选项
670
+ const peerDepsOption = packageManager === 'npm' ? ' --legacy-peer-deps' : '';
625
671
  const timeout = this.getInstallTimeout();
626
672
  const buildEnv = this.getBuildEnvironment();
627
673
  if (isChina) {
628
- logger.info('✺ Located in China, using npm/rsProxy CN mirror.');
674
+ logger.info(`✺ Located in China, using ${packageManager}/rsProxy CN mirror.`);
629
675
  const projectCnConf = path.join(tauriSrcPath, 'rust_proxy.toml');
630
676
  await fsExtra.copy(projectCnConf, projectConf);
631
- await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${legacyPeerDeps} --silent`, timeout, buildEnv);
677
+ await shellExec(`cd "${npmDirectory}" && ${packageManager} install${registryOption}${peerDepsOption} --silent`, timeout, buildEnv);
632
678
  }
633
679
  else {
634
- await shellExec(`cd "${npmDirectory}" && ${packageManager} install${legacyPeerDeps} --silent`, timeout, buildEnv);
680
+ await shellExec(`cd "${npmDirectory}" && ${packageManager} install${peerDepsOption} --silent`, timeout, buildEnv);
635
681
  }
636
682
  spinner.succeed(chalk.green('Package installed!'));
637
683
  if (!tauriTargetPathExists) {
@@ -647,15 +693,17 @@ class BaseBuilder {
647
693
  async buildAndCopy(url, target) {
648
694
  const { name } = this.options;
649
695
  await mergeConfig(url, this.options, tauriConfig);
696
+ // Detect available package manager
697
+ const packageManager = await this.detectPackageManager();
650
698
  // Build app
651
699
  const buildSpinner = getSpinner('Building app...');
652
- // Let spinner run for a moment so user can see it, then stop before npm command
700
+ // Let spinner run for a moment so user can see it, then stop before package manager command
653
701
  await new Promise((resolve) => setTimeout(resolve, 500));
654
702
  buildSpinner.stop();
655
703
  // Show static message to keep the status visible
656
704
  logger.warn('✸ Building app...');
657
705
  const buildEnv = this.getBuildEnvironment();
658
- await shellExec(`cd "${npmDirectory}" && ${this.getBuildCommand()}`, this.getBuildTimeout(), buildEnv);
706
+ await shellExec(`cd "${npmDirectory}" && ${this.getBuildCommand(packageManager)}`, this.getBuildTimeout(), buildEnv);
659
707
  // Copy app
660
708
  const fileName = this.getFileName();
661
709
  const fileType = this.getFileType(target);
@@ -669,18 +717,48 @@ class BaseBuilder {
669
717
  getFileType(target) {
670
718
  return target;
671
719
  }
672
- getBuildCommand() {
720
+ /**
721
+ * 解析目标架构
722
+ */
723
+ resolveTargetArch(requestedArch) {
724
+ if (requestedArch === 'auto' || !requestedArch) {
725
+ return process.arch;
726
+ }
727
+ return requestedArch;
728
+ }
729
+ /**
730
+ * 获取Tauri构建目标
731
+ */
732
+ getTauriTarget(arch, platform = process.platform) {
733
+ const platformMappings = BaseBuilder.ARCH_MAPPINGS[platform];
734
+ if (!platformMappings)
735
+ return null;
736
+ return platformMappings[arch] || null;
737
+ }
738
+ /**
739
+ * 获取架构显示名称(用于文件名)
740
+ */
741
+ getArchDisplayName(arch) {
742
+ return BaseBuilder.ARCH_DISPLAY_NAMES[arch] || arch;
743
+ }
744
+ /**
745
+ * 构建基础构建命令
746
+ */
747
+ buildBaseCommand(packageManager, configPath, target) {
673
748
  const baseCommand = this.options.debug
674
- ? 'npm run build:debug'
675
- : 'npm run build';
676
- // Use temporary config directory to avoid modifying source files
677
- const configPath = path.join(npmDirectory, 'src-tauri', '.pake', 'tauri.conf.json');
678
- let fullCommand = `${baseCommand} -- -c "${configPath}"`;
679
- // For macOS, use app bundles by default unless DMG is explicitly requested
680
- if (IS_MAC && this.options.targets === 'app') {
681
- fullCommand += ' --bundles app';
749
+ ? `${packageManager} run build:debug`
750
+ : `${packageManager} run build`;
751
+ const argSeparator = packageManager === 'npm' ? ' --' : '';
752
+ let fullCommand = `${baseCommand}${argSeparator} -c "${configPath}"`;
753
+ if (target) {
754
+ fullCommand += ` --target ${target}`;
682
755
  }
683
- // Add features
756
+ return fullCommand;
757
+ }
758
+ /**
759
+ * 获取构建特性列表
760
+ */
761
+ getBuildFeatures() {
684
762
  const features = ['cli-build'];
685
763
  // Add macos-proxy feature for modern macOS (Darwin 23+ = macOS 14+)
686
764
  if (IS_MAC) {
@@ -689,6 +767,18 @@ class BaseBuilder {
689
767
  features.push('macos-proxy');
690
768
  }
691
769
  }
770
+ return features;
771
+ }
772
+ getBuildCommand(packageManager = 'pnpm') {
773
+ // Use temporary config directory to avoid modifying source files
774
+ const configPath = path.join(npmDirectory, 'src-tauri', '.pake', 'tauri.conf.json');
775
+ let fullCommand = this.buildBaseCommand(packageManager, configPath);
776
+ // For macOS, use app bundles by default unless DMG is explicitly requested
777
+ if (IS_MAC && this.options.targets === 'app') {
778
+ fullCommand += ' --bundles app';
779
+ }
780
+ // Add features
781
+ const features = this.getBuildFeatures();
692
782
  if (features.length > 0) {
693
783
  fullCommand += ` --features ${features.join(',')}`;
694
784
  }
@@ -715,12 +805,40 @@ class BaseBuilder {
715
805
  return path.join(npmDirectory, this.getBasePath(), bundleDir, `${fileName}.${fileType}`);
716
806
  }
717
807
  }
808
+ BaseBuilder.packageManagerCache = null;
809
+ // 架构映射配置
810
+ BaseBuilder.ARCH_MAPPINGS = {
811
+ darwin: {
812
+ arm64: 'aarch64-apple-darwin',
813
+ x64: 'x86_64-apple-darwin',
814
+ universal: 'universal-apple-darwin',
815
+ },
816
+ win32: {
817
+ arm64: 'aarch64-pc-windows-msvc',
818
+ x64: 'x86_64-pc-windows-msvc',
819
+ },
820
+ linux: {
821
+ arm64: 'aarch64-unknown-linux-gnu',
822
+ x64: 'x86_64-unknown-linux-gnu',
823
+ },
824
+ };
825
+ // 架构名称映射(用于文件名生成)
826
+ BaseBuilder.ARCH_DISPLAY_NAMES = {
827
+ arm64: 'aarch64',
828
+ x64: 'x64',
829
+ universal: 'universal',
830
+ };
718
831
 
719
832
  class MacBuilder extends BaseBuilder {
720
833
  constructor(options) {
721
834
  super(options);
722
835
  // Store the original targets value for architecture selection
723
- this.buildArch = options.targets || 'auto';
836
+ // For macOS, targets can be architecture names or format names
837
+ // Filter out non-architecture values
838
+ const validArchs = ['intel', 'apple', 'universal', 'auto', 'x64', 'arm64'];
839
+ this.buildArch = validArchs.includes(options.targets || '')
840
+ ? options.targets
841
+ : 'auto';
724
842
  // Use DMG by default for distribution
725
843
  // Only create app bundles for testing to avoid user interaction
726
844
  if (process.env.PAKE_CREATE_APP === '1') {
@@ -751,83 +869,42 @@ class MacBuilder extends BaseBuilder {
751
869
  }
752
870
  else {
753
871
  // Auto-detect based on current architecture
754
- arch = process.arch === 'arm64' ? 'aarch64' : process.arch;
872
+ arch = this.getArchDisplayName(this.resolveTargetArch(this.buildArch));
755
873
  }
756
874
  return `${name}_${tauriConfig.version}_${arch}`;
757
875
  }
758
- getBuildCommand() {
759
- // Determine if we need universal build
760
- const needsUniversal = this.buildArch === 'universal' || this.options.multiArch;
761
- if (needsUniversal) {
762
- const baseCommand = this.options.debug
763
- ? 'npm run tauri build -- --debug'
764
- : 'npm run tauri build --';
765
- // Use temporary config directory to avoid modifying source files
766
- const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
767
- let fullCommand = `${baseCommand} --target universal-apple-darwin -c "${configPath}"`;
768
- // Add features
769
- const features = ['cli-build'];
770
- // Add macos-proxy feature for modern macOS (Darwin 23+ = macOS 14+)
771
- const macOSVersion = this.getMacOSMajorVersion();
772
- if (macOSVersion >= 23) {
773
- features.push('macos-proxy');
774
- }
775
- if (features.length > 0) {
776
- fullCommand += ` --features ${features.join(',')}`;
777
- }
778
- return fullCommand;
876
+ getActualArch() {
877
+ if (this.buildArch === 'universal' || this.options.multiArch) {
878
+ return 'universal';
779
879
  }
780
880
  else if (this.buildArch === 'apple') {
781
- // Build for Apple Silicon only
782
- const baseCommand = this.options.debug
783
- ? 'npm run tauri build -- --debug'
784
- : 'npm run tauri build --';
785
- const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
786
- let fullCommand = `${baseCommand} --target aarch64-apple-darwin -c "${configPath}"`;
787
- // Add features
788
- const features = ['cli-build'];
789
- const macOSVersion = this.getMacOSMajorVersion();
790
- if (macOSVersion >= 23) {
791
- features.push('macos-proxy');
792
- }
793
- if (features.length > 0) {
794
- fullCommand += ` --features ${features.join(',')}`;
795
- }
796
- return fullCommand;
881
+ return 'arm64';
797
882
  }
798
883
  else if (this.buildArch === 'intel') {
799
- // Build for Intel only
800
- const baseCommand = this.options.debug
801
- ? 'npm run tauri build -- --debug'
802
- : 'npm run tauri build --';
803
- const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
804
- let fullCommand = `${baseCommand} --target x86_64-apple-darwin -c "${configPath}"`;
805
- // Add features
806
- const features = ['cli-build'];
807
- const macOSVersion = this.getMacOSMajorVersion();
808
- if (macOSVersion >= 23) {
809
- features.push('macos-proxy');
810
- }
811
- if (features.length > 0) {
812
- fullCommand += ` --features ${features.join(',')}`;
813
- }
814
- return fullCommand;
884
+ return 'x64';
815
885
  }
816
- return super.getBuildCommand();
886
+ return this.resolveTargetArch(this.buildArch);
817
887
  }
818
- getBasePath() {
819
- const needsUniversal = this.buildArch === 'universal' || this.options.multiArch;
820
- const basePath = this.options.debug ? 'debug' : 'release';
821
- if (needsUniversal) {
822
- return `src-tauri/target/universal-apple-darwin/${basePath}/bundle`;
823
- }
824
- else if (this.buildArch === 'apple') {
825
- return `src-tauri/target/aarch64-apple-darwin/${basePath}/bundle`;
888
+ getBuildCommand(packageManager = 'pnpm') {
889
+ const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
890
+ const actualArch = this.getActualArch();
891
+ const buildTarget = this.getTauriTarget(actualArch, 'darwin');
892
+ if (!buildTarget) {
893
+ throw new Error(`Unsupported architecture: ${actualArch} for macOS`);
826
894
  }
827
- else if (this.buildArch === 'intel') {
828
- return `src-tauri/target/x86_64-apple-darwin/${basePath}/bundle`;
895
+ let fullCommand = this.buildBaseCommand(packageManager, configPath, buildTarget);
896
+ // Add features
897
+ const features = this.getBuildFeatures();
898
+ if (features.length > 0) {
899
+ fullCommand += ` --features ${features.join(',')}`;
829
900
  }
830
- return super.getBasePath();
901
+ return fullCommand;
902
+ }
903
+ getBasePath() {
904
+ const basePath = this.options.debug ? 'debug' : 'release';
905
+ const actualArch = this.getActualArch();
906
+ const target = this.getTauriTarget(actualArch, 'darwin');
907
+ return `src-tauri/target/${target}/${basePath}/bundle`;
831
908
  }
832
909
  }
833
910
 
@@ -835,57 +912,29 @@ class WinBuilder extends BaseBuilder {
835
912
  constructor(options) {
836
913
  super(options);
837
914
  this.buildFormat = 'msi';
838
- // Store the original targets value for architecture selection
839
- this.buildArch = options.targets || 'auto';
840
- // Set targets to msi format for Tauri
915
+ // For Windows, targets can be architecture names or format names
916
+ // Filter out non-architecture values
917
+ const validArchs = ['x64', 'arm64', 'auto'];
918
+ this.buildArch = validArchs.includes(options.targets || '')
919
+ ? this.resolveTargetArch(options.targets)
920
+ : this.resolveTargetArch('auto');
841
921
  this.options.targets = this.buildFormat;
842
922
  }
843
923
  getFileName() {
844
924
  const { name } = this.options;
845
925
  const language = tauriConfig.bundle.windows.wix.language[0];
846
- // Determine architecture name based on explicit targets option or auto-detect
847
- let targetArch;
848
- if (this.buildArch === 'arm64') {
849
- targetArch = 'aarch64';
850
- }
851
- else if (this.buildArch === 'x64') {
852
- targetArch = 'x64';
853
- }
854
- else {
855
- // Auto-detect based on current architecture if no explicit target
856
- const archMap = {
857
- x64: 'x64',
858
- arm64: 'aarch64',
859
- };
860
- targetArch = archMap[process.arch] || process.arch;
861
- }
926
+ const targetArch = this.getArchDisplayName(this.buildArch);
862
927
  return `${name}_${tauriConfig.version}_${targetArch}_${language}`;
863
928
  }
864
- getBuildCommand() {
865
- const baseCommand = this.options.debug
866
- ? 'npm run build:debug'
867
- : 'npm run build';
868
- // Use temporary config directory to avoid modifying source files
929
+ getBuildCommand(packageManager = 'pnpm') {
869
930
  const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
870
- let fullCommand = `${baseCommand} -- -c "${configPath}"`;
871
- // Determine build target based on explicit targets option or auto-detect
872
- let buildTarget;
873
- if (this.buildArch === 'arm64') {
874
- buildTarget = 'aarch64-pc-windows-msvc';
875
- }
876
- else if (this.buildArch === 'x64') {
877
- buildTarget = 'x86_64-pc-windows-msvc';
931
+ const buildTarget = this.getTauriTarget(this.buildArch, 'win32');
932
+ if (!buildTarget) {
933
+ throw new Error(`Unsupported architecture: ${this.buildArch} for Windows`);
878
934
  }
879
- else {
880
- // Auto-detect based on current architecture if no explicit target
881
- buildTarget =
882
- process.arch === 'arm64'
883
- ? 'aarch64-pc-windows-msvc'
884
- : 'x86_64-pc-windows-msvc';
885
- }
886
- fullCommand += ` --target ${buildTarget}`;
935
+ let fullCommand = this.buildBaseCommand(packageManager, configPath, buildTarget);
887
936
  // Add features
888
- const features = ['cli-build'];
937
+ const features = this.getBuildFeatures();
889
938
  if (features.length > 0) {
890
939
  fullCommand += ` --features ${features.join(',')}`;
891
940
  }
@@ -893,21 +942,7 @@ class WinBuilder extends BaseBuilder {
893
942
  }
894
943
  getBasePath() {
895
944
  const basePath = this.options.debug ? 'debug' : 'release';
896
- // Determine target based on explicit targets option or auto-detect
897
- let target;
898
- if (this.buildArch === 'arm64') {
899
- target = 'aarch64-pc-windows-msvc';
900
- }
901
- else if (this.buildArch === 'x64') {
902
- target = 'x86_64-pc-windows-msvc';
903
- }
904
- else {
905
- // Auto-detect based on current architecture if no explicit target
906
- target =
907
- process.arch === 'arm64'
908
- ? 'aarch64-pc-windows-msvc'
909
- : 'x86_64-pc-windows-msvc';
910
- }
945
+ const target = this.getTauriTarget(this.buildArch, 'win32');
911
946
  return `src-tauri/target/${target}/${basePath}/bundle/`;
912
947
  }
913
948
  }
@@ -923,7 +958,7 @@ class LinuxBuilder extends BaseBuilder {
923
958
  }
924
959
  else {
925
960
  this.buildFormat = target;
926
- this.buildArch = 'auto';
961
+ this.buildArch = this.resolveTargetArch('auto');
927
962
  }
928
963
  // Set targets to format for Tauri
929
964
  this.options.targets = this.buildFormat;
@@ -931,15 +966,17 @@ class LinuxBuilder extends BaseBuilder {
931
966
  getFileName() {
932
967
  const { name, targets } = this.options;
933
968
  const version = tauriConfig.version;
934
- // Determine architecture based on explicit target or auto-detect
969
+ // Determine architecture display name
935
970
  let arch;
936
971
  if (this.buildArch === 'arm64') {
937
972
  arch = targets === 'rpm' || targets === 'appimage' ? 'aarch64' : 'arm64';
938
973
  }
939
974
  else {
940
975
  // Auto-detect or default to current architecture
941
- arch = process.arch === 'x64' ? 'amd64' : process.arch;
942
- if (arch === 'arm64' && (targets === 'rpm' || targets === 'appimage')) {
976
+ const resolvedArch = this.buildArch === 'x64' ? 'amd64' : this.buildArch;
977
+ arch = resolvedArch;
978
+ if (resolvedArch === 'arm64' &&
979
+ (targets === 'rpm' || targets === 'appimage')) {
943
980
  arch = 'aarch64';
944
981
  }
945
982
  }
@@ -958,19 +995,15 @@ class LinuxBuilder extends BaseBuilder {
958
995
  }
959
996
  }
960
997
  }
961
- getBuildCommand() {
962
- const baseCommand = this.options.debug
963
- ? 'npm run build:debug'
964
- : 'npm run build';
965
- // Use temporary config directory to avoid modifying source files
998
+ getBuildCommand(packageManager = 'pnpm') {
966
999
  const configPath = path.join('src-tauri', '.pake', 'tauri.conf.json');
967
- let fullCommand = `${baseCommand} -- -c "${configPath}"`;
968
- // Add ARM64 target if explicitly specified
969
- if (this.buildArch === 'arm64') {
970
- fullCommand += ' --target aarch64-unknown-linux-gnu';
971
- }
1000
+ // Only add target if it's ARM64
1001
+ const buildTarget = this.buildArch === 'arm64'
1002
+ ? this.getTauriTarget(this.buildArch, 'linux')
1003
+ : undefined;
1004
+ let fullCommand = this.buildBaseCommand(packageManager, configPath, buildTarget);
972
1005
  // Add features
973
- const features = ['cli-build'];
1006
+ const features = this.getBuildFeatures();
974
1007
  if (features.length > 0) {
975
1008
  fullCommand += ` --features ${features.join(',')}`;
976
1009
  }
@@ -979,7 +1012,8 @@ class LinuxBuilder extends BaseBuilder {
979
1012
  getBasePath() {
980
1013
  const basePath = this.options.debug ? 'debug' : 'release';
981
1014
  if (this.buildArch === 'arm64') {
982
- return `src-tauri/target/aarch64-unknown-linux-gnu/${basePath}/bundle/`;
1015
+ const target = this.getTauriTarget(this.buildArch, 'linux');
1016
+ return `src-tauri/target/${target}/${basePath}/bundle/`;
983
1017
  }
984
1018
  return super.getBasePath();
985
1019
  }
@@ -1028,8 +1062,10 @@ const DEFAULT_PAKE_OPTIONS = {
1028
1062
  debug: false,
1029
1063
  inject: [],
1030
1064
  installerLanguage: 'en-US',
1031
- hideOnClose: true,
1065
+ hideOnClose: undefined, // Platform-specific: true for macOS, false for others
1032
1066
  incognito: false,
1067
+ wasm: false,
1068
+ enableDragDrop: false,
1033
1069
  };
1034
1070
 
1035
1071
  async function checkUpdateTips() {
@@ -1474,13 +1510,19 @@ program
1474
1510
  .addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon')
1475
1511
  .default(DEFAULT_PAKE_OPTIONS.systemTrayIcon)
1476
1512
  .hideHelp())
1477
- .addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting')
1513
+ .addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting (default: true for macOS, false for others)')
1478
1514
  .default(DEFAULT_PAKE_OPTIONS.hideOnClose)
1479
1515
  .hideHelp())
1480
1516
  .addOption(new Option('--title <string>', 'Window title').hideHelp())
1481
1517
  .addOption(new Option('--incognito', 'Launch app in incognito/private mode')
1482
1518
  .default(DEFAULT_PAKE_OPTIONS.incognito)
1483
1519
  .hideHelp())
1520
+ .addOption(new Option('--wasm', 'Enable WebAssembly support (Flutter Web, etc.)')
1521
+ .default(DEFAULT_PAKE_OPTIONS.wasm)
1522
+ .hideHelp())
1523
+ .addOption(new Option('--enable-drag-drop', 'Enable drag and drop functionality')
1524
+ .default(DEFAULT_PAKE_OPTIONS.enableDragDrop)
1525
+ .hideHelp())
1484
1526
  .addOption(new Option('--installer-language <string>', 'Installer language')
1485
1527
  .default(DEFAULT_PAKE_OPTIONS.installerLanguage)
1486
1528
  .hideHelp())
@@ -1488,13 +1530,10 @@ program
1488
1530
  .action(async (url, options) => {
1489
1531
  await checkUpdateTips();
1490
1532
  if (!url) {
1491
- program.outputHelp((str) => {
1492
- return str
1493
- .split('\n')
1494
- .filter((line) => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line))
1495
- .join('\n');
1533
+ program.help({
1534
+ error: false,
1496
1535
  });
1497
- process.exit(0);
1536
+ return;
1498
1537
  }
1499
1538
  log.setDefaultLevel('info');
1500
1539
  if (options.debug) {