@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.
- package/README.md +250 -0
- package/dist/index.js +680 -0
- package/dist/index.js.map +7 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logic/appleDeviceKit.d.ts +68 -0
- package/dist/types/logic/appleDeviceKit.d.ts.map +1 -0
- package/dist/types/logic/devicesMonitor.d.ts +45 -0
- package/dist/types/logic/devicesMonitor.d.ts.map +1 -0
- package/dist/types/types.d.ts +127 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils/debug.d.ts +9 -0
- package/dist/types/utils/debug.d.ts.map +1 -0
- package/dist/types/utils/exec.d.ts +14 -0
- package/dist/types/utils/exec.d.ts.map +1 -0
- package/dist/types/utils/idevicePath.d.ts +19 -0
- package/dist/types/utils/idevicePath.d.ts.map +1 -0
- package/package.json +63 -0
- package/resources/bin/windows/bz2.dll +0 -0
- package/resources/bin/windows/getopt.dll +0 -0
- package/resources/bin/windows/iconv-2.dll +0 -0
- package/resources/bin/windows/idevice_id.exe +0 -0
- package/resources/bin/windows/ideviceactivation.exe +0 -0
- package/resources/bin/windows/idevicedebug.exe +0 -0
- package/resources/bin/windows/ideviceinfo.exe +0 -0
- package/resources/bin/windows/ideviceinstaller.exe +0 -0
- package/resources/bin/windows/idevicepair.exe +0 -0
- package/resources/bin/windows/imobiledevice.dll +0 -0
- package/resources/bin/windows/iproxy.exe +0 -0
- package/resources/bin/windows/libcrypto-1_1-x64.dll +0 -0
- package/resources/bin/windows/libcurl.dll +0 -0
- package/resources/bin/windows/libssl-1_1-x64.dll +0 -0
- package/resources/bin/windows/libusb-1.0.dll +0 -0
- package/resources/bin/windows/libusb0.dll +0 -0
- package/resources/bin/windows/libxml2.dll +0 -0
- package/resources/bin/windows/lzma.dll +0 -0
- package/resources/bin/windows/pcre.dll +0 -0
- package/resources/bin/windows/pcreposix.dll +0 -0
- package/resources/bin/windows/plist.dll +0 -0
- package/resources/bin/windows/pthreadVC3.dll +0 -0
- package/resources/bin/windows/readline.dll +0 -0
- package/resources/bin/windows/usbmuxd.dll +0 -0
- package/resources/bin/windows/usbmuxd.exe +0 -0
- package/resources/bin/windows/vcruntime140.dll +0 -0
- package/resources/bin/windows/zip.dll +0 -0
- package/resources/bin/windows/zlib1.dll +0 -0
- 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 @@
|
|
|
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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
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
|
+
|