appium-ios-remotexpc 0.0.2 → 0.0.4
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/CHANGELOG.md +12 -0
- package/build/src/base-plist-service.d.ts +51 -0
- package/build/src/base-plist-service.d.ts.map +1 -0
- package/build/src/base-plist-service.js +61 -0
- package/build/src/base-socket-service.d.ts +15 -0
- package/build/src/base-socket-service.d.ts.map +1 -0
- package/build/src/base-socket-service.js +46 -0
- package/build/src/index.d.ts +9 -0
- package/build/src/index.d.ts.map +1 -0
- package/build/src/index.js +7 -0
- package/build/src/lib/apple-tv/constants.d.ts +49 -0
- package/build/src/lib/apple-tv/constants.d.ts.map +1 -0
- package/build/src/lib/apple-tv/constants.js +71 -0
- package/build/src/lib/apple-tv/errors.d.ts +17 -0
- package/build/src/lib/apple-tv/errors.d.ts.map +1 -0
- package/build/src/lib/apple-tv/errors.js +30 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts +19 -0
- package/build/src/lib/apple-tv/tlv/decoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/decoder.js +49 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts +10 -0
- package/build/src/lib/apple-tv/tlv/encoder.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/encoder.js +20 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts +4 -0
- package/build/src/lib/apple-tv/tlv/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/index.js +3 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts +14 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts.map +1 -0
- package/build/src/lib/apple-tv/tlv/pairing-tlv.js +27 -0
- package/build/src/lib/apple-tv/types.d.ts +36 -0
- package/build/src/lib/apple-tv/types.d.ts.map +1 -0
- package/build/src/lib/apple-tv/types.js +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts +40 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/buffer-utils.js +76 -0
- package/build/src/lib/apple-tv/utils/index.d.ts +3 -0
- package/build/src/lib/apple-tv/utils/index.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/index.js +2 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts +9 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.d.ts.map +1 -0
- package/build/src/lib/apple-tv/utils/uuid-generator.js +36 -0
- package/build/src/lib/lockdown/index.d.ts +87 -0
- package/build/src/lib/lockdown/index.d.ts.map +1 -0
- package/build/src/lib/lockdown/index.js +324 -0
- package/build/src/lib/pair-record/index.d.ts +3 -0
- package/build/src/lib/pair-record/index.d.ts.map +1 -0
- package/build/src/lib/pair-record/index.js +2 -0
- package/build/src/lib/pair-record/pair-record.d.ts +48 -0
- package/build/src/lib/pair-record/pair-record.d.ts.map +1 -0
- package/build/src/lib/pair-record/pair-record.js +85 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-creator.js +475 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts +14 -0
- package/build/src/lib/plist/binary-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/binary-plist-parser.js +449 -0
- package/build/src/lib/plist/constants.d.ts +36 -0
- package/build/src/lib/plist/constants.d.ts.map +1 -0
- package/build/src/lib/plist/constants.js +43 -0
- package/build/src/lib/plist/index.d.ts +14 -0
- package/build/src/lib/plist/index.d.ts.map +1 -0
- package/build/src/lib/plist/index.js +16 -0
- package/build/src/lib/plist/length-based-splitter.d.ts +43 -0
- package/build/src/lib/plist/length-based-splitter.d.ts.map +1 -0
- package/build/src/lib/plist/length-based-splitter.js +228 -0
- package/build/src/lib/plist/plist-creator.d.ts +8 -0
- package/build/src/lib/plist/plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/plist-creator.js +33 -0
- package/build/src/lib/plist/plist-decoder.d.ts +25 -0
- package/build/src/lib/plist/plist-decoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-decoder.js +103 -0
- package/build/src/lib/plist/plist-encoder.d.ts +10 -0
- package/build/src/lib/plist/plist-encoder.d.ts.map +1 -0
- package/build/src/lib/plist/plist-encoder.js +27 -0
- package/build/src/lib/plist/plist-parser.d.ts +9 -0
- package/build/src/lib/plist/plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/plist-parser.js +109 -0
- package/build/src/lib/plist/plist-service.d.ts +86 -0
- package/build/src/lib/plist/plist-service.d.ts.map +1 -0
- package/build/src/lib/plist/plist-service.js +180 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts +9 -0
- package/build/src/lib/plist/unified-plist-creator.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-creator.js +14 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts +8 -0
- package/build/src/lib/plist/unified-plist-parser.d.ts.map +1 -0
- package/build/src/lib/plist/unified-plist-parser.js +23 -0
- package/build/src/lib/plist/utils.d.ts +97 -0
- package/build/src/lib/plist/utils.d.ts.map +1 -0
- package/build/src/lib/plist/utils.js +287 -0
- package/build/src/lib/remote-xpc/constants.d.ts +20 -0
- package/build/src/lib/remote-xpc/constants.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/constants.js +21 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts +74 -0
- package/build/src/lib/remote-xpc/handshake-frames.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake-frames.js +285 -0
- package/build/src/lib/remote-xpc/handshake.d.ts +14 -0
- package/build/src/lib/remote-xpc/handshake.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/handshake.js +95 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts +55 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/remote-xpc-connection.js +365 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts +22 -0
- package/build/src/lib/remote-xpc/xpc-protocol.d.ts.map +1 -0
- package/build/src/lib/remote-xpc/xpc-protocol.js +368 -0
- package/build/src/lib/tunnel/index.d.ts +69 -0
- package/build/src/lib/tunnel/index.d.ts.map +1 -0
- package/build/src/lib/tunnel/index.js +205 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts +46 -0
- package/build/src/lib/tunnel/packet-stream-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-client.js +152 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts +37 -0
- package/build/src/lib/tunnel/packet-stream-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/packet-stream-server.js +109 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts +85 -0
- package/build/src/lib/tunnel/tunnel-api-client.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-api-client.js +207 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts +68 -0
- package/build/src/lib/tunnel/tunnel-registry-server.d.ts.map +1 -0
- package/build/src/lib/tunnel/tunnel-registry-server.js +351 -0
- package/build/src/lib/types.d.ts +238 -0
- package/build/src/lib/types.d.ts.map +1 -0
- package/build/src/lib/types.js +4 -0
- package/build/src/lib/usbmux/index.d.ts +177 -0
- package/build/src/lib/usbmux/index.d.ts.map +1 -0
- package/build/src/lib/usbmux/index.js +490 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts +19 -0
- package/build/src/lib/usbmux/usbmux-decoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-decoder.js +38 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts +12 -0
- package/build/src/lib/usbmux/usbmux-encoder.d.ts.map +1 -0
- package/build/src/lib/usbmux/usbmux-encoder.js +32 -0
- package/build/src/service-connection.d.ts +34 -0
- package/build/src/service-connection.d.ts.map +1 -0
- package/build/src/service-connection.js +51 -0
- package/build/src/services/index.d.ts +6 -0
- package/build/src/services/index.d.ts.map +1 -0
- package/build/src/services/index.js +5 -0
- package/build/src/services/ios/base-service.d.ts +35 -0
- package/build/src/services/ios/base-service.d.ts.map +1 -0
- package/build/src/services/ios/base-service.js +55 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts +46 -0
- package/build/src/services/ios/diagnostic-service/index.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/index.js +169 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts +5 -0
- package/build/src/services/ios/diagnostic-service/keys.d.ts.map +1 -0
- package/build/src/services/ios/diagnostic-service/keys.js +770 -0
- package/build/src/services/ios/syslog-service/index.d.ts +91 -0
- package/build/src/services/ios/syslog-service/index.d.ts.map +1 -0
- package/build/src/services/ios/syslog-service/index.js +323 -0
- package/build/src/services/ios/tunnel-service/index.d.ts +17 -0
- package/build/src/services/ios/tunnel-service/index.d.ts.map +1 -0
- package/build/src/services/ios/tunnel-service/index.js +57 -0
- package/build/src/services.d.ts +14 -0
- package/build/src/services.d.ts.map +1 -0
- package/build/src/services.js +48 -0
- package/package.json +12 -3
- package/.github/dependabot.yml +0 -38
- package/.github/workflows/format-check.yml +0 -43
- package/.github/workflows/lint-and-build.yml +0 -40
- package/.github/workflows/pr-title.yml +0 -16
- package/.github/workflows/publish.js.yml +0 -41
- package/.github/workflows/test-validation.yml +0 -40
- package/.mocharc.json +0 -8
- package/.prettierignore +0 -3
- package/.prettierrc +0 -17
- package/.releaserc +0 -48
- package/assets/images/ios-arch.png +0 -0
- package/eslint.config.js +0 -45
- package/npm-shrinkwrap.json +0 -2711
- package/test/integration/diagnostics-test.ts +0 -44
- package/test/integration/read-pair-record-test.ts +0 -39
- package/test/integration/tunnel-test.ts +0 -104
- package/test/unit/apple-tv/tlv/decoder.spec.ts +0 -144
- package/test/unit/apple-tv/tlv/encoder.spec.ts +0 -91
- package/test/unit/apple-tv/tlv/pairing-tlv.spec.ts +0 -101
- package/test/unit/apple-tv/tlv/tlv-integration.spec.ts +0 -146
- package/test/unit/apple-tv/utils/buffer-utils.spec.ts +0 -74
- package/test/unit/apple-tv/utils/uuid-generator.spec.ts +0 -39
- package/test/unit/fixtures/index.ts +0 -88
- package/test/unit/fixtures/usbmuxconnectmessage.bin +0 -0
- package/test/unit/fixtures/usbmuxlistdevicemessage.bin +0 -0
- package/test/unit/plist/error-handling.spec.ts +0 -101
- package/test/unit/plist/fixtures/sample.binary.plist +0 -0
- package/test/unit/plist/fixtures/sample.xml.plist +0 -38
- package/test/unit/plist/plist-parser.spec.ts +0 -283
- package/test/unit/plist/plist.spec.ts +0 -205
- package/test/unit/plist/tag-position-handling.spec.ts +0 -90
- package/test/unit/plist/unified-plist-parser.spec.ts +0 -227
- package/test/unit/plist/utils.spec.ts +0 -249
- package/test/unit/plist/xml-cleaning.spec.ts +0 -60
- package/test/unit/tunnel/tunnel-registry-server.spec.ts +0 -194
- package/test/unit/usbmux/usbmux-specs.ts +0 -71
- package/tsconfig.json +0 -36
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Transform } from 'stream';
|
|
2
|
+
import { parsePlist } from '../plist/index.js';
|
|
3
|
+
const HEADER_LENGTH = 16;
|
|
4
|
+
export class UsbmuxDecoder extends Transform {
|
|
5
|
+
_buffer = Buffer.alloc(0);
|
|
6
|
+
constructor() {
|
|
7
|
+
super({ objectMode: true });
|
|
8
|
+
}
|
|
9
|
+
_transform(chunk, encoding, callback) {
|
|
10
|
+
// Append the new chunk to the internal buffer
|
|
11
|
+
this._buffer = Buffer.concat([this._buffer, chunk]);
|
|
12
|
+
// Process complete messages in the buffer
|
|
13
|
+
while (this._buffer.length >= HEADER_LENGTH) {
|
|
14
|
+
// Read header length field (total length of the message)
|
|
15
|
+
const totalLength = this._buffer.readUInt32LE(0);
|
|
16
|
+
// Check if we have received the full message
|
|
17
|
+
if (this._buffer.length < totalLength) {
|
|
18
|
+
break; // Wait for more data
|
|
19
|
+
}
|
|
20
|
+
// Extract the full message
|
|
21
|
+
const message = this._buffer.slice(0, totalLength);
|
|
22
|
+
this._decode(message);
|
|
23
|
+
// Remove the processed message from the buffer
|
|
24
|
+
this._buffer = this._buffer.slice(totalLength);
|
|
25
|
+
}
|
|
26
|
+
callback();
|
|
27
|
+
}
|
|
28
|
+
_decode(data) {
|
|
29
|
+
const header = {
|
|
30
|
+
length: data.readUInt32LE(0),
|
|
31
|
+
version: data.readUInt32LE(4),
|
|
32
|
+
type: data.readUInt32LE(8),
|
|
33
|
+
tag: data.readUInt32LE(12),
|
|
34
|
+
};
|
|
35
|
+
const payload = data.slice(HEADER_LENGTH);
|
|
36
|
+
this.push({ header, payload: parsePlist(payload) });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Transform, type TransformCallback } from 'stream';
|
|
2
|
+
import type { PlistDictionary } from '../types.js';
|
|
3
|
+
export interface UsbmuxEncodeData {
|
|
4
|
+
payload: PlistDictionary;
|
|
5
|
+
tag: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class UsbmuxEncoder extends Transform {
|
|
8
|
+
constructor();
|
|
9
|
+
_transform(data: UsbmuxEncodeData, encoding: BufferEncoding, callback: TransformCallback): void;
|
|
10
|
+
private _encode;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=usbmux-encoder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usbmux-encoder.d.ts","sourceRoot":"","sources":["../../../../src/lib/usbmux/usbmux-encoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAG3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,eAAe,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,aAAc,SAAQ,SAAS;;IAK1C,UAAU,CACR,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI;IAKP,OAAO,CAAC,OAAO;CA0BhB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Transform } from 'stream';
|
|
2
|
+
import { createPlist } from '../plist/index.js';
|
|
3
|
+
const HEADER_LENGTH = 16;
|
|
4
|
+
const VERSION = 1;
|
|
5
|
+
const TYPE = 8;
|
|
6
|
+
export class UsbmuxEncoder extends Transform {
|
|
7
|
+
constructor() {
|
|
8
|
+
super({ objectMode: true });
|
|
9
|
+
}
|
|
10
|
+
_transform(data, encoding, callback) {
|
|
11
|
+
this._encode(data);
|
|
12
|
+
callback();
|
|
13
|
+
}
|
|
14
|
+
_encode(data) {
|
|
15
|
+
const plistData = createPlist(data.payload, false);
|
|
16
|
+
const payloadBuffer = Buffer.isBuffer(plistData)
|
|
17
|
+
? plistData
|
|
18
|
+
: Buffer.from(plistData);
|
|
19
|
+
const header = {
|
|
20
|
+
length: HEADER_LENGTH + payloadBuffer.length,
|
|
21
|
+
version: VERSION,
|
|
22
|
+
type: TYPE,
|
|
23
|
+
tag: data.tag,
|
|
24
|
+
};
|
|
25
|
+
const headerBuffer = Buffer.allocUnsafe(HEADER_LENGTH);
|
|
26
|
+
headerBuffer.writeUInt32LE(header.length, 0);
|
|
27
|
+
headerBuffer.writeUInt32LE(header.version, 4);
|
|
28
|
+
headerBuffer.writeUInt32LE(header.type, 8);
|
|
29
|
+
headerBuffer.writeUInt32LE(header.tag, 12);
|
|
30
|
+
this.push(Buffer.concat([headerBuffer, payloadBuffer], headerBuffer.length + payloadBuffer.length));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import net from 'node:net';
|
|
2
|
+
import { BasePlistService } from './base-plist-service.js';
|
|
3
|
+
import type { PlistServiceOptions } from './lib/plist/plist-service.js';
|
|
4
|
+
import type { PlistDictionary } from './lib/types.js';
|
|
5
|
+
export interface ServiceConnectionOptions {
|
|
6
|
+
keepAlive?: boolean;
|
|
7
|
+
createConnectionTimeout?: number;
|
|
8
|
+
plistOptions?: PlistServiceOptions;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* ServiceConnection for communicating with Apple device services over TCP
|
|
12
|
+
*/
|
|
13
|
+
export declare class ServiceConnection extends BasePlistService {
|
|
14
|
+
constructor(socket: net.Socket, options?: ServiceConnectionOptions);
|
|
15
|
+
/**
|
|
16
|
+
* Creates a TCP connection to the specified host and port
|
|
17
|
+
*/
|
|
18
|
+
static createUsingTCP(hostname: string, port: string, options?: ServiceConnectionOptions): Promise<ServiceConnection>;
|
|
19
|
+
/**
|
|
20
|
+
* Sends a plist request to the device and returns the response
|
|
21
|
+
*/
|
|
22
|
+
sendPlistRequest(requestObj: PlistDictionary, timeout?: number): Promise<PlistDictionary>;
|
|
23
|
+
/**
|
|
24
|
+
* Gets the underlying socket
|
|
25
|
+
* @returns The socket used by this service
|
|
26
|
+
*/
|
|
27
|
+
getSocket(): net.Socket;
|
|
28
|
+
/**
|
|
29
|
+
* Closes the connection
|
|
30
|
+
*/
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
33
|
+
export default ServiceConnection;
|
|
34
|
+
//# sourceMappingURL=service-connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service-connection.d.ts","sourceRoot":"","sources":["../../src/service-connection.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,gBAAgB;gBACzC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB;IAIlE;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,iBAAiB,CAAC;IAyB7B;;OAEG;IACH,gBAAgB,CACd,UAAU,EAAE,eAAe,EAC3B,OAAO,SAAQ,GACd,OAAO,CAAC,eAAe,CAAC;IAI3B;;;OAGG;IACH,SAAS,IAAI,GAAG,CAAC,MAAM;IAIvB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import net from 'node:net';
|
|
2
|
+
import { BasePlistService } from './base-plist-service.js';
|
|
3
|
+
/**
|
|
4
|
+
* ServiceConnection for communicating with Apple device services over TCP
|
|
5
|
+
*/
|
|
6
|
+
export class ServiceConnection extends BasePlistService {
|
|
7
|
+
constructor(socket, options) {
|
|
8
|
+
super(socket, options?.plistOptions);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Creates a TCP connection to the specified host and port
|
|
12
|
+
*/
|
|
13
|
+
static createUsingTCP(hostname, port, options) {
|
|
14
|
+
const keepAlive = options?.keepAlive ?? true;
|
|
15
|
+
const createConnectionTimeout = options?.createConnectionTimeout ?? 30000;
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const socket = net.createConnection({ host: hostname, port: Number(port) }, () => {
|
|
18
|
+
socket.setTimeout(0);
|
|
19
|
+
if (keepAlive) {
|
|
20
|
+
socket.setKeepAlive(true);
|
|
21
|
+
}
|
|
22
|
+
resolve(new ServiceConnection(socket, options));
|
|
23
|
+
});
|
|
24
|
+
socket.setTimeout(createConnectionTimeout, () => {
|
|
25
|
+
socket.destroy();
|
|
26
|
+
reject(new Error('Connection timed out'));
|
|
27
|
+
});
|
|
28
|
+
socket.on('error', (err) => reject(err));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Sends a plist request to the device and returns the response
|
|
33
|
+
*/
|
|
34
|
+
sendPlistRequest(requestObj, timeout = 10000) {
|
|
35
|
+
return this.sendAndReceive(requestObj, timeout);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets the underlying socket
|
|
39
|
+
* @returns The socket used by this service
|
|
40
|
+
*/
|
|
41
|
+
getSocket() {
|
|
42
|
+
return this.getPlistService().getSocket();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Closes the connection
|
|
46
|
+
*/
|
|
47
|
+
close() {
|
|
48
|
+
super.close();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export default ServiceConnection;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TunnelRegistryServer, startTunnelRegistryServer } from '../lib/tunnel/tunnel-registry-server.js';
|
|
2
|
+
import * as diagnostics from './ios/diagnostic-service/index.js';
|
|
3
|
+
import * as syslog from './ios/syslog-service/index.js';
|
|
4
|
+
import * as tunnel from './ios/tunnel-service/index.js';
|
|
5
|
+
export { diagnostics, syslog, tunnel, TunnelRegistryServer, startTunnelRegistryServer, };
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EAC1B,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,mCAAmC,CAAC;AACjE,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAC;AACxD,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAC;AAExD,OAAO,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,oBAAoB,EACpB,yBAAyB,GAC1B,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { TunnelRegistryServer, startTunnelRegistryServer, } from '../lib/tunnel/tunnel-registry-server.js';
|
|
2
|
+
import * as diagnostics from './ios/diagnostic-service/index.js';
|
|
3
|
+
import * as syslog from './ios/syslog-service/index.js';
|
|
4
|
+
import * as tunnel from './ios/tunnel-service/index.js';
|
|
5
|
+
export { diagnostics, syslog, tunnel, TunnelRegistryServer, startTunnelRegistryServer, };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ServiceConnection } from '../../service-connection.js';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for service information
|
|
4
|
+
*/
|
|
5
|
+
export interface Service {
|
|
6
|
+
serviceName: string;
|
|
7
|
+
port: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Base class for iOS services that provides common functionality
|
|
11
|
+
*/
|
|
12
|
+
export declare class BaseService {
|
|
13
|
+
protected readonly address: [string, number];
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new BaseService instance
|
|
16
|
+
* @param address Tuple containing [host, port]
|
|
17
|
+
*/
|
|
18
|
+
constructor(address: [string, number]);
|
|
19
|
+
/**
|
|
20
|
+
* Starts a lockdown service without sending a check-in message
|
|
21
|
+
* @param service Service information
|
|
22
|
+
* @param options Additional options for the connection
|
|
23
|
+
* @returns Promise resolving to a ServiceConnection
|
|
24
|
+
*/
|
|
25
|
+
startLockdownWithoutCheckin(service: Service, options?: Record<string, any>): Promise<ServiceConnection>;
|
|
26
|
+
/**
|
|
27
|
+
* Starts a lockdown service with proper check-in
|
|
28
|
+
* @param service Service information
|
|
29
|
+
* @param options Additional options for the connection
|
|
30
|
+
* @returns Promise resolving to a ServiceConnection
|
|
31
|
+
*/
|
|
32
|
+
startLockdownService(service: Service, options?: Record<string, any>): Promise<ServiceConnection>;
|
|
33
|
+
}
|
|
34
|
+
export default BaseService;
|
|
35
|
+
//# sourceMappingURL=base-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-service.d.ts","sourceRoot":"","sources":["../../../../src/services/ios/base-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAIhE;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7C;;;OAGG;gBACS,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IAIrC;;;;;OAKG;IACU,2BAA2B,CACtC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAChC,OAAO,CAAC,iBAAiB,CAAC;IAM7B;;;;;OAKG;IACU,oBAAoB,CAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAChC,OAAO,CAAC,iBAAiB,CAAC;CA0B9B;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { logger } from '@appium/support';
|
|
2
|
+
import { ServiceConnection } from '../../service-connection.js';
|
|
3
|
+
const log = logger.getLogger('BaseService');
|
|
4
|
+
/**
|
|
5
|
+
* Base class for iOS services that provides common functionality
|
|
6
|
+
*/
|
|
7
|
+
export class BaseService {
|
|
8
|
+
address;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new BaseService instance
|
|
11
|
+
* @param address Tuple containing [host, port]
|
|
12
|
+
*/
|
|
13
|
+
constructor(address) {
|
|
14
|
+
this.address = address;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Starts a lockdown service without sending a check-in message
|
|
18
|
+
* @param service Service information
|
|
19
|
+
* @param options Additional options for the connection
|
|
20
|
+
* @returns Promise resolving to a ServiceConnection
|
|
21
|
+
*/
|
|
22
|
+
async startLockdownWithoutCheckin(service, options = {}) {
|
|
23
|
+
// Get the port for the requested service
|
|
24
|
+
const port = service.port;
|
|
25
|
+
return ServiceConnection.createUsingTCP(this.address[0], port, options);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Starts a lockdown service with proper check-in
|
|
29
|
+
* @param service Service information
|
|
30
|
+
* @param options Additional options for the connection
|
|
31
|
+
* @returns Promise resolving to a ServiceConnection
|
|
32
|
+
*/
|
|
33
|
+
async startLockdownService(service, options = {}) {
|
|
34
|
+
try {
|
|
35
|
+
const connection = await this.startLockdownWithoutCheckin(service, options);
|
|
36
|
+
const checkin = {
|
|
37
|
+
Label: 'appium-internal',
|
|
38
|
+
ProtocolVersion: '2',
|
|
39
|
+
Request: 'RSDCheckin',
|
|
40
|
+
};
|
|
41
|
+
const response = await connection.sendPlistRequest(checkin);
|
|
42
|
+
log.debug(`Service check-in response: ${JSON.stringify(response, null, 2)}`);
|
|
43
|
+
return connection;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
log.error('Error during check-in:', error);
|
|
47
|
+
if (error instanceof Error) {
|
|
48
|
+
log.error('Error message:', error.message);
|
|
49
|
+
log.error('Error stack:', error.stack);
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export default BaseService;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { DiagnosticsService as DiagnosticsServiceInterface, PlistDictionary } from '../../../lib/types.js';
|
|
2
|
+
import { BaseService } from '../base-service.js';
|
|
3
|
+
/**
|
|
4
|
+
* DiagnosticsService provides an API to:
|
|
5
|
+
* - Query MobileGestalt & IORegistry keys
|
|
6
|
+
* - Reboot, shutdown or put the device in sleep mode
|
|
7
|
+
* - Get WiFi information
|
|
8
|
+
*/
|
|
9
|
+
declare class DiagnosticsService extends BaseService implements DiagnosticsServiceInterface {
|
|
10
|
+
static readonly RSD_SERVICE_NAME = "com.apple.mobile.diagnostics_relay.shim.remote";
|
|
11
|
+
constructor(address: [string, number]);
|
|
12
|
+
/**
|
|
13
|
+
* Restart the device
|
|
14
|
+
* @returns Promise that resolves when the restart request is sent
|
|
15
|
+
*/
|
|
16
|
+
restart(): Promise<PlistDictionary>;
|
|
17
|
+
/**
|
|
18
|
+
* Shutdown the device
|
|
19
|
+
* @returns Promise that resolves when the shutdown request is sent
|
|
20
|
+
*/
|
|
21
|
+
shutdown(): Promise<PlistDictionary>;
|
|
22
|
+
/**
|
|
23
|
+
* Put the device in sleep mode
|
|
24
|
+
* @returns Promise that resolves when the sleep request is sent
|
|
25
|
+
*/
|
|
26
|
+
sleep(): Promise<PlistDictionary>;
|
|
27
|
+
/**
|
|
28
|
+
* Query IORegistry
|
|
29
|
+
* @returns Object containing the IORegistry information
|
|
30
|
+
* @param options
|
|
31
|
+
*/
|
|
32
|
+
ioregistry(options?: {
|
|
33
|
+
plane?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
ioClass?: string;
|
|
36
|
+
returnRawJson?: boolean;
|
|
37
|
+
timeout?: number;
|
|
38
|
+
}): Promise<PlistDictionary[] | Record<string, any>>;
|
|
39
|
+
private getServiceConfig;
|
|
40
|
+
private connectToDiagnosticService;
|
|
41
|
+
private sendRequest;
|
|
42
|
+
private processIORegistryResponse;
|
|
43
|
+
private handleMultipartIORegistryResponse;
|
|
44
|
+
}
|
|
45
|
+
export default DiagnosticsService;
|
|
46
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/services/ios/diagnostic-service/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,IAAI,2BAA2B,EACjD,eAAe,EAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjD;;;;;GAKG;AACH,cAAM,kBACJ,SAAQ,WACR,YAAW,2BAA2B;IAEtC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,oDACmB;gBAEvC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IAIrC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;IAazC;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC;IAa1C;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IAavC;;;;OAIG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE;QACzB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,eAAe,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IA4CpD,OAAO,CAAC,gBAAgB;YAOV,0BAA0B;YAK1B,WAAW;IAoBzB,OAAO,CAAC,yBAAyB;YA0CnB,iCAAiC;CA8BhD;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { logger } from '@appium/support';
|
|
2
|
+
import { PlistServiceDecoder } from '../../../lib/plist/plist-decoder.js';
|
|
3
|
+
import { BaseService } from '../base-service.js';
|
|
4
|
+
const log = logger.getLogger('DiagnosticService');
|
|
5
|
+
/**
|
|
6
|
+
* DiagnosticsService provides an API to:
|
|
7
|
+
* - Query MobileGestalt & IORegistry keys
|
|
8
|
+
* - Reboot, shutdown or put the device in sleep mode
|
|
9
|
+
* - Get WiFi information
|
|
10
|
+
*/
|
|
11
|
+
class DiagnosticsService extends BaseService {
|
|
12
|
+
static RSD_SERVICE_NAME = 'com.apple.mobile.diagnostics_relay.shim.remote';
|
|
13
|
+
constructor(address) {
|
|
14
|
+
super(address);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Restart the device
|
|
18
|
+
* @returns Promise that resolves when the restart request is sent
|
|
19
|
+
*/
|
|
20
|
+
async restart() {
|
|
21
|
+
try {
|
|
22
|
+
const request = {
|
|
23
|
+
Request: 'Restart',
|
|
24
|
+
};
|
|
25
|
+
return await this.sendRequest(request);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
log.error(`Error restarting device: ${error}`);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Shutdown the device
|
|
34
|
+
* @returns Promise that resolves when the shutdown request is sent
|
|
35
|
+
*/
|
|
36
|
+
async shutdown() {
|
|
37
|
+
try {
|
|
38
|
+
const request = {
|
|
39
|
+
Request: 'Shutdown',
|
|
40
|
+
};
|
|
41
|
+
return await this.sendRequest(request);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
log.error(`Error shutting down device: ${error}`);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Put the device in sleep mode
|
|
50
|
+
* @returns Promise that resolves when the sleep request is sent
|
|
51
|
+
*/
|
|
52
|
+
async sleep() {
|
|
53
|
+
try {
|
|
54
|
+
const request = {
|
|
55
|
+
Request: 'Sleep',
|
|
56
|
+
};
|
|
57
|
+
return await this.sendRequest(request);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
log.error(`Error putting device to sleep: ${error}`);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Query IORegistry
|
|
66
|
+
* @returns Object containing the IORegistry information
|
|
67
|
+
* @param options
|
|
68
|
+
*/
|
|
69
|
+
async ioregistry(options) {
|
|
70
|
+
try {
|
|
71
|
+
const request = {
|
|
72
|
+
Request: 'IORegistry',
|
|
73
|
+
};
|
|
74
|
+
if (options?.plane) {
|
|
75
|
+
request.CurrentPlane = options.plane;
|
|
76
|
+
}
|
|
77
|
+
if (options?.name) {
|
|
78
|
+
request.EntryName = options.name;
|
|
79
|
+
}
|
|
80
|
+
if (options?.ioClass) {
|
|
81
|
+
request.EntryClass = options.ioClass;
|
|
82
|
+
}
|
|
83
|
+
PlistServiceDecoder.lastDecodedResult = null;
|
|
84
|
+
const timeout = options?.timeout || 3000;
|
|
85
|
+
log.debug('Sending IORegistry request...');
|
|
86
|
+
const conn = await this.connectToDiagnosticService();
|
|
87
|
+
const response = await conn.sendPlistRequest(request, timeout);
|
|
88
|
+
log.debug(`IORegistry response size: ${JSON.stringify(response).length} bytes`);
|
|
89
|
+
if (options?.returnRawJson) {
|
|
90
|
+
return await this.handleMultipartIORegistryResponse(conn, response, timeout);
|
|
91
|
+
}
|
|
92
|
+
return this.processIORegistryResponse(response);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
log.error(`Error querying IORegistry: ${error}`);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
getServiceConfig() {
|
|
100
|
+
return {
|
|
101
|
+
serviceName: DiagnosticsService.RSD_SERVICE_NAME,
|
|
102
|
+
port: this.address[1].toString(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async connectToDiagnosticService() {
|
|
106
|
+
const service = this.getServiceConfig();
|
|
107
|
+
return await this.startLockdownService(service);
|
|
108
|
+
}
|
|
109
|
+
async sendRequest(request, timeout) {
|
|
110
|
+
const conn = await this.connectToDiagnosticService();
|
|
111
|
+
const response = await conn.sendPlistRequest(request, timeout);
|
|
112
|
+
log.debug(`${request.Request} response received`);
|
|
113
|
+
if (!response) {
|
|
114
|
+
return {};
|
|
115
|
+
}
|
|
116
|
+
if (Array.isArray(response)) {
|
|
117
|
+
return response.length > 0 ? response[0] : {};
|
|
118
|
+
}
|
|
119
|
+
return response;
|
|
120
|
+
}
|
|
121
|
+
processIORegistryResponse(response) {
|
|
122
|
+
if (PlistServiceDecoder.lastDecodedResult) {
|
|
123
|
+
if (Array.isArray(PlistServiceDecoder.lastDecodedResult)) {
|
|
124
|
+
return PlistServiceDecoder.lastDecodedResult;
|
|
125
|
+
}
|
|
126
|
+
return [PlistServiceDecoder.lastDecodedResult];
|
|
127
|
+
}
|
|
128
|
+
if (!response) {
|
|
129
|
+
throw new Error('Invalid response from IORegistry');
|
|
130
|
+
}
|
|
131
|
+
if (Array.isArray(response)) {
|
|
132
|
+
if (response.length === 0 && typeof response === 'object') {
|
|
133
|
+
log.debug('Received empty array response');
|
|
134
|
+
return [{ IORegistryResponse: 'No data found' }];
|
|
135
|
+
}
|
|
136
|
+
return response;
|
|
137
|
+
}
|
|
138
|
+
if (typeof response === 'object' &&
|
|
139
|
+
!Buffer.isBuffer(response) &&
|
|
140
|
+
!(response instanceof Date)) {
|
|
141
|
+
const responseObj = response;
|
|
142
|
+
if (responseObj.Diagnostics &&
|
|
143
|
+
typeof responseObj.Diagnostics === 'object') {
|
|
144
|
+
return [responseObj.Diagnostics];
|
|
145
|
+
}
|
|
146
|
+
return [responseObj];
|
|
147
|
+
}
|
|
148
|
+
return [{ value: response }];
|
|
149
|
+
}
|
|
150
|
+
async handleMultipartIORegistryResponse(conn, initialResponse, timeout) {
|
|
151
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
152
|
+
const emptyRequest = {
|
|
153
|
+
Request: 'Status',
|
|
154
|
+
};
|
|
155
|
+
log.debug('Sending follow-up request for additional data');
|
|
156
|
+
const additionalResponse = await conn.sendPlistRequest(emptyRequest, timeout);
|
|
157
|
+
log.debug('Additional response: ', additionalResponse);
|
|
158
|
+
const hasDiagnostics = 'Diagnostics' in additionalResponse &&
|
|
159
|
+
typeof additionalResponse.Diagnostics === 'object' &&
|
|
160
|
+
additionalResponse.Diagnostics !== null &&
|
|
161
|
+
'IORegistry' in additionalResponse.Diagnostics;
|
|
162
|
+
if (additionalResponse.Status !== 'Success' && hasDiagnostics) {
|
|
163
|
+
throw new Error(`Error getting diagnostic data: ${additionalResponse}`);
|
|
164
|
+
}
|
|
165
|
+
log.debug('Using additional response with IORegistry data');
|
|
166
|
+
return additionalResponse.Diagnostics.IORegistry;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export default DiagnosticsService;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../../../src/services/ios/diagnostic-service/keys.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EA8vBrC,CAAC"}
|