@mcesystems/apple-kit 1.0.22 → 1.0.24

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/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
@@ -1089,7 +1094,7 @@ async function isPaired(udid) {
1089
1094
  return false;
1090
1095
  }
1091
1096
  }
1092
- async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1097
+ async function trustDevice(udid, timeout2 = 6e4, onWaitingForTrust) {
1093
1098
  logTask(`Trusting device ${udid}`);
1094
1099
  if (await isPaired(udid)) {
1095
1100
  logInfo(`Device ${udid} is already trusted`);
@@ -1104,7 +1109,7 @@ async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1104
1109
  logInfo("Please accept the trust dialog on the device...");
1105
1110
  onWaitingForTrust?.();
1106
1111
  try {
1107
- await waitForPairing(udid, timeout, 1e3);
1112
+ await waitForPairing(udid, timeout2, 1e3);
1108
1113
  logInfo(`Device ${udid} is now trusted`);
1109
1114
  return true;
1110
1115
  } catch {
@@ -1112,17 +1117,17 @@ async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1112
1117
  return false;
1113
1118
  }
1114
1119
  }
1115
- async function waitForPairing(udid, timeout = 12e4, pollInterval = 1e3) {
1120
+ async function waitForPairing(udid, timeout2 = 12e4, pollInterval = 1e3) {
1116
1121
  logTask(`Waiting for pairing on device ${udid}`);
1117
1122
  const startTime = Date.now();
1118
- while (Date.now() - startTime < timeout) {
1123
+ while (Date.now() - startTime < timeout2) {
1119
1124
  if (await isPaired(udid)) {
1120
1125
  logInfo(`Device ${udid} is now paired`);
1121
1126
  return true;
1122
1127
  }
1123
1128
  await new Promise((resolve) => setTimeout(resolve, pollInterval));
1124
1129
  }
1125
- throw new Error(`Timeout waiting for device pairing after ${timeout}ms`);
1130
+ throw new Error(`Timeout waiting for device pairing after ${timeout2}ms`);
1126
1131
  }
1127
1132
  async function pair(udid) {
1128
1133
  logTask(`Initiating pairing for device ${udid}`);
@@ -1415,11 +1420,13 @@ var AppleDeviceKit = class {
1415
1420
  constructor(udid, logicalPort) {
1416
1421
  this.logicalPort = logicalPort;
1417
1422
  this.deviceId = udid;
1418
- logInfo(`AppleDeviceKit initialized for device: ${this.deviceId}, logical port: ${this.logicalPort}`);
1423
+ logInfo(
1424
+ `AppleDeviceKit initialized for device: ${this.deviceId}, logical port: ${this.logicalPort}`
1425
+ );
1419
1426
  }
1420
1427
  deviceId;
1421
1428
  proxyProcess = null;
1422
- portAllocation = null;
1429
+ devicePort = null;
1423
1430
  isDisposed = false;
1424
1431
  /**
1425
1432
  * Throws if the kit has been disposed
@@ -1450,9 +1457,9 @@ var AppleDeviceKit = class {
1450
1457
  * @param timeout Timeout in milliseconds (default: 120000)
1451
1458
  * @param pollInterval Poll interval in milliseconds (default: 1000)
1452
1459
  */
1453
- async waitForPairing(timeout = 12e4, pollInterval = 1e3) {
1460
+ async waitForPairing(timeout2 = 12e4, pollInterval = 1e3) {
1454
1461
  this.ensureNotDisposed();
1455
- return waitForPairing(this.deviceId, timeout, pollInterval);
1462
+ return waitForPairing(this.deviceId, timeout2, pollInterval);
1456
1463
  }
1457
1464
  /**
1458
1465
  * Attempt to pair/trust the device
@@ -1475,9 +1482,9 @@ var AppleDeviceKit = class {
1475
1482
  * @param onWaitingForTrust Callback when waiting for user to accept trust dialog
1476
1483
  * @returns true if device is now trusted
1477
1484
  */
1478
- async trustDevice(timeout = 6e4, onWaitingForTrust) {
1485
+ async trustDevice(timeout2 = 6e4, onWaitingForTrust) {
1479
1486
  this.ensureNotDisposed();
1480
- return trustDevice(this.deviceId, timeout, onWaitingForTrust);
1487
+ return trustDevice(this.deviceId, timeout2, onWaitingForTrust);
1481
1488
  }
1482
1489
  /**
1483
1490
  * Unpair/untrust the device
@@ -1547,10 +1554,9 @@ var AppleDeviceKit = class {
1547
1554
  async startPortForwardAsync(devicePort, startupTimeout = 500) {
1548
1555
  this.ensureNotDisposed();
1549
1556
  this.killProxyProcess();
1550
- const portManager = getSharedPortManager();
1551
- this.portAllocation = await portManager.allocate(this.logicalPort, devicePort);
1557
+ this.devicePort = await getPorts({ port: portNumbers(3e4, 31e3) });
1552
1558
  const { result, process: process2 } = await startPortForward(
1553
- this.portAllocation.localPort,
1559
+ this.devicePort,
1554
1560
  devicePort,
1555
1561
  this.deviceId,
1556
1562
  startupTimeout
@@ -1572,10 +1578,8 @@ var AppleDeviceKit = class {
1572
1578
  */
1573
1579
  closePortForward() {
1574
1580
  this.killProxyProcess();
1575
- if (this.portAllocation) {
1576
- const portManager = getSharedPortManager();
1577
- portManager.release(this.logicalPort);
1578
- this.portAllocation = null;
1581
+ if (this.devicePort) {
1582
+ this.devicePort = null;
1579
1583
  }
1580
1584
  }
1581
1585
  /**
@@ -1615,14 +1619,8 @@ var AppleDeviceKit = class {
1615
1619
  * Get the currently allocated local port for forwarding
1616
1620
  * Returns undefined if no port forward is active
1617
1621
  */
1618
- getAllocatedPort() {
1619
- return this.portAllocation?.localPort;
1620
- }
1621
- /**
1622
- * Get the current port allocation info
1623
- */
1624
- getPortAllocation() {
1625
- return this.portAllocation;
1622
+ getDevicePort() {
1623
+ return this.devicePort;
1626
1624
  }
1627
1625
  /**
1628
1626
  * Check if this kit has been disposed
@@ -1659,8 +1657,6 @@ var AppleDeviceKit = class {
1659
1657
  };
1660
1658
  // Annotate the CommonJS export names for ESM import in node:
1661
1659
  0 && (module.exports = {
1662
- AppleDeviceKit,
1663
- PortManager,
1664
- getSharedPortManager
1660
+ AppleDeviceKit
1665
1661
  });
1666
1662
  //# sourceMappingURL=index.js.map