@mcesystems/apple-kit 1.0.23 → 1.0.25

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.
Files changed (116) hide show
  1. package/README.md +284 -250
  2. package/dist/index.js +304 -174
  3. package/dist/index.js.map +4 -4
  4. package/dist/index.mjs +303 -173
  5. package/dist/index.mjs.map +4 -4
  6. package/dist/resources/bin/darwin/idevice_id +0 -0
  7. package/dist/resources/bin/darwin/idevicedebug +0 -0
  8. package/dist/resources/bin/darwin/idevicediagnostics +0 -0
  9. package/dist/resources/bin/darwin/ideviceinfo +0 -0
  10. package/dist/resources/bin/darwin/ideviceinstaller +0 -0
  11. package/dist/resources/bin/darwin/idevicename +0 -0
  12. package/dist/resources/bin/darwin/idevicepair +0 -0
  13. package/dist/resources/bin/darwin/idevicescreenshot +0 -0
  14. package/dist/resources/bin/darwin/idevicesyslog +0 -0
  15. package/dist/resources/bin/darwin/iproxy +0 -0
  16. package/dist/resources/bin/darwin/libcrypto.3.dylib +0 -0
  17. package/dist/resources/bin/darwin/libimobiledevice-1.0.6.dylib +0 -0
  18. package/dist/resources/bin/darwin/libimobiledevice-glue-1.0.0.dylib +0 -0
  19. package/dist/resources/bin/darwin/liblzma.5.dylib +0 -0
  20. package/dist/resources/bin/darwin/libplist-2.0.4.dylib +0 -0
  21. package/dist/resources/bin/darwin/libssl.3.dylib +0 -0
  22. package/dist/resources/bin/darwin/libusbmuxd-2.0.7.dylib +0 -0
  23. package/dist/resources/bin/darwin/libzip.5.dylib +0 -0
  24. package/dist/resources/bin/darwin/libzstd.1.dylib +0 -0
  25. package/{resources → dist/resources}/licenses/LGPL-2.1.txt +33 -33
  26. package/dist/types/index.d.ts +0 -2
  27. package/dist/types/index.d.ts.map +1 -1
  28. package/dist/types/logic/actions/device.d.ts.map +1 -1
  29. package/dist/types/logic/actions/proxy.d.ts.map +1 -1
  30. package/dist/types/logic/appleDeviceKit.d.ts +2 -7
  31. package/dist/types/logic/appleDeviceKit.d.ts.map +1 -1
  32. package/package.json +7 -4
  33. package/scripts/README.md +209 -0
  34. package/scripts/build-windows.sh.template +134 -0
  35. package/scripts/export-resources.ts +444 -0
  36. package/dist/types/utils/portManager.d.ts +0 -68
  37. package/dist/types/utils/portManager.d.ts.map +0 -1
  38. package/resources/bin/windows/bz2.dll +0 -0
  39. package/resources/bin/windows/getopt.dll +0 -0
  40. package/resources/bin/windows/iconv-2.dll +0 -0
  41. package/resources/bin/windows/idevice_id.exe +0 -0
  42. package/resources/bin/windows/ideviceactivation.exe +0 -0
  43. package/resources/bin/windows/idevicedebug.exe +0 -0
  44. package/resources/bin/windows/ideviceinfo.exe +0 -0
  45. package/resources/bin/windows/ideviceinstaller.exe +0 -0
  46. package/resources/bin/windows/idevicepair.exe +0 -0
  47. package/resources/bin/windows/imobiledevice.dll +0 -0
  48. package/resources/bin/windows/iproxy.exe +0 -0
  49. package/resources/bin/windows/libcrypto-1_1-x64.dll +0 -0
  50. package/resources/bin/windows/libcurl.dll +0 -0
  51. package/resources/bin/windows/libideviceactivation-1.0.dll +0 -0
  52. package/resources/bin/windows/libimobiledevice-1.0.dll +0 -0
  53. package/resources/bin/windows/libimobiledevice-glue-1.0.dll +0 -0
  54. package/resources/bin/windows/libplist-2.0.dll +0 -0
  55. package/resources/bin/windows/libssl-1_1-x64.dll +0 -0
  56. package/resources/bin/windows/libusb-1.0.dll +0 -0
  57. package/resources/bin/windows/libusb0.dll +0 -0
  58. package/resources/bin/windows/libusbmuxd-2.0.dll +0 -0
  59. package/resources/bin/windows/libxml2.dll +0 -0
  60. package/resources/bin/windows/lzma.dll +0 -0
  61. package/resources/bin/windows/pcre.dll +0 -0
  62. package/resources/bin/windows/pcreposix.dll +0 -0
  63. package/resources/bin/windows/plist.dll +0 -0
  64. package/resources/bin/windows/pthreadVC3.dll +0 -0
  65. package/resources/bin/windows/readline.dll +0 -0
  66. package/resources/bin/windows/usbmuxd.dll +0 -0
  67. package/resources/bin/windows/usbmuxd.exe +0 -0
  68. package/resources/bin/windows/vcruntime140.dll +0 -0
  69. package/resources/bin/windows/zip.dll +0 -0
  70. package/resources/bin/windows/zlib1.dll +0 -0
  71. package/resources/lib/include/libimobiledevice/afc.h +0 -413
  72. package/resources/lib/include/libimobiledevice/bt_packet_logger.h +0 -156
  73. package/resources/lib/include/libimobiledevice/companion_proxy.h +0 -212
  74. package/resources/lib/include/libimobiledevice/debugserver.h +0 -272
  75. package/resources/lib/include/libimobiledevice/diagnostics_relay.h +0 -228
  76. package/resources/lib/include/libimobiledevice/file_relay.h +0 -166
  77. package/resources/lib/include/libimobiledevice/heartbeat.h +0 -137
  78. package/resources/lib/include/libimobiledevice/house_arrest.h +0 -180
  79. package/resources/lib/include/libimobiledevice/installation_proxy.h +0 -505
  80. package/resources/lib/include/libimobiledevice/libimobiledevice.h +0 -444
  81. package/resources/lib/include/libimobiledevice/lockdown.h +0 -577
  82. package/resources/lib/include/libimobiledevice/misagent.h +0 -168
  83. package/resources/lib/include/libimobiledevice/mobile_image_mounter.h +0 -275
  84. package/resources/lib/include/libimobiledevice/mobileactivation.h +0 -192
  85. package/resources/lib/include/libimobiledevice/mobilebackup.h +0 -246
  86. package/resources/lib/include/libimobiledevice/mobilebackup2.h +0 -214
  87. package/resources/lib/include/libimobiledevice/mobilesync.h +0 -359
  88. package/resources/lib/include/libimobiledevice/notification_proxy.h +0 -202
  89. package/resources/lib/include/libimobiledevice/ostrace.h +0 -198
  90. package/resources/lib/include/libimobiledevice/preboard.h +0 -187
  91. package/resources/lib/include/libimobiledevice/property_list_service.h +0 -184
  92. package/resources/lib/include/libimobiledevice/restore.h +0 -179
  93. package/resources/lib/include/libimobiledevice/reverse_proxy.h +0 -213
  94. package/resources/lib/include/libimobiledevice/sbservices.h +0 -175
  95. package/resources/lib/include/libimobiledevice/screenshotr.h +0 -118
  96. package/resources/lib/include/libimobiledevice/service.h +0 -202
  97. package/resources/lib/include/libimobiledevice/syslog_relay.h +0 -184
  98. package/resources/lib/include/libimobiledevice/webinspector.h +0 -137
  99. package/resources/lib/include/plist/Array.h +0 -80
  100. package/resources/lib/include/plist/Boolean.h +0 -48
  101. package/resources/lib/include/plist/Data.h +0 -50
  102. package/resources/lib/include/plist/Date.h +0 -54
  103. package/resources/lib/include/plist/Dictionary.h +0 -73
  104. package/resources/lib/include/plist/Integer.h +0 -54
  105. package/resources/lib/include/plist/Key.h +0 -49
  106. package/resources/lib/include/plist/Node.h +0 -57
  107. package/resources/lib/include/plist/Real.h +0 -48
  108. package/resources/lib/include/plist/String.h +0 -52
  109. package/resources/lib/include/plist/Structure.h +0 -62
  110. package/resources/lib/include/plist/Uid.h +0 -48
  111. package/resources/lib/include/plist/plist++.h +0 -39
  112. package/resources/lib/include/plist/plist.h +0 -1448
  113. package/resources/lib/libimobiledevice-1.0.dll +0 -0
  114. package/resources/lib/libimobiledevice-1.0.dll.a +0 -0
  115. package/resources/lib/libplist-2.0.dll +0 -0
  116. package/resources/lib/libplist-2.0.dll.a +0 -0
package/dist/index.js CHANGED
@@ -510,7 +510,7 @@ var require_has_flag = __commonJS({
510
510
  var require_supports_color = __commonJS({
511
511
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports2, module2) {
512
512
  "use strict";
513
- var os = require("os");
513
+ var os2 = require("os");
514
514
  var tty = require("tty");
515
515
  var hasFlag = require_has_flag();
516
516
  var { env } = process;
@@ -558,7 +558,7 @@ var require_supports_color = __commonJS({
558
558
  return min;
559
559
  }
560
560
  if (process.platform === "win32") {
561
- const osRelease = os.release().split(".");
561
+ const osRelease = os2.release().split(".");
562
562
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
563
563
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
564
564
  }
@@ -796,151 +796,156 @@ var require_src = __commonJS({
796
796
  // src/index.ts
797
797
  var index_exports = {};
798
798
  __export(index_exports, {
799
- AppleDeviceKit: () => AppleDeviceKit,
800
- PortManager: () => PortManager,
801
- getSharedPortManager: () => getSharedPortManager
799
+ AppleDeviceKit: () => AppleDeviceKit
802
800
  });
803
801
  module.exports = __toCommonJS(index_exports);
804
802
 
805
- // src/utils/debug.ts
806
- var import_debug = __toESM(require_src());
807
- var debug = (0, import_debug.default)("apple-kit");
808
- var debugTask = (0, import_debug.default)("apple-kit:task");
809
- var debugWarning = (0, import_debug.default)("apple-kit:warning");
810
- var debugError = (0, import_debug.default)("apple-kit:error");
811
- function logInfo(message) {
812
- debug(message);
813
- }
814
- function logTask(message) {
815
- debugTask(message);
816
- }
817
-
818
- // src/utils/portManager.ts
819
- var import_node_net = require("node:net");
820
- var PortManager = class {
821
- allocations = /* @__PURE__ */ new Map();
822
- basePort;
823
- maxPortRange;
824
- /**
825
- * Create a new PortManager
826
- *
827
- * @param basePort Starting port number for allocation (default: 30000)
828
- * @param maxPortRange Maximum range of ports to search (default: 1000)
829
- */
830
- constructor(basePort = 3e4, maxPortRange = 1e3) {
831
- this.basePort = basePort;
832
- this.maxPortRange = maxPortRange;
803
+ // ../../node_modules/.pnpm/get-port@7.1.0/node_modules/get-port/index.js
804
+ var import_node_net = __toESM(require("node:net"), 1);
805
+ var import_node_os = __toESM(require("node:os"), 1);
806
+ var Locked = class extends Error {
807
+ constructor(port) {
808
+ super(`${port} is locked`);
833
809
  }
834
- /**
835
- * Find an available port starting from the given port number
836
- */
837
- async findAvailablePort(startPort) {
838
- const maxPort = this.basePort + this.maxPortRange;
839
- for (let port = startPort; port < maxPort; port++) {
840
- const isAllocated = Array.from(this.allocations.values()).some(
841
- (a) => a.localPort === port
842
- );
843
- if (isAllocated) {
844
- continue;
845
- }
846
- const isAvailable = await this.isPortAvailable(port);
847
- if (isAvailable) {
848
- return port;
849
- }
810
+ };
811
+ var lockedPorts = {
812
+ old: /* @__PURE__ */ new Set(),
813
+ young: /* @__PURE__ */ new Set()
814
+ };
815
+ var releaseOldLockedPortsIntervalMs = 1e3 * 15;
816
+ var minPort = 1024;
817
+ var maxPort = 65535;
818
+ var timeout;
819
+ var getLocalHosts = () => {
820
+ const interfaces = import_node_os.default.networkInterfaces();
821
+ const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
822
+ for (const _interface of Object.values(interfaces)) {
823
+ for (const config of _interface) {
824
+ results.add(config.address);
850
825
  }
851
- throw new Error(
852
- `No available ports found in range ${startPort}-${maxPort}`
853
- );
854
826
  }
855
- /**
856
- * Check if a port is available for binding
857
- */
858
- isPortAvailable(port) {
859
- return new Promise((resolve) => {
860
- const server = (0, import_node_net.createServer)();
861
- server.once("error", () => {
862
- resolve(false);
863
- });
864
- server.once("listening", () => {
865
- server.close(() => {
866
- resolve(true);
867
- });
868
- });
869
- server.listen(port, "127.0.0.1");
827
+ return results;
828
+ };
829
+ var checkAvailablePort = (options) => new Promise((resolve, reject) => {
830
+ const server = import_node_net.default.createServer();
831
+ server.unref();
832
+ server.on("error", reject);
833
+ server.listen(options, () => {
834
+ const { port } = server.address();
835
+ server.close(() => {
836
+ resolve(port);
870
837
  });
838
+ });
839
+ });
840
+ var getAvailablePort = async (options, hosts) => {
841
+ if (options.host || options.port === 0) {
842
+ return checkAvailablePort(options);
871
843
  }
872
- /**
873
- * Allocate a local port for a logical port
874
- *
875
- * @param logicalPort The logical port number (USB hub position)
876
- * @param devicePort The device port to forward to
877
- * @returns The allocated port info
878
- */
879
- async allocate(logicalPort, devicePort) {
880
- const existing = this.allocations.get(logicalPort);
881
- if (existing) {
882
- logTask(`Reusing existing port allocation for logical port ${logicalPort}: ${existing.localPort}`);
883
- return existing;
844
+ for (const host of hosts) {
845
+ try {
846
+ await checkAvailablePort({ port: options.port, host });
847
+ } catch (error) {
848
+ if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) {
849
+ throw error;
850
+ }
884
851
  }
885
- const preferredPort = this.basePort + logicalPort;
886
- let localPort;
887
- const preferredAvailable = await this.isPortAvailable(preferredPort);
888
- if (preferredAvailable) {
889
- localPort = preferredPort;
890
- } else {
891
- localPort = await this.findAvailablePort(this.basePort);
852
+ }
853
+ return options.port;
854
+ };
855
+ var portCheckSequence = function* (ports) {
856
+ if (ports) {
857
+ yield* ports;
858
+ }
859
+ yield 0;
860
+ };
861
+ async function getPorts(options) {
862
+ let ports;
863
+ let exclude = /* @__PURE__ */ new Set();
864
+ if (options) {
865
+ if (options.port) {
866
+ ports = typeof options.port === "number" ? [options.port] : options.port;
867
+ }
868
+ if (options.exclude) {
869
+ const excludeIterable = options.exclude;
870
+ if (typeof excludeIterable[Symbol.iterator] !== "function") {
871
+ throw new TypeError("The `exclude` option must be an iterable.");
872
+ }
873
+ for (const element of excludeIterable) {
874
+ if (typeof element !== "number") {
875
+ throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");
876
+ }
877
+ if (!Number.isSafeInteger(element)) {
878
+ throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`);
879
+ }
880
+ }
881
+ exclude = new Set(excludeIterable);
892
882
  }
893
- const allocation = {
894
- logicalPort,
895
- localPort,
896
- devicePort
897
- };
898
- this.allocations.set(logicalPort, allocation);
899
- logTask(`Allocated port ${localPort} for logical port ${logicalPort} -> device port ${devicePort}`);
900
- return allocation;
901
883
  }
902
- /**
903
- * Release the port allocation for a logical port
904
- */
905
- release(logicalPort) {
906
- const allocation = this.allocations.get(logicalPort);
907
- if (allocation) {
908
- logTask(`Released port ${allocation.localPort} for logical port ${logicalPort}`);
909
- this.allocations.delete(logicalPort);
884
+ if (timeout === void 0) {
885
+ timeout = setTimeout(() => {
886
+ timeout = void 0;
887
+ lockedPorts.old = lockedPorts.young;
888
+ lockedPorts.young = /* @__PURE__ */ new Set();
889
+ }, releaseOldLockedPortsIntervalMs);
890
+ if (timeout.unref) {
891
+ timeout.unref();
910
892
  }
911
893
  }
912
- /**
913
- * Get the current allocation for a logical port
914
- */
915
- getAllocation(logicalPort) {
916
- return this.allocations.get(logicalPort);
894
+ const hosts = getLocalHosts();
895
+ for (const port of portCheckSequence(ports)) {
896
+ try {
897
+ if (exclude.has(port)) {
898
+ continue;
899
+ }
900
+ let availablePort = await getAvailablePort({ ...options, port }, hosts);
901
+ while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) {
902
+ if (port !== 0) {
903
+ throw new Locked(port);
904
+ }
905
+ availablePort = await getAvailablePort({ ...options, port }, hosts);
906
+ }
907
+ lockedPorts.young.add(availablePort);
908
+ return availablePort;
909
+ } catch (error) {
910
+ if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) {
911
+ throw error;
912
+ }
913
+ }
917
914
  }
918
- /**
919
- * Get all current allocations
920
- */
921
- getAllAllocations() {
922
- return Array.from(this.allocations.values());
915
+ throw new Error("No available ports found");
916
+ }
917
+ function portNumbers(from, to) {
918
+ if (!Number.isInteger(from) || !Number.isInteger(to)) {
919
+ throw new TypeError("`from` and `to` must be integer numbers");
923
920
  }
924
- /**
925
- * Release all allocations
926
- */
927
- releaseAll() {
928
- logTask(`Releasing all port allocations (${this.allocations.size} ports)`);
929
- this.allocations.clear();
921
+ if (from < minPort || from > maxPort) {
922
+ throw new RangeError(`'from' must be between ${minPort} and ${maxPort}`);
930
923
  }
931
- /**
932
- * Check if a logical port has an allocation
933
- */
934
- hasAllocation(logicalPort) {
935
- return this.allocations.has(logicalPort);
924
+ if (to < minPort || to > maxPort) {
925
+ throw new RangeError(`'to' must be between ${minPort} and ${maxPort}`);
936
926
  }
937
- };
938
- var sharedPortManager = null;
939
- function getSharedPortManager() {
940
- if (!sharedPortManager) {
941
- sharedPortManager = new PortManager();
927
+ if (from > to) {
928
+ throw new RangeError("`to` must be greater than or equal to `from`");
942
929
  }
943
- return sharedPortManager;
930
+ const generator = function* (from2, to2) {
931
+ for (let port = from2; port <= to2; port++) {
932
+ yield port;
933
+ }
934
+ };
935
+ return generator(from, to);
936
+ }
937
+
938
+ // src/utils/debug.ts
939
+ var import_debug = __toESM(require_src());
940
+ var debug = (0, import_debug.default)("apple-kit");
941
+ var debugTask = (0, import_debug.default)("apple-kit:task");
942
+ var debugWarning = (0, import_debug.default)("apple-kit:warning");
943
+ var debugError = (0, import_debug.default)("apple-kit:error");
944
+ function logInfo(message) {
945
+ debug(message);
946
+ }
947
+ function logTask(message) {
948
+ debugTask(message);
944
949
  }
945
950
 
946
951
  // src/logic/actions/device.ts
@@ -981,7 +986,15 @@ function parseAppList(output) {
981
986
  }
982
987
 
983
988
  // src/logic/actions/device.ts
989
+ var import_meta = {};
984
990
  var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
991
+ function getModuleDir() {
992
+ if (typeof import_meta !== "undefined" && import_meta.url) {
993
+ const { fileURLToPath } = require("node:url");
994
+ return (0, import_node_path.dirname)(fileURLToPath(import_meta.url));
995
+ }
996
+ return __dirname;
997
+ }
985
998
  async function getDeviceInfo(udid) {
986
999
  logTask(`Getting device info for ${udid}`);
987
1000
  const result = await runIDeviceTool("ideviceinfo", ["-u", udid]);
@@ -1010,12 +1023,17 @@ async function getDeviceInfo(udid) {
1010
1023
  };
1011
1024
  }
1012
1025
  async function runIDeviceTool(toolName, args = [], options = {}) {
1013
- const command = `"${toolName}${process.platform === "win32" ? ".exe" : ""}" ${args.map((a) => `"${a}"`).join(" ")}`;
1026
+ const binPath = getIDeviceBinPath();
1027
+ const ext = process.platform === "win32" ? ".exe" : "";
1028
+ const toolPath = binPath ? (0, import_node_path.join)(binPath, `${toolName}${ext}`) : `${toolName}${ext}`;
1029
+ const command = `"${toolPath}" ${args.map((a) => `"${a}"`).join(" ")}`;
1014
1030
  return execIDevice(command, options);
1015
1031
  }
1016
1032
  async function execIDevice(command, options = {}) {
1017
1033
  const binPath = getIDeviceBinPath();
1018
- options.cwd = binPath;
1034
+ if (binPath) {
1035
+ options.cwd = binPath;
1036
+ }
1019
1037
  const result = await execAsync(command, {
1020
1038
  ...options,
1021
1039
  env: process.env,
@@ -1027,12 +1045,66 @@ async function execIDevice(command, options = {}) {
1027
1045
  stderr: result.stderr.toString()
1028
1046
  };
1029
1047
  }
1048
+ function getPlatformDir() {
1049
+ const platform = process.platform;
1050
+ if (platform === "win32") {
1051
+ return "windows";
1052
+ }
1053
+ if (platform === "darwin") {
1054
+ return "darwin";
1055
+ }
1056
+ if (platform === "linux") {
1057
+ return "linux";
1058
+ }
1059
+ return platform;
1060
+ }
1061
+ function getBundledResourcesPath() {
1062
+ const moduleDir = getModuleDir();
1063
+ let packageRoot;
1064
+ if (moduleDir.includes("dist")) {
1065
+ packageRoot = (0, import_node_path.join)(moduleDir, "..", "..");
1066
+ } else {
1067
+ packageRoot = (0, import_node_path.join)(moduleDir, "..", "..", "..", "..");
1068
+ }
1069
+ const platformDir = getPlatformDir();
1070
+ const distPath = (0, import_node_path.join)(packageRoot, "dist", "resources", "bin", platformDir);
1071
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(distPath, "idevice_id")) || (0, import_node_fs.existsSync)((0, import_node_path.join)(distPath, "idevice_id.exe"))) {
1072
+ return distPath;
1073
+ }
1074
+ const devPath = (0, import_node_path.join)(packageRoot, "resources", "bin", platformDir);
1075
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(devPath, "idevice_id")) || (0, import_node_fs.existsSync)((0, import_node_path.join)(devPath, "idevice_id.exe"))) {
1076
+ return devPath;
1077
+ }
1078
+ return null;
1079
+ }
1030
1080
  function getResourcesBinPath() {
1031
- const binPath = process.env.IDeviceBinPath;
1032
- if (!binPath) {
1033
- throw new Error("IDeviceBinPath is not set");
1081
+ const envBinPath = process.env.IDeviceBinPath;
1082
+ if (envBinPath) {
1083
+ return envBinPath;
1084
+ }
1085
+ const bundledPath = getBundledResourcesPath();
1086
+ if (bundledPath) {
1087
+ return bundledPath;
1088
+ }
1089
+ if (process.platform === "darwin") {
1090
+ const homebrewArmPath = "/opt/homebrew/bin";
1091
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(homebrewArmPath, "idevice_id"))) {
1092
+ return homebrewArmPath;
1093
+ }
1094
+ const homebrewIntelPath = "/usr/local/bin";
1095
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(homebrewIntelPath, "idevice_id"))) {
1096
+ return homebrewIntelPath;
1097
+ }
1034
1098
  }
1035
- return binPath;
1099
+ if (process.platform === "linux") {
1100
+ const linuxPaths = ["/usr/bin", "/usr/local/bin"];
1101
+ for (const linuxPath of linuxPaths) {
1102
+ if ((0, import_node_fs.existsSync)((0, import_node_path.join)(linuxPath, "idevice_id"))) {
1103
+ return linuxPath;
1104
+ }
1105
+ }
1106
+ }
1107
+ return "";
1036
1108
  }
1037
1109
  function getIDeviceBinPath() {
1038
1110
  return getResourcesBinPath();
@@ -1089,7 +1161,7 @@ async function isPaired(udid) {
1089
1161
  return false;
1090
1162
  }
1091
1163
  }
1092
- async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1164
+ async function trustDevice(udid, timeout2 = 6e4, onWaitingForTrust) {
1093
1165
  logTask(`Trusting device ${udid}`);
1094
1166
  if (await isPaired(udid)) {
1095
1167
  logInfo(`Device ${udid} is already trusted`);
@@ -1104,7 +1176,7 @@ async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1104
1176
  logInfo("Please accept the trust dialog on the device...");
1105
1177
  onWaitingForTrust?.();
1106
1178
  try {
1107
- await waitForPairing(udid, timeout, 1e3);
1179
+ await waitForPairing(udid, timeout2, 1e3);
1108
1180
  logInfo(`Device ${udid} is now trusted`);
1109
1181
  return true;
1110
1182
  } catch {
@@ -1112,17 +1184,17 @@ async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1112
1184
  return false;
1113
1185
  }
1114
1186
  }
1115
- async function waitForPairing(udid, timeout = 12e4, pollInterval = 1e3) {
1187
+ async function waitForPairing(udid, timeout2 = 12e4, pollInterval = 1e3) {
1116
1188
  logTask(`Waiting for pairing on device ${udid}`);
1117
1189
  const startTime = Date.now();
1118
- while (Date.now() - startTime < timeout) {
1190
+ while (Date.now() - startTime < timeout2) {
1119
1191
  if (await isPaired(udid)) {
1120
1192
  logInfo(`Device ${udid} is now paired`);
1121
1193
  return true;
1122
1194
  }
1123
1195
  await new Promise((resolve) => setTimeout(resolve, pollInterval));
1124
1196
  }
1125
- throw new Error(`Timeout waiting for device pairing after ${timeout}ms`);
1197
+ throw new Error(`Timeout waiting for device pairing after ${timeout2}ms`);
1126
1198
  }
1127
1199
  async function pair(udid) {
1128
1200
  logTask(`Initiating pairing for device ${udid}`);
@@ -1341,27 +1413,94 @@ async function launchAppWithPymobiledevice3(bundleId, args, udid) {
1341
1413
 
1342
1414
  // src/logic/actions/proxy.ts
1343
1415
  var import_node_child_process2 = require("node:child_process");
1416
+ var import_node_fs2 = require("node:fs");
1344
1417
  var import_node_path2 = require("node:path");
1418
+ var import_meta2 = {};
1419
+ function getModuleDir2() {
1420
+ if (typeof import_meta2 !== "undefined" && import_meta2.url) {
1421
+ const { fileURLToPath } = require("node:url");
1422
+ return (0, import_node_path2.dirname)(fileURLToPath(import_meta2.url));
1423
+ }
1424
+ return __dirname;
1425
+ }
1426
+ function getPlatformDir2() {
1427
+ const platform = process.platform;
1428
+ if (platform === "win32") {
1429
+ return "windows";
1430
+ }
1431
+ if (platform === "darwin") {
1432
+ return "darwin";
1433
+ }
1434
+ if (platform === "linux") {
1435
+ return "linux";
1436
+ }
1437
+ return platform;
1438
+ }
1439
+ function getBundledResourcesPath2() {
1440
+ const moduleDir = getModuleDir2();
1441
+ let packageRoot;
1442
+ if (moduleDir.includes("dist")) {
1443
+ packageRoot = (0, import_node_path2.join)(moduleDir, "..", "..");
1444
+ } else {
1445
+ packageRoot = (0, import_node_path2.join)(moduleDir, "..", "..", "..", "..");
1446
+ }
1447
+ const platformDir = getPlatformDir2();
1448
+ const distPath = (0, import_node_path2.join)(packageRoot, "dist", "resources", "bin", platformDir);
1449
+ if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(distPath, "iproxy")) || (0, import_node_fs2.existsSync)((0, import_node_path2.join)(distPath, "iproxy.exe"))) {
1450
+ return distPath;
1451
+ }
1452
+ const devPath = (0, import_node_path2.join)(packageRoot, "resources", "bin", platformDir);
1453
+ if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(devPath, "iproxy")) || (0, import_node_fs2.existsSync)((0, import_node_path2.join)(devPath, "iproxy.exe"))) {
1454
+ return devPath;
1455
+ }
1456
+ return null;
1457
+ }
1345
1458
  function getResourcesBinPath2() {
1346
- const binPath = process.env.IDeviceBinPath;
1347
- if (!binPath) {
1348
- throw new Error("IDeviceBinPath is not set");
1459
+ const envBinPath = process.env.IDeviceBinPath;
1460
+ if (envBinPath) {
1461
+ return envBinPath;
1462
+ }
1463
+ const bundledPath = getBundledResourcesPath2();
1464
+ if (bundledPath) {
1465
+ return bundledPath;
1466
+ }
1467
+ if (process.platform === "darwin") {
1468
+ const homebrewArmPath = "/opt/homebrew/bin";
1469
+ if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(homebrewArmPath, "iproxy"))) {
1470
+ return homebrewArmPath;
1471
+ }
1472
+ const homebrewIntelPath = "/usr/local/bin";
1473
+ if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(homebrewIntelPath, "iproxy"))) {
1474
+ return homebrewIntelPath;
1475
+ }
1476
+ }
1477
+ if (process.platform === "linux") {
1478
+ const linuxPaths = ["/usr/bin", "/usr/local/bin"];
1479
+ for (const linuxPath of linuxPaths) {
1480
+ if ((0, import_node_fs2.existsSync)((0, import_node_path2.join)(linuxPath, "iproxy"))) {
1481
+ return linuxPath;
1482
+ }
1483
+ }
1349
1484
  }
1350
- return binPath;
1485
+ return "";
1351
1486
  }
1352
1487
  function startPortForward(localPort, devicePort, udid, startupTimeout = 500) {
1353
1488
  return new Promise((resolve, reject) => {
1354
1489
  logTask(`Starting port forward ${localPort} -> ${devicePort} for device ${udid}`);
1355
1490
  const binPath = getResourcesBinPath2();
1356
- const toolPath = (0, import_node_path2.join)(binPath, `iproxy${process.platform === "win32" ? ".exe" : ""}`);
1491
+ const ext = process.platform === "win32" ? ".exe" : "";
1492
+ const toolPath = binPath ? (0, import_node_path2.join)(binPath, `iproxy${ext}`) : `iproxy${ext}`;
1493
+ const spawnOptions = {
1494
+ windowsHide: true,
1495
+ stdio: ["ignore", "pipe", "pipe"]
1496
+ };
1497
+ if (binPath) {
1498
+ spawnOptions.cwd = binPath;
1499
+ }
1357
1500
  const child = (0, import_node_child_process2.spawn)(
1358
1501
  toolPath,
1359
1502
  [localPort.toString(), devicePort.toString(), "-u", udid],
1360
- {
1361
- cwd: binPath,
1362
- windowsHide: true,
1363
- stdio: ["ignore", "pipe", "pipe"]
1364
- }
1503
+ spawnOptions
1365
1504
  );
1366
1505
  let hasResolved = false;
1367
1506
  let stderrOutput = "";
@@ -1415,11 +1554,13 @@ var AppleDeviceKit = class {
1415
1554
  constructor(udid, logicalPort) {
1416
1555
  this.logicalPort = logicalPort;
1417
1556
  this.deviceId = udid;
1418
- logInfo(`AppleDeviceKit initialized for device: ${this.deviceId}, logical port: ${this.logicalPort}`);
1557
+ logInfo(
1558
+ `AppleDeviceKit initialized for device: ${this.deviceId}, logical port: ${this.logicalPort}`
1559
+ );
1419
1560
  }
1420
1561
  deviceId;
1421
1562
  proxyProcess = null;
1422
- portAllocation = null;
1563
+ localDevicePort = null;
1423
1564
  isDisposed = false;
1424
1565
  /**
1425
1566
  * Throws if the kit has been disposed
@@ -1450,9 +1591,9 @@ var AppleDeviceKit = class {
1450
1591
  * @param timeout Timeout in milliseconds (default: 120000)
1451
1592
  * @param pollInterval Poll interval in milliseconds (default: 1000)
1452
1593
  */
1453
- async waitForPairing(timeout = 12e4, pollInterval = 1e3) {
1594
+ async waitForPairing(timeout2 = 12e4, pollInterval = 1e3) {
1454
1595
  this.ensureNotDisposed();
1455
- return waitForPairing(this.deviceId, timeout, pollInterval);
1596
+ return waitForPairing(this.deviceId, timeout2, pollInterval);
1456
1597
  }
1457
1598
  /**
1458
1599
  * Attempt to pair/trust the device
@@ -1475,9 +1616,9 @@ var AppleDeviceKit = class {
1475
1616
  * @param onWaitingForTrust Callback when waiting for user to accept trust dialog
1476
1617
  * @returns true if device is now trusted
1477
1618
  */
1478
- async trustDevice(timeout = 6e4, onWaitingForTrust) {
1619
+ async trustDevice(timeout2 = 6e4, onWaitingForTrust) {
1479
1620
  this.ensureNotDisposed();
1480
- return trustDevice(this.deviceId, timeout, onWaitingForTrust);
1621
+ return trustDevice(this.deviceId, timeout2, onWaitingForTrust);
1481
1622
  }
1482
1623
  /**
1483
1624
  * Unpair/untrust the device
@@ -1547,10 +1688,9 @@ var AppleDeviceKit = class {
1547
1688
  async startPortForwardAsync(devicePort, startupTimeout = 500) {
1548
1689
  this.ensureNotDisposed();
1549
1690
  this.killProxyProcess();
1550
- const portManager = getSharedPortManager();
1551
- this.portAllocation = await portManager.allocate(this.logicalPort, devicePort);
1691
+ this.localDevicePort = await getPorts({ port: portNumbers(3e4, 31e3) });
1552
1692
  const { result, process: process2 } = await startPortForward(
1553
- this.portAllocation.localPort,
1693
+ this.localDevicePort,
1554
1694
  devicePort,
1555
1695
  this.deviceId,
1556
1696
  startupTimeout
@@ -1572,10 +1712,8 @@ var AppleDeviceKit = class {
1572
1712
  */
1573
1713
  closePortForward() {
1574
1714
  this.killProxyProcess();
1575
- if (this.portAllocation) {
1576
- const portManager = getSharedPortManager();
1577
- portManager.release(this.logicalPort);
1578
- this.portAllocation = null;
1715
+ if (this.localDevicePort) {
1716
+ this.localDevicePort = null;
1579
1717
  }
1580
1718
  }
1581
1719
  /**
@@ -1615,14 +1753,8 @@ var AppleDeviceKit = class {
1615
1753
  * Get the currently allocated local port for forwarding
1616
1754
  * Returns undefined if no port forward is active
1617
1755
  */
1618
- getAllocatedPort() {
1619
- return this.portAllocation?.localPort;
1620
- }
1621
- /**
1622
- * Get the current port allocation info
1623
- */
1624
- getPortAllocation() {
1625
- return this.portAllocation;
1756
+ getDevicePort() {
1757
+ return this.localDevicePort;
1626
1758
  }
1627
1759
  /**
1628
1760
  * Check if this kit has been disposed
@@ -1659,8 +1791,6 @@ var AppleDeviceKit = class {
1659
1791
  };
1660
1792
  // Annotate the CommonJS export names for ESM import in node:
1661
1793
  0 && (module.exports = {
1662
- AppleDeviceKit,
1663
- PortManager,
1664
- getSharedPortManager
1794
+ AppleDeviceKit
1665
1795
  });
1666
1796
  //# sourceMappingURL=index.js.map