@ebowwa/ios-devices 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/dist/device-ctl.d.ts +128 -0
- package/dist/device-ctl.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5365 -0
- package/dist/index.js.map +22 -0
- package/dist/lib-imobiledevice.d.ts +162 -0
- package/dist/lib-imobiledevice.d.ts.map +1 -0
- package/dist/sim-ctl.d.ts +216 -0
- package/dist/sim-ctl.d.ts.map +1 -0
- package/dist/types.d.ts +487 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/unified-api.d.ts +122 -0
- package/dist/unified-api.d.ts.map +1 -0
- package/dist/utils.d.ts +47 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +49 -0
- package/src/device-ctl.ts +547 -0
- package/src/index.ts +8 -0
- package/src/lib-imobiledevice.ts +404 -0
- package/src/shell-quote.d.ts +5 -0
- package/src/sim-ctl.ts +502 -0
- package/src/types.ts +315 -0
- package/src/unified-api.ts +578 -0
- package/src/utils.ts +174 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LibIMobileDevice - Wrapper for idevice* tools
|
|
3
|
+
* Cross-platform iOS device communication (works with iOS 4+)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { exec, execILDevice, type ExecOptions } from './utils.js';
|
|
7
|
+
import {
|
|
8
|
+
type CommandResult,
|
|
9
|
+
type LogEntry,
|
|
10
|
+
type LogFilter,
|
|
11
|
+
type BackupInfo,
|
|
12
|
+
type ProvisioningProfile,
|
|
13
|
+
type Location,
|
|
14
|
+
type DiagnosticsType,
|
|
15
|
+
} from './types.js';
|
|
16
|
+
|
|
17
|
+
export interface LibIMobileDeviceOptions {
|
|
18
|
+
udid?: string;
|
|
19
|
+
timeout?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class LibIMobileDevice {
|
|
23
|
+
private options: LibIMobileDeviceOptions;
|
|
24
|
+
|
|
25
|
+
constructor(options: LibIMobileDeviceOptions = {}) {
|
|
26
|
+
this.options = options;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private buildArgs(extra: string[] = []): string[] {
|
|
30
|
+
const args: string[] = [];
|
|
31
|
+
if (this.options.udid) {
|
|
32
|
+
args.push('--udid', this.options.udid);
|
|
33
|
+
}
|
|
34
|
+
return [...args, ...extra];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ==========================================================================
|
|
38
|
+
// Device Information
|
|
39
|
+
// ==========================================================================
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* List connected devices
|
|
43
|
+
*/
|
|
44
|
+
async listDevices(): Promise<CommandResult> {
|
|
45
|
+
return execILDevice('idevice_id', ['-l']);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get device info
|
|
50
|
+
*/
|
|
51
|
+
async getDeviceInfo(): Promise<CommandResult> {
|
|
52
|
+
return execILDevice('ideviceinfo', this.buildArgs());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get device name
|
|
57
|
+
*/
|
|
58
|
+
async getDeviceName(): Promise<CommandResult> {
|
|
59
|
+
return execILDevice('idevicename', this.buildArgs());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Set device name
|
|
64
|
+
*/
|
|
65
|
+
async setDeviceName(name: string): Promise<CommandResult> {
|
|
66
|
+
return execILDevice('idevicename', this.buildArgs([name]));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get device date/time
|
|
71
|
+
*/
|
|
72
|
+
async getDeviceDate(): Promise<CommandResult> {
|
|
73
|
+
return execILDevice('idevicedate', this.buildArgs());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ==========================================================================
|
|
77
|
+
// Syslog
|
|
78
|
+
// ==========================================================================
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Stream syslog (returns immediately, use for real-time monitoring)
|
|
82
|
+
*/
|
|
83
|
+
async streamSyslog(filter?: LogFilter): Promise<CommandResult> {
|
|
84
|
+
const args = this.buildArgs();
|
|
85
|
+
|
|
86
|
+
if (filter?.match) args.push('--match', filter.match);
|
|
87
|
+
if (filter?.unmatch) args.push('--unmatch', filter.unmatch);
|
|
88
|
+
if (filter?.process) args.push('--process', filter.process);
|
|
89
|
+
if (filter?.exclude) args.push('--exclude', filter.exclude);
|
|
90
|
+
if (filter?.kernel) args.push('--kernel');
|
|
91
|
+
if (filter?.trigger) args.push('--trigger', filter.trigger);
|
|
92
|
+
if (filter?.untrigger) args.push('--untrigger', filter.untrigger);
|
|
93
|
+
|
|
94
|
+
return execILDevice('idevicesyslog', args, { timeout: 0 }); // No timeout for streaming
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Get syslog archive
|
|
99
|
+
*/
|
|
100
|
+
async getSyslogArchive(outputPath: string, options?: {
|
|
101
|
+
startTime?: number;
|
|
102
|
+
ageLimit?: string;
|
|
103
|
+
sizeLimit?: string;
|
|
104
|
+
}): Promise<CommandResult> {
|
|
105
|
+
const args = this.buildArgs(['archive', outputPath]);
|
|
106
|
+
|
|
107
|
+
if (options?.startTime) {
|
|
108
|
+
args.push('--start-time', String(options.startTime));
|
|
109
|
+
}
|
|
110
|
+
if (options?.ageLimit) {
|
|
111
|
+
args.push('--age-limit', options.ageLimit);
|
|
112
|
+
}
|
|
113
|
+
if (options?.sizeLimit) {
|
|
114
|
+
args.push('--size-limit', options.sizeLimit);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return execILDevice('idevicesyslog', args, { timeout: 120000 });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get process list from syslog
|
|
122
|
+
*/
|
|
123
|
+
async getProcessList(): Promise<CommandResult> {
|
|
124
|
+
return execILDevice('idevicesyslog', this.buildArgs(['pidlist']));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ==========================================================================
|
|
128
|
+
// Screenshot
|
|
129
|
+
// ==========================================================================
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Take screenshot
|
|
133
|
+
*/
|
|
134
|
+
async takeScreenshot(outputPath?: string): Promise<CommandResult> {
|
|
135
|
+
const args = this.buildArgs();
|
|
136
|
+
if (outputPath) {
|
|
137
|
+
args.push('--output', outputPath);
|
|
138
|
+
}
|
|
139
|
+
return execILDevice('idevicescreenshot', args);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ==========================================================================
|
|
143
|
+
// Location
|
|
144
|
+
// ==========================================================================
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Set simulated location
|
|
148
|
+
*/
|
|
149
|
+
async setLocation(latitude: number, longitude: number): Promise<CommandResult> {
|
|
150
|
+
return execILDevice('idevicesetlocation', this.buildArgs([String(latitude), String(longitude)]));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Reset location (stop simulation)
|
|
155
|
+
*/
|
|
156
|
+
async resetLocation(): Promise<CommandResult> {
|
|
157
|
+
return execILDevice('idevicesetlocation', this.buildArgs(['reset']));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ==========================================================================
|
|
161
|
+
// Diagnostics
|
|
162
|
+
// ==========================================================================
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get diagnostics info
|
|
166
|
+
*/
|
|
167
|
+
async getDiagnostics(type: DiagnosticsType = 'All'): Promise<CommandResult> {
|
|
168
|
+
return execILDevice('idevicediagnostics', this.buildArgs(['diagnostics', type]));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Get IO Registry
|
|
173
|
+
*/
|
|
174
|
+
async getIORegistry(plane?: 'IODeviceTree' | 'IOPower' | 'IOService'): Promise<CommandResult> {
|
|
175
|
+
const args = this.buildArgs(['ioreg']);
|
|
176
|
+
if (plane) {
|
|
177
|
+
args.push(plane);
|
|
178
|
+
}
|
|
179
|
+
return execILDevice('idevicediagnostics', args);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get IO Registry entry
|
|
184
|
+
*/
|
|
185
|
+
async getIORegistryEntry(key: string): Promise<CommandResult> {
|
|
186
|
+
return execILDevice('idevicediagnostics', this.buildArgs(['ioregentry', key]));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get MobileGestalt values
|
|
191
|
+
*/
|
|
192
|
+
async getMobileGestalt(...keys: string[]): Promise<CommandResult> {
|
|
193
|
+
return execILDevice('idevicediagnostics', this.buildArgs(['mobilegestalt', ...keys]));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Shutdown device
|
|
198
|
+
*/
|
|
199
|
+
async shutdown(): Promise<CommandResult> {
|
|
200
|
+
return execILDevice('idevicediagnostics', this.buildArgs(['shutdown']));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Restart device
|
|
205
|
+
*/
|
|
206
|
+
async restart(): Promise<CommandResult> {
|
|
207
|
+
return execILDevice('idevicediagnostics', this.buildArgs(['restart']));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Sleep device
|
|
212
|
+
*/
|
|
213
|
+
async sleep(): Promise<CommandResult> {
|
|
214
|
+
return execILDevice('idevicediagnostics', this.buildArgs(['sleep']));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ==========================================================================
|
|
218
|
+
// Pairing
|
|
219
|
+
// ==========================================================================
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Pair with device
|
|
223
|
+
*/
|
|
224
|
+
async pair(): Promise<CommandResult> {
|
|
225
|
+
return execILDevice('idevicepair', this.buildArgs());
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Validate pairing
|
|
230
|
+
*/
|
|
231
|
+
async validatePair(): Promise<CommandResult> {
|
|
232
|
+
return execILDevice('idevicepair', this.buildArgs(['validate']));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// ==========================================================================
|
|
236
|
+
// Backup
|
|
237
|
+
// ==========================================================================
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Create backup
|
|
241
|
+
*/
|
|
242
|
+
async createBackup(directory: string, encrypt?: boolean, password?: string): Promise<CommandResult> {
|
|
243
|
+
const args = this.buildArgs(['backup', directory]);
|
|
244
|
+
if (encrypt) {
|
|
245
|
+
args.push('--encryption');
|
|
246
|
+
if (password) {
|
|
247
|
+
args.push('--password', password);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return execILDevice('idevicebackup2', args, { timeout: 600000 }); // 10 min
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Restore backup
|
|
255
|
+
*/
|
|
256
|
+
async restoreBackup(directory: string, password?: string): Promise<CommandResult> {
|
|
257
|
+
const args = this.buildArgs(['restore', directory]);
|
|
258
|
+
if (password) {
|
|
259
|
+
args.push('--password', password);
|
|
260
|
+
}
|
|
261
|
+
return execILDevice('idevicebackup2', args, { timeout: 600000 });
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Get backup info
|
|
266
|
+
*/
|
|
267
|
+
async getBackupInfo(directory: string): Promise<CommandResult> {
|
|
268
|
+
return execILDevice('idevicebackup2', this.buildArgs(['info', directory]));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* List backups
|
|
273
|
+
*/
|
|
274
|
+
async listBackups(): Promise<CommandResult> {
|
|
275
|
+
return execILDevice('idevicebackup2', this.buildArgs(['list']));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Unpack backup
|
|
280
|
+
*/
|
|
281
|
+
async unpackBackup(directory: string): Promise<CommandResult> {
|
|
282
|
+
return execILDevice('idevicebackup2', this.buildArgs(['unback', directory]), { timeout: 300000 });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ==========================================================================
|
|
286
|
+
// Provisioning Profiles
|
|
287
|
+
// ==========================================================================
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* List provisioning profiles
|
|
291
|
+
*/
|
|
292
|
+
async listProfiles(): Promise<CommandResult> {
|
|
293
|
+
return execILDevice('ideviceprovision', this.buildArgs(['list']));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Install provisioning profile
|
|
298
|
+
*/
|
|
299
|
+
async installProfile(profilePath: string): Promise<CommandResult> {
|
|
300
|
+
return execILDevice('ideviceprovision', this.buildArgs(['install', profilePath]));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Remove provisioning profile
|
|
305
|
+
*/
|
|
306
|
+
async removeProfile(uuid: string): Promise<CommandResult> {
|
|
307
|
+
return execILDevice('ideviceprovision', this.buildArgs(['remove', uuid]));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ==========================================================================
|
|
311
|
+
// Crash Reports
|
|
312
|
+
// ==========================================================================
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Download crash reports
|
|
316
|
+
*/
|
|
317
|
+
async downloadCrashReports(outputDirectory: string, options?: {
|
|
318
|
+
extract?: boolean;
|
|
319
|
+
keep?: boolean;
|
|
320
|
+
}): Promise<CommandResult> {
|
|
321
|
+
const args = this.buildArgs([outputDirectory]);
|
|
322
|
+
if (options?.extract) {
|
|
323
|
+
args.push('--extract');
|
|
324
|
+
}
|
|
325
|
+
if (options?.keep) {
|
|
326
|
+
args.push('--keep');
|
|
327
|
+
}
|
|
328
|
+
return execILDevice('idevicecrashreport', args);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// ==========================================================================
|
|
332
|
+
// Developer Mode
|
|
333
|
+
// ==========================================================================
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* List developer mode status
|
|
337
|
+
*/
|
|
338
|
+
async listDevMode(): Promise<CommandResult> {
|
|
339
|
+
return execILDevice('idevicedevmodectl', ['list']);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// ==========================================================================
|
|
343
|
+
// Image Mounting
|
|
344
|
+
// ==========================================================================
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Mount developer disk image
|
|
348
|
+
*/
|
|
349
|
+
async mountImage(imagePath: string, signaturePath?: string): Promise<CommandResult> {
|
|
350
|
+
const args = this.buildArgs([imagePath]);
|
|
351
|
+
if (signaturePath) {
|
|
352
|
+
args.push('--signature', signaturePath);
|
|
353
|
+
}
|
|
354
|
+
return execILDevice('ideviceimagemounter', args);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// ==========================================================================
|
|
358
|
+
// Recovery Mode
|
|
359
|
+
// ==========================================================================
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Enter recovery mode
|
|
363
|
+
*/
|
|
364
|
+
async enterRecovery(): Promise<CommandResult> {
|
|
365
|
+
return execILDevice('ideviceenterrecovery', this.buildArgs());
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ==========================================================================
|
|
369
|
+
// Bluetooth Logging
|
|
370
|
+
// ==========================================================================
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Start Bluetooth packet logging
|
|
374
|
+
*/
|
|
375
|
+
async startBluetoothLogging(outputPath?: string): Promise<CommandResult> {
|
|
376
|
+
const args = this.buildArgs();
|
|
377
|
+
if (outputPath) {
|
|
378
|
+
args.push('--output', outputPath);
|
|
379
|
+
}
|
|
380
|
+
return execILDevice('idevicebtlogger', args, { timeout: 0 });
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// ==========================================================================
|
|
384
|
+
// Debug Server
|
|
385
|
+
// ==========================================================================
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Start debug server proxy
|
|
389
|
+
*/
|
|
390
|
+
async startDebugServerProxy(port: number = 6666): Promise<CommandResult> {
|
|
391
|
+
return execILDevice('idevicedebugserverproxy', this.buildArgs([String(port)]), { timeout: 0 });
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// ==========================================================================
|
|
395
|
+
// AFC Client (File System)
|
|
396
|
+
// ==========================================================================
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Start AFC shell
|
|
400
|
+
*/
|
|
401
|
+
async startAFCShell(): Promise<CommandResult> {
|
|
402
|
+
return execILDevice('afcclient', this.buildArgs(), { timeout: 0 });
|
|
403
|
+
}
|
|
404
|
+
}
|