appium-ios-remotexpc 0.0.3 → 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 +6 -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 -43
- 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,351 @@
|
|
|
1
|
+
import { logger } from '@appium/support';
|
|
2
|
+
import * as http from 'node:http';
|
|
3
|
+
import { URL } from 'node:url';
|
|
4
|
+
// Constants
|
|
5
|
+
const DEFAULT_TUNNEL_REGISTRY_PORT = 42314;
|
|
6
|
+
const API_BASE_PATH = '/remotexpc/tunnels';
|
|
7
|
+
// Logger instance
|
|
8
|
+
const log = logger.getLogger('TunnelRegistryServer');
|
|
9
|
+
// Helper functions
|
|
10
|
+
/**
|
|
11
|
+
* Parse JSON body from HTTP request
|
|
12
|
+
*/
|
|
13
|
+
async function parseJSONBody(req) {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
let body = '';
|
|
16
|
+
req.on('data', (chunk) => {
|
|
17
|
+
body += chunk.toString();
|
|
18
|
+
});
|
|
19
|
+
req.on('end', () => {
|
|
20
|
+
try {
|
|
21
|
+
resolve(body ? JSON.parse(body) : {});
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
reject(error);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
req.on('error', reject);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Send JSON response
|
|
32
|
+
*/
|
|
33
|
+
function sendJSON(res, statusCode, data) {
|
|
34
|
+
const statusText = http.STATUS_CODES[statusCode] || '';
|
|
35
|
+
let responseBody;
|
|
36
|
+
if (data && typeof data === 'object' && data !== null) {
|
|
37
|
+
if ('error' in data) {
|
|
38
|
+
responseBody = { status: statusText, ...data };
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
responseBody = { status: statusText, ...data };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
responseBody = { status: statusText, data };
|
|
46
|
+
}
|
|
47
|
+
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
48
|
+
res.end(JSON.stringify(responseBody));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Tunnel Registry Server - provides API endpoints for tunnel registry operations
|
|
52
|
+
*/
|
|
53
|
+
export class TunnelRegistryServer {
|
|
54
|
+
server;
|
|
55
|
+
port;
|
|
56
|
+
tunnelsInfo;
|
|
57
|
+
registry = {
|
|
58
|
+
tunnels: {},
|
|
59
|
+
metadata: {
|
|
60
|
+
lastUpdated: new Date().toISOString(),
|
|
61
|
+
totalTunnels: 0,
|
|
62
|
+
activeTunnels: 0,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Create a new TunnelRegistryServer
|
|
67
|
+
* @param tunnelsInfo - Registry data object
|
|
68
|
+
* @param port - Port to listen on
|
|
69
|
+
*/
|
|
70
|
+
constructor(tunnelsInfo, port) {
|
|
71
|
+
this.port = port;
|
|
72
|
+
this.tunnelsInfo = tunnelsInfo;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get tunnels from registry
|
|
76
|
+
*/
|
|
77
|
+
get tunnels() {
|
|
78
|
+
return this.registry.tunnels;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Get auto-calculated metadata
|
|
82
|
+
*/
|
|
83
|
+
get metadata() {
|
|
84
|
+
const tunnelCount = Object.keys(this.tunnels).length;
|
|
85
|
+
return {
|
|
86
|
+
lastUpdated: new Date().toISOString(),
|
|
87
|
+
totalTunnels: tunnelCount,
|
|
88
|
+
activeTunnels: tunnelCount, // Assuming all tunnels are active
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get a complete registry with tunnels and metadata
|
|
93
|
+
*/
|
|
94
|
+
get fullRegistry() {
|
|
95
|
+
return {
|
|
96
|
+
tunnels: this.tunnels,
|
|
97
|
+
metadata: this.metadata,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Start the server
|
|
102
|
+
*/
|
|
103
|
+
async start() {
|
|
104
|
+
try {
|
|
105
|
+
// Load the registry first
|
|
106
|
+
await this.loadRegistry();
|
|
107
|
+
// Create HTTP server with request handler
|
|
108
|
+
this.server = http.createServer(async (req, res) => {
|
|
109
|
+
await this.handleRequest(req, res);
|
|
110
|
+
});
|
|
111
|
+
// Start listening
|
|
112
|
+
await new Promise((resolve, reject) => {
|
|
113
|
+
this.server?.listen(this.port, () => {
|
|
114
|
+
log.info(`Tunnel Registry Server started on port ${this.port}`);
|
|
115
|
+
log.info(`API available at http://localhost:${this.port}${API_BASE_PATH}`);
|
|
116
|
+
resolve();
|
|
117
|
+
});
|
|
118
|
+
// Handle server errors
|
|
119
|
+
this.server?.on('error', (error) => {
|
|
120
|
+
log.error(`Server error: ${error}`);
|
|
121
|
+
reject(error);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
log.error(`Failed to start server: ${error}`);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Stop the server
|
|
132
|
+
*/
|
|
133
|
+
async stop() {
|
|
134
|
+
if (!this.server) {
|
|
135
|
+
log.warn('Server not running');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
await new Promise((resolve, reject) => {
|
|
140
|
+
this.server?.close((error) => {
|
|
141
|
+
if (error) {
|
|
142
|
+
reject(error);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
resolve();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
log.info('Tunnel Registry Server stopped');
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
log.error(`Error stopping server: ${error}`);
|
|
153
|
+
throw error;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Main request handler
|
|
158
|
+
*/
|
|
159
|
+
async handleRequest(req, res) {
|
|
160
|
+
const url = new URL(req.url || '', `http://localhost:${this.port}`);
|
|
161
|
+
const method = req.method || 'GET';
|
|
162
|
+
const pathname = url.pathname;
|
|
163
|
+
// Log the request
|
|
164
|
+
log.debug(`${method} ${pathname}`);
|
|
165
|
+
// Match routes
|
|
166
|
+
const basePath = API_BASE_PATH;
|
|
167
|
+
try {
|
|
168
|
+
// GET /remotexpc/tunnels - Get all tunnels
|
|
169
|
+
if (method === 'GET' && pathname === basePath) {
|
|
170
|
+
await this.getAllTunnels(res);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
// GET /remotexpc/tunnels/device/:deviceId - Get tunnel by device ID
|
|
174
|
+
const deviceMatch = pathname.match(new RegExp(`^${basePath}/device/(.+)$`));
|
|
175
|
+
if (method === 'GET' && deviceMatch) {
|
|
176
|
+
const deviceIdStr = deviceMatch[1];
|
|
177
|
+
const deviceId = parseInt(deviceIdStr, 10);
|
|
178
|
+
await this.getTunnelByDeviceId(res, deviceId);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// GET /remotexpc/tunnels/:udid - Get tunnel by UDID
|
|
182
|
+
const udidMatch = pathname.match(new RegExp(`^${basePath}/([^/]+)$`));
|
|
183
|
+
if (method === 'GET' &&
|
|
184
|
+
udidMatch &&
|
|
185
|
+
!udidMatch[1].startsWith('device/')) {
|
|
186
|
+
const udid = udidMatch[1];
|
|
187
|
+
await this.getTunnelByUdid(res, udid);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// PUT /remotexpc/tunnels/:udid - Update tunnel
|
|
191
|
+
if (method === 'PUT' && udidMatch) {
|
|
192
|
+
const udid = udidMatch[1];
|
|
193
|
+
await this.updateTunnel(req, res, udid);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// No route matched
|
|
197
|
+
sendJSON(res, 404, { error: 'Not found' });
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
log.error(`Request handling error: ${error}`);
|
|
201
|
+
sendJSON(res, 500, {
|
|
202
|
+
error: 'Internal server error',
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Handler for getting all tunnels
|
|
208
|
+
*/
|
|
209
|
+
async getAllTunnels(res) {
|
|
210
|
+
try {
|
|
211
|
+
await this.loadRegistry();
|
|
212
|
+
sendJSON(res, 200, this.fullRegistry);
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
log.error(`Error getting all tunnels: ${error}`);
|
|
216
|
+
sendJSON(res, 500, {
|
|
217
|
+
error: 'Failed to get tunnels',
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Handler for getting a tunnel by UDID
|
|
223
|
+
*/
|
|
224
|
+
async getTunnelByUdid(res, udid) {
|
|
225
|
+
try {
|
|
226
|
+
await this.loadRegistry();
|
|
227
|
+
const tunnel = this.tunnels[udid];
|
|
228
|
+
if (!tunnel) {
|
|
229
|
+
sendJSON(res, 404, {
|
|
230
|
+
error: `Tunnel not found for UDID: ${udid}`,
|
|
231
|
+
});
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
sendJSON(res, 200, tunnel);
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
log.error(`Error getting tunnel by UDID: ${error}`);
|
|
238
|
+
sendJSON(res, 500, {
|
|
239
|
+
error: 'Failed to get tunnel',
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Handler for getting a tunnel by device ID
|
|
245
|
+
*/
|
|
246
|
+
async getTunnelByDeviceId(res, deviceId) {
|
|
247
|
+
try {
|
|
248
|
+
await this.loadRegistry();
|
|
249
|
+
if (isNaN(deviceId)) {
|
|
250
|
+
sendJSON(res, 400, { error: 'Invalid device ID' });
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const tunnel = Object.values(this.tunnels).find((t) => t.deviceId === deviceId);
|
|
254
|
+
if (!tunnel) {
|
|
255
|
+
sendJSON(res, 404, {
|
|
256
|
+
error: `Tunnel not found for device ID: ${deviceId}`,
|
|
257
|
+
});
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
sendJSON(res, 200, tunnel);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
log.error(`Error getting tunnel by device ID: ${error}`);
|
|
264
|
+
sendJSON(res, 500, {
|
|
265
|
+
error: 'Failed to get tunnel',
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Handler for updating a tunnel
|
|
271
|
+
*/
|
|
272
|
+
async updateTunnel(req, res, udid) {
|
|
273
|
+
try {
|
|
274
|
+
await this.loadRegistry();
|
|
275
|
+
let tunnelData = null;
|
|
276
|
+
try {
|
|
277
|
+
tunnelData = await parseJSONBody(req);
|
|
278
|
+
}
|
|
279
|
+
catch (parseError) {
|
|
280
|
+
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
281
|
+
log.error(`Failed to parse JSON body: ${errorMessage}`);
|
|
282
|
+
sendJSON(res, 400, {
|
|
283
|
+
error: 'Malformed JSON in request body',
|
|
284
|
+
});
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (!tunnelData || typeof tunnelData !== 'object') {
|
|
288
|
+
sendJSON(res, 400, {
|
|
289
|
+
error: 'Invalid tunnel data',
|
|
290
|
+
});
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
// Ensure the UDID in the path matches the one in the body
|
|
294
|
+
if (tunnelData.udid !== udid) {
|
|
295
|
+
sendJSON(res, 400, {
|
|
296
|
+
error: 'UDID mismatch between path and body',
|
|
297
|
+
});
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
// Update the tunnel
|
|
301
|
+
this.registry.tunnels[udid] = {
|
|
302
|
+
...tunnelData,
|
|
303
|
+
lastUpdated: Date.now(),
|
|
304
|
+
};
|
|
305
|
+
sendJSON(res, 200, {
|
|
306
|
+
success: true,
|
|
307
|
+
tunnel: this.registry.tunnels[udid],
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
log.error(`Error updating tunnel: ${error}`);
|
|
312
|
+
sendJSON(res, 500, {
|
|
313
|
+
error: 'Failed to update tunnel',
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Load the registry from provided data
|
|
319
|
+
*/
|
|
320
|
+
async loadRegistry() {
|
|
321
|
+
try {
|
|
322
|
+
if (this.tunnelsInfo) {
|
|
323
|
+
this.registry = this.tunnelsInfo;
|
|
324
|
+
}
|
|
325
|
+
// Use the provided registry object or default empty registry
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
log.warn(`Failed to load registry: ${error}`);
|
|
329
|
+
// If there's an error, use the default empty registry
|
|
330
|
+
this.registry = {
|
|
331
|
+
tunnels: {},
|
|
332
|
+
metadata: {
|
|
333
|
+
lastUpdated: new Date().toISOString(),
|
|
334
|
+
totalTunnels: 0,
|
|
335
|
+
activeTunnels: 0,
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Create and start a TunnelRegistryServer instance
|
|
343
|
+
* @param tunnelInfos - Registry data object
|
|
344
|
+
* @param port - Port to listen on
|
|
345
|
+
* @returns The started TunnelRegistryServer instance
|
|
346
|
+
*/
|
|
347
|
+
export async function startTunnelRegistryServer(tunnelInfos, port = DEFAULT_TUNNEL_REGISTRY_PORT) {
|
|
348
|
+
const server = new TunnelRegistryServer(tunnelInfos, port);
|
|
349
|
+
await server.start();
|
|
350
|
+
return server;
|
|
351
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common type definitions for the appium-ios-remotexpc library
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
5
|
+
import type { PacketData } from 'tuntap-bridge';
|
|
6
|
+
import type { BaseService, Service } from '../services/ios/base-service.js';
|
|
7
|
+
import type { Device } from './usbmux/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Represents a value that can be stored in a plist
|
|
10
|
+
*/
|
|
11
|
+
export type PlistValue = string | number | bigint | boolean | Date | Buffer | PlistArray | PlistDictionary | null;
|
|
12
|
+
/**
|
|
13
|
+
* Represents an array in a plist
|
|
14
|
+
*/
|
|
15
|
+
export type PlistArray = Array<PlistValue>;
|
|
16
|
+
/**
|
|
17
|
+
* Represents a dictionary in a plist
|
|
18
|
+
*/
|
|
19
|
+
export interface PlistDictionary {
|
|
20
|
+
[key: string]: PlistValue;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Represents a message that can be sent or received via plist
|
|
24
|
+
*/
|
|
25
|
+
export type PlistMessage = PlistDictionary;
|
|
26
|
+
/**
|
|
27
|
+
* Represents a value that can be encoded in XPC protocol
|
|
28
|
+
*/
|
|
29
|
+
export type XPCValue = string | number | bigint | boolean | Date | Buffer | Uint8Array | XPCArray | XPCDictionary | null;
|
|
30
|
+
/**
|
|
31
|
+
* Represents an array in XPC protocol
|
|
32
|
+
*/
|
|
33
|
+
export type XPCArray = Array<XPCValue>;
|
|
34
|
+
/**
|
|
35
|
+
* Represents a dictionary in XPC protocol
|
|
36
|
+
*/
|
|
37
|
+
export interface XPCDictionary {
|
|
38
|
+
[key: string]: XPCValue;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Represents a callback function for handling responses
|
|
42
|
+
*/
|
|
43
|
+
export type ResponseCallback<T> = (data: T) => void;
|
|
44
|
+
export interface TunnelRegistryEntry {
|
|
45
|
+
/** Unique device identifier */
|
|
46
|
+
udid: string;
|
|
47
|
+
/** Numeric device ID */
|
|
48
|
+
deviceId: number;
|
|
49
|
+
/** IP address of the tunnel */
|
|
50
|
+
address: string;
|
|
51
|
+
/** Remote Service Discovery (RSD) port number */
|
|
52
|
+
rsdPort: number;
|
|
53
|
+
/** Packet stream port number */
|
|
54
|
+
packetStreamPort: number;
|
|
55
|
+
/** Type of connection (e.g., 'USB', 'Network') */
|
|
56
|
+
connectionType: string;
|
|
57
|
+
/** Product identifier of the device */
|
|
58
|
+
productId: number;
|
|
59
|
+
/** Timestamp when the tunnel was created (milliseconds since epoch) */
|
|
60
|
+
createdAt: number;
|
|
61
|
+
/** Timestamp when the tunnel was last updated (milliseconds since epoch) */
|
|
62
|
+
lastUpdated: number;
|
|
63
|
+
}
|
|
64
|
+
export interface TunnelRegistry {
|
|
65
|
+
/** Map of UDID to tunnel registry entries */
|
|
66
|
+
tunnels: Record<string, TunnelRegistryEntry>;
|
|
67
|
+
/** Metadata about the registry */
|
|
68
|
+
metadata: {
|
|
69
|
+
/** ISO 8601 timestamp of last registry update */
|
|
70
|
+
lastUpdated: string;
|
|
71
|
+
/** Total number of tunnels in the registry */
|
|
72
|
+
totalTunnels: number;
|
|
73
|
+
/** Number of currently active tunnels */
|
|
74
|
+
activeTunnels: number;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export interface SocketInfo {
|
|
78
|
+
/** Device server information */
|
|
79
|
+
server: Device;
|
|
80
|
+
/** Port number for the socket connection */
|
|
81
|
+
port: number;
|
|
82
|
+
/** Device-specific information */
|
|
83
|
+
deviceInfo: {
|
|
84
|
+
/** Unique device identifier */
|
|
85
|
+
udid: string;
|
|
86
|
+
/** IP address of the device */
|
|
87
|
+
address: string;
|
|
88
|
+
/** Optional Remote Service Discovery (RSD) port number */
|
|
89
|
+
rsdPort?: number;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export interface TunnelResult {
|
|
93
|
+
/** Device information */
|
|
94
|
+
device: Device;
|
|
95
|
+
/** Tunnel connection details */
|
|
96
|
+
tunnel: {
|
|
97
|
+
/** IP address of the tunnel */
|
|
98
|
+
Address: string;
|
|
99
|
+
/** Optional Remote Service Discovery (RSD) port number */
|
|
100
|
+
RsdPort?: number;
|
|
101
|
+
};
|
|
102
|
+
/** Optional packet stream port number */
|
|
103
|
+
packetStreamPort?: number;
|
|
104
|
+
/** Indicates whether the tunnel creation was successful */
|
|
105
|
+
success: boolean;
|
|
106
|
+
/** Error message if tunnel creation failed */
|
|
107
|
+
error?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Represents the instance side of DiagnosticsService
|
|
111
|
+
*/
|
|
112
|
+
export interface DiagnosticsService extends BaseService {
|
|
113
|
+
/**
|
|
114
|
+
* Restart the device
|
|
115
|
+
* @returns Promise that resolves when the restart request is sent
|
|
116
|
+
*/
|
|
117
|
+
restart(): Promise<PlistDictionary>;
|
|
118
|
+
/**
|
|
119
|
+
* Shutdown the device
|
|
120
|
+
* @returns Promise that resolves when the shutdown request is sent
|
|
121
|
+
*/
|
|
122
|
+
shutdown(): Promise<PlistDictionary>;
|
|
123
|
+
/**
|
|
124
|
+
* Put the device in sleep mode
|
|
125
|
+
* @returns Promise that resolves when the sleep request is sent
|
|
126
|
+
*/
|
|
127
|
+
sleep(): Promise<PlistDictionary>;
|
|
128
|
+
/**
|
|
129
|
+
* Query IORegistry
|
|
130
|
+
* @param options Options for the IORegistry query
|
|
131
|
+
* @returns Object containing the IORegistry information
|
|
132
|
+
*/
|
|
133
|
+
ioregistry(options?: {
|
|
134
|
+
plane?: string;
|
|
135
|
+
name?: string;
|
|
136
|
+
ioClass?: string;
|
|
137
|
+
returnRawJson?: boolean;
|
|
138
|
+
timeout?: number;
|
|
139
|
+
}): Promise<PlistDictionary[] | Record<string, any>>;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Represents the static side of DiagnosticsService
|
|
143
|
+
*/
|
|
144
|
+
export interface DiagnosticsServiceConstructor {
|
|
145
|
+
/**
|
|
146
|
+
* Service name for Remote Service Discovery
|
|
147
|
+
*/
|
|
148
|
+
readonly RSD_SERVICE_NAME: string;
|
|
149
|
+
/**
|
|
150
|
+
* Creates a new DiagnosticsService instance
|
|
151
|
+
* @param address Tuple containing [host, port]
|
|
152
|
+
*/
|
|
153
|
+
new (address: [string, number]): DiagnosticsService;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Options for configuring syslog capture
|
|
157
|
+
*/
|
|
158
|
+
export interface SyslogOptions {
|
|
159
|
+
/** Process ID to filter logs by */
|
|
160
|
+
pid?: number;
|
|
161
|
+
/** Whether to enable verbose logging */
|
|
162
|
+
enableVerboseLogging?: boolean;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Interface for a packet source that can provide packet data
|
|
166
|
+
*/
|
|
167
|
+
export interface PacketSource {
|
|
168
|
+
/** Add a packet consumer to receive packets */
|
|
169
|
+
addPacketConsumer: (consumer: PacketConsumer) => void;
|
|
170
|
+
/** Remove a packet consumer */
|
|
171
|
+
removePacketConsumer: (consumer: PacketConsumer) => void;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Interface for a packet consumer that can process packets
|
|
175
|
+
*/
|
|
176
|
+
export interface PacketConsumer {
|
|
177
|
+
/** Handler for received packets */
|
|
178
|
+
onPacket: (packet: PacketData) => void;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Represents the instance side of SyslogService
|
|
182
|
+
*/
|
|
183
|
+
export interface SyslogService extends EventEmitter {
|
|
184
|
+
/**
|
|
185
|
+
* Starts capturing syslog data from the device
|
|
186
|
+
* @param service Service information
|
|
187
|
+
* @param packetSource Source of packet data (can be PacketConsumer or AsyncIterable)
|
|
188
|
+
* @param options Configuration options for syslog capture
|
|
189
|
+
* @returns Promise resolving to the initial response from the service
|
|
190
|
+
*/
|
|
191
|
+
start(service: Service, packetSource: PacketSource | AsyncIterable<PacketData>, options?: SyslogOptions): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Stops capturing syslog data
|
|
194
|
+
* @returns Promise that resolves when capture is stopped
|
|
195
|
+
*/
|
|
196
|
+
stop(): Promise<void>;
|
|
197
|
+
/**
|
|
198
|
+
* Restart the device
|
|
199
|
+
* @param service Service information
|
|
200
|
+
* @returns Promise that resolves when the restart request is sent
|
|
201
|
+
*/
|
|
202
|
+
restart(service: Service): Promise<void>;
|
|
203
|
+
/**
|
|
204
|
+
* Event emitter for 'start' events
|
|
205
|
+
*/
|
|
206
|
+
on(event: 'start', listener: (response: any) => void): this;
|
|
207
|
+
/**
|
|
208
|
+
* Event emitter for 'stop' events
|
|
209
|
+
*/
|
|
210
|
+
on(event: 'stop', listener: () => void): this;
|
|
211
|
+
/**
|
|
212
|
+
* Event emitter for 'message' events
|
|
213
|
+
*/
|
|
214
|
+
on(event: 'message', listener: (message: string) => void): this;
|
|
215
|
+
/**
|
|
216
|
+
* Event emitter for 'plist' events
|
|
217
|
+
*/
|
|
218
|
+
on(event: 'plist', listener: (data: any) => void): this;
|
|
219
|
+
/**
|
|
220
|
+
* Event emitter for 'error' events
|
|
221
|
+
*/
|
|
222
|
+
on(event: 'error', listener: (error: Error) => void): this;
|
|
223
|
+
/**
|
|
224
|
+
* Event emitter for any events
|
|
225
|
+
*/
|
|
226
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Represents the static side of SyslogService
|
|
230
|
+
*/
|
|
231
|
+
export interface SyslogServiceConstructor {
|
|
232
|
+
/**
|
|
233
|
+
* Creates a new SyslogService instance
|
|
234
|
+
* @param address Tuple containing [host, port]
|
|
235
|
+
*/
|
|
236
|
+
new (address: [string, number]): SyslogService;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/types.ts"],"names":[],"mappings":"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"}
|