@mcesystems/apple-kit 1.0.33 → 1.0.34

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcesystems/apple-kit",
3
- "version": "1.0.33",
3
+ "version": "1.0.34",
4
4
  "description": "iOS device management toolkit using libimobiledevice command-line tools",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -24,7 +24,10 @@ import {
24
24
  existsSync,
25
25
  mkdirSync,
26
26
  readFileSync,
27
+ readdirSync,
27
28
  readlinkSync,
29
+ rmSync,
30
+ unlinkSync,
28
31
  writeFileSync,
29
32
  } from "node:fs";
30
33
  import path from "node:path";
@@ -67,6 +70,10 @@ const HOMEBREW_INTEL_PATH = "/usr/local";
67
70
  // MSYS2 paths on Windows
68
71
  const MSYS2_DEFAULT_PATH = "C:\\msys64";
69
72
 
73
+ // Pre-built resources configuration
74
+ const PREBUILT_RESOURCES_DIR = path.join(__dirname, "..", "prebuilt");
75
+ const LIBIMOBILEDEVICE_VERSION = "1.0.0";
76
+
70
77
  // System library prefixes that should NOT be copied (they exist on all macOS)
71
78
  const SYSTEM_LIB_PREFIXES = ["/System/Library/", "/usr/lib/", "/Library/Apple/"];
72
79
 
@@ -298,7 +305,7 @@ async function codesignBinary(binaryPath: string): Promise<boolean> {
298
305
  async function verifyBinary(
299
306
  binaryPath: string,
300
307
  binDir: string
301
- ): Promise<{ success: boolean; error?: string }> {
308
+ ): Promise<{ success: boolean; error?: string; }> {
302
309
  const binaryName = path.basename(binaryPath);
303
310
 
304
311
  // Check that otool shows no broken paths
@@ -337,7 +344,7 @@ async function verifyBinary(
337
344
  if (!binaryName.endsWith(".dylib")) {
338
345
  try {
339
346
  // Use spawn with a timeout to test if the binary loads
340
- const result = await new Promise<{ success: boolean; error?: string }>((resolve) => {
347
+ const result = await new Promise<{ success: boolean; error?: string; }>((resolve) => {
341
348
  const child = spawn(binaryPath, ["--help"], {
342
349
  timeout: 5000,
343
350
  env: { ...process.env, DYLD_LIBRARY_PATH: binDir },
@@ -569,17 +576,117 @@ async function exportDarwinResources(targetDir: string, skipVerify: boolean): Pr
569
576
  // Windows Export
570
577
  // ============================================================================
571
578
 
579
+ /**
580
+ * Get the path to the pre-built Windows resources archive
581
+ */
582
+ function getPrebuiltWindowsArchivePath(): string {
583
+ return path.join(PREBUILT_RESOURCES_DIR, `libimobiledevice-windows-v${LIBIMOBILEDEVICE_VERSION}.tar.gz`);
584
+ }
585
+
586
+ /**
587
+ * Check if pre-built Windows resources exist
588
+ */
589
+ function hasPrebuiltWindowsResources(): boolean {
590
+ const archivePath = getPrebuiltWindowsArchivePath();
591
+ return existsSync(archivePath);
592
+ }
593
+
594
+ /**
595
+ * Extract pre-built Windows resources to target directory
596
+ */
597
+ async function extractPrebuiltWindowsResources(targetDir: string): Promise<void> {
598
+ const archivePath = getPrebuiltWindowsArchivePath();
599
+ const windowsBinDir = path.join(targetDir, "bin", "windows");
600
+
601
+ console.log(`Extracting pre-built resources from: ${path.basename(archivePath)}`);
602
+ mkdirSync(windowsBinDir, { recursive: true });
603
+
604
+ // Use tar command to extract (available on Windows 10+ and via MSYS2)
605
+ try {
606
+ await execAsync(`tar -xzf "${archivePath}" -C "${windowsBinDir}"`);
607
+ console.log(`✓ Extracted pre-built Windows resources to: ${windowsBinDir}`);
608
+ } catch (error) {
609
+ throw new Error(`Failed to extract pre-built resources: ${error}`);
610
+ }
611
+ }
612
+
613
+ /**
614
+ * Create a tar.gz archive of the built Windows resources
615
+ */
616
+ async function createWindowsResourcesArchive(targetDir: string): Promise<void> {
617
+ const windowsBinDir = path.join(targetDir, "bin", "windows");
618
+ const archivePath = getPrebuiltWindowsArchivePath();
619
+
620
+ // Ensure prebuilt directory exists
621
+ mkdirSync(PREBUILT_RESOURCES_DIR, { recursive: true });
622
+
623
+ console.log(`\nCreating pre-built resources archive: ${path.basename(archivePath)}`);
624
+
625
+ // Get list of files in windows bin directory
626
+ const files = readdirSync(windowsBinDir);
627
+ if (files.length === 0) {
628
+ console.warn("Warning: No files to archive in Windows bin directory");
629
+ return;
630
+ }
631
+
632
+ // Use tar command to create archive
633
+ try {
634
+ await execAsync(`tar -czf "${archivePath}" -C "${windowsBinDir}" .`);
635
+ console.log(`✓ Created pre-built resources archive: ${archivePath}`);
636
+ } catch (error) {
637
+ console.warn(`Warning: Failed to create archive: ${error}`);
638
+ }
639
+ }
640
+
641
+ /**
642
+ * Clean up build artifacts (build script and limd-build folder)
643
+ */
644
+ function cleanupWindowsBuildArtifacts(targetDir: string): void {
645
+ const scriptPath = path.join(targetDir, "build-windows.sh");
646
+ const buildDir = path.join(targetDir, "limd-build");
647
+
648
+ console.log("\nCleaning up build artifacts...");
649
+
650
+ // Remove build script
651
+ if (existsSync(scriptPath)) {
652
+ unlinkSync(scriptPath);
653
+ console.log(" ✓ Removed build-windows.sh");
654
+ }
655
+
656
+ // Remove limd-build directory
657
+ if (existsSync(buildDir)) {
658
+ rmSync(buildDir, { recursive: true, force: true });
659
+ console.log(" ✓ Removed limd-build directory");
660
+ }
661
+ }
662
+
572
663
  async function exportWindowsResources(targetDir: string): Promise<void> {
573
664
  console.log("\n=== Exporting Windows Resources ===\n");
574
665
 
575
666
  // Check if we're on Windows
576
667
  if (process.platform !== "win32") {
668
+ // On non-Windows, check for pre-built resources first
669
+ if (hasPrebuiltWindowsResources()) {
670
+ console.log("Found pre-built Windows resources, extracting...");
671
+ await extractPrebuiltWindowsResources(targetDir);
672
+ return;
673
+ }
674
+
577
675
  console.log("Note: Windows resources can only be built on Windows.");
578
676
  console.log("Generating build script for later use...\n");
579
677
  generateWindowsBuildScript(targetDir);
580
678
  return;
581
679
  }
582
680
 
681
+ // On Windows, check for pre-built resources first
682
+ if (hasPrebuiltWindowsResources()) {
683
+ console.log("Found pre-built Windows resources, extracting...");
684
+ await extractPrebuiltWindowsResources(targetDir);
685
+ return;
686
+ }
687
+
688
+ console.log("No pre-built resources found, building from source...");
689
+
583
690
  // Check for MSYS2
584
691
  const msys2Path = process.env.MSYS2_PATH || MSYS2_DEFAULT_PATH;
585
692
  if (!existsSync(msys2Path)) {
@@ -593,9 +700,68 @@ async function exportWindowsResources(targetDir: string): Promise<void> {
593
700
  // Generate the build script
594
701
  generateWindowsBuildScript(targetDir);
595
702
 
596
- console.log("\nTo build Windows resources:");
597
- console.log("1. Open MSYS2 MinGW 64-bit shell");
598
- console.log(`2. Run: bash "${path.join(targetDir, "build-windows.sh")}"`);
703
+ // Run the build script through MSYS2's bash
704
+ const scriptPath = path.join(targetDir, "build-windows.sh");
705
+ await runMsys2Build(msys2Path, scriptPath);
706
+
707
+ // Clean up build artifacts
708
+ cleanupWindowsBuildArtifacts(targetDir);
709
+
710
+ // Create archive for future use
711
+ await createWindowsResourcesArchive(targetDir);
712
+ }
713
+
714
+ async function runMsys2Build(msys2Path: string, scriptPath: string): Promise<void> {
715
+ console.log("\nRunning Windows build through MSYS2...");
716
+ console.log("(This may take 10-30 minutes depending on your system)\n");
717
+
718
+ const envPath = path.join(msys2Path, "usr", "bin", "env.exe");
719
+ const bashPath = path.join(msys2Path, "usr", "bin", "bash.exe");
720
+
721
+ if (!existsSync(envPath)) {
722
+ console.error(`Error: MSYS2 env not found at ${envPath}`);
723
+ console.error("Please ensure MSYS2 is properly installed.");
724
+ process.exit(1);
725
+ }
726
+
727
+ if (!existsSync(bashPath)) {
728
+ console.error(`Error: MSYS2 bash not found at ${bashPath}`);
729
+ console.error("Please ensure MSYS2 is properly installed.");
730
+ process.exit(1);
731
+ }
732
+
733
+ // Convert Windows path to MSYS2-compatible path
734
+ const msysScriptPath = scriptPath.replace(/\\/g, "/").replace(/^([A-Z]):/, (_, drive) => `/${drive.toLowerCase()}`);
735
+
736
+ return new Promise((resolve, reject) => {
737
+ // Use MSYS2's env.exe to properly set MSYSTEM for the MinGW64 environment
738
+ // This ensures the PATH and other environment variables are set correctly
739
+ const child = spawn(envPath, [
740
+ "MSYSTEM=MINGW64",
741
+ "CHERE_INVOKING=1",
742
+ bashPath,
743
+ "-l",
744
+ "-c",
745
+ `bash "${msysScriptPath}"`,
746
+ ], {
747
+ stdio: "inherit",
748
+ });
749
+
750
+ child.on("error", (err) => {
751
+ console.error(`Failed to start MSYS2 build: ${err.message}`);
752
+ reject(err);
753
+ });
754
+
755
+ child.on("close", (code) => {
756
+ if (code === 0) {
757
+ console.log("\n✓ Windows build completed successfully");
758
+ resolve();
759
+ } else {
760
+ console.error(`\n✗ Windows build failed with exit code ${code}`);
761
+ reject(new Error(`Build failed with exit code ${code}`));
762
+ }
763
+ });
764
+ });
599
765
  }
600
766
 
601
767
  function generateWindowsBuildScript(targetDir: string): void {