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.
Files changed (192) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/src/base-plist-service.d.ts +51 -0
  3. package/build/src/base-plist-service.d.ts.map +1 -0
  4. package/build/src/base-plist-service.js +61 -0
  5. package/build/src/base-socket-service.d.ts +15 -0
  6. package/build/src/base-socket-service.d.ts.map +1 -0
  7. package/build/src/base-socket-service.js +46 -0
  8. package/build/src/index.d.ts +9 -0
  9. package/build/src/index.d.ts.map +1 -0
  10. package/build/src/index.js +7 -0
  11. package/build/src/lib/apple-tv/constants.d.ts +49 -0
  12. package/build/src/lib/apple-tv/constants.d.ts.map +1 -0
  13. package/build/src/lib/apple-tv/constants.js +71 -0
  14. package/build/src/lib/apple-tv/errors.d.ts +17 -0
  15. package/build/src/lib/apple-tv/errors.d.ts.map +1 -0
  16. package/build/src/lib/apple-tv/errors.js +30 -0
  17. package/build/src/lib/apple-tv/tlv/decoder.d.ts +19 -0
  18. package/build/src/lib/apple-tv/tlv/decoder.d.ts.map +1 -0
  19. package/build/src/lib/apple-tv/tlv/decoder.js +49 -0
  20. package/build/src/lib/apple-tv/tlv/encoder.d.ts +10 -0
  21. package/build/src/lib/apple-tv/tlv/encoder.d.ts.map +1 -0
  22. package/build/src/lib/apple-tv/tlv/encoder.js +20 -0
  23. package/build/src/lib/apple-tv/tlv/index.d.ts +4 -0
  24. package/build/src/lib/apple-tv/tlv/index.d.ts.map +1 -0
  25. package/build/src/lib/apple-tv/tlv/index.js +3 -0
  26. package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts +14 -0
  27. package/build/src/lib/apple-tv/tlv/pairing-tlv.d.ts.map +1 -0
  28. package/build/src/lib/apple-tv/tlv/pairing-tlv.js +27 -0
  29. package/build/src/lib/apple-tv/types.d.ts +36 -0
  30. package/build/src/lib/apple-tv/types.d.ts.map +1 -0
  31. package/build/src/lib/apple-tv/types.js +1 -0
  32. package/build/src/lib/apple-tv/utils/buffer-utils.d.ts +40 -0
  33. package/build/src/lib/apple-tv/utils/buffer-utils.d.ts.map +1 -0
  34. package/build/src/lib/apple-tv/utils/buffer-utils.js +76 -0
  35. package/build/src/lib/apple-tv/utils/index.d.ts +3 -0
  36. package/build/src/lib/apple-tv/utils/index.d.ts.map +1 -0
  37. package/build/src/lib/apple-tv/utils/index.js +2 -0
  38. package/build/src/lib/apple-tv/utils/uuid-generator.d.ts +9 -0
  39. package/build/src/lib/apple-tv/utils/uuid-generator.d.ts.map +1 -0
  40. package/build/src/lib/apple-tv/utils/uuid-generator.js +36 -0
  41. package/build/src/lib/lockdown/index.d.ts +87 -0
  42. package/build/src/lib/lockdown/index.d.ts.map +1 -0
  43. package/build/src/lib/lockdown/index.js +324 -0
  44. package/build/src/lib/pair-record/index.d.ts +3 -0
  45. package/build/src/lib/pair-record/index.d.ts.map +1 -0
  46. package/build/src/lib/pair-record/index.js +2 -0
  47. package/build/src/lib/pair-record/pair-record.d.ts +48 -0
  48. package/build/src/lib/pair-record/pair-record.d.ts.map +1 -0
  49. package/build/src/lib/pair-record/pair-record.js +85 -0
  50. package/build/src/lib/plist/binary-plist-creator.d.ts +14 -0
  51. package/build/src/lib/plist/binary-plist-creator.d.ts.map +1 -0
  52. package/build/src/lib/plist/binary-plist-creator.js +475 -0
  53. package/build/src/lib/plist/binary-plist-parser.d.ts +14 -0
  54. package/build/src/lib/plist/binary-plist-parser.d.ts.map +1 -0
  55. package/build/src/lib/plist/binary-plist-parser.js +449 -0
  56. package/build/src/lib/plist/constants.d.ts +36 -0
  57. package/build/src/lib/plist/constants.d.ts.map +1 -0
  58. package/build/src/lib/plist/constants.js +43 -0
  59. package/build/src/lib/plist/index.d.ts +14 -0
  60. package/build/src/lib/plist/index.d.ts.map +1 -0
  61. package/build/src/lib/plist/index.js +16 -0
  62. package/build/src/lib/plist/length-based-splitter.d.ts +43 -0
  63. package/build/src/lib/plist/length-based-splitter.d.ts.map +1 -0
  64. package/build/src/lib/plist/length-based-splitter.js +228 -0
  65. package/build/src/lib/plist/plist-creator.d.ts +8 -0
  66. package/build/src/lib/plist/plist-creator.d.ts.map +1 -0
  67. package/build/src/lib/plist/plist-creator.js +33 -0
  68. package/build/src/lib/plist/plist-decoder.d.ts +25 -0
  69. package/build/src/lib/plist/plist-decoder.d.ts.map +1 -0
  70. package/build/src/lib/plist/plist-decoder.js +103 -0
  71. package/build/src/lib/plist/plist-encoder.d.ts +10 -0
  72. package/build/src/lib/plist/plist-encoder.d.ts.map +1 -0
  73. package/build/src/lib/plist/plist-encoder.js +27 -0
  74. package/build/src/lib/plist/plist-parser.d.ts +9 -0
  75. package/build/src/lib/plist/plist-parser.d.ts.map +1 -0
  76. package/build/src/lib/plist/plist-parser.js +109 -0
  77. package/build/src/lib/plist/plist-service.d.ts +86 -0
  78. package/build/src/lib/plist/plist-service.d.ts.map +1 -0
  79. package/build/src/lib/plist/plist-service.js +180 -0
  80. package/build/src/lib/plist/unified-plist-creator.d.ts +9 -0
  81. package/build/src/lib/plist/unified-plist-creator.d.ts.map +1 -0
  82. package/build/src/lib/plist/unified-plist-creator.js +14 -0
  83. package/build/src/lib/plist/unified-plist-parser.d.ts +8 -0
  84. package/build/src/lib/plist/unified-plist-parser.d.ts.map +1 -0
  85. package/build/src/lib/plist/unified-plist-parser.js +23 -0
  86. package/build/src/lib/plist/utils.d.ts +97 -0
  87. package/build/src/lib/plist/utils.d.ts.map +1 -0
  88. package/build/src/lib/plist/utils.js +287 -0
  89. package/build/src/lib/remote-xpc/constants.d.ts +20 -0
  90. package/build/src/lib/remote-xpc/constants.d.ts.map +1 -0
  91. package/build/src/lib/remote-xpc/constants.js +21 -0
  92. package/build/src/lib/remote-xpc/handshake-frames.d.ts +74 -0
  93. package/build/src/lib/remote-xpc/handshake-frames.d.ts.map +1 -0
  94. package/build/src/lib/remote-xpc/handshake-frames.js +285 -0
  95. package/build/src/lib/remote-xpc/handshake.d.ts +14 -0
  96. package/build/src/lib/remote-xpc/handshake.d.ts.map +1 -0
  97. package/build/src/lib/remote-xpc/handshake.js +95 -0
  98. package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts +55 -0
  99. package/build/src/lib/remote-xpc/remote-xpc-connection.d.ts.map +1 -0
  100. package/build/src/lib/remote-xpc/remote-xpc-connection.js +365 -0
  101. package/build/src/lib/remote-xpc/xpc-protocol.d.ts +22 -0
  102. package/build/src/lib/remote-xpc/xpc-protocol.d.ts.map +1 -0
  103. package/build/src/lib/remote-xpc/xpc-protocol.js +368 -0
  104. package/build/src/lib/tunnel/index.d.ts +69 -0
  105. package/build/src/lib/tunnel/index.d.ts.map +1 -0
  106. package/build/src/lib/tunnel/index.js +205 -0
  107. package/build/src/lib/tunnel/packet-stream-client.d.ts +46 -0
  108. package/build/src/lib/tunnel/packet-stream-client.d.ts.map +1 -0
  109. package/build/src/lib/tunnel/packet-stream-client.js +152 -0
  110. package/build/src/lib/tunnel/packet-stream-server.d.ts +37 -0
  111. package/build/src/lib/tunnel/packet-stream-server.d.ts.map +1 -0
  112. package/build/src/lib/tunnel/packet-stream-server.js +109 -0
  113. package/build/src/lib/tunnel/tunnel-api-client.d.ts +85 -0
  114. package/build/src/lib/tunnel/tunnel-api-client.d.ts.map +1 -0
  115. package/build/src/lib/tunnel/tunnel-api-client.js +207 -0
  116. package/build/src/lib/tunnel/tunnel-registry-server.d.ts +68 -0
  117. package/build/src/lib/tunnel/tunnel-registry-server.d.ts.map +1 -0
  118. package/build/src/lib/tunnel/tunnel-registry-server.js +351 -0
  119. package/build/src/lib/types.d.ts +238 -0
  120. package/build/src/lib/types.d.ts.map +1 -0
  121. package/build/src/lib/types.js +4 -0
  122. package/build/src/lib/usbmux/index.d.ts +177 -0
  123. package/build/src/lib/usbmux/index.d.ts.map +1 -0
  124. package/build/src/lib/usbmux/index.js +490 -0
  125. package/build/src/lib/usbmux/usbmux-decoder.d.ts +19 -0
  126. package/build/src/lib/usbmux/usbmux-decoder.d.ts.map +1 -0
  127. package/build/src/lib/usbmux/usbmux-decoder.js +38 -0
  128. package/build/src/lib/usbmux/usbmux-encoder.d.ts +12 -0
  129. package/build/src/lib/usbmux/usbmux-encoder.d.ts.map +1 -0
  130. package/build/src/lib/usbmux/usbmux-encoder.js +32 -0
  131. package/build/src/service-connection.d.ts +34 -0
  132. package/build/src/service-connection.d.ts.map +1 -0
  133. package/build/src/service-connection.js +51 -0
  134. package/build/src/services/index.d.ts +6 -0
  135. package/build/src/services/index.d.ts.map +1 -0
  136. package/build/src/services/index.js +5 -0
  137. package/build/src/services/ios/base-service.d.ts +35 -0
  138. package/build/src/services/ios/base-service.d.ts.map +1 -0
  139. package/build/src/services/ios/base-service.js +55 -0
  140. package/build/src/services/ios/diagnostic-service/index.d.ts +46 -0
  141. package/build/src/services/ios/diagnostic-service/index.d.ts.map +1 -0
  142. package/build/src/services/ios/diagnostic-service/index.js +169 -0
  143. package/build/src/services/ios/diagnostic-service/keys.d.ts +5 -0
  144. package/build/src/services/ios/diagnostic-service/keys.d.ts.map +1 -0
  145. package/build/src/services/ios/diagnostic-service/keys.js +770 -0
  146. package/build/src/services/ios/syslog-service/index.d.ts +91 -0
  147. package/build/src/services/ios/syslog-service/index.d.ts.map +1 -0
  148. package/build/src/services/ios/syslog-service/index.js +323 -0
  149. package/build/src/services/ios/tunnel-service/index.d.ts +17 -0
  150. package/build/src/services/ios/tunnel-service/index.d.ts.map +1 -0
  151. package/build/src/services/ios/tunnel-service/index.js +57 -0
  152. package/build/src/services.d.ts +14 -0
  153. package/build/src/services.d.ts.map +1 -0
  154. package/build/src/services.js +48 -0
  155. package/package.json +12 -3
  156. package/.github/dependabot.yml +0 -38
  157. package/.github/workflows/format-check.yml +0 -43
  158. package/.github/workflows/lint-and-build.yml +0 -40
  159. package/.github/workflows/pr-title.yml +0 -16
  160. package/.github/workflows/publish.js.yml +0 -41
  161. package/.github/workflows/test-validation.yml +0 -40
  162. package/.mocharc.json +0 -8
  163. package/.prettierignore +0 -3
  164. package/.prettierrc +0 -17
  165. package/.releaserc +0 -48
  166. package/assets/images/ios-arch.png +0 -0
  167. package/eslint.config.js +0 -45
  168. package/npm-shrinkwrap.json +0 -2711
  169. package/test/integration/diagnostics-test.ts +0 -44
  170. package/test/integration/read-pair-record-test.ts +0 -39
  171. package/test/integration/tunnel-test.ts +0 -104
  172. package/test/unit/apple-tv/tlv/decoder.spec.ts +0 -144
  173. package/test/unit/apple-tv/tlv/encoder.spec.ts +0 -91
  174. package/test/unit/apple-tv/tlv/pairing-tlv.spec.ts +0 -101
  175. package/test/unit/apple-tv/tlv/tlv-integration.spec.ts +0 -146
  176. package/test/unit/apple-tv/utils/buffer-utils.spec.ts +0 -74
  177. package/test/unit/apple-tv/utils/uuid-generator.spec.ts +0 -39
  178. package/test/unit/fixtures/index.ts +0 -88
  179. package/test/unit/fixtures/usbmuxconnectmessage.bin +0 -0
  180. package/test/unit/fixtures/usbmuxlistdevicemessage.bin +0 -0
  181. package/test/unit/plist/error-handling.spec.ts +0 -101
  182. package/test/unit/plist/fixtures/sample.binary.plist +0 -0
  183. package/test/unit/plist/fixtures/sample.xml.plist +0 -38
  184. package/test/unit/plist/plist-parser.spec.ts +0 -283
  185. package/test/unit/plist/plist.spec.ts +0 -205
  186. package/test/unit/plist/tag-position-handling.spec.ts +0 -90
  187. package/test/unit/plist/unified-plist-parser.spec.ts +0 -227
  188. package/test/unit/plist/utils.spec.ts +0 -249
  189. package/test/unit/plist/xml-cleaning.spec.ts +0 -60
  190. package/test/unit/tunnel/tunnel-registry-server.spec.ts +0 -194
  191. package/test/unit/usbmux/usbmux-specs.ts +0 -71
  192. package/tsconfig.json +0 -36
@@ -0,0 +1,152 @@
1
+ import { logger } from '@appium/support';
2
+ import { EventEmitter } from 'events';
3
+ import { createConnection } from 'net';
4
+ const log = logger.getLogger('PacketStreamClient');
5
+ /**
6
+ * Constants for packet stream protocol
7
+ */
8
+ const PACKET_LENGTH_PREFIX_SIZE = 10;
9
+ /**
10
+ * Client that connects to a PacketStreamServer to receive packet data
11
+ * Implements the PacketSource interface required by SyslogService
12
+ */
13
+ export class PacketStreamClient extends EventEmitter {
14
+ host;
15
+ port;
16
+ socket = null;
17
+ packetConsumers = new Set();
18
+ buffer = Buffer.alloc(0);
19
+ connected = false;
20
+ constructor(host, port) {
21
+ super();
22
+ this.host = host;
23
+ this.port = port;
24
+ }
25
+ async connect() {
26
+ if (this.connected) {
27
+ log.info('Already connected');
28
+ return;
29
+ }
30
+ return new Promise((resolve, reject) => {
31
+ this.socket = createConnection({ host: this.host, port: this.port }, () => {
32
+ log.info(`Connected to packet stream server at ${this.host}:${this.port}`);
33
+ this.connected = true;
34
+ resolve();
35
+ });
36
+ this.socket.on('data', (data) => {
37
+ this.handleData(data);
38
+ });
39
+ this.socket.once('close', () => {
40
+ log.info('Disconnected from packet stream server');
41
+ this.connected = false;
42
+ this.emit('close');
43
+ });
44
+ this.socket.on('error', (err) => {
45
+ log.error(`Socket error: ${err}`);
46
+ this.connected = false;
47
+ if (!this.socket) {
48
+ reject(err);
49
+ }
50
+ else {
51
+ this.emit('error', err);
52
+ }
53
+ });
54
+ });
55
+ }
56
+ isConnected() {
57
+ return this.connected;
58
+ }
59
+ async disconnect() {
60
+ if (this.socket && !this.socket.destroyed) {
61
+ this.socket.destroy();
62
+ this.socket = null;
63
+ }
64
+ this.connected = false;
65
+ this.packetConsumers.clear();
66
+ }
67
+ addPacketConsumer(consumer) {
68
+ this.packetConsumers.add(consumer);
69
+ }
70
+ removePacketConsumer(consumer) {
71
+ this.packetConsumers.delete(consumer);
72
+ }
73
+ /**
74
+ * Handle incoming data from the socket
75
+ */
76
+ handleData(data) {
77
+ this.buffer = Buffer.concat([this.buffer, data]);
78
+ this.processBuffer();
79
+ }
80
+ /**
81
+ * Process buffered data to extract complete messages
82
+ */
83
+ processBuffer() {
84
+ while (this.buffer.length >= PACKET_LENGTH_PREFIX_SIZE) {
85
+ const messageLength = this.extractMessageLength();
86
+ if (messageLength === null) {
87
+ // Invalid length, reset buffer
88
+ this.buffer = Buffer.alloc(0);
89
+ break;
90
+ }
91
+ const totalMessageSize = PACKET_LENGTH_PREFIX_SIZE + messageLength;
92
+ if (this.buffer.length < totalMessageSize) {
93
+ // Wait for more data
94
+ break;
95
+ }
96
+ const messageData = this.buffer.slice(PACKET_LENGTH_PREFIX_SIZE, totalMessageSize);
97
+ this.buffer = this.buffer.slice(totalMessageSize);
98
+ this.processMessage(messageData);
99
+ }
100
+ }
101
+ /**
102
+ * Extract message length from buffer
103
+ * @returns Message length or null if invalid
104
+ */
105
+ extractMessageLength() {
106
+ const lengthStr = this.buffer
107
+ .slice(0, PACKET_LENGTH_PREFIX_SIZE)
108
+ .toString();
109
+ const messageLength = parseInt(lengthStr, 10);
110
+ if (isNaN(messageLength)) {
111
+ log.error('Invalid message length, clearing buffer');
112
+ return null;
113
+ }
114
+ return messageLength;
115
+ }
116
+ /**
117
+ * Process a single message
118
+ */
119
+ processMessage(messageData) {
120
+ try {
121
+ const packet = this.parsePacket(messageData);
122
+ this.notifyConsumers(packet);
123
+ }
124
+ catch (err) {
125
+ log.error(`Error processing message: ${err}`);
126
+ }
127
+ }
128
+ /**
129
+ * Parse packet data from message buffer
130
+ */
131
+ parsePacket(messageData) {
132
+ const packet = JSON.parse(messageData.toString());
133
+ // Reconstruct Buffer from JSON
134
+ if (packet.payload && typeof packet.payload === 'object') {
135
+ packet.payload = Buffer.from(packet.payload);
136
+ }
137
+ return packet;
138
+ }
139
+ /**
140
+ * Notify all packet consumers
141
+ */
142
+ notifyConsumers(packet) {
143
+ for (const consumer of this.packetConsumers) {
144
+ try {
145
+ consumer.onPacket(packet);
146
+ }
147
+ catch (err) {
148
+ log.error(`Error in packet consumer: ${err}`);
149
+ }
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,37 @@
1
+ import { EventEmitter } from 'events';
2
+ import type { PacketConsumer } from 'tuntap-bridge';
3
+ /**
4
+ * Server that exposes packet streaming from a tunnel over TCP
5
+ * This allows cross-process access to tunnel packet streams
6
+ */
7
+ export declare class PacketStreamServer extends EventEmitter {
8
+ private readonly port;
9
+ private server;
10
+ private readonly clients;
11
+ private packetConsumer;
12
+ constructor(port: number);
13
+ /**
14
+ * Start the packet stream server
15
+ * @throws {Error} If server is already started
16
+ */
17
+ start(): Promise<void>;
18
+ stop(): Promise<void>;
19
+ getPacketConsumer(): PacketConsumer | null;
20
+ /**
21
+ * Handle new client connection
22
+ */
23
+ private handleClientConnection;
24
+ /**
25
+ * Create packet consumer that broadcasts packets to all connected clients
26
+ */
27
+ private createPacketConsumer;
28
+ /**
29
+ * Broadcast packet to all connected clients
30
+ */
31
+ private broadcastPacket;
32
+ /**
33
+ * Create a message buffer with length prefix
34
+ */
35
+ private createMessage;
36
+ }
37
+ //# sourceMappingURL=packet-stream-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packet-stream-server.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/packet-stream-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,eAAe,CAAC;AAYhE;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAKtC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,cAAc,CAA+B;gBAExB,IAAI,EAAE,MAAM;IAIzC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAI1C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAe9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoBvB;;OAEG;IACH,OAAO,CAAC,aAAa;CAItB"}
@@ -0,0 +1,109 @@
1
+ import { logger } from '@appium/support';
2
+ import { EventEmitter } from 'events';
3
+ import { createServer } from 'net';
4
+ const log = logger.getLogger('PacketStreamServer');
5
+ /**
6
+ * Server that exposes packet streaming from a tunnel over TCP
7
+ * This allows cross-process access to tunnel packet streams
8
+ */
9
+ export class PacketStreamServer extends EventEmitter {
10
+ port;
11
+ server = null;
12
+ clients = new Set();
13
+ packetConsumer = null;
14
+ constructor(port) {
15
+ super();
16
+ this.port = port;
17
+ }
18
+ /**
19
+ * Start the packet stream server
20
+ * @throws {Error} If server is already started
21
+ */
22
+ async start() {
23
+ if (this.server) {
24
+ throw new Error('Server already started');
25
+ }
26
+ this.server = createServer((client) => {
27
+ this.handleClientConnection(client);
28
+ });
29
+ this.packetConsumer = this.createPacketConsumer();
30
+ return new Promise((resolve, reject) => {
31
+ this.server.listen(this.port, () => {
32
+ log.info(`Packet stream server listening on port ${this.port}`);
33
+ resolve();
34
+ });
35
+ this.server.on('error', reject);
36
+ });
37
+ }
38
+ async stop() {
39
+ for (const client of this.clients) {
40
+ client.destroy();
41
+ }
42
+ this.clients.clear();
43
+ if (this.server) {
44
+ return new Promise((resolve) => {
45
+ this.server?.close(() => {
46
+ this.server = null;
47
+ resolve();
48
+ });
49
+ });
50
+ }
51
+ }
52
+ getPacketConsumer() {
53
+ return this.packetConsumer;
54
+ }
55
+ /**
56
+ * Handle new client connection
57
+ */
58
+ handleClientConnection(client) {
59
+ log.info(`Client connected from ${client.remoteAddress}`);
60
+ this.clients.add(client);
61
+ client.on('close', () => {
62
+ log.info(`Client disconnected from ${client.remoteAddress}`);
63
+ this.clients.delete(client);
64
+ });
65
+ client.on('error', (err) => {
66
+ log.error(`Client error: ${err}`);
67
+ this.clients.delete(client);
68
+ });
69
+ }
70
+ /**
71
+ * Create packet consumer that broadcasts packets to all connected clients
72
+ */
73
+ createPacketConsumer() {
74
+ return {
75
+ onPacket: (packet) => {
76
+ this.broadcastPacket(packet);
77
+ },
78
+ };
79
+ }
80
+ /**
81
+ * Broadcast packet to all connected clients
82
+ */
83
+ broadcastPacket(packet) {
84
+ try {
85
+ const serialized = JSON.stringify(packet);
86
+ const message = this.createMessage(serialized);
87
+ for (const client of this.clients) {
88
+ if (!client.destroyed) {
89
+ client.write(message, (err) => {
90
+ if (err) {
91
+ log.error(`Failed to write to client: ${err}`);
92
+ this.clients.delete(client);
93
+ }
94
+ });
95
+ }
96
+ }
97
+ }
98
+ catch (err) {
99
+ log.error(`Failed to broadcast packet: ${err}`);
100
+ }
101
+ }
102
+ /**
103
+ * Create a message buffer with length prefix
104
+ */
105
+ createMessage(data) {
106
+ const lengthPrefix = data.length.toString().padStart(10, '0');
107
+ return Buffer.concat([Buffer.from(lengthPrefix), Buffer.from(data)]);
108
+ }
109
+ }
@@ -0,0 +1,85 @@
1
+ import type { TunnelRegistry, TunnelRegistryEntry } from '../types.js';
2
+ /**
3
+ * API client for tunnel registry operations
4
+ * This client handles communication with the API server for tunnel data
5
+ */
6
+ export declare class TunnelApiClient {
7
+ private apiBaseUrl;
8
+ /**
9
+ * Create a new TunnelApiClient
10
+ * @param apiBaseUrl - Base URL for the API server
11
+ */
12
+ constructor(apiBaseUrl?: string);
13
+ /**
14
+ * Set the API base URL
15
+ * @param url - New base URL for the API server
16
+ */
17
+ setApiBaseUrl(url: string): void;
18
+ /**
19
+ * Get the API base URL
20
+ * @returns The current API base URL
21
+ */
22
+ getApiBaseUrl(): string;
23
+ /**
24
+ * Fetch all tunnel registry data from the API server
25
+ * @returns The complete tunnel registry
26
+ */
27
+ fetchRegistry(): Promise<TunnelRegistry>;
28
+ /**
29
+ * Get a specific tunnel by UDID
30
+ * @param udid - Device UDID
31
+ * @returns Tunnel registry entry or null if not found
32
+ */
33
+ getTunnelByUdid(udid: string): Promise<TunnelRegistryEntry | null>;
34
+ /**
35
+ * Get tunnel by device ID
36
+ * @param deviceId - Device ID
37
+ * @returns Tunnel registry entry or null if not found
38
+ */
39
+ getTunnelByDeviceId(deviceId: number): Promise<TunnelRegistryEntry | null>;
40
+ /**
41
+ * Get all tunnels
42
+ * @returns Array of tunnel registry entries
43
+ */
44
+ getAllTunnels(): Promise<TunnelRegistryEntry[]>;
45
+ /**
46
+ * Check if a tunnel exists for a specific UDID
47
+ * @param udid - Device UDID
48
+ * @returns True if tunnel exists, false otherwise
49
+ */
50
+ hasTunnel(udid: string): Promise<boolean>;
51
+ /**
52
+ * Get registry metadata
53
+ * @returns Registry metadata
54
+ */
55
+ getMetadata(): Promise<TunnelRegistry['metadata']>;
56
+ /**
57
+ * Get tunnel connection details formatted for easy use
58
+ * @param udid - Device UDID
59
+ * @returns Connection details or null if tunnel not found
60
+ */
61
+ getTunnelConnection(udid: string): Promise<{
62
+ host: string;
63
+ port: number;
64
+ udid: string;
65
+ packetStreamPort: number;
66
+ } | null>;
67
+ /**
68
+ * List all available device UDIDs with tunnels
69
+ * @returns Array of device UDIDs
70
+ */
71
+ getAvailableDevices(): Promise<string[]>;
72
+ /**
73
+ * Update or create a tunnel entry
74
+ * @param entry - Tunnel registry entry to update or create
75
+ * @returns True if successful, false otherwise
76
+ */
77
+ updateTunnel(entry: TunnelRegistryEntry): Promise<boolean>;
78
+ /**
79
+ * Delete a tunnel entry
80
+ * @param udid - Device UDID
81
+ * @returns True if successful, false otherwise
82
+ */
83
+ deleteTunnel(udid: string): Promise<boolean>;
84
+ }
85
+ //# sourceMappingURL=tunnel-api-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-api-client.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/tunnel-api-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIvE;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAS;IAE3B;;;OAGG;gBACS,UAAU,GAAE,MAAmD;IAI3E;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIhC;;;OAGG;IACH,aAAa,IAAI,MAAM;IAIvB;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,cAAc,CAAC;IAuB9C;;;;OAIG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAmBxE;;;;OAIG;IACG,mBAAmB,CACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAmBtC;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAUrD;;;;OAIG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAcxD;;;;OAIG;IACG,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAC/C,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,EAAE,MAAM,CAAC;KAC1B,GAAG,IAAI,CAAC;IAcT;;;OAGG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAU9C;;;;OAIG;IACG,YAAY,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBhE;;;;OAIG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAYnD"}
@@ -0,0 +1,207 @@
1
+ import { logger } from '@appium/support';
2
+ const log = logger.getLogger('TunnelApiClient');
3
+ /**
4
+ * API client for tunnel registry operations
5
+ * This client handles communication with the API server for tunnel data
6
+ */
7
+ export class TunnelApiClient {
8
+ apiBaseUrl;
9
+ /**
10
+ * Create a new TunnelApiClient
11
+ * @param apiBaseUrl - Base URL for the API server
12
+ */
13
+ constructor(apiBaseUrl = 'http://localhost:42314/remotexpc/tunnels') {
14
+ this.apiBaseUrl = apiBaseUrl;
15
+ }
16
+ /**
17
+ * Set the API base URL
18
+ * @param url - New base URL for the API server
19
+ */
20
+ setApiBaseUrl(url) {
21
+ this.apiBaseUrl = url;
22
+ }
23
+ /**
24
+ * Get the API base URL
25
+ * @returns The current API base URL
26
+ */
27
+ getApiBaseUrl() {
28
+ return this.apiBaseUrl;
29
+ }
30
+ /**
31
+ * Fetch all tunnel registry data from the API server
32
+ * @returns The complete tunnel registry
33
+ */
34
+ async fetchRegistry() {
35
+ try {
36
+ const response = await fetch(this.apiBaseUrl);
37
+ if (!response.ok) {
38
+ throw new Error(`API request failed with status: ${response.status}`);
39
+ }
40
+ return (await response.json());
41
+ }
42
+ catch (error) {
43
+ log.warn(`Failed to fetch tunnel registry from API: ${error}`);
44
+ // Return empty registry as fallback
45
+ return {
46
+ tunnels: {},
47
+ metadata: {
48
+ lastUpdated: new Date().toISOString(),
49
+ totalTunnels: 0,
50
+ activeTunnels: 0,
51
+ },
52
+ };
53
+ }
54
+ }
55
+ /**
56
+ * Get a specific tunnel by UDID
57
+ * @param udid - Device UDID
58
+ * @returns Tunnel registry entry or null if not found
59
+ */
60
+ async getTunnelByUdid(udid) {
61
+ try {
62
+ const response = await fetch(`${this.apiBaseUrl}/${udid}`);
63
+ if (response.status === 404) {
64
+ return null;
65
+ }
66
+ if (!response.ok) {
67
+ throw new Error(`API request failed with status: ${response.status}`);
68
+ }
69
+ return (await response.json());
70
+ }
71
+ catch (error) {
72
+ log.warn(`Failed to fetch tunnel for UDID ${udid}: ${error}`);
73
+ return null;
74
+ }
75
+ }
76
+ /**
77
+ * Get tunnel by device ID
78
+ * @param deviceId - Device ID
79
+ * @returns Tunnel registry entry or null if not found
80
+ */
81
+ async getTunnelByDeviceId(deviceId) {
82
+ try {
83
+ const response = await fetch(`${this.apiBaseUrl}/device/${deviceId}`);
84
+ if (response.status === 404) {
85
+ return null;
86
+ }
87
+ if (!response.ok) {
88
+ throw new Error(`API request failed with status: ${response.status}`);
89
+ }
90
+ return (await response.json());
91
+ }
92
+ catch (error) {
93
+ log.warn(`Failed to fetch tunnel for device ID ${deviceId}: ${error}`);
94
+ return null;
95
+ }
96
+ }
97
+ /**
98
+ * Get all tunnels
99
+ * @returns Array of tunnel registry entries
100
+ */
101
+ async getAllTunnels() {
102
+ try {
103
+ const registry = await this.fetchRegistry();
104
+ return Object.values(registry.tunnels);
105
+ }
106
+ catch (error) {
107
+ log.warn(`Failed to fetch all tunnels: ${error}`);
108
+ return [];
109
+ }
110
+ }
111
+ /**
112
+ * Check if a tunnel exists for a specific UDID
113
+ * @param udid - Device UDID
114
+ * @returns True if tunnel exists, false otherwise
115
+ */
116
+ async hasTunnel(udid) {
117
+ const tunnel = await this.getTunnelByUdid(udid);
118
+ return tunnel !== null;
119
+ }
120
+ /**
121
+ * Get registry metadata
122
+ * @returns Registry metadata
123
+ */
124
+ async getMetadata() {
125
+ try {
126
+ const registry = await this.fetchRegistry();
127
+ return registry.metadata;
128
+ }
129
+ catch (error) {
130
+ log.warn(`Failed to fetch registry metadata: ${error}`);
131
+ return {
132
+ lastUpdated: new Date().toISOString(),
133
+ totalTunnels: 0,
134
+ activeTunnels: 0,
135
+ };
136
+ }
137
+ }
138
+ /**
139
+ * Get tunnel connection details formatted for easy use
140
+ * @param udid - Device UDID
141
+ * @returns Connection details or null if tunnel not found
142
+ */
143
+ async getTunnelConnection(udid) {
144
+ const tunnel = await this.getTunnelByUdid(udid);
145
+ if (!tunnel) {
146
+ return null;
147
+ }
148
+ return {
149
+ host: tunnel.address,
150
+ port: tunnel.rsdPort,
151
+ udid: tunnel.udid,
152
+ packetStreamPort: tunnel.packetStreamPort,
153
+ };
154
+ }
155
+ /**
156
+ * List all available device UDIDs with tunnels
157
+ * @returns Array of device UDIDs
158
+ */
159
+ async getAvailableDevices() {
160
+ try {
161
+ const registry = await this.fetchRegistry();
162
+ return Object.keys(registry.tunnels);
163
+ }
164
+ catch (error) {
165
+ log.warn(`Failed to fetch available devices: ${error}`);
166
+ return [];
167
+ }
168
+ }
169
+ /**
170
+ * Update or create a tunnel entry
171
+ * @param entry - Tunnel registry entry to update or create
172
+ * @returns True if successful, false otherwise
173
+ */
174
+ async updateTunnel(entry) {
175
+ try {
176
+ const response = await fetch(`${this.apiBaseUrl}/${entry.udid}`, {
177
+ method: 'PUT',
178
+ headers: {
179
+ 'Content-Type': 'application/json',
180
+ },
181
+ body: JSON.stringify(entry),
182
+ });
183
+ return response.ok;
184
+ }
185
+ catch (error) {
186
+ log.error(`Failed to update tunnel for UDID ${entry.udid}: ${error}`);
187
+ return false;
188
+ }
189
+ }
190
+ /**
191
+ * Delete a tunnel entry
192
+ * @param udid - Device UDID
193
+ * @returns True if successful, false otherwise
194
+ */
195
+ async deleteTunnel(udid) {
196
+ try {
197
+ const response = await fetch(`${this.apiBaseUrl}/${udid}`, {
198
+ method: 'DELETE',
199
+ });
200
+ return response.ok;
201
+ }
202
+ catch (error) {
203
+ log.error(`Failed to delete tunnel for UDID ${udid}: ${error}`);
204
+ return false;
205
+ }
206
+ }
207
+ }
@@ -0,0 +1,68 @@
1
+ import type { TunnelRegistry } from '../types.js';
2
+ /**
3
+ * Tunnel Registry Server - provides API endpoints for tunnel registry operations
4
+ */
5
+ export declare class TunnelRegistryServer {
6
+ private server?;
7
+ port: number;
8
+ tunnelsInfo?: TunnelRegistry;
9
+ private registry;
10
+ /**
11
+ * Create a new TunnelRegistryServer
12
+ * @param tunnelsInfo - Registry data object
13
+ * @param port - Port to listen on
14
+ */
15
+ constructor(tunnelsInfo: TunnelRegistry | undefined, port: number);
16
+ /**
17
+ * Get tunnels from registry
18
+ */
19
+ private get tunnels();
20
+ /**
21
+ * Get auto-calculated metadata
22
+ */
23
+ private get metadata();
24
+ /**
25
+ * Get a complete registry with tunnels and metadata
26
+ */
27
+ private get fullRegistry();
28
+ /**
29
+ * Start the server
30
+ */
31
+ start(): Promise<void>;
32
+ /**
33
+ * Stop the server
34
+ */
35
+ stop(): Promise<void>;
36
+ /**
37
+ * Main request handler
38
+ */
39
+ private handleRequest;
40
+ /**
41
+ * Handler for getting all tunnels
42
+ */
43
+ private getAllTunnels;
44
+ /**
45
+ * Handler for getting a tunnel by UDID
46
+ */
47
+ private getTunnelByUdid;
48
+ /**
49
+ * Handler for getting a tunnel by device ID
50
+ */
51
+ private getTunnelByDeviceId;
52
+ /**
53
+ * Handler for updating a tunnel
54
+ */
55
+ private updateTunnel;
56
+ /**
57
+ * Load the registry from provided data
58
+ */
59
+ private loadRegistry;
60
+ }
61
+ /**
62
+ * Create and start a TunnelRegistryServer instance
63
+ * @param tunnelInfos - Registry data object
64
+ * @param port - Port to listen on
65
+ * @returns The started TunnelRegistryServer instance
66
+ */
67
+ export declare function startTunnelRegistryServer(tunnelInfos: TunnelRegistry | undefined, port?: number): Promise<TunnelRegistryServer>;
68
+ //# sourceMappingURL=tunnel-registry-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-registry-server.d.ts","sourceRoot":"","sources":["../../../../src/lib/tunnel/tunnel-registry-server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAuDvE;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,cAAc,CAAC;IACpC,OAAO,CAAC,QAAQ,CAOd;IAEF;;;;OAIG;gBACS,WAAW,EAAE,cAAc,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM;IAKjE;;OAEG;IACH,OAAO,KAAK,OAAO,GAElB;IAED;;OAEG;IACH,OAAO,KAAK,QAAQ,GAOnB;IAED;;OAEG;IACH,OAAO,KAAK,YAAY,GAKvB;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B;;OAEG;YACW,aAAa;IA6D3B;;OAEG;YACW,aAAa;IAY3B;;OAEG;YACW,eAAe;IAwB7B;;OAEG;YACW,mBAAmB;IAgCjC;;OAEG;YACW,YAAY;IAqD1B;;OAEG;YACW,YAAY;CAmB3B;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,cAAc,GAAG,SAAS,EACvC,IAAI,GAAE,MAAqC,GAC1C,OAAO,CAAC,oBAAoB,CAAC,CAI/B"}