@mcesystems/apple-kit 1.0.23 → 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.mjs 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"(exports, module) {
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
  }
@@ -793,145 +793,152 @@ var require_src = __commonJS({
793
793
  }
794
794
  });
795
795
 
796
- // src/utils/debug.ts
797
- var import_debug = __toESM(require_src());
798
- var debug = (0, import_debug.default)("apple-kit");
799
- var debugTask = (0, import_debug.default)("apple-kit:task");
800
- var debugWarning = (0, import_debug.default)("apple-kit:warning");
801
- var debugError = (0, import_debug.default)("apple-kit:error");
802
- function logInfo(message) {
803
- debug(message);
804
- }
805
- function logTask(message) {
806
- debugTask(message);
807
- }
808
-
809
- // src/utils/portManager.ts
810
- import { createServer } from "node:net";
811
- var PortManager = class {
812
- allocations = /* @__PURE__ */ new Map();
813
- basePort;
814
- maxPortRange;
815
- /**
816
- * Create a new PortManager
817
- *
818
- * @param basePort Starting port number for allocation (default: 30000)
819
- * @param maxPortRange Maximum range of ports to search (default: 1000)
820
- */
821
- constructor(basePort = 3e4, maxPortRange = 1e3) {
822
- this.basePort = basePort;
823
- this.maxPortRange = maxPortRange;
796
+ // ../../node_modules/.pnpm/get-port@7.1.0/node_modules/get-port/index.js
797
+ import net from "node:net";
798
+ import os from "node:os";
799
+ var Locked = class extends Error {
800
+ constructor(port) {
801
+ super(`${port} is locked`);
824
802
  }
825
- /**
826
- * Find an available port starting from the given port number
827
- */
828
- async findAvailablePort(startPort) {
829
- const maxPort = this.basePort + this.maxPortRange;
830
- for (let port = startPort; port < maxPort; port++) {
831
- const isAllocated = Array.from(this.allocations.values()).some(
832
- (a) => a.localPort === port
833
- );
834
- if (isAllocated) {
835
- continue;
836
- }
837
- const isAvailable = await this.isPortAvailable(port);
838
- if (isAvailable) {
839
- return port;
840
- }
803
+ };
804
+ var lockedPorts = {
805
+ old: /* @__PURE__ */ new Set(),
806
+ young: /* @__PURE__ */ new Set()
807
+ };
808
+ var releaseOldLockedPortsIntervalMs = 1e3 * 15;
809
+ var minPort = 1024;
810
+ var maxPort = 65535;
811
+ var timeout;
812
+ var getLocalHosts = () => {
813
+ const interfaces = os.networkInterfaces();
814
+ const results = /* @__PURE__ */ new Set([void 0, "0.0.0.0"]);
815
+ for (const _interface of Object.values(interfaces)) {
816
+ for (const config of _interface) {
817
+ results.add(config.address);
841
818
  }
842
- throw new Error(
843
- `No available ports found in range ${startPort}-${maxPort}`
844
- );
845
819
  }
846
- /**
847
- * Check if a port is available for binding
848
- */
849
- isPortAvailable(port) {
850
- return new Promise((resolve) => {
851
- const server = createServer();
852
- server.once("error", () => {
853
- resolve(false);
854
- });
855
- server.once("listening", () => {
856
- server.close(() => {
857
- resolve(true);
858
- });
859
- });
860
- server.listen(port, "127.0.0.1");
820
+ return results;
821
+ };
822
+ var checkAvailablePort = (options) => new Promise((resolve, reject) => {
823
+ const server = net.createServer();
824
+ server.unref();
825
+ server.on("error", reject);
826
+ server.listen(options, () => {
827
+ const { port } = server.address();
828
+ server.close(() => {
829
+ resolve(port);
861
830
  });
831
+ });
832
+ });
833
+ var getAvailablePort = async (options, hosts) => {
834
+ if (options.host || options.port === 0) {
835
+ return checkAvailablePort(options);
862
836
  }
863
- /**
864
- * Allocate a local port for a logical port
865
- *
866
- * @param logicalPort The logical port number (USB hub position)
867
- * @param devicePort The device port to forward to
868
- * @returns The allocated port info
869
- */
870
- async allocate(logicalPort, devicePort) {
871
- const existing = this.allocations.get(logicalPort);
872
- if (existing) {
873
- logTask(`Reusing existing port allocation for logical port ${logicalPort}: ${existing.localPort}`);
874
- return existing;
837
+ for (const host of hosts) {
838
+ try {
839
+ await checkAvailablePort({ port: options.port, host });
840
+ } catch (error) {
841
+ if (!["EADDRNOTAVAIL", "EINVAL"].includes(error.code)) {
842
+ throw error;
843
+ }
875
844
  }
876
- const preferredPort = this.basePort + logicalPort;
877
- let localPort;
878
- const preferredAvailable = await this.isPortAvailable(preferredPort);
879
- if (preferredAvailable) {
880
- localPort = preferredPort;
881
- } else {
882
- localPort = await this.findAvailablePort(this.basePort);
845
+ }
846
+ return options.port;
847
+ };
848
+ var portCheckSequence = function* (ports) {
849
+ if (ports) {
850
+ yield* ports;
851
+ }
852
+ yield 0;
853
+ };
854
+ async function getPorts(options) {
855
+ let ports;
856
+ let exclude = /* @__PURE__ */ new Set();
857
+ if (options) {
858
+ if (options.port) {
859
+ ports = typeof options.port === "number" ? [options.port] : options.port;
860
+ }
861
+ if (options.exclude) {
862
+ const excludeIterable = options.exclude;
863
+ if (typeof excludeIterable[Symbol.iterator] !== "function") {
864
+ throw new TypeError("The `exclude` option must be an iterable.");
865
+ }
866
+ for (const element of excludeIterable) {
867
+ if (typeof element !== "number") {
868
+ throw new TypeError("Each item in the `exclude` option must be a number corresponding to the port you want excluded.");
869
+ }
870
+ if (!Number.isSafeInteger(element)) {
871
+ throw new TypeError(`Number ${element} in the exclude option is not a safe integer and can't be used`);
872
+ }
873
+ }
874
+ exclude = new Set(excludeIterable);
883
875
  }
884
- const allocation = {
885
- logicalPort,
886
- localPort,
887
- devicePort
888
- };
889
- this.allocations.set(logicalPort, allocation);
890
- logTask(`Allocated port ${localPort} for logical port ${logicalPort} -> device port ${devicePort}`);
891
- return allocation;
892
876
  }
893
- /**
894
- * Release the port allocation for a logical port
895
- */
896
- release(logicalPort) {
897
- const allocation = this.allocations.get(logicalPort);
898
- if (allocation) {
899
- logTask(`Released port ${allocation.localPort} for logical port ${logicalPort}`);
900
- this.allocations.delete(logicalPort);
877
+ if (timeout === void 0) {
878
+ timeout = setTimeout(() => {
879
+ timeout = void 0;
880
+ lockedPorts.old = lockedPorts.young;
881
+ lockedPorts.young = /* @__PURE__ */ new Set();
882
+ }, releaseOldLockedPortsIntervalMs);
883
+ if (timeout.unref) {
884
+ timeout.unref();
901
885
  }
902
886
  }
903
- /**
904
- * Get the current allocation for a logical port
905
- */
906
- getAllocation(logicalPort) {
907
- return this.allocations.get(logicalPort);
887
+ const hosts = getLocalHosts();
888
+ for (const port of portCheckSequence(ports)) {
889
+ try {
890
+ if (exclude.has(port)) {
891
+ continue;
892
+ }
893
+ let availablePort = await getAvailablePort({ ...options, port }, hosts);
894
+ while (lockedPorts.old.has(availablePort) || lockedPorts.young.has(availablePort)) {
895
+ if (port !== 0) {
896
+ throw new Locked(port);
897
+ }
898
+ availablePort = await getAvailablePort({ ...options, port }, hosts);
899
+ }
900
+ lockedPorts.young.add(availablePort);
901
+ return availablePort;
902
+ } catch (error) {
903
+ if (!["EADDRINUSE", "EACCES"].includes(error.code) && !(error instanceof Locked)) {
904
+ throw error;
905
+ }
906
+ }
908
907
  }
909
- /**
910
- * Get all current allocations
911
- */
912
- getAllAllocations() {
913
- return Array.from(this.allocations.values());
908
+ throw new Error("No available ports found");
909
+ }
910
+ function portNumbers(from, to) {
911
+ if (!Number.isInteger(from) || !Number.isInteger(to)) {
912
+ throw new TypeError("`from` and `to` must be integer numbers");
914
913
  }
915
- /**
916
- * Release all allocations
917
- */
918
- releaseAll() {
919
- logTask(`Releasing all port allocations (${this.allocations.size} ports)`);
920
- this.allocations.clear();
914
+ if (from < minPort || from > maxPort) {
915
+ throw new RangeError(`'from' must be between ${minPort} and ${maxPort}`);
921
916
  }
922
- /**
923
- * Check if a logical port has an allocation
924
- */
925
- hasAllocation(logicalPort) {
926
- return this.allocations.has(logicalPort);
917
+ if (to < minPort || to > maxPort) {
918
+ throw new RangeError(`'to' must be between ${minPort} and ${maxPort}`);
927
919
  }
928
- };
929
- var sharedPortManager = null;
930
- function getSharedPortManager() {
931
- if (!sharedPortManager) {
932
- sharedPortManager = new PortManager();
920
+ if (from > to) {
921
+ throw new RangeError("`to` must be greater than or equal to `from`");
933
922
  }
934
- return sharedPortManager;
923
+ const generator = function* (from2, to2) {
924
+ for (let port = from2; port <= to2; port++) {
925
+ yield port;
926
+ }
927
+ };
928
+ return generator(from, to);
929
+ }
930
+
931
+ // src/utils/debug.ts
932
+ var import_debug = __toESM(require_src());
933
+ var debug = (0, import_debug.default)("apple-kit");
934
+ var debugTask = (0, import_debug.default)("apple-kit:task");
935
+ var debugWarning = (0, import_debug.default)("apple-kit:warning");
936
+ var debugError = (0, import_debug.default)("apple-kit:error");
937
+ function logInfo(message) {
938
+ debug(message);
939
+ }
940
+ function logTask(message) {
941
+ debugTask(message);
935
942
  }
936
943
 
937
944
  // src/logic/actions/device.ts
@@ -1080,7 +1087,7 @@ async function isPaired(udid) {
1080
1087
  return false;
1081
1088
  }
1082
1089
  }
1083
- async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1090
+ async function trustDevice(udid, timeout2 = 6e4, onWaitingForTrust) {
1084
1091
  logTask(`Trusting device ${udid}`);
1085
1092
  if (await isPaired(udid)) {
1086
1093
  logInfo(`Device ${udid} is already trusted`);
@@ -1095,7 +1102,7 @@ async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1095
1102
  logInfo("Please accept the trust dialog on the device...");
1096
1103
  onWaitingForTrust?.();
1097
1104
  try {
1098
- await waitForPairing(udid, timeout, 1e3);
1105
+ await waitForPairing(udid, timeout2, 1e3);
1099
1106
  logInfo(`Device ${udid} is now trusted`);
1100
1107
  return true;
1101
1108
  } catch {
@@ -1103,17 +1110,17 @@ async function trustDevice(udid, timeout = 6e4, onWaitingForTrust) {
1103
1110
  return false;
1104
1111
  }
1105
1112
  }
1106
- async function waitForPairing(udid, timeout = 12e4, pollInterval = 1e3) {
1113
+ async function waitForPairing(udid, timeout2 = 12e4, pollInterval = 1e3) {
1107
1114
  logTask(`Waiting for pairing on device ${udid}`);
1108
1115
  const startTime = Date.now();
1109
- while (Date.now() - startTime < timeout) {
1116
+ while (Date.now() - startTime < timeout2) {
1110
1117
  if (await isPaired(udid)) {
1111
1118
  logInfo(`Device ${udid} is now paired`);
1112
1119
  return true;
1113
1120
  }
1114
1121
  await new Promise((resolve) => setTimeout(resolve, pollInterval));
1115
1122
  }
1116
- throw new Error(`Timeout waiting for device pairing after ${timeout}ms`);
1123
+ throw new Error(`Timeout waiting for device pairing after ${timeout2}ms`);
1117
1124
  }
1118
1125
  async function pair(udid) {
1119
1126
  logTask(`Initiating pairing for device ${udid}`);
@@ -1406,11 +1413,13 @@ var AppleDeviceKit = class {
1406
1413
  constructor(udid, logicalPort) {
1407
1414
  this.logicalPort = logicalPort;
1408
1415
  this.deviceId = udid;
1409
- logInfo(`AppleDeviceKit initialized for device: ${this.deviceId}, logical port: ${this.logicalPort}`);
1416
+ logInfo(
1417
+ `AppleDeviceKit initialized for device: ${this.deviceId}, logical port: ${this.logicalPort}`
1418
+ );
1410
1419
  }
1411
1420
  deviceId;
1412
1421
  proxyProcess = null;
1413
- portAllocation = null;
1422
+ devicePort = null;
1414
1423
  isDisposed = false;
1415
1424
  /**
1416
1425
  * Throws if the kit has been disposed
@@ -1441,9 +1450,9 @@ var AppleDeviceKit = class {
1441
1450
  * @param timeout Timeout in milliseconds (default: 120000)
1442
1451
  * @param pollInterval Poll interval in milliseconds (default: 1000)
1443
1452
  */
1444
- async waitForPairing(timeout = 12e4, pollInterval = 1e3) {
1453
+ async waitForPairing(timeout2 = 12e4, pollInterval = 1e3) {
1445
1454
  this.ensureNotDisposed();
1446
- return waitForPairing(this.deviceId, timeout, pollInterval);
1455
+ return waitForPairing(this.deviceId, timeout2, pollInterval);
1447
1456
  }
1448
1457
  /**
1449
1458
  * Attempt to pair/trust the device
@@ -1466,9 +1475,9 @@ var AppleDeviceKit = class {
1466
1475
  * @param onWaitingForTrust Callback when waiting for user to accept trust dialog
1467
1476
  * @returns true if device is now trusted
1468
1477
  */
1469
- async trustDevice(timeout = 6e4, onWaitingForTrust) {
1478
+ async trustDevice(timeout2 = 6e4, onWaitingForTrust) {
1470
1479
  this.ensureNotDisposed();
1471
- return trustDevice(this.deviceId, timeout, onWaitingForTrust);
1480
+ return trustDevice(this.deviceId, timeout2, onWaitingForTrust);
1472
1481
  }
1473
1482
  /**
1474
1483
  * Unpair/untrust the device
@@ -1538,10 +1547,9 @@ var AppleDeviceKit = class {
1538
1547
  async startPortForwardAsync(devicePort, startupTimeout = 500) {
1539
1548
  this.ensureNotDisposed();
1540
1549
  this.killProxyProcess();
1541
- const portManager = getSharedPortManager();
1542
- this.portAllocation = await portManager.allocate(this.logicalPort, devicePort);
1550
+ this.devicePort = await getPorts({ port: portNumbers(3e4, 31e3) });
1543
1551
  const { result, process: process2 } = await startPortForward(
1544
- this.portAllocation.localPort,
1552
+ this.devicePort,
1545
1553
  devicePort,
1546
1554
  this.deviceId,
1547
1555
  startupTimeout
@@ -1563,10 +1571,8 @@ var AppleDeviceKit = class {
1563
1571
  */
1564
1572
  closePortForward() {
1565
1573
  this.killProxyProcess();
1566
- if (this.portAllocation) {
1567
- const portManager = getSharedPortManager();
1568
- portManager.release(this.logicalPort);
1569
- this.portAllocation = null;
1574
+ if (this.devicePort) {
1575
+ this.devicePort = null;
1570
1576
  }
1571
1577
  }
1572
1578
  /**
@@ -1606,14 +1612,8 @@ var AppleDeviceKit = class {
1606
1612
  * Get the currently allocated local port for forwarding
1607
1613
  * Returns undefined if no port forward is active
1608
1614
  */
1609
- getAllocatedPort() {
1610
- return this.portAllocation?.localPort;
1611
- }
1612
- /**
1613
- * Get the current port allocation info
1614
- */
1615
- getPortAllocation() {
1616
- return this.portAllocation;
1615
+ getDevicePort() {
1616
+ return this.devicePort;
1617
1617
  }
1618
1618
  /**
1619
1619
  * Check if this kit has been disposed
@@ -1649,8 +1649,6 @@ var AppleDeviceKit = class {
1649
1649
  }
1650
1650
  };
1651
1651
  export {
1652
- AppleDeviceKit,
1653
- PortManager,
1654
- getSharedPortManager
1652
+ AppleDeviceKit
1655
1653
  };
1656
1654
  //# sourceMappingURL=index.mjs.map