@choochmeque/tauri-windows-bundle 0.1.2 → 0.1.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
@@ -483,8 +483,9 @@ function updatePackageJson(projectRoot) {
483
483
 
484
484
  function prepareAppxContent(projectRoot, arch, config, tauriConfig, minVersion) {
485
485
  const target = arch === 'x64' ? 'x86_64-pc-windows-msvc' : 'aarch64-pc-windows-msvc';
486
- const buildDir = path.join(projectRoot, 'target', target, 'release');
487
- const appxDir = path.join(projectRoot, 'target', 'appx', arch);
486
+ const srcTauriDir = path.join(projectRoot, 'src-tauri');
487
+ const buildDir = path.join(srcTauriDir, 'target', target, 'release');
488
+ const appxDir = path.join(srcTauriDir, 'target', 'appx', arch);
488
489
  // Create directories
489
490
  fs.mkdirSync(path.join(appxDir, 'Assets'), { recursive: true });
490
491
  // Copy exe
@@ -544,6 +545,33 @@ function copyBundledResources(projectRoot, appxDir, tauriConfig) {
544
545
  }
545
546
 
546
547
  const execPromise = promisify(exec);
548
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
549
+ class Spinner {
550
+ frameIndex = 0;
551
+ intervalId = null;
552
+ message;
553
+ constructor(message) {
554
+ this.message = message;
555
+ }
556
+ start() {
557
+ this.intervalId = setInterval(() => {
558
+ const frame = SPINNER_FRAMES[this.frameIndex];
559
+ process.stdout.write(`\r${frame} ${this.message}`);
560
+ this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;
561
+ }, 80);
562
+ }
563
+ stop(success = true) {
564
+ if (this.intervalId) {
565
+ clearInterval(this.intervalId);
566
+ this.intervalId = null;
567
+ }
568
+ const symbol = success ? '✓' : '✗';
569
+ process.stdout.write(`\r${symbol} ${this.message}\n`);
570
+ }
571
+ fail() {
572
+ this.stop(false);
573
+ }
574
+ }
547
575
  async function execAsync(command, options) {
548
576
  const result = await execPromise(command, { ...options, encoding: 'utf8' });
549
577
  return { stdout: result.stdout, stderr: result.stderr };
@@ -596,6 +624,8 @@ async function promptInstall(message) {
596
624
  });
597
625
  }
598
626
  async function execWithProgress(command, options) {
627
+ const verbose = options?.verbose ?? false;
628
+ const message = options?.message ?? 'Running...';
599
629
  return new Promise((resolve, reject) => {
600
630
  const [cmd, ...args] = command.split(' ');
601
631
  const child = spawn(cmd, args, {
@@ -603,21 +633,46 @@ async function execWithProgress(command, options) {
603
633
  stdio: ['inherit', 'pipe', 'pipe'],
604
634
  shell: true,
605
635
  });
636
+ let spinner = null;
637
+ let capturedOutput = '';
638
+ if (!verbose) {
639
+ spinner = new Spinner(message);
640
+ spinner.start();
641
+ }
606
642
  child.stdout?.on('data', (data) => {
607
- process.stdout.write(data);
643
+ if (verbose) {
644
+ process.stdout.write(data);
645
+ }
646
+ else {
647
+ capturedOutput += data.toString();
648
+ }
608
649
  });
609
650
  child.stderr?.on('data', (data) => {
610
- process.stderr.write(data);
651
+ if (verbose) {
652
+ process.stderr.write(data);
653
+ }
654
+ else {
655
+ capturedOutput += data.toString();
656
+ }
611
657
  });
612
658
  child.on('close', (code) => {
613
659
  if (code === 0) {
660
+ spinner?.stop(true);
614
661
  resolve();
615
662
  }
616
663
  else {
664
+ spinner?.fail();
665
+ if (!verbose && capturedOutput) {
666
+ console.error('\nBuild output:\n' + capturedOutput);
667
+ }
617
668
  reject(new Error(`Command failed with exit code ${code}`));
618
669
  }
619
670
  });
620
671
  child.on('error', (error) => {
672
+ spinner?.fail();
673
+ if (!verbose && capturedOutput) {
674
+ console.error('\nBuild output:\n' + capturedOutput);
675
+ }
621
676
  reject(error);
622
677
  });
623
678
  });
@@ -629,10 +684,11 @@ async function build(options) {
629
684
  if (!(await isMsixbundleCliInstalled())) {
630
685
  const shouldInstall = await promptInstall('msixbundle-cli is required but not installed.\n' + 'Install it now? (requires Rust/Cargo)');
631
686
  if (shouldInstall) {
632
- console.log('Installing msixbundle-cli...\n');
633
687
  try {
634
- await execWithProgress('cargo install msixbundle-cli');
635
- console.log('\n msixbundle-cli installed\n');
688
+ await execWithProgress('cargo install msixbundle-cli', {
689
+ verbose: options.verbose,
690
+ message: 'Installing msixbundle-cli...',
691
+ });
636
692
  }
637
693
  catch (error) {
638
694
  console.error('Failed to install msixbundle-cli:', error);
@@ -677,27 +733,28 @@ async function build(options) {
677
733
  const appxDirs = [];
678
734
  const runner = options.runner || DEFAULT_RUNNER;
679
735
  for (const arch of architectures) {
680
- console.log(`Building for ${arch}...`);
681
736
  // Build Tauri app
682
737
  const target = arch === 'x64' ? 'x86_64-pc-windows-msvc' : 'aarch64-pc-windows-msvc';
683
738
  const releaseFlag = options.release ? '--release' : '';
684
739
  // Build command based on runner
685
- // --bundles none skips MSI/NSIS bundling since we're creating MSIX
740
+ // --no-bundle skips MSI/NSIS bundling since we're creating MSIX
686
741
  let buildCommand;
687
742
  if (runner === 'npm') {
688
743
  // npm requires -- to pass args to the script
689
- buildCommand =
690
- `npm run tauri build -- --target ${target} --bundles none ${releaseFlag}`.trim();
744
+ buildCommand = `npm run tauri build -- --target ${target} --no-bundle ${releaseFlag}`.trim();
691
745
  }
692
746
  else {
693
747
  // cargo, pnpm, yarn, bun, etc.
694
- buildCommand =
695
- `${runner} tauri build --target ${target} --bundles none ${releaseFlag}`.trim();
748
+ buildCommand = `${runner} tauri build --target ${target} --no-bundle ${releaseFlag}`.trim();
696
749
  }
697
750
  try {
698
- console.log(` Running: ${buildCommand}\n`);
751
+ if (options.verbose) {
752
+ console.log(` Running: ${buildCommand}\n`);
753
+ }
699
754
  await execWithProgress(buildCommand, {
700
755
  cwd: projectRoot,
756
+ verbose: options.verbose,
757
+ message: `Building for ${arch}...`,
701
758
  });
702
759
  }
703
760
  catch (error) {
@@ -712,7 +769,7 @@ async function build(options) {
712
769
  }
713
770
  // Call msixbundle-cli
714
771
  console.log('\nCreating MSIX package...');
715
- const outDir = path.join(projectRoot, 'target', 'msix');
772
+ const outDir = path.join(projectRoot, 'src-tauri', 'target', 'msix');
716
773
  const args = [
717
774
  '--out-dir',
718
775
  outDir,
@@ -1472,6 +1529,7 @@ program
1472
1529
  .option('--release', 'Build in release mode')
1473
1530
  .option('--min-windows <version>', 'Minimum Windows version', '10.0.17763.0')
1474
1531
  .option('--runner <runner>', 'Build runner (cargo, pnpm, npm, yarn, etc.)', 'cargo')
1532
+ .option('--verbose', 'Show full build output instead of spinner')
1475
1533
  .action(async (options) => {
1476
1534
  try {
1477
1535
  await build(options);
package/dist/index.js CHANGED
@@ -481,8 +481,9 @@ function updatePackageJson(projectRoot) {
481
481
 
482
482
  function prepareAppxContent(projectRoot, arch, config, tauriConfig, minVersion) {
483
483
  const target = arch === 'x64' ? 'x86_64-pc-windows-msvc' : 'aarch64-pc-windows-msvc';
484
- const buildDir = path.join(projectRoot, 'target', target, 'release');
485
- const appxDir = path.join(projectRoot, 'target', 'appx', arch);
484
+ const srcTauriDir = path.join(projectRoot, 'src-tauri');
485
+ const buildDir = path.join(srcTauriDir, 'target', target, 'release');
486
+ const appxDir = path.join(srcTauriDir, 'target', 'appx', arch);
486
487
  // Create directories
487
488
  fs.mkdirSync(path.join(appxDir, 'Assets'), { recursive: true });
488
489
  // Copy exe
@@ -542,6 +543,33 @@ function copyBundledResources(projectRoot, appxDir, tauriConfig) {
542
543
  }
543
544
 
544
545
  const execPromise = promisify(exec);
546
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
547
+ class Spinner {
548
+ frameIndex = 0;
549
+ intervalId = null;
550
+ message;
551
+ constructor(message) {
552
+ this.message = message;
553
+ }
554
+ start() {
555
+ this.intervalId = setInterval(() => {
556
+ const frame = SPINNER_FRAMES[this.frameIndex];
557
+ process.stdout.write(`\r${frame} ${this.message}`);
558
+ this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;
559
+ }, 80);
560
+ }
561
+ stop(success = true) {
562
+ if (this.intervalId) {
563
+ clearInterval(this.intervalId);
564
+ this.intervalId = null;
565
+ }
566
+ const symbol = success ? '✓' : '✗';
567
+ process.stdout.write(`\r${symbol} ${this.message}\n`);
568
+ }
569
+ fail() {
570
+ this.stop(false);
571
+ }
572
+ }
545
573
  async function execAsync(command, options) {
546
574
  const result = await execPromise(command, { ...options, encoding: 'utf8' });
547
575
  return { stdout: result.stdout, stderr: result.stderr };
@@ -594,6 +622,8 @@ async function promptInstall(message) {
594
622
  });
595
623
  }
596
624
  async function execWithProgress(command, options) {
625
+ const verbose = options?.verbose ?? false;
626
+ const message = options?.message ?? 'Running...';
597
627
  return new Promise((resolve, reject) => {
598
628
  const [cmd, ...args] = command.split(' ');
599
629
  const child = spawn(cmd, args, {
@@ -601,21 +631,46 @@ async function execWithProgress(command, options) {
601
631
  stdio: ['inherit', 'pipe', 'pipe'],
602
632
  shell: true,
603
633
  });
634
+ let spinner = null;
635
+ let capturedOutput = '';
636
+ if (!verbose) {
637
+ spinner = new Spinner(message);
638
+ spinner.start();
639
+ }
604
640
  child.stdout?.on('data', (data) => {
605
- process.stdout.write(data);
641
+ if (verbose) {
642
+ process.stdout.write(data);
643
+ }
644
+ else {
645
+ capturedOutput += data.toString();
646
+ }
606
647
  });
607
648
  child.stderr?.on('data', (data) => {
608
- process.stderr.write(data);
649
+ if (verbose) {
650
+ process.stderr.write(data);
651
+ }
652
+ else {
653
+ capturedOutput += data.toString();
654
+ }
609
655
  });
610
656
  child.on('close', (code) => {
611
657
  if (code === 0) {
658
+ spinner?.stop(true);
612
659
  resolve();
613
660
  }
614
661
  else {
662
+ spinner?.fail();
663
+ if (!verbose && capturedOutput) {
664
+ console.error('\nBuild output:\n' + capturedOutput);
665
+ }
615
666
  reject(new Error(`Command failed with exit code ${code}`));
616
667
  }
617
668
  });
618
669
  child.on('error', (error) => {
670
+ spinner?.fail();
671
+ if (!verbose && capturedOutput) {
672
+ console.error('\nBuild output:\n' + capturedOutput);
673
+ }
619
674
  reject(error);
620
675
  });
621
676
  });
@@ -627,10 +682,11 @@ async function build(options) {
627
682
  if (!(await isMsixbundleCliInstalled())) {
628
683
  const shouldInstall = await promptInstall('msixbundle-cli is required but not installed.\n' + 'Install it now? (requires Rust/Cargo)');
629
684
  if (shouldInstall) {
630
- console.log('Installing msixbundle-cli...\n');
631
685
  try {
632
- await execWithProgress('cargo install msixbundle-cli');
633
- console.log('\n msixbundle-cli installed\n');
686
+ await execWithProgress('cargo install msixbundle-cli', {
687
+ verbose: options.verbose,
688
+ message: 'Installing msixbundle-cli...',
689
+ });
634
690
  }
635
691
  catch (error) {
636
692
  console.error('Failed to install msixbundle-cli:', error);
@@ -675,27 +731,28 @@ async function build(options) {
675
731
  const appxDirs = [];
676
732
  const runner = options.runner || DEFAULT_RUNNER;
677
733
  for (const arch of architectures) {
678
- console.log(`Building for ${arch}...`);
679
734
  // Build Tauri app
680
735
  const target = arch === 'x64' ? 'x86_64-pc-windows-msvc' : 'aarch64-pc-windows-msvc';
681
736
  const releaseFlag = options.release ? '--release' : '';
682
737
  // Build command based on runner
683
- // --bundles none skips MSI/NSIS bundling since we're creating MSIX
738
+ // --no-bundle skips MSI/NSIS bundling since we're creating MSIX
684
739
  let buildCommand;
685
740
  if (runner === 'npm') {
686
741
  // npm requires -- to pass args to the script
687
- buildCommand =
688
- `npm run tauri build -- --target ${target} --bundles none ${releaseFlag}`.trim();
742
+ buildCommand = `npm run tauri build -- --target ${target} --no-bundle ${releaseFlag}`.trim();
689
743
  }
690
744
  else {
691
745
  // cargo, pnpm, yarn, bun, etc.
692
- buildCommand =
693
- `${runner} tauri build --target ${target} --bundles none ${releaseFlag}`.trim();
746
+ buildCommand = `${runner} tauri build --target ${target} --no-bundle ${releaseFlag}`.trim();
694
747
  }
695
748
  try {
696
- console.log(` Running: ${buildCommand}\n`);
749
+ if (options.verbose) {
750
+ console.log(` Running: ${buildCommand}\n`);
751
+ }
697
752
  await execWithProgress(buildCommand, {
698
753
  cwd: projectRoot,
754
+ verbose: options.verbose,
755
+ message: `Building for ${arch}...`,
699
756
  });
700
757
  }
701
758
  catch (error) {
@@ -710,7 +767,7 @@ async function build(options) {
710
767
  }
711
768
  // Call msixbundle-cli
712
769
  console.log('\nCreating MSIX package...');
713
- const outDir = path.join(projectRoot, 'target', 'msix');
770
+ const outDir = path.join(projectRoot, 'src-tauri', 'target', 'msix');
714
771
  const args = [
715
772
  '--out-dir',
716
773
  outDir,
package/dist/types.d.ts CHANGED
@@ -103,6 +103,7 @@ export interface BuildOptions {
103
103
  release?: boolean;
104
104
  minWindows?: string;
105
105
  runner?: string;
106
+ verbose?: boolean;
106
107
  }
107
108
  export declare const DEFAULT_RUNNER = "cargo";
108
109
  export interface MsixAsset {
@@ -1,3 +1,12 @@
1
+ export declare class Spinner {
2
+ private frameIndex;
3
+ private intervalId;
4
+ private message;
5
+ constructor(message: string);
6
+ start(): void;
7
+ stop(success?: boolean): void;
8
+ fail(): void;
9
+ }
1
10
  export declare function execAsync(command: string, options?: {
2
11
  cwd?: string;
3
12
  }): Promise<{
@@ -9,6 +18,9 @@ export declare function getMsixbundleCliVersion(): Promise<string | null>;
9
18
  export declare function isVersionSufficient(version: string, minVersion: string): boolean;
10
19
  export declare const MIN_MSIXBUNDLE_CLI_VERSION = "1.0.0";
11
20
  export declare function promptInstall(message: string): Promise<boolean>;
12
- export declare function execWithProgress(command: string, options?: {
21
+ export interface ExecWithProgressOptions {
13
22
  cwd?: string;
14
- }): Promise<void>;
23
+ verbose?: boolean;
24
+ message?: string;
25
+ }
26
+ export declare function execWithProgress(command: string, options?: ExecWithProgressOptions): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@choochmeque/tauri-windows-bundle",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "MSIX packaging tool for Tauri apps - Windows Store ready bundles",
5
5
  "type": "module",
6
6
  "bin": {