appium-ios-device 3.1.12 → 3.1.13

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 (174) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/index.js +7 -8
  3. package/build/lib/afc/index.d.ts +2 -2
  4. package/build/lib/afc/index.d.ts.map +1 -1
  5. package/build/lib/afc/index.js +20 -21
  6. package/build/lib/afc/index.js.map +1 -1
  7. package/build/lib/afc/protocol.d.ts +12 -2
  8. package/build/lib/afc/protocol.d.ts.map +1 -1
  9. package/build/lib/afc/protocol.js +17 -12
  10. package/build/lib/afc/protocol.js.map +1 -1
  11. package/build/lib/afc/transformer/afcdecoder.d.ts +1 -1
  12. package/build/lib/afc/transformer/afcdecoder.d.ts.map +1 -1
  13. package/build/lib/afc/transformer/afcdecoder.js.map +1 -1
  14. package/build/lib/afc/transformer/afcencoder.d.ts +1 -1
  15. package/build/lib/afc/transformer/afcencoder.d.ts.map +1 -1
  16. package/build/lib/afc/transformer/afcencoder.js.map +1 -1
  17. package/build/lib/base-service.js.map +1 -1
  18. package/build/lib/constants.d.ts.map +1 -1
  19. package/build/lib/constants.js +2 -4
  20. package/build/lib/constants.js.map +1 -1
  21. package/build/lib/house-arrest/index.d.ts +2 -2
  22. package/build/lib/house-arrest/index.d.ts.map +1 -1
  23. package/build/lib/house-arrest/index.js +2 -3
  24. package/build/lib/house-arrest/index.js.map +1 -1
  25. package/build/lib/imagemounter/index.d.ts +1 -1
  26. package/build/lib/imagemounter/index.d.ts.map +1 -1
  27. package/build/lib/imagemounter/index.js +27 -28
  28. package/build/lib/imagemounter/index.js.map +1 -1
  29. package/build/lib/imagemounter/utils/list_developer_image.d.ts +10 -15
  30. package/build/lib/imagemounter/utils/list_developer_image.d.ts.map +1 -1
  31. package/build/lib/imagemounter/utils/list_developer_image.js +43 -43
  32. package/build/lib/imagemounter/utils/list_developer_image.js.map +1 -1
  33. package/build/lib/installation-proxy/index.d.ts +2 -2
  34. package/build/lib/installation-proxy/index.d.ts.map +1 -1
  35. package/build/lib/installation-proxy/index.js +2 -3
  36. package/build/lib/installation-proxy/index.js.map +1 -1
  37. package/build/lib/instrument/headers.d.ts +75 -100
  38. package/build/lib/instrument/headers.d.ts.map +1 -1
  39. package/build/lib/instrument/headers.js +78 -83
  40. package/build/lib/instrument/headers.js.map +1 -1
  41. package/build/lib/instrument/index.d.ts +7 -11
  42. package/build/lib/instrument/index.d.ts.map +1 -1
  43. package/build/lib/instrument/index.js +18 -20
  44. package/build/lib/instrument/index.js.map +1 -1
  45. package/build/lib/instrument/transformer/dtx-decode.js.map +1 -1
  46. package/build/lib/instrument/transformer/dtx-encode.js.map +1 -1
  47. package/build/lib/instrument/transformer/nskeyed.d.ts +30 -30
  48. package/build/lib/instrument/transformer/nskeyed.d.ts.map +1 -1
  49. package/build/lib/instrument/transformer/nskeyed.js +45 -45
  50. package/build/lib/instrument/transformer/nskeyed.js.map +1 -1
  51. package/build/lib/lockdown/index.d.ts +2 -2
  52. package/build/lib/lockdown/index.d.ts.map +1 -1
  53. package/build/lib/lockdown/index.js +2 -3
  54. package/build/lib/lockdown/index.js.map +1 -1
  55. package/build/lib/mcinstall/index.d.ts +2 -2
  56. package/build/lib/mcinstall/index.d.ts.map +1 -1
  57. package/build/lib/mcinstall/index.js +8 -9
  58. package/build/lib/mcinstall/index.js.map +1 -1
  59. package/build/lib/notification-proxy/index.d.ts +2 -2
  60. package/build/lib/notification-proxy/index.d.ts.map +1 -1
  61. package/build/lib/notification-proxy/index.js +2 -3
  62. package/build/lib/notification-proxy/index.js.map +1 -1
  63. package/build/lib/plist-service/index.d.ts +1 -1
  64. package/build/lib/plist-service/index.d.ts.map +1 -1
  65. package/build/lib/plist-service/index.js.map +1 -1
  66. package/build/lib/plist-service/transformer/plist-service-decoder.d.ts +1 -1
  67. package/build/lib/plist-service/transformer/plist-service-decoder.d.ts.map +1 -1
  68. package/build/lib/plist-service/transformer/plist-service-decoder.js.map +1 -1
  69. package/build/lib/plist-service/transformer/plist-service-encoder.d.ts +1 -1
  70. package/build/lib/plist-service/transformer/plist-service-encoder.d.ts.map +1 -1
  71. package/build/lib/plist-service/transformer/plist-service-encoder.js.map +1 -1
  72. package/build/lib/services.d.ts +94 -13
  73. package/build/lib/services.d.ts.map +1 -1
  74. package/build/lib/services.js +90 -1
  75. package/build/lib/services.js.map +1 -1
  76. package/build/lib/simulatelocation/index.d.ts +2 -2
  77. package/build/lib/simulatelocation/index.d.ts.map +1 -1
  78. package/build/lib/simulatelocation/index.js +2 -3
  79. package/build/lib/simulatelocation/index.js.map +1 -1
  80. package/build/lib/ssl-helper.d.ts +8 -2
  81. package/build/lib/ssl-helper.d.ts.map +1 -1
  82. package/build/lib/ssl-helper.js +7 -0
  83. package/build/lib/ssl-helper.js.map +1 -1
  84. package/build/lib/syslog/index.d.ts +2 -2
  85. package/build/lib/syslog/index.d.ts.map +1 -1
  86. package/build/lib/syslog/index.js +2 -3
  87. package/build/lib/syslog/index.js.map +1 -1
  88. package/build/lib/syslog/transformer/syslog-decoder.d.ts +8 -8
  89. package/build/lib/syslog/transformer/syslog-decoder.d.ts.map +1 -1
  90. package/build/lib/syslog/transformer/syslog-decoder.js +32 -32
  91. package/build/lib/syslog/transformer/syslog-decoder.js.map +1 -1
  92. package/build/lib/testmanagerd/index.d.ts +2 -2
  93. package/build/lib/testmanagerd/index.d.ts.map +1 -1
  94. package/build/lib/testmanagerd/index.js +4 -7
  95. package/build/lib/testmanagerd/index.js.map +1 -1
  96. package/build/lib/usbmux/index.d.ts +38 -38
  97. package/build/lib/usbmux/index.d.ts.map +1 -1
  98. package/build/lib/usbmux/index.js +93 -93
  99. package/build/lib/usbmux/index.js.map +1 -1
  100. package/build/lib/usbmux/transformer/usbmux-decoder.d.ts +1 -1
  101. package/build/lib/usbmux/transformer/usbmux-decoder.d.ts.map +1 -1
  102. package/build/lib/usbmux/transformer/usbmux-decoder.js.map +1 -1
  103. package/build/lib/usbmux/transformer/usbmux-encoder.d.ts +1 -1
  104. package/build/lib/usbmux/transformer/usbmux-encoder.d.ts.map +1 -1
  105. package/build/lib/usbmux/transformer/usbmux-encoder.js.map +1 -1
  106. package/build/lib/util/uuid/parse.d.ts +5 -0
  107. package/build/lib/util/uuid/parse.d.ts.map +1 -1
  108. package/build/lib/util/uuid/parse.js +5 -0
  109. package/build/lib/util/uuid/parse.js.map +1 -1
  110. package/build/lib/util/uuid/stringify.d.ts +6 -0
  111. package/build/lib/util/uuid/stringify.d.ts.map +1 -1
  112. package/build/lib/util/uuid/stringify.js +18 -12
  113. package/build/lib/util/uuid/stringify.js.map +1 -1
  114. package/build/lib/util/uuid/validate.d.ts +5 -0
  115. package/build/lib/util/uuid/validate.d.ts.map +1 -1
  116. package/build/lib/util/uuid/validate.js +5 -0
  117. package/build/lib/util/uuid/validate.js.map +1 -1
  118. package/build/lib/utilities.d.ts +58 -58
  119. package/build/lib/utilities.d.ts.map +1 -1
  120. package/build/lib/utilities.js +2 -2
  121. package/build/lib/utilities.js.map +1 -1
  122. package/build/lib/webinspector/index.d.ts +44 -39
  123. package/build/lib/webinspector/index.d.ts.map +1 -1
  124. package/build/lib/webinspector/index.js +39 -35
  125. package/build/lib/webinspector/index.js.map +1 -1
  126. package/build/lib/webinspector/transformer/webinspector-decoder.d.ts +1 -1
  127. package/build/lib/webinspector/transformer/webinspector-decoder.d.ts.map +1 -1
  128. package/build/lib/webinspector/transformer/webinspector-decoder.js.map +1 -1
  129. package/build/lib/webinspector/transformer/webinspector-encoder.d.ts +1 -1
  130. package/build/lib/webinspector/transformer/webinspector-encoder.d.ts.map +1 -1
  131. package/build/lib/webinspector/transformer/webinspector-encoder.js.map +1 -1
  132. package/build/lib/xctest.d.ts +17 -17
  133. package/build/lib/xctest.d.ts.map +1 -1
  134. package/build/lib/xctest.js.map +1 -1
  135. package/index.js +7 -9
  136. package/lib/afc/index.js +23 -24
  137. package/lib/afc/protocol.js +17 -17
  138. package/lib/afc/transformer/afcdecoder.js +1 -2
  139. package/lib/afc/transformer/afcencoder.js +1 -2
  140. package/lib/base-service.js +2 -4
  141. package/lib/constants.js +2 -4
  142. package/lib/house-arrest/index.js +2 -3
  143. package/lib/imagemounter/index.js +28 -29
  144. package/lib/imagemounter/utils/list_developer_image.js +52 -54
  145. package/lib/installation-proxy/index.js +2 -3
  146. package/lib/instrument/headers.js +74 -87
  147. package/lib/instrument/index.js +19 -21
  148. package/lib/instrument/transformer/dtx-decode.js +1 -3
  149. package/lib/instrument/transformer/dtx-encode.js +1 -3
  150. package/lib/instrument/transformer/nskeyed.js +56 -67
  151. package/lib/lockdown/index.js +2 -3
  152. package/lib/mcinstall/index.js +9 -10
  153. package/lib/notification-proxy/index.js +2 -3
  154. package/lib/plist-service/index.js +1 -2
  155. package/lib/plist-service/transformer/plist-service-decoder.js +1 -2
  156. package/lib/plist-service/transformer/plist-service-encoder.js +1 -2
  157. package/lib/services.js +101 -26
  158. package/lib/simulatelocation/index.js +2 -3
  159. package/lib/ssl-helper.js +9 -4
  160. package/lib/syslog/index.js +2 -3
  161. package/lib/syslog/transformer/syslog-decoder.js +35 -36
  162. package/lib/testmanagerd/index.js +4 -11
  163. package/lib/usbmux/index.js +111 -112
  164. package/lib/usbmux/transformer/usbmux-decoder.js +1 -2
  165. package/lib/usbmux/transformer/usbmux-encoder.js +1 -2
  166. package/lib/util/uuid/parse.ts +5 -0
  167. package/lib/util/uuid/stringify.ts +21 -15
  168. package/lib/util/uuid/validate.ts +5 -0
  169. package/lib/utilities.js +10 -23
  170. package/lib/webinspector/index.js +47 -43
  171. package/lib/webinspector/transformer/webinspector-decoder.js +1 -2
  172. package/lib/webinspector/transformer/webinspector-encoder.js +1 -2
  173. package/lib/xctest.js +1 -2
  174. package/package.json +1 -1
@@ -10,6 +10,40 @@ const ARROW_CODE = '^'.charCodeAt(0);
10
10
  const ARROW_SHIFT = 0x40;
11
11
  const ESCAPE_TOKEN_LEN = 4;
12
12
 
13
+ export class SyslogDecoder extends Stream.Transform {
14
+ constructor(bufferLength) {
15
+ super({objectMode: true});
16
+ this.bufferIndex = 0;
17
+ this.buffer = Buffer.allocUnsafe(bufferLength);
18
+ }
19
+
20
+ _transform(data, encoding, onData) {
21
+ this._decode(data);
22
+ onData();
23
+ }
24
+
25
+ _decode(data) {
26
+ for (const byte of data) {
27
+ // Don't store the null delimiter messages
28
+ if (byte === NULL_DELIMITER_CODE) {
29
+ continue;
30
+ }
31
+ // Push the data when new line is sent
32
+ if (byte === NEW_LINE_CODE) {
33
+ if (this.bufferIndex > 0) {
34
+ const stringBuffer = Buffer.allocUnsafe(this.bufferIndex);
35
+ this.buffer.copy(stringBuffer, 0, 0, this.bufferIndex);
36
+ this.push(toUtf8String(stringBuffer), 'utf8');
37
+ this.bufferIndex = 0;
38
+ }
39
+ continue;
40
+ }
41
+ this.buffer[this.bufferIndex] = byte;
42
+ this.bufferIndex++;
43
+ }
44
+ }
45
+ }
46
+
13
47
  /**
14
48
  * Unescapes utf8-encoded characters, so the output looks
15
49
  * like a valid string. See https://github.com/appium/appium/issues/14476
@@ -19,7 +53,7 @@ const ESCAPE_TOKEN_LEN = 4;
19
53
  * @returns {string} The unescaped string or the same string if no unescaping
20
54
  * is necessary.
21
55
  */
22
- function toUtf8String(logBuffer) {
56
+ export function toUtf8String(logBuffer) {
23
57
  const parseUtf8Bytes = (start) => {
24
58
  let cursor = start;
25
59
  const token = new Uint8Array(ESCAPE_TOKEN_LEN);
@@ -57,39 +91,4 @@ function toUtf8String(logBuffer) {
57
91
  return Buffer.from(utf8Codes).toString('utf8');
58
92
  }
59
93
 
60
- class SyslogDecoder extends Stream.Transform {
61
- constructor(bufferLength) {
62
- super({objectMode: true});
63
- this.bufferIndex = 0;
64
- this.buffer = Buffer.allocUnsafe(bufferLength);
65
- }
66
-
67
- _transform(data, encoding, onData) {
68
- this._decode(data);
69
- onData();
70
- }
71
-
72
- _decode(data) {
73
- for (const byte of data) {
74
- // Don't store the null delimiter messages
75
- if (byte === NULL_DELIMITER_CODE) {
76
- continue;
77
- }
78
- // Push the data when new line is sent
79
- if (byte === NEW_LINE_CODE) {
80
- if (this.bufferIndex > 0) {
81
- const stringBuffer = Buffer.allocUnsafe(this.bufferIndex);
82
- this.buffer.copy(stringBuffer, 0, 0, this.bufferIndex);
83
- this.push(toUtf8String(stringBuffer), 'utf8');
84
- this.bufferIndex = 0;
85
- }
86
- continue;
87
- }
88
- this.buffer[this.bufferIndex] = byte;
89
- this.bufferIndex++;
90
- }
91
- }
92
- }
93
-
94
- export {SyslogDecoder, toUtf8String};
95
94
  export default SyslogDecoder;
@@ -1,18 +1,11 @@
1
1
  import {InstrumentService} from '../instrument';
2
2
 
3
- const TESTMANAGERD_SERVICE_NAME_VERSION_14 = 'com.apple.testmanagerd.lockdown.secure';
4
- const TESTMANAGERD_SERVICE_NAME = 'com.apple.testmanagerd.lockdown';
3
+ export const TESTMANAGERD_SERVICE_NAME_VERSION_14 = 'com.apple.testmanagerd.lockdown.secure';
4
+ export const TESTMANAGERD_SERVICE_NAME = 'com.apple.testmanagerd.lockdown';
5
5
 
6
- const TESTMANAGERD_CHANNEL = Object.freeze({
6
+ export const TESTMANAGERD_CHANNEL = Object.freeze({
7
7
  DAEMON_CONNECTION_INTERFACE:
8
8
  'dtxproxy:XCTestManager_IDEInterface:XCTestManager_DaemonConnectionInterface',
9
9
  });
10
10
 
11
- class TestmanagerdService extends InstrumentService {}
12
-
13
- export {
14
- TestmanagerdService,
15
- TESTMANAGERD_SERVICE_NAME_VERSION_14,
16
- TESTMANAGERD_SERVICE_NAME,
17
- TESTMANAGERD_CHANNEL,
18
- };
11
+ export class TestmanagerdService extends InstrumentService {}
@@ -38,117 +38,7 @@ const DEFAULT_USBMUXD_HOST = '127.0.0.1';
38
38
  const PROG_NAME = name;
39
39
  const CLIENT_VERSION_STRING = `${name}-${version}`;
40
40
 
41
- function swap16(val) {
42
- return ((val & 0xff) << 8) | ((val >> 8) & 0xff);
43
- }
44
-
45
- /**
46
- * @typedef {Object} SocketOptions
47
- * @property {string} [socketPath="/var/run/usbmuxd"] The full path to the usbmuxd Unix socket
48
- * @property {number} [socketPort=27015] The port number to connect to
49
- * @property {string} [socketHost="127.0.0.1"] The host name to connect to
50
- * @property {number} [timeout=5000] The number of milliseconds to wait until
51
- * the socket is connected
52
- */
53
-
54
- /**
55
- * Connects a socket to usbmuxd service
56
- *
57
- * @param {SocketOptions} opts
58
- * @throws {Error} If there was an error while accessing the socket or
59
- * a connection error happened
60
- * @throws {B.TimeoutError} if connection timeout happened
61
- * @returns {Promise<NodeJS.Socket>} Connected socket instance
62
- */
63
- async function getDefaultSocket(opts = {}) {
64
- const defaults = {
65
- socketPath: DEFAULT_USBMUXD_SOCKET,
66
- socketPort: DEFAULT_USBMUXD_PORT,
67
- socketHost: DEFAULT_USBMUXD_HOST,
68
- timeout: 5000,
69
- };
70
-
71
- const hasOpts = Object.values(opts).some((v) => !_.isNil(v));
72
- const envOpts = hasOpts ? {} : getSocketOptionsFromEnv();
73
-
74
- /**
75
- * Retrieves the first non-nullable value of a socket option based on the provided key.
76
- * The value is resolved in the following order of precedence:
77
- * 1. The value from the `opts` parameter
78
- * 2. The value from `USBMUXD_SOCKET_ADDRESS` environment variable
79
- * 3. The default value from `defaults` object
80
- *
81
- * @template {keyof SocketOptions} K
82
- * @param {K} key
83
- * @returns {NonNullable<SocketOptions[K]>}
84
- */
85
- const getOption = (key) => opts[key] ?? envOpts[key] ?? defaults[key];
86
-
87
- const socketPath = getOption('socketPath');
88
- const socketPort = getOption('socketPort');
89
- const socketHost = getOption('socketHost');
90
- const timeout = opts.timeout ?? defaults.timeout;
91
-
92
- const hasExplicitPath = !!(opts.socketPath || envOpts.socketPath);
93
- const hasExplicitHostPort = !!(
94
- opts.socketHost ||
95
- opts.socketPort ||
96
- envOpts.socketHost ||
97
- envOpts.socketPort
98
- );
99
- const isWinOrWsl =
100
- process.platform === 'win32' ||
101
- (process.platform === 'linux' && /microsoft/i.test(os.release()));
102
- const preferPath = hasExplicitPath || !(hasExplicitHostPort || isWinOrWsl);
103
-
104
- let socket;
105
-
106
- if (preferPath) {
107
- const pathExists = await fs.exists(socketPath);
108
- if (!pathExists) {
109
- throw new Error(
110
- `The usbmuxd socket path '${socketPath}' does not exist or is not accessible`,
111
- );
112
- }
113
- socket = net.createConnection(socketPath);
114
- } else {
115
- socket = net.createConnection(socketPort, socketHost);
116
- }
117
-
118
- return await new B((resolve, reject) => {
119
- socket.once('error', reject);
120
- socket.once('connect', () => resolve(socket));
121
- }).timeout(timeout ?? 5000);
122
- }
123
-
124
- /**
125
- * Get socket options from USBMUXD_SOCKET_ADDRESS environment variable
126
- *
127
- * @returns {Partial<SocketOptions>}
128
- */
129
- function getSocketOptionsFromEnv() {
130
- let usbmuxdSocketAddress = process.env.USBMUXD_SOCKET_ADDRESS;
131
- if (!usbmuxdSocketAddress) {
132
- return {};
133
- }
134
- log.debug(
135
- `Using USBMUXD_SOCKET_ADDRESS environment variable as default socket: ${usbmuxdSocketAddress}`,
136
- );
137
- // "unix:" or "UNIX:" prefix is optional for unix socket paths.
138
- usbmuxdSocketAddress = usbmuxdSocketAddress.replace(/^(unix):/i, '');
139
- const [ip, port] = usbmuxdSocketAddress.split(':');
140
- if (ip && port) {
141
- return {
142
- socketHost: ip,
143
- socketPort: parseInt(port, 10),
144
- };
145
- }
146
- return {
147
- socketPath: usbmuxdSocketAddress,
148
- };
149
- }
150
-
151
- class Usbmux extends BaseServiceSocket {
41
+ export class Usbmux extends BaseServiceSocket {
152
42
  constructor(socketClient) {
153
43
  super(socketClient);
154
44
 
@@ -344,5 +234,114 @@ class Usbmux extends BaseServiceSocket {
344
234
  }
345
235
  }
346
236
 
347
- export {Usbmux, getDefaultSocket};
237
+ /**
238
+ * @typedef {Object} SocketOptions
239
+ * @property {string} [socketPath="/var/run/usbmuxd"] The full path to the usbmuxd Unix socket
240
+ * @property {number} [socketPort=27015] The port number to connect to
241
+ * @property {string} [socketHost="127.0.0.1"] The host name to connect to
242
+ * @property {number} [timeout=5000] The number of milliseconds to wait until
243
+ * the socket is connected
244
+ */
245
+
246
+ /**
247
+ * Connects a socket to usbmuxd service
248
+ *
249
+ * @param {SocketOptions} opts
250
+ * @throws {Error} If there was an error while accessing the socket or
251
+ * a connection error happened
252
+ * @throws {B.TimeoutError} if connection timeout happened
253
+ * @returns {Promise<NodeJS.Socket>} Connected socket instance
254
+ */
255
+ export async function getDefaultSocket(opts = {}) {
256
+ const defaults = {
257
+ socketPath: DEFAULT_USBMUXD_SOCKET,
258
+ socketPort: DEFAULT_USBMUXD_PORT,
259
+ socketHost: DEFAULT_USBMUXD_HOST,
260
+ timeout: 5000,
261
+ };
262
+
263
+ const hasOpts = Object.values(opts).some((v) => !_.isNil(v));
264
+ const envOpts = hasOpts ? {} : getSocketOptionsFromEnv();
265
+
266
+ /**
267
+ * Retrieves the first non-nullable value of a socket option based on the provided key.
268
+ * The value is resolved in the following order of precedence:
269
+ * 1. The value from the `opts` parameter
270
+ * 2. The value from `USBMUXD_SOCKET_ADDRESS` environment variable
271
+ * 3. The default value from `defaults` object
272
+ *
273
+ * @template {keyof SocketOptions} K
274
+ * @param {K} key
275
+ * @returns {NonNullable<SocketOptions[K]>}
276
+ */
277
+ const getOption = (key) => opts[key] ?? envOpts[key] ?? defaults[key];
278
+
279
+ const socketPath = getOption('socketPath');
280
+ const socketPort = getOption('socketPort');
281
+ const socketHost = getOption('socketHost');
282
+ const timeout = opts.timeout ?? defaults.timeout;
283
+
284
+ const hasExplicitPath = !!(opts.socketPath || envOpts.socketPath);
285
+ const hasExplicitHostPort = !!(
286
+ opts.socketHost ||
287
+ opts.socketPort ||
288
+ envOpts.socketHost ||
289
+ envOpts.socketPort
290
+ );
291
+ const isWinOrWsl =
292
+ process.platform === 'win32' ||
293
+ (process.platform === 'linux' && /microsoft/i.test(os.release()));
294
+ const preferPath = hasExplicitPath || !(hasExplicitHostPort || isWinOrWsl);
295
+
296
+ let socket;
297
+
298
+ if (preferPath) {
299
+ const pathExists = await fs.exists(socketPath);
300
+ if (!pathExists) {
301
+ throw new Error(
302
+ `The usbmuxd socket path '${socketPath}' does not exist or is not accessible`,
303
+ );
304
+ }
305
+ socket = net.createConnection(socketPath);
306
+ } else {
307
+ socket = net.createConnection(socketPort, socketHost);
308
+ }
309
+
310
+ return await new B((resolve, reject) => {
311
+ socket.once('error', reject);
312
+ socket.once('connect', () => resolve(socket));
313
+ }).timeout(timeout ?? 5000);
314
+ }
315
+
316
+ function swap16(val) {
317
+ return ((val & 0xff) << 8) | ((val >> 8) & 0xff);
318
+ }
319
+
320
+ /**
321
+ * Get socket options from USBMUXD_SOCKET_ADDRESS environment variable
322
+ *
323
+ * @returns {Partial<SocketOptions>}
324
+ */
325
+ function getSocketOptionsFromEnv() {
326
+ let usbmuxdSocketAddress = process.env.USBMUXD_SOCKET_ADDRESS;
327
+ if (!usbmuxdSocketAddress) {
328
+ return {};
329
+ }
330
+ log.debug(
331
+ `Using USBMUXD_SOCKET_ADDRESS environment variable as default socket: ${usbmuxdSocketAddress}`,
332
+ );
333
+ // "unix:" or "UNIX:" prefix is optional for unix socket paths.
334
+ usbmuxdSocketAddress = usbmuxdSocketAddress.replace(/^(unix):/i, '');
335
+ const [ip, port] = usbmuxdSocketAddress.split(':');
336
+ if (ip && port) {
337
+ return {
338
+ socketHost: ip,
339
+ socketPort: parseInt(port, 10),
340
+ };
341
+ }
342
+ return {
343
+ socketPath: usbmuxdSocketAddress,
344
+ };
345
+ }
346
+
348
347
  export default Usbmux;
@@ -3,7 +3,7 @@ import {plist} from '@appium/support';
3
3
 
4
4
  const HEADER_LENGTH = 16;
5
5
 
6
- class UsbmuxDecoder extends Stream.Transform {
6
+ export class UsbmuxDecoder extends Stream.Transform {
7
7
  constructor() {
8
8
  super({objectMode: true});
9
9
  }
@@ -26,5 +26,4 @@ class UsbmuxDecoder extends Stream.Transform {
26
26
  }
27
27
  }
28
28
 
29
- export {UsbmuxDecoder};
30
29
  export default UsbmuxDecoder;
@@ -5,7 +5,7 @@ const HEADER_LENGTH = 16;
5
5
  const VERSION = 1;
6
6
  const TYPE = 8;
7
7
 
8
- class UsbmuxEncoder extends Stream.Transform {
8
+ export class UsbmuxEncoder extends Stream.Transform {
9
9
  constructor() {
10
10
  super({objectMode: true});
11
11
  }
@@ -38,5 +38,4 @@ class UsbmuxEncoder extends Stream.Transform {
38
38
  }
39
39
  }
40
40
 
41
- export {UsbmuxEncoder};
42
41
  export default UsbmuxEncoder;
@@ -23,6 +23,11 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
 
24
24
  import {validate} from './validate';
25
25
 
26
+ /**
27
+ * Parses a UUID string into its 16-byte representation.
28
+ * @param {string} uuid
29
+ * @returns {Uint8Array}
30
+ */
26
31
  export function parse(uuid: string): Uint8Array {
27
32
  if (!validate(uuid)) {
28
33
  throw TypeError('Invalid UUID');
@@ -30,6 +30,27 @@ import _ from 'lodash';
30
30
  */
31
31
  const byteToHex: string[] = _.range(256).map((i) => (i + 0x100).toString(16).slice(1));
32
32
 
33
+ /**
34
+ * Converts a 16-byte UUID array into canonical string form.
35
+ * @param {Uint8Array} arr
36
+ * @param {number} [offset=0]
37
+ * @returns {string}
38
+ */
39
+ export function stringify(arr: Uint8Array, offset: number = 0): string {
40
+ const uuid = unsafeStringify(arr, offset);
41
+
42
+ // Consistency check for valid UUID. If this throws, it's likely due to one
43
+ // of the following:
44
+ // - One or more input array values don't map to a hex octet (leading to
45
+ // "undefined" in the uuid)
46
+ // - Invalid input values for the RFC `version` or `variant` fields
47
+ if (!validate(uuid)) {
48
+ throw TypeError('Stringified UUID is invalid');
49
+ }
50
+
51
+ return uuid;
52
+ }
53
+
33
54
  function unsafeStringify(arr: Uint8Array, offset: number = 0): string {
34
55
  return (
35
56
  byteToHex[arr[offset + 0]] +
@@ -54,18 +75,3 @@ function unsafeStringify(arr: Uint8Array, offset: number = 0): string {
54
75
  byteToHex[arr[offset + 15]]
55
76
  ).toLowerCase();
56
77
  }
57
-
58
- export function stringify(arr: Uint8Array, offset: number = 0): string {
59
- const uuid = unsafeStringify(arr, offset);
60
-
61
- // Consistency check for valid UUID. If this throws, it's likely due to one
62
- // of the following:
63
- // - One or more input array values don't map to a hex octet (leading to
64
- // "undefined" in the uuid)
65
- // - Invalid input values for the RFC `version` or `variant` fields
66
- if (!validate(uuid)) {
67
- throw TypeError('Stringified UUID is invalid');
68
- }
69
-
70
- return uuid;
71
- }
@@ -24,6 +24,11 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
  const REGEX =
25
25
  /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/i;
26
26
 
27
+ /**
28
+ * Checks whether a value is a supported UUID string.
29
+ * @param {unknown} uuid
30
+ * @returns {boolean}
31
+ */
27
32
  export function validate(uuid: unknown): boolean {
28
33
  return typeof uuid === 'string' && REGEX.test(uuid);
29
34
  }
package/lib/utilities.js CHANGED
@@ -20,7 +20,7 @@ const LOCKDOWN_REQUEST = {
20
20
  * @returns {Promise<string[]>} The list of device serial numbers (udid) or
21
21
  * an empty list if no devices are connected
22
22
  */
23
- async function getConnectedDevices(socket = null) {
23
+ export async function getConnectedDevices(socket = null) {
24
24
  let usbmux;
25
25
  try {
26
26
  usbmux = new Usbmux(socket || (await getDefaultSocket()));
@@ -44,7 +44,7 @@ async function getConnectedDevices(socket = null) {
44
44
  * @param {import('net').Socket?} socket the socket of usbmuxd. It will default to /var/run/usbmuxd if it is not passed
45
45
  * @returns {Promise<string>}
46
46
  */
47
- async function getOSVersion(udid, socket = null) {
47
+ export async function getOSVersion(udid, socket = null) {
48
48
  const usbmux = new Usbmux(socket || (await getDefaultSocket()));
49
49
  try {
50
50
  // lockdown doesn't need to be closed since it uses the same socket usbmux uses
@@ -62,7 +62,7 @@ async function getOSVersion(udid, socket = null) {
62
62
  * @param {import('net').Socket?} socket the socket of usbmuxd. It will default to /var/run/usbmuxd if it is not passed
63
63
  * @returns {Promise<string>}
64
64
  */
65
- async function getDeviceName(udid, socket = null) {
65
+ export async function getDeviceName(udid, socket = null) {
66
66
  const usbmux = new Usbmux(socket || (await getDefaultSocket()));
67
67
  try {
68
68
  // lockdown doesn't need to be closed since it uses the same socket usbmux uses
@@ -112,7 +112,7 @@ async function getDeviceName(udid, socket = null) {
112
112
  * "WiFiAddress"=>"00:00:00:00:00:00"
113
113
  * }
114
114
  */
115
- async function getDeviceInfo(udid, socket = null) {
115
+ export async function getDeviceInfo(udid, socket = null) {
116
116
  const usbmux = new Usbmux(socket || (await getDefaultSocket()));
117
117
  try {
118
118
  const lockdown = await usbmux.connectLockdown(udid);
@@ -138,7 +138,7 @@ async function getDeviceInfo(udid, socket = null) {
138
138
  * @param {import('net').Socket?} socket the socket of usbmuxd. It will default to /var/run/usbmuxd if it is not passed
139
139
  * @returns {Promise<DeviceTime>}
140
140
  */
141
- async function getDeviceTime(udid, socket = null) {
141
+ export async function getDeviceTime(udid, socket = null) {
142
142
  const lockdown = await startLockdownSession(udid, socket);
143
143
  try {
144
144
  return {
@@ -159,7 +159,7 @@ async function getDeviceTime(udid, socket = null) {
159
159
  * @param {import('net').Socket?} socket the socket of usbmuxd. It will default to /var/run/usbmuxd if it is not passed
160
160
  * @returns {Promise<import('./lockdown').Lockdown>}
161
161
  */
162
- async function startLockdownSession(udid, socket = null) {
162
+ export async function startLockdownSession(udid, socket = null) {
163
163
  const usbmux = new Usbmux(socket || (await getDefaultSocket()));
164
164
  try {
165
165
  const pairRecord = await usbmux.readPairRecord(udid);
@@ -188,7 +188,7 @@ async function startLockdownSession(udid, socket = null) {
188
188
  * @param {boolean} handshakeOnly only handshake and return the initial socket
189
189
  * @returns {Promise<import('tls').TLSSocket|Object>} The socket or the object returned in the callback if the callback function exists
190
190
  */
191
- async function connectPortSSL(udid, port, socket = null, handshakeOnly = false) {
191
+ export async function connectPortSSL(udid, port, socket = null, handshakeOnly = false) {
192
192
  const usbmux = new Usbmux(socket || (await getDefaultSocket()));
193
193
  try {
194
194
  const device = await usbmux.findDevice(udid);
@@ -219,7 +219,7 @@ async function connectPortSSL(udid, port, socket = null, handshakeOnly = false)
219
219
  * @param {import('net').Socket?} socket the socket of usbmuxd. It will default to /var/run/usbmuxd if it is not passed
220
220
  * @returns {Promise<NodeJS.Socket|Object>} The socket or the object returned in the callback if the callback function exists
221
221
  */
222
- async function connectPort(udid, port, socket = null) {
222
+ export async function connectPort(udid, port, socket = null) {
223
223
  const usbmux = new Usbmux(socket || (await getDefaultSocket()));
224
224
  try {
225
225
  const device = await usbmux.findDevice(udid);
@@ -247,7 +247,7 @@ async function connectPort(udid, port, socket = null) {
247
247
  * @returns {Promise<import('./imagemounter/utils/list_developer_image').ImagePath>}
248
248
  * @throws If opts error or failed on searching image
249
249
  */
250
- async function fetchImageFromGithubRepo(udid, opts) {
250
+ export async function fetchImageFromGithubRepo(udid, opts) {
251
251
  const osVersion = await getOSVersion(udid);
252
252
  if (!opts.githubRepo) {
253
253
  throw new TypeError(
@@ -262,7 +262,7 @@ async function fetchImageFromGithubRepo(udid, opts) {
262
262
  * @param {number} defaultSize - Default frame size in bytes
263
263
  * @returns {number} Configured frame size in bytes
264
264
  */
265
- function getMaxFrameLength(defaultSize) {
265
+ export function getMaxFrameLength(defaultSize) {
266
266
  const envValue = process.env.APPIUM_IOS_MAX_FRAME_SIZE;
267
267
  if (envValue) {
268
268
  const parsed = _.parseInt(envValue, 10);
@@ -272,16 +272,3 @@ function getMaxFrameLength(defaultSize) {
272
272
  }
273
273
  return defaultSize;
274
274
  }
275
-
276
- export {
277
- getConnectedDevices,
278
- getOSVersion,
279
- getDeviceName,
280
- getDeviceTime,
281
- startLockdownSession,
282
- connectPort,
283
- connectPortSSL,
284
- getDeviceInfo,
285
- fetchImageFromGithubRepo,
286
- getMaxFrameLength,
287
- };
@@ -11,52 +11,12 @@ import {log} from '../logger';
11
11
  import {BaseServiceSocket} from '../base-service';
12
12
  import {getMaxFrameLength} from '../utilities';
13
13
 
14
- const WEB_INSPECTOR_SERVICE_NAME = 'com.apple.webinspector';
14
+ export const WEB_INSPECTOR_SERVICE_NAME = 'com.apple.webinspector';
15
15
  const MAX_FRAME_SIZE = 20 * MB;
16
16
 
17
17
  const PARTIAL_MESSAGE_SUPPORT_DEPRECATION_VERSION = 11;
18
18
 
19
- function cleanupRpcObject(obj) {
20
- const isArray = _.isArray(obj);
21
- if (!_.isPlainObject(obj) && !isArray) {
22
- return obj;
23
- }
24
-
25
- if (isArray) {
26
- return _.filter(obj, _.negate(_.isNil));
27
- }
28
-
29
- return _.reduce(
30
- obj,
31
- (result, value, key) => {
32
- if (!_.isNil(value)) {
33
- result[key] = cleanupRpcObject(value);
34
- }
35
- return result;
36
- },
37
- {},
38
- );
39
- }
40
-
41
- /**
42
- * @typedef {Object} WebInspectorServiceOptions
43
- *
44
- * @property {number} majorOsVersion The major version of the os version
45
- * @property {boolean} isSimulator Whether the device is a simulator
46
- * @property {number?} socketChunkSize Size, in bytes of the chunks to send to
47
- * real device (only iOS 11+). Defaults to
48
- * 16384 bytes (the TLSSocket max).
49
- * @property {boolean} verbose Turn on logging of each message sent or received.
50
- * Defaults to false
51
- * @property {boolean} verboseHexDump Turn on logging of _all_ communication as
52
- * hex dump. Defaults to false
53
- * @property {*} socketClient The socket client where the communication will happen
54
- * @property {number} maxFrameLength [20 * 1024 * 1024] - The maximum size
55
- * in bytes of a single data frame
56
- * in the device communication protocol
57
- */
58
-
59
- class WebInspectorService extends BaseServiceSocket {
19
+ export class WebInspectorService extends BaseServiceSocket {
60
20
  /** @type {number|undefined} */
61
21
  _majorOsVersion;
62
22
 
@@ -244,5 +204,49 @@ class WebInspectorService extends BaseServiceSocket {
244
204
  }
245
205
  }
246
206
 
247
- export {WebInspectorService, WEB_INSPECTOR_SERVICE_NAME, cleanupRpcObject};
207
+ /**
208
+ * @typedef {Object} WebInspectorServiceOptions
209
+ *
210
+ * @property {number} majorOsVersion The major version of the os version
211
+ * @property {boolean} isSimulator Whether the device is a simulator
212
+ * @property {number?} socketChunkSize Size, in bytes of the chunks to send to
213
+ * real device (only iOS 11+). Defaults to
214
+ * 16384 bytes (the TLSSocket max).
215
+ * @property {boolean} verbose Turn on logging of each message sent or received.
216
+ * Defaults to false
217
+ * @property {boolean} verboseHexDump Turn on logging of _all_ communication as
218
+ * hex dump. Defaults to false
219
+ * @property {*} socketClient The socket client where the communication will happen
220
+ * @property {number} maxFrameLength [20 * 1024 * 1024] - The maximum size
221
+ * in bytes of a single data frame
222
+ * in the device communication protocol
223
+ */
224
+
225
+ /**
226
+ * Removes nullish values recursively from RPC payloads.
227
+ * @param {any} obj
228
+ * @returns {any}
229
+ */
230
+ export function cleanupRpcObject(obj) {
231
+ const isArray = _.isArray(obj);
232
+ if (!_.isPlainObject(obj) && !isArray) {
233
+ return obj;
234
+ }
235
+
236
+ if (isArray) {
237
+ return _.filter(obj, _.negate(_.isNil));
238
+ }
239
+
240
+ return _.reduce(
241
+ obj,
242
+ (result, value, key) => {
243
+ if (!_.isNil(value)) {
244
+ result[key] = cleanupRpcObject(value);
245
+ }
246
+ return result;
247
+ },
248
+ {},
249
+ );
250
+ }
251
+
248
252
  export default WebInspectorService;
@@ -1,7 +1,7 @@
1
1
  import Stream from 'node:stream';
2
2
  import {plist} from '@appium/support';
3
3
 
4
- class WebInspectorDecoder extends Stream.Transform {
4
+ export class WebInspectorDecoder extends Stream.Transform {
5
5
  constructor(maxLength) {
6
6
  super({objectMode: true});
7
7
  this._frameBufferIndex = 0;
@@ -49,5 +49,4 @@ class WebInspectorDecoder extends Stream.Transform {
49
49
  }
50
50
  }
51
51
 
52
- export {WebInspectorDecoder};
53
52
  export default WebInspectorDecoder;
@@ -3,7 +3,7 @@ import {plist} from '@appium/support';
3
3
 
4
4
  const WEBINSPECTOR_PARTIAL_PACKET_CHUNK_SIZE = 8096;
5
5
 
6
- class WebInspectorEncoder extends Stream.Transform {
6
+ export class WebInspectorEncoder extends Stream.Transform {
7
7
  constructor() {
8
8
  super({objectMode: true});
9
9
  }
@@ -25,5 +25,4 @@ class WebInspectorEncoder extends Stream.Transform {
25
25
  }
26
26
  }
27
27
 
28
- export {WebInspectorEncoder};
29
28
  export default WebInspectorEncoder;