@mcesystems/apple-kit 1.0.0

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 (47) hide show
  1. package/README.md +250 -0
  2. package/dist/index.js +680 -0
  3. package/dist/index.js.map +7 -0
  4. package/dist/types/index.d.ts +11 -0
  5. package/dist/types/index.d.ts.map +1 -0
  6. package/dist/types/logic/appleDeviceKit.d.ts +68 -0
  7. package/dist/types/logic/appleDeviceKit.d.ts.map +1 -0
  8. package/dist/types/logic/devicesMonitor.d.ts +45 -0
  9. package/dist/types/logic/devicesMonitor.d.ts.map +1 -0
  10. package/dist/types/types.d.ts +127 -0
  11. package/dist/types/types.d.ts.map +1 -0
  12. package/dist/types/utils/debug.d.ts +9 -0
  13. package/dist/types/utils/debug.d.ts.map +1 -0
  14. package/dist/types/utils/exec.d.ts +14 -0
  15. package/dist/types/utils/exec.d.ts.map +1 -0
  16. package/dist/types/utils/idevicePath.d.ts +19 -0
  17. package/dist/types/utils/idevicePath.d.ts.map +1 -0
  18. package/package.json +63 -0
  19. package/resources/bin/windows/bz2.dll +0 -0
  20. package/resources/bin/windows/getopt.dll +0 -0
  21. package/resources/bin/windows/iconv-2.dll +0 -0
  22. package/resources/bin/windows/idevice_id.exe +0 -0
  23. package/resources/bin/windows/ideviceactivation.exe +0 -0
  24. package/resources/bin/windows/idevicedebug.exe +0 -0
  25. package/resources/bin/windows/ideviceinfo.exe +0 -0
  26. package/resources/bin/windows/ideviceinstaller.exe +0 -0
  27. package/resources/bin/windows/idevicepair.exe +0 -0
  28. package/resources/bin/windows/imobiledevice.dll +0 -0
  29. package/resources/bin/windows/iproxy.exe +0 -0
  30. package/resources/bin/windows/libcrypto-1_1-x64.dll +0 -0
  31. package/resources/bin/windows/libcurl.dll +0 -0
  32. package/resources/bin/windows/libssl-1_1-x64.dll +0 -0
  33. package/resources/bin/windows/libusb-1.0.dll +0 -0
  34. package/resources/bin/windows/libusb0.dll +0 -0
  35. package/resources/bin/windows/libxml2.dll +0 -0
  36. package/resources/bin/windows/lzma.dll +0 -0
  37. package/resources/bin/windows/pcre.dll +0 -0
  38. package/resources/bin/windows/pcreposix.dll +0 -0
  39. package/resources/bin/windows/plist.dll +0 -0
  40. package/resources/bin/windows/pthreadVC3.dll +0 -0
  41. package/resources/bin/windows/readline.dll +0 -0
  42. package/resources/bin/windows/usbmuxd.dll +0 -0
  43. package/resources/bin/windows/usbmuxd.exe +0 -0
  44. package/resources/bin/windows/vcruntime140.dll +0 -0
  45. package/resources/bin/windows/zip.dll +0 -0
  46. package/resources/bin/windows/zlib1.dll +0 -0
  47. package/resources/licenses/LGPL-2.1.txt +33 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/logic/appleDeviceKit.ts", "../src/utils/debug.ts", "../src/utils/exec.ts", "../src/utils/idevicePath.ts", "../src/logic/devicesMonitor.ts", "../src/utils/usbmuxd.ts"],
4
+ "sourcesContent": ["import type { ChildProcess } from \"node:child_process\";\r\nimport { spawn } from \"node:child_process\";\r\nimport type { AppInfo, DeviceListEntry, iOSDeviceInfo } from \"../types\";\r\nimport { logInfo, logTask } from \"../utils/debug\";\r\nimport { runIDeviceTool } from \"../utils/exec\";\r\nimport { getIDeviceBinPath, getIDeviceToolPath } from \"../utils/idevicePath\";\r\n\r\n/**\r\n * Parse plist-style output from ideviceinfo\r\n */\r\nfunction parsePlistOutput(output: string): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const lines = output.split(\"\\n\");\r\n\r\n for (const line of lines) {\r\n const colonIndex = line.indexOf(\":\");\r\n if (colonIndex > 0) {\r\n const key = line.substring(0, colonIndex).trim();\r\n const value = line.substring(colonIndex + 1).trim();\r\n result[key] = value;\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Parse idevice_id output\r\n */\r\nfunction parseDeviceList(output: string): DeviceListEntry[] {\r\n const devices: DeviceListEntry[] = [];\r\n const lines = output.trim().split(\"\\n\");\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (trimmed) {\r\n // Format: \"UDID (connection type)\" or just \"UDID\"\r\n const match = trimmed.match(/^([A-Fa-f0-9-]+)(?:\\s+\\((\\w+)\\))?/);\r\n if (match) {\r\n devices.push({\r\n udid: match[1],\r\n connectionType: match[2] === \"Network\" ? 2 : 1,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return devices;\r\n}\r\n\r\n/**\r\n * Parse ideviceinstaller list output\r\n */\r\nfunction parseAppList(output: string): AppInfo[] {\r\n const apps: AppInfo[] = [];\r\n const lines = output.trim().split(\"\\n\");\r\n\r\n for (const line of lines) {\r\n // Format: \"com.example.app, Version, \"Display Name\"\"\r\n const match = line.match(/^([^,]+),\\s*([^,]+),\\s*\"?([^\"]+)\"?/);\r\n if (match) {\r\n apps.push({\r\n bundleId: match[1].trim(),\r\n version: match[2].trim(),\r\n displayName: match[3].trim(),\r\n bundleVersion: \"\",\r\n });\r\n }\r\n }\r\n\r\n return apps;\r\n}\r\n\r\n/**\r\n * Port forwarding handle\r\n */\r\nexport interface PortForwardHandle {\r\n /** Stop the port forwarding */\r\n stop: () => void;\r\n /** The local port being forwarded */\r\n localPort: number;\r\n /** The device port being forwarded to */\r\n devicePort: number;\r\n /** The underlying process */\r\n process: ChildProcess;\r\n}\r\n\r\n/**\r\n * Activation state\r\n */\r\nexport interface ActivationState {\r\n isActivated: boolean;\r\n activationState: string;\r\n}\r\n\r\n/**\r\n * AppleDeviceKit - iOS device operations wrapper\r\n * \r\n * Uses idevice command-line tools for iOS device operations.\r\n * Each instance is associated with a specific device by UDID.\r\n */\r\nexport class AppleDeviceKit {\r\n private deviceId: string;\r\n\r\n constructor(\r\n udid: string,\r\n private readonly port: number\r\n ) {\r\n this.deviceId = udid;\r\n logInfo(`AppleDeviceKit initialized for device: ${this.deviceId}`);\r\n }\r\n\r\n // ==================== Device Info ====================\r\n\r\n /**\r\n * Get detailed device information\r\n */\r\n public async getDeviceInfo(): Promise<iOSDeviceInfo> {\r\n logTask(`Getting device info for ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceinfo\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceinfo tool not found\");\r\n }\r\n\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId]);\r\n const props = parsePlistOutput(stdout);\r\n\r\n return {\r\n deviceName: props.DeviceName || \"\",\r\n productType: props.ProductType || \"\",\r\n productVersion: props.ProductVersion || \"\",\r\n buildVersion: props.BuildVersion || \"\",\r\n serialNumber: props.SerialNumber || \"\",\r\n udid: props.UniqueDeviceID || this.deviceId,\r\n wifiAddress: props.WiFiAddress || \"\",\r\n bluetoothAddress: props.BluetoothAddress || \"\",\r\n phoneNumber: props.PhoneNumber || \"\",\r\n cpuArchitecture: props.CPUArchitecture || \"\",\r\n hardwareModel: props.HardwareModel || \"\",\r\n modelNumber: props.ModelNumber || \"\",\r\n regionInfo: props.RegionInfo || \"\",\r\n timeZone: props.TimeZone || \"\",\r\n uniqueChipID: props.UniqueChipID || \"\",\r\n isPaired: true, // If we can get info, device is paired\r\n };\r\n }\r\n\r\n // ==================== Trust/Pairing ====================\r\n\r\n /**\r\n * Check if device is paired/trusted with this computer\r\n */\r\n public async isPaired(): Promise<boolean> {\r\n logTask(`Checking pairing status for ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"idevicepair\");\r\n if (!toolPath) {\r\n throw new Error(\"idevicepair tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"validate\"]);\r\n return stdout.toLowerCase().includes(\"success\");\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Wait for device to be paired\r\n * Polls the pairing status until successful or timeout\r\n * \r\n * @param timeout Timeout in milliseconds (default: 120000)\r\n * @param pollInterval Poll interval in milliseconds (default: 1000)\r\n */\r\n public async waitForPairing(timeout = 120000, pollInterval = 1000): Promise<boolean> {\r\n logTask(`Waiting for pairing on device ${this.deviceId}`);\r\n\r\n const startTime = Date.now();\r\n\r\n while (Date.now() - startTime < timeout) {\r\n if (await this.isPaired()) {\r\n logInfo(`Device ${this.deviceId} is now paired`);\r\n return true;\r\n }\r\n\r\n await new Promise(resolve => setTimeout(resolve, pollInterval));\r\n }\r\n\r\n throw new Error(`Timeout waiting for device pairing after ${timeout}ms`);\r\n }\r\n\r\n /**\r\n * Attempt to pair/trust the device\r\n * User must accept the trust dialog on the device\r\n */\r\n public async pair(): Promise<boolean> {\r\n logTask(`Initiating pairing for device ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"idevicepair\");\r\n if (!toolPath) {\r\n throw new Error(\"idevicepair tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"pair\"]);\r\n return stdout.toLowerCase().includes(\"success\");\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error);\r\n if (errorMsg.includes(\"Please accept the trust dialog\")) {\r\n // Pairing dialog shown on device\r\n return false;\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Unpair/untrust the device\r\n */\r\n public async unpair(): Promise<boolean> {\r\n logTask(`Unpairing device ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"idevicepair\");\r\n if (!toolPath) {\r\n throw new Error(\"idevicepair tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"unpair\"]);\r\n return stdout.toLowerCase().includes(\"success\");\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n // ==================== App Installation ====================\r\n\r\n /**\r\n * Install an IPA file on the device (install agent)\r\n * \r\n * @param ipaPath Path to the IPA file\r\n */\r\n public async installApp(ipaPath: string): Promise<void> {\r\n logTask(`Installing app ${ipaPath} on device ${this.deviceId}`);\r\n\r\n if (!(await this.isPaired())) {\r\n await this.waitForPairing(10000);\r\n }\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceinstaller\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceinstaller tool not found\");\r\n }\r\n\r\n await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"-i\", ipaPath]);\r\n }\r\n\r\n /**\r\n * Uninstall an app by bundle ID (uninstall agent)\r\n * \r\n * @param bundleId Application bundle identifier\r\n */\r\n public async uninstallApp(bundleId: string): Promise<void> {\r\n logTask(`Uninstalling app ${bundleId} from device ${this.deviceId}`);\r\n\r\n if (!(await this.isPaired())) {\r\n await this.waitForPairing(10000);\r\n }\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceinstaller\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceinstaller tool not found\");\r\n }\r\n\r\n await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"-U\", bundleId]);\r\n }\r\n\r\n /**\r\n * Check if an app is installed on the device\r\n * \r\n * @param bundleId Application bundle identifier\r\n */\r\n public async isAppInstalled(bundleId: string): Promise<boolean> {\r\n logTask(`Checking if app ${bundleId} is installed on device ${this.deviceId}`);\r\n\r\n const apps = await this.listApps();\r\n return apps.some(app => app.bundleId === bundleId);\r\n }\r\n\r\n /**\r\n * List all installed user applications\r\n */\r\n public async listApps(): Promise<AppInfo[]> {\r\n logTask(`Listing apps on device ${this.deviceId}`);\r\n\r\n if (!(await this.isPaired())) {\r\n await this.waitForPairing(10000);\r\n }\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceinstaller\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceinstaller tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"-l\"]);\r\n return parseAppList(stdout);\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n // ==================== Launch Application ====================\r\n\r\n /**\r\n * Launch an application on the device\r\n * \r\n * @param bundleId Application bundle identifier to launch\r\n * @param args Optional arguments to pass to the app\r\n */\r\n public async launchApp(bundleId: string, args: string[] = []): Promise<void> {\r\n logTask(`Launching app ${bundleId} on device ${this.deviceId}`);\r\n\r\n if (!(await this.isPaired())) {\r\n await this.waitForPairing(10000);\r\n }\r\n\r\n const toolPath = getIDeviceToolPath(\"idevicedebug\");\r\n if (!toolPath) {\r\n throw new Error(\"idevicedebug tool not found\");\r\n }\r\n\r\n const toolArgs = [\"-u\", this.deviceId, \"run\", bundleId, ...args];\r\n await runIDeviceTool(toolPath, toolArgs);\r\n }\r\n\r\n // ==================== Port Forwarding ====================\r\n\r\n /**\r\n * Start port forwarding from local port to device port\r\n * \r\n * @param localPort Local port to listen on\r\n * @param devicePort Device port to forward to\r\n * @returns Handle to stop the port forwarding\r\n */\r\n public startPortForward(localPort: number, devicePort: number): PortForwardHandle {\r\n logTask(`Starting port forward ${localPort} -> ${devicePort} for device ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"iproxy\");\r\n if (!toolPath) {\r\n throw new Error(\"iproxy tool not found\");\r\n }\r\n\r\n const binPath = getIDeviceBinPath();\r\n const env = {\r\n ...process.env,\r\n PATH: `${binPath};${process.env.PATH}`,\r\n };\r\n\r\n // iproxy LOCAL_PORT DEVICE_PORT -u UDID\r\n const proc = spawn(toolPath, [\r\n localPort.toString(),\r\n devicePort.toString(),\r\n \"-u\",\r\n this.deviceId\r\n ], {\r\n env,\r\n windowsHide: true,\r\n stdio: \"pipe\",\r\n });\r\n\r\n proc.on(\"error\", (err) => {\r\n logInfo(`Port forward error: ${err.message}`);\r\n });\r\n\r\n return {\r\n stop: () => {\r\n proc.kill();\r\n },\r\n localPort,\r\n devicePort,\r\n process: proc,\r\n };\r\n }\r\n\r\n /**\r\n * Start port forwarding and wait for it to be ready\r\n * \r\n * @param localPort Local port to listen on\r\n * @param devicePort Device port to forward to\r\n * @param _timeout Timeout in milliseconds (reserved for future use)\r\n */\r\n public async startPortForwardAsync(\r\n localPort: number,\r\n devicePort: number,\r\n _timeout = 5000\r\n ): Promise<PortForwardHandle> {\r\n const handle = this.startPortForward(localPort, devicePort);\r\n\r\n // Give iproxy a moment to start\r\n await new Promise(resolve => setTimeout(resolve, 500));\r\n\r\n // Check if process is still running\r\n if (handle.process.killed || handle.process.exitCode !== null) {\r\n throw new Error(\"Port forwarding failed to start\");\r\n }\r\n\r\n return handle;\r\n }\r\n\r\n // ==================== Activation ====================\r\n\r\n /**\r\n * Get the activation state of the device\r\n */\r\n public async getActivationState(): Promise<ActivationState> {\r\n logTask(`Getting activation state for device ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceinfo\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceinfo tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"-k\", \"ActivationState\"]);\r\n const state = stdout.trim();\r\n\r\n return {\r\n isActivated: state === \"Activated\",\r\n activationState: state,\r\n };\r\n } catch {\r\n return {\r\n isActivated: false,\r\n activationState: \"Unknown\",\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Activate the device\r\n * Note: This requires a valid activation record or Apple server access\r\n */\r\n public async activate(): Promise<boolean> {\r\n logTask(`Activating device ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceactivation\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceactivation tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"activate\"]);\r\n return stdout.toLowerCase().includes(\"success\") ||\r\n stdout.toLowerCase().includes(\"activated\");\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error);\r\n throw new Error(`Activation failed: ${errorMsg}`);\r\n }\r\n }\r\n\r\n /**\r\n * Deactivate the device\r\n */\r\n public async deactivate(): Promise<boolean> {\r\n logTask(`Deactivating device ${this.deviceId}`);\r\n\r\n const toolPath = getIDeviceToolPath(\"ideviceactivation\");\r\n if (!toolPath) {\r\n throw new Error(\"ideviceactivation tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-u\", this.deviceId, \"deactivate\"]);\r\n return stdout.toLowerCase().includes(\"success\");\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Get activation state as string\r\n */\r\n public async getActivationStateString(): Promise<string> {\r\n const state = await this.getActivationState();\r\n return state.activationState;\r\n }\r\n\r\n // ==================== Device Identifiers ====================\r\n\r\n /**\r\n * Get the device UDID\r\n */\r\n public getDeviceId(): string {\r\n return this.deviceId;\r\n }\r\n\r\n /**\r\n * Get the logical port number\r\n */\r\n public getPort(): number {\r\n return this.port;\r\n }\r\n\r\n // ==================== Static Methods ====================\r\n\r\n /**\r\n * Static method to list all connected iOS devices\r\n */\r\n public static async listDevices(): Promise<DeviceListEntry[]> {\r\n const toolPath = getIDeviceToolPath(\"idevice_id\");\r\n if (!toolPath) {\r\n throw new Error(\"idevice_id tool not found\");\r\n }\r\n\r\n try {\r\n const { stdout } = await runIDeviceTool(toolPath, [\"-l\"]);\r\n return parseDeviceList(stdout);\r\n } catch {\r\n return [];\r\n }\r\n }\r\n}\r\n", "import createDebug from \"debug\";\r\n\r\nconst debug = createDebug(\"apple-kit\");\r\nconst debugTask = createDebug(\"apple-kit:task\");\r\n\r\n/**\r\n * Log general information\r\n */\r\nexport function logInfo(message: string): void {\r\n\tdebug(message);\r\n}\r\n\r\n/**\r\n * Log task-specific information\r\n */\r\nexport function logTask(message: string): void {\r\n\tdebugTask(message);\r\n}\r\n\r\n", "import { exec as execCallback, type ExecOptions } from \"node:child_process\";\r\nimport { promisify } from \"node:util\";\r\nimport { getIDeviceBinPath } from \"./idevicePath\";\r\n\r\nconst execAsync = promisify(execCallback);\r\n\r\nexport interface ExecResult {\r\n\tstdout: string;\r\n\tstderr: string;\r\n}\r\n\r\n/**\r\n * Execute a command with idevice tools in PATH\r\n */\r\nexport async function execIDevice(command: string, options: ExecOptions = {}): Promise<ExecResult> {\r\n\tconst binPath = getIDeviceBinPath();\r\n\t\r\n\t// Add our bin path to PATH so DLLs can be found\r\n\tconst env = {\r\n\t\t...process.env,\r\n\t\tPATH: `${binPath};${process.env.PATH}`,\r\n\t};\r\n\t\r\n\tconst result = await execAsync(command, {\r\n\t\t...options,\r\n\t\tenv,\r\n\t\twindowsHide: true,\r\n\t\tencoding: \"utf8\",\r\n\t});\r\n\t\r\n\treturn {\r\n\t\tstdout: result.stdout.toString(),\r\n\t\tstderr: result.stderr.toString(),\r\n\t};\r\n}\r\n\r\n/**\r\n * Execute an idevice tool command\r\n */\r\nexport async function runIDeviceTool(\r\n\ttoolPath: string,\r\n\targs: string[] = [],\r\n\toptions: ExecOptions = {}\r\n): Promise<ExecResult> {\r\n\tconst command = `\"${toolPath}\" ${args.map(a => `\"${a}\"`).join(\" \")}`;\r\n\treturn execIDevice(command, options);\r\n}\r\n\r\n", "import { existsSync } from \"node:fs\";\r\nimport { dirname, join } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\n\r\n// ESM compatibility: get __dirname equivalent\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\n/**\r\n * Get the path to idevice binaries from resources\r\n */\r\nfunction getResourcesBinPath(): string {\r\n // When built, we're in dist/utils/idevicePath.js\r\n // Resources are at package root: ../../resources/bin/<platform>\r\n const packageRoot = dirname(dirname(__dirname));\r\n\r\n const platform = process.platform;\r\n let platformDir: string;\r\n\r\n switch (platform) {\r\n case \"win32\":\r\n platformDir = \"windows\";\r\n break;\r\n case \"darwin\":\r\n platformDir = \"darwin\";\r\n break;\r\n case \"linux\":\r\n platformDir = \"linux\";\r\n break;\r\n default:\r\n throw new Error(`Unsupported platform: ${platform}`);\r\n }\r\n\r\n return join(packageRoot, \"resources\", \"bin\", platformDir);\r\n}\r\n\r\n/**\r\n * Get the path to a specific idevice tool\r\n */\r\nexport function getIDeviceToolPath(toolName: string): string | null {\r\n const binPath = getResourcesBinPath();\r\n const ext = process.platform === \"win32\" ? \".exe\" : \"\";\r\n const toolPath = join(binPath, `${toolName}${ext}`);\r\n\r\n if (existsSync(toolPath)) {\r\n return toolPath;\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Get paths to all required idevice tools\r\n */\r\nexport function getIDeviceTools() {\r\n return {\r\n idevice_id: getIDeviceToolPath(\"idevice_id\"),\r\n ideviceinfo: getIDeviceToolPath(\"ideviceinfo\"),\r\n ideviceinstaller: getIDeviceToolPath(\"ideviceinstaller\"),\r\n idevicepair: getIDeviceToolPath(\"idevicepair\"),\r\n idevicename: getIDeviceToolPath(\"idevicename\"),\r\n idevicedebug: getIDeviceToolPath(\"idevicedebug\"),\r\n iproxy: getIDeviceToolPath(\"iproxy\"),\r\n ideviceactivation: getIDeviceToolPath(\"ideviceactivation\"),\r\n };\r\n}\r\n\r\n/**\r\n * Get the bin path for PATH environment variable\r\n */\r\nexport function getIDeviceBinPath(): string {\r\n return getResourcesBinPath();\r\n}\r\n\r\n", "import EventEmitter from \"node:events\";\r\nimport type { AppleListenerConfig } from \"../types\";\r\nimport { logInfo } from \"../utils/debug\";\r\nimport { AppleDeviceKit } from \"./appleDeviceKit\";\r\nimport usbDeviceListener from \"@mcesystems/usb-device-listener\";\r\nimport type { DeviceInfo, ListenerConfig } from \"@mcesystems/usb-device-listener\";\r\n\r\n// Apple vendor ID\r\nconst APPLE_VID = 0x05ac;\r\n\r\n/**\r\n * DevicesMonitor - Monitor iOS device connections via USB\r\n * \r\n * Uses usb-device-listener for plug-and-play detection and filters\r\n * for Apple devices (VID 0x05AC).\r\n */\r\nexport class DevicesMonitor {\r\n private kits: Map<string, AppleDeviceKit> = new Map();\r\n private eventEmitter?: EventEmitter;\r\n\r\n constructor(\r\n private config: AppleListenerConfig = {},\r\n private identifyAlreadyConnected = false\r\n ) { }\r\n\r\n /**\r\n * Start tracking iOS device connections\r\n * \r\n * @returns EventEmitter that emits:\r\n * - 'added': (deviceKit: AppleDeviceKit) when a device is connected\r\n * - 'removed': (deviceId: string, port: number) when a device is disconnected\r\n */\r\n public async startTracking(): Promise<EventEmitter> {\r\n logInfo(\"Starting iOS devices monitor\");\r\n\r\n // Build listener config with Apple device filter\r\n const listenerConfig: ListenerConfig = {\r\n logicalPortMap: this.config.logicalPortMap,\r\n // Filter for Apple devices only\r\n listenOnlyDevices: [\r\n { vid: APPLE_VID.toString(16).toUpperCase().padStart(4, \"0\"), pid: \"\" }\r\n ]\r\n };\r\n\r\n usbDeviceListener.startListening(listenerConfig);\r\n this.eventEmitter = new EventEmitter();\r\n\r\n if (this.identifyAlreadyConnected || this.config.identifyAlreadyConnected) {\r\n await this.identifyConnectedDevices();\r\n }\r\n\r\n usbDeviceListener.onDeviceAdd((device: DeviceInfo) => {\r\n // Check if this is an Apple device\r\n if (device.vid !== APPLE_VID) {\r\n return;\r\n }\r\n\r\n logInfo(`Apple device connected: ${device.deviceId}`);\r\n\r\n // Get the UDID by querying connected iOS devices\r\n this.findAndEmitDevice(device);\r\n });\r\n\r\n usbDeviceListener.onDeviceRemove((device: DeviceInfo) => {\r\n // Check if this is an Apple device\r\n if (device.vid !== APPLE_VID) {\r\n return;\r\n }\r\n\r\n logInfo(`Apple device disconnected: ${device.deviceId}`);\r\n\r\n // Find and remove the kit by location\r\n for (const [udid, kit] of this.kits.entries()) {\r\n if (kit.getPort() === device.logicalPort) {\r\n this.kits.delete(udid);\r\n this.eventEmitter?.emit(\"removed\", udid, device.logicalPort);\r\n break;\r\n }\r\n }\r\n });\r\n\r\n return this.eventEmitter;\r\n }\r\n\r\n /**\r\n * Stop tracking device connections\r\n */\r\n public async stopTracking(): Promise<void> {\r\n if (!this.eventEmitter) {\r\n return;\r\n }\r\n\r\n logInfo(\"Stopping iOS devices monitor\");\r\n this.eventEmitter.removeAllListeners();\r\n this.kits.clear();\r\n this.eventEmitter = undefined;\r\n usbDeviceListener.stopListening();\r\n }\r\n\r\n /**\r\n * Get all currently tracked device kits\r\n */\r\n public getKits(): Map<string, AppleDeviceKit> {\r\n return new Map(this.kits);\r\n }\r\n\r\n /**\r\n * Get a specific device kit by UDID\r\n */\r\n public getKit(udid: string): AppleDeviceKit | undefined {\r\n return this.kits.get(udid);\r\n }\r\n\r\n /**\r\n * Find connected iOS device and emit event\r\n */\r\n private async findAndEmitDevice(usbDevice: DeviceInfo): Promise<void> {\r\n // Query libimobiledevice for connected iOS devices\r\n const iOSDevices = await AppleDeviceKit.listDevices();\r\n\r\n if (iOSDevices.length === 0) {\r\n // Device might not be ready yet, retry after a short delay\r\n setTimeout(() => this.findAndEmitDevice(usbDevice), 500);\r\n return;\r\n }\r\n\r\n // For now, match by order of appearance\r\n // In a production scenario, you might want to correlate by additional means\r\n for (const iDevice of iOSDevices) {\r\n if (this.kits.has(iDevice.udid)) {\r\n continue; // Already tracking this device\r\n }\r\n\r\n const port = usbDevice.logicalPort ?? 0;\r\n const kit = new AppleDeviceKit(iDevice.udid, port);\r\n this.kits.set(iDevice.udid, kit);\r\n\r\n // Emit after a short delay to allow device to settle\r\n setTimeout(() => {\r\n this.eventEmitter?.emit(\"added\", kit);\r\n }, 0);\r\n\r\n break; // Only match one device per USB event\r\n }\r\n }\r\n\r\n /**\r\n * Identify already connected iOS devices\r\n */\r\n private async identifyConnectedDevices(): Promise<void> {\r\n logInfo(\"Identifying already connected iOS devices\");\r\n\r\n const iOSDevices = await AppleDeviceKit.listDevices();\r\n const usbDevices = usbDeviceListener.listDevices()\r\n .filter(d => d.vid === APPLE_VID);\r\n\r\n for (let i = 0; i < iOSDevices.length; i++) {\r\n const iDevice = iOSDevices[i];\r\n const usbDevice = usbDevices[i];\r\n\r\n if (this.kits.has(iDevice.udid)) {\r\n continue;\r\n }\r\n\r\n const port = usbDevice?.logicalPort ?? 0;\r\n const kit = new AppleDeviceKit(iDevice.udid, port);\r\n this.kits.set(iDevice.udid, kit);\r\n\r\n // Emit events asynchronously\r\n setTimeout(() => {\r\n this.eventEmitter?.emit(\"added\", kit);\r\n }, 0);\r\n }\r\n }\r\n}\r\n", "import type { ChildProcess } from \"node:child_process\";\r\nimport { spawn } from \"node:child_process\";\r\nimport { getIDeviceBinPath, getIDeviceToolPath } from \"./idevicePath\";\r\nimport { logInfo } from \"./debug\";\r\n\r\n/**\r\n * USBMuxD daemon handle\r\n */\r\nexport interface UsbmuxdHandle {\r\n\t/** Stop the usbmuxd daemon */\r\n\tstop: () => void;\r\n\t/** Check if the daemon is running */\r\n\tisRunning: () => boolean;\r\n\t/** The underlying process */\r\n\tprocess: ChildProcess;\r\n}\r\n\r\nlet usbmuxdProcess: ChildProcess | null = null;\r\n\r\n/**\r\n * Start the usbmuxd daemon\r\n * \r\n * This allows communicating with iOS devices without iTunes installed.\r\n * On Windows, iTunes normally provides the Apple Mobile Device Service.\r\n * Running usbmuxd.exe replaces that need.\r\n * \r\n * @param foreground If true, runs in foreground mode (default: false)\r\n * @returns Handle to control the daemon\r\n */\r\nexport function startUsbmuxd(foreground = false): UsbmuxdHandle {\r\n\tif (usbmuxdProcess && !usbmuxdProcess.killed) {\r\n\t\tlogInfo(\"usbmuxd is already running\");\r\n\t\treturn {\r\n\t\t\tstop: () => stopUsbmuxd(),\r\n\t\t\tisRunning: () => !usbmuxdProcess?.killed,\r\n\t\t\tprocess: usbmuxdProcess,\r\n\t\t};\r\n\t}\r\n\t\r\n\tconst toolPath = getIDeviceToolPath(\"usbmuxd\");\r\n\tif (!toolPath) {\r\n\t\tthrow new Error(\"usbmuxd executable not found\");\r\n\t}\r\n\t\r\n\tconst binPath = getIDeviceBinPath();\r\n\tconst env = {\r\n\t\t...process.env,\r\n\t\tPATH: `${binPath};${process.env.PATH}`,\r\n\t};\r\n\t\r\n\tconst args: string[] = [];\r\n\tif (foreground) {\r\n\t\targs.push(\"-f\"); // Foreground mode\r\n\t}\r\n\targs.push(\"-v\"); // Verbose for debugging\r\n\t\r\n\tlogInfo(`Starting usbmuxd: ${toolPath}`);\r\n\t\r\n\tusbmuxdProcess = spawn(toolPath, args, {\r\n\t\tenv,\r\n\t\twindowsHide: true,\r\n\t\tstdio: \"pipe\",\r\n\t\tdetached: !foreground,\r\n\t});\r\n\t\r\n\tusbmuxdProcess.stdout?.on(\"data\", (data) => {\r\n\t\tlogInfo(`usbmuxd: ${data.toString().trim()}`);\r\n\t});\r\n\t\r\n\tusbmuxdProcess.stderr?.on(\"data\", (data) => {\r\n\t\tlogInfo(`usbmuxd error: ${data.toString().trim()}`);\r\n\t});\r\n\t\r\n\tusbmuxdProcess.on(\"error\", (err) => {\r\n\t\tlogInfo(`usbmuxd failed to start: ${err.message}`);\r\n\t});\r\n\t\r\n\tusbmuxdProcess.on(\"exit\", (code) => {\r\n\t\tlogInfo(`usbmuxd exited with code ${code}`);\r\n\t\tusbmuxdProcess = null;\r\n\t});\r\n\t\r\n\t// Detach if running in background\r\n\tif (!foreground) {\r\n\t\tusbmuxdProcess.unref();\r\n\t}\r\n\t\r\n\treturn {\r\n\t\tstop: () => stopUsbmuxd(),\r\n\t\tisRunning: () => usbmuxdProcess !== null && !usbmuxdProcess.killed,\r\n\t\tprocess: usbmuxdProcess,\r\n\t};\r\n}\r\n\r\n/**\r\n * Stop the usbmuxd daemon\r\n */\r\nexport function stopUsbmuxd(): void {\r\n\tif (usbmuxdProcess && !usbmuxdProcess.killed) {\r\n\t\tlogInfo(\"Stopping usbmuxd\");\r\n\t\tusbmuxdProcess.kill();\r\n\t\tusbmuxdProcess = null;\r\n\t}\r\n}\r\n\r\n/**\r\n * Check if usbmuxd is running\r\n */\r\nexport function isUsbmuxdRunning(): boolean {\r\n\treturn usbmuxdProcess !== null && !usbmuxdProcess.killed;\r\n}\r\n\r\n/**\r\n * Ensure usbmuxd is running\r\n * \r\n * Starts usbmuxd if it's not already running.\r\n * This is useful to call before device operations if iTunes is not installed.\r\n */\r\nexport function ensureUsbmuxd(): UsbmuxdHandle {\r\n\tif (isUsbmuxdRunning()) {\r\n\t\treturn {\r\n\t\t\tstop: () => stopUsbmuxd(),\r\n\t\t\tisRunning: () => isUsbmuxdRunning(),\r\n\t\t\tprocess: usbmuxdProcess!,\r\n\t\t};\r\n\t}\r\n\t\r\n\treturn startUsbmuxd();\r\n}\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": ["spawn", "spawn"]
7
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @mcesystems/apple-kit
3
+ *
4
+ * iOS device management toolkit using libimobiledevice.
5
+ * Provides device detection, app installation/uninstallation,
6
+ * and device property access through native N-API bindings.
7
+ */
8
+ export { AppleDeviceKit } from "./logic/appleDeviceKit";
9
+ export { DevicesMonitor } from "./logic/devicesMonitor";
10
+ export type { AppInfo, AppleListenerConfig, DeviceListEntry, iOSDeviceInfo, } from "./types";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EACX,OAAO,EACP,mBAAmB,EACnB,eAAe,EACf,aAAa,GACb,MAAM,SAAS,CAAC"}
@@ -0,0 +1,68 @@
1
+ import type { AppInfo, DeviceListEntry, iOSDeviceInfo } from "../types";
2
+ /**
3
+ * AppleDeviceKit - iOS device operations wrapper
4
+ *
5
+ * Uses idevice command-line tools for iOS device operations.
6
+ * Each instance is associated with a specific device by UDID.
7
+ */
8
+ export declare class AppleDeviceKit {
9
+ private readonly port;
10
+ private deviceId;
11
+ constructor(udid: string, port: number);
12
+ /**
13
+ * Get detailed device information
14
+ */
15
+ getDeviceInfo(): Promise<iOSDeviceInfo>;
16
+ /**
17
+ * Check if device is paired/trusted with this computer
18
+ */
19
+ isPaired(): Promise<boolean>;
20
+ /**
21
+ * Wait for device to be paired
22
+ * Polls the pairing status until successful or timeout
23
+ *
24
+ * @param timeout Timeout in milliseconds (default: 120000)
25
+ * @param pollInterval Poll interval in milliseconds (default: 1000)
26
+ */
27
+ waitForPairing(timeout?: number, pollInterval?: number): Promise<boolean>;
28
+ /**
29
+ * Attempt to pair/trust the device
30
+ * User must accept the trust dialog on the device
31
+ */
32
+ pair(): Promise<boolean>;
33
+ /**
34
+ * Install an IPA file on the device
35
+ *
36
+ * @param ipaPath Path to the IPA file
37
+ */
38
+ installApp(ipaPath: string): Promise<void>;
39
+ /**
40
+ * Uninstall an app by bundle ID
41
+ *
42
+ * @param bundleId Application bundle identifier
43
+ */
44
+ uninstallApp(bundleId: string): Promise<void>;
45
+ /**
46
+ * Check if an app is installed on the device
47
+ *
48
+ * @param bundleId Application bundle identifier
49
+ */
50
+ isAppInstalled(bundleId: string): Promise<boolean>;
51
+ /**
52
+ * List all installed user applications
53
+ */
54
+ listApps(): Promise<AppInfo[]>;
55
+ /**
56
+ * Get the device UDID
57
+ */
58
+ getDeviceId(): string;
59
+ /**
60
+ * Get the logical port number
61
+ */
62
+ getPort(): number;
63
+ /**
64
+ * Static method to list all connected iOS devices
65
+ */
66
+ static listDevices(): Promise<DeviceListEntry[]>;
67
+ }
68
+ //# sourceMappingURL=appleDeviceKit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appleDeviceKit.d.ts","sourceRoot":"","sources":["../../../src/logic/appleDeviceKit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAuExE;;;;;GAKG;AACH,qBAAa,cAAc;IAKnB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJzB,OAAO,CAAC,QAAQ,CAAS;gBAGrB,IAAI,EAAE,MAAM,EACK,IAAI,EAAE,MAAM;IAMjC;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC;IA+BpD;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBzC;;;;;;OAMG;IACU,cAAc,CAAC,OAAO,SAAS,EAAE,YAAY,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpF;;;OAGG;IACU,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBrC;;;;OAIG;IACU,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAevD;;;;OAIG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D;;;;OAIG;IACU,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO/D;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAoB3C;;OAEG;IACI,WAAW,IAAI,MAAM;IAI5B;;OAEG;IACI,OAAO,IAAI,MAAM;IAIxB;;OAEG;WACiB,WAAW,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;CAahE"}
@@ -0,0 +1,45 @@
1
+ import EventEmitter from "node:events";
2
+ import type { AppleListenerConfig } from "../types";
3
+ import { AppleDeviceKit } from "./appleDeviceKit";
4
+ /**
5
+ * DevicesMonitor - Monitor iOS device connections via USB
6
+ *
7
+ * Uses usb-device-listener for plug-and-play detection and filters
8
+ * for Apple devices (VID 0x05AC).
9
+ */
10
+ export declare class DevicesMonitor {
11
+ private config;
12
+ private identifyAlreadyConnected;
13
+ private kits;
14
+ private eventEmitter?;
15
+ constructor(config?: AppleListenerConfig, identifyAlreadyConnected?: boolean);
16
+ /**
17
+ * Start tracking iOS device connections
18
+ *
19
+ * @returns EventEmitter that emits:
20
+ * - 'added': (deviceKit: AppleDeviceKit) when a device is connected
21
+ * - 'removed': (deviceId: string, port: number) when a device is disconnected
22
+ */
23
+ startTracking(): Promise<EventEmitter>;
24
+ /**
25
+ * Stop tracking device connections
26
+ */
27
+ stopTracking(): Promise<void>;
28
+ /**
29
+ * Get all currently tracked device kits
30
+ */
31
+ getKits(): Map<string, AppleDeviceKit>;
32
+ /**
33
+ * Get a specific device kit by UDID
34
+ */
35
+ getKit(udid: string): AppleDeviceKit | undefined;
36
+ /**
37
+ * Find connected iOS device and emit event
38
+ */
39
+ private findAndEmitDevice;
40
+ /**
41
+ * Identify already connected iOS devices
42
+ */
43
+ private identifyConnectedDevices;
44
+ }
45
+ //# sourceMappingURL=devicesMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devicesMonitor.d.ts","sourceRoot":"","sources":["../../../src/logic/devicesMonitor.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAOlD;;;;;GAKG;AACH,qBAAa,cAAc;IAKnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,wBAAwB;IALpC,OAAO,CAAC,IAAI,CAA0C;IACtD,OAAO,CAAC,YAAY,CAAC,CAAe;gBAGxB,MAAM,GAAE,mBAAwB,EAChC,wBAAwB,UAAQ;IAG5C;;;;;;OAMG;IACU,aAAa,IAAI,OAAO,CAAC,YAAY,CAAC;IAoDnD;;OAEG;IACU,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAY1C;;OAEG;IACI,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI7C;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIvD;;OAEG;YACW,iBAAiB;IA8B/B;;OAEG;YACW,wBAAwB;CAyBzC"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Apple Kit Type Definitions
3
+ *
4
+ * Type-safe interfaces for iOS device management
5
+ */
6
+ /**
7
+ * Device list entry returned by native listDevices
8
+ */
9
+ export interface DeviceListEntry {
10
+ /**
11
+ * Device UDID (Unique Device Identifier)
12
+ */
13
+ udid: string;
14
+ /**
15
+ * Connection type
16
+ * 1 = USB
17
+ * 2 = Network/WiFi
18
+ */
19
+ connectionType: number;
20
+ }
21
+ /**
22
+ * iOS device information
23
+ */
24
+ export interface iOSDeviceInfo {
25
+ /**
26
+ * Device display name (e.g., "John's iPhone")
27
+ */
28
+ deviceName: string;
29
+ /**
30
+ * Product type identifier (e.g., "iPhone14,2")
31
+ */
32
+ productType: string;
33
+ /**
34
+ * iOS version (e.g., "17.0.1")
35
+ */
36
+ productVersion: string;
37
+ /**
38
+ * Build version (e.g., "21A340")
39
+ */
40
+ buildVersion: string;
41
+ /**
42
+ * Device serial number
43
+ */
44
+ serialNumber: string;
45
+ /**
46
+ * Device UDID
47
+ */
48
+ udid: string;
49
+ /**
50
+ * WiFi MAC address
51
+ */
52
+ wifiAddress: string;
53
+ /**
54
+ * Bluetooth MAC address
55
+ */
56
+ bluetoothAddress: string;
57
+ /**
58
+ * Phone number (if available)
59
+ */
60
+ phoneNumber: string;
61
+ /**
62
+ * CPU architecture (e.g., "arm64")
63
+ */
64
+ cpuArchitecture: string;
65
+ /**
66
+ * Hardware model identifier
67
+ */
68
+ hardwareModel: string;
69
+ /**
70
+ * Model number
71
+ */
72
+ modelNumber: string;
73
+ /**
74
+ * Region info
75
+ */
76
+ regionInfo: string;
77
+ /**
78
+ * Device time zone
79
+ */
80
+ timeZone: string;
81
+ /**
82
+ * Unique chip ID (ECID) as string
83
+ */
84
+ uniqueChipID: string;
85
+ /**
86
+ * Whether the device is paired/trusted with this computer
87
+ */
88
+ isPaired: boolean;
89
+ }
90
+ /**
91
+ * Installed application info
92
+ */
93
+ export interface AppInfo {
94
+ /**
95
+ * Bundle identifier (e.g., "com.example.app")
96
+ */
97
+ bundleId: string;
98
+ /**
99
+ * Display name shown to user
100
+ */
101
+ displayName: string;
102
+ /**
103
+ * App version (CFBundleShortVersionString)
104
+ */
105
+ version: string;
106
+ /**
107
+ * Bundle version (CFBundleVersion)
108
+ */
109
+ bundleVersion: string;
110
+ }
111
+ /**
112
+ * Configuration for the devices monitor
113
+ */
114
+ export interface AppleListenerConfig {
115
+ /**
116
+ * Map physical port locations to logical port numbers
117
+ *
118
+ * Key: Location info string (e.g., "Port_#0005.Hub_#0002")
119
+ * Value: Logical port number (e.g., 1, 2, 3)
120
+ */
121
+ logicalPortMap?: Record<string, number>;
122
+ /**
123
+ * Whether to identify already connected devices on start
124
+ */
125
+ identifyAlreadyConnected?: boolean;
126
+ }
127
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACpB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACtC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Log general information
3
+ */
4
+ export declare function logInfo(message: string): void;
5
+ /**
6
+ * Log task-specific information
7
+ */
8
+ export declare function logTask(message: string): void;
9
+ //# sourceMappingURL=debug.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../../src/utils/debug.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE7C"}
@@ -0,0 +1,14 @@
1
+ import { type ExecOptions } from "node:child_process";
2
+ export interface ExecResult {
3
+ stdout: string;
4
+ stderr: string;
5
+ }
6
+ /**
7
+ * Execute a command with idevice tools in PATH
8
+ */
9
+ export declare function execIDevice(command: string, options?: ExecOptions): Promise<ExecResult>;
10
+ /**
11
+ * Execute an idevice tool command
12
+ */
13
+ export declare function runIDeviceTool(toolPath: string, args?: string[], options?: ExecOptions): Promise<ExecResult>;
14
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../../src/utils/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAM5E,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoBjG;AAED;;GAEG;AACH,wBAAsB,cAAc,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,WAAgB,GACvB,OAAO,CAAC,UAAU,CAAC,CAGrB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Get the path to a specific idevice tool
3
+ */
4
+ export declare function getIDeviceToolPath(toolName: string): string | null;
5
+ /**
6
+ * Get paths to all required idevice tools
7
+ */
8
+ export declare function getIDeviceTools(): {
9
+ idevice_id: string | null;
10
+ ideviceinfo: string | null;
11
+ ideviceinstaller: string | null;
12
+ idevicepair: string | null;
13
+ idevicename: string | null;
14
+ };
15
+ /**
16
+ * Get the bin path for PATH environment variable
17
+ */
18
+ export declare function getIDeviceBinPath(): string;
19
+ //# sourceMappingURL=idevicePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idevicePath.d.ts","sourceRoot":"","sources":["../../../src/utils/idevicePath.ts"],"names":[],"mappings":"AAoCA;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUlE;AAED;;GAEG;AACH,wBAAgB,eAAe;;;;;;EAQ9B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@mcesystems/apple-kit",
3
+ "version": "1.0.0",
4
+ "description": "iOS device management toolkit using libimobiledevice command-line tools",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/types/index.d.ts"
12
+ }
13
+ },
14
+ "keywords": [
15
+ "ios",
16
+ "apple",
17
+ "iphone",
18
+ "ipad",
19
+ "device",
20
+ "management",
21
+ "libimobiledevice",
22
+ "ideviceinstaller",
23
+ "typescript",
24
+ "esm",
25
+ "device-detection",
26
+ "app-install"
27
+ ],
28
+ "author": "Device Management Tools Contributors",
29
+ "license": "ISC",
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "dependencies": {
34
+ "debug": "^4.4.3",
35
+ "@mcesystems/usb-device-listener": "1.0.4"
36
+ },
37
+ "devDependencies": {
38
+ "@types/debug": "^4.1.12",
39
+ "@types/node": "^22.10.2",
40
+ "cross-env": "^10.1.0",
41
+ "esbuild": "^0.27.0",
42
+ "esbuild-plugin-copy": "^2.1.1",
43
+ "rimraf": "^6.0.1",
44
+ "tsx": "^4.21.0",
45
+ "typescript": "^5.7.2",
46
+ "vitest": "^2.1.8"
47
+ },
48
+ "files": [
49
+ "dist",
50
+ "resources",
51
+ "README.md"
52
+ ],
53
+ "scripts": {
54
+ "build": "tsx esbuild.config.ts && tsc --emitDeclarationOnly",
55
+ "clean": "rimraf dist",
56
+ "check:types": "tsc --noEmit",
57
+ "pack": "npm pack",
58
+ "test": "vitest run",
59
+ "test:watch": "vitest",
60
+ "listDevices": "cross-env DEBUG=* tsx ./src/examples/list-devices.ts",
61
+ "installApp": "cross-env DEBUG=* tsx ./src/examples/install-app.ts"
62
+ }
63
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,33 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 2.1, February 1999
3
+
4
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+
7
+ Everyone is permitted to copy and distribute verbatim copies
8
+ of this license document, but changing it is not allowed.
9
+
10
+ [This is the first released version of the Lesser GPL. It also counts
11
+ as the successor of the GNU Library Public License, version 2, hence
12
+ the version number 2.1.]
13
+
14
+ Preamble
15
+
16
+ The licenses for most software are designed to take away your
17
+ freedom to share and change it. By contrast, the GNU General Public
18
+ Licenses are intended to guarantee your freedom to share and change
19
+ free software--to make sure the software is free for all its users.
20
+
21
+ This license, the Lesser General Public License, applies to some
22
+ specially designated software packages--typically libraries--of the
23
+ Free Software Foundation and other authors who decide to use it. You
24
+ can use it too, but we suggest you first think carefully about whether
25
+ this license or the ordinary General Public License is the better
26
+ strategy to use in any particular case, based on the explanations below.
27
+
28
+ libimobiledevice is licensed under the GNU Lesser General Public License
29
+ version 2.1 or later (LGPL-2.1+).
30
+
31
+ For the full text of the LGPL-2.1 license, see:
32
+ https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
33
+