@ebowwa/ios-devices 1.0.0 → 1.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/ios-devices",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "iOS device control library wrapping xcrun devicectl, libimobiledevice, and simctl",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/device-ctl.ts CHANGED
@@ -50,24 +50,30 @@ export class DeviceCtl {
50
50
  return this.parseDevicesFromText(result.stdout);
51
51
  }
52
52
 
53
- const data = result.json as { devices?: Array<Record<string, unknown>> };
54
- return (data.devices || []).map(this.parseDeviceFromJson);
53
+ // JSON structure is { result: { devices: [...] } }
54
+ const data = result.json as { result?: { devices?: Array<Record<string, unknown>> } };
55
+ const devices = data.result?.devices || [];
56
+ return devices.map((d) => this.parseDeviceFromJson(d));
55
57
  }
56
58
 
57
59
  private parseDeviceFromJson(device: Record<string, unknown>): IOSDevice {
60
+ const hardware = (device.hardwareProperties as Record<string, unknown>) || {};
61
+ const deviceProps = (device.deviceProperties as Record<string, unknown>) || {};
62
+ const connectionProps = (device.connectionProperties as Record<string, unknown>) || {};
63
+
58
64
  return {
59
- identifier: device.udid as string || device.identifier as string,
60
- name: device.name as string || device.deviceName as string || 'Unknown',
61
- model: device.model as string || '',
62
- modelCode: device.modelCode as string || '',
63
- productType: device.productType as string || '',
64
- osVersion: device.osVersion as string || device.productVersion as string || '',
65
- osBuildVersion: device.buildVersion as string || '',
66
- architecture: device.architecture as string || 'arm64e',
67
- platform: this.detectPlatform(device.productType as string),
68
- connectionType: this.detectConnectionType(device),
69
- isTrusted: device.trusted as boolean ?? true,
70
- isAvailable: device.available as boolean ?? true,
65
+ identifier: device.identifier as string || hardware.udid as string,
66
+ name: deviceProps.name as string || 'Unknown',
67
+ model: hardware.marketingName as string || '',
68
+ modelCode: hardware.hardwareModel as string || '',
69
+ productType: hardware.productType as string || '',
70
+ osVersion: deviceProps.osVersionNumber as string || '',
71
+ osBuildVersion: deviceProps.osBuildUpdate as string || '',
72
+ architecture: 'arm64e',
73
+ platform: this.detectPlatform(hardware.productType as string),
74
+ connectionType: this.detectConnectionType(connectionProps),
75
+ isTrusted: connectionProps.pairingState === 'paired',
76
+ isAvailable: connectionProps.tunnelState === 'connected' || connectionProps.pairingState === 'paired',
71
77
  };
72
78
  }
73
79
 
@@ -76,22 +82,32 @@ export class DeviceCtl {
76
82
  const devices: IOSDevice[] = [];
77
83
 
78
84
  for (const line of lines) {
79
- // Parse format: "Device Name (iOS 18.1) [UDID]"
80
- const match = line.match(/^(.+?)\s*\((.+?)\)\s*\[([A-F0-9-]+)\]/i);
81
- if (match) {
85
+ // Parse table format: "Name Hostname Identifier State Model"
86
+ // Columns are separated by multiple spaces
87
+ const parts = line.split(/\s{2,}/).filter(p => p.trim());
88
+ if (parts.length >= 4 && parts[0] !== 'Name' && !parts[0].startsWith('-')) {
89
+ const name = parts[0].trim();
90
+ const identifier = parts[2].trim();
91
+ const state = parts[3].trim().toLowerCase();
92
+ const model = parts.length > 4 ? parts[4].trim() : '';
93
+
94
+ // Extract model code from parentheses if present, e.g., "iPhone 11 (iPhone12,1)"
95
+ const modelMatch = model.match(/\(([^)]+)\)/);
96
+ const modelCode = modelMatch ? modelMatch[1] : '';
97
+
82
98
  devices.push({
83
- identifier: match[3],
84
- name: match[1].trim(),
85
- model: '',
86
- modelCode: '',
87
- productType: '',
88
- osVersion: match[2],
99
+ identifier,
100
+ name,
101
+ model: model.replace(/\s*\([^)]+\)/, '').trim(),
102
+ modelCode,
103
+ productType: modelCode || model,
104
+ osVersion: '',
89
105
  osBuildVersion: '',
90
106
  architecture: 'arm64e',
91
- platform: 'iOS',
107
+ platform: this.detectPlatform(model),
92
108
  connectionType: 'USB',
93
109
  isTrusted: true,
94
- isAvailable: true,
110
+ isAvailable: state === 'connected',
95
111
  });
96
112
  }
97
113
  }
@@ -108,10 +124,9 @@ export class DeviceCtl {
108
124
  return 'iOS';
109
125
  }
110
126
 
111
- private detectConnectionType(device: Record<string, unknown>): 'USB' | 'Network' | 'Wireless' {
112
- if (device.connectionType) return device.connectionType as 'USB' | 'Network' | 'Wireless';
113
- if (device.networkDevice === true) return 'Network';
114
- if (device.wirelessEnabled === true) return 'Wireless';
127
+ private detectConnectionType(connectionProps: Record<string, unknown>): 'USB' | 'Network' | 'Wireless' {
128
+ const tunnelState = connectionProps.tunnelState as string;
129
+ if (tunnelState === 'connected') return 'Network';
115
130
  return 'USB';
116
131
  }
117
132