appium 2.0.0-beta.9 → 2.0.0-rc.2

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 (208) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +149 -58
  3. package/build/lib/appium.d.ts +229 -0
  4. package/build/lib/appium.d.ts.map +1 -0
  5. package/build/lib/appium.js +677 -449
  6. package/build/lib/appium.js.map +1 -0
  7. package/build/lib/cli/args.d.ts +17 -0
  8. package/build/lib/cli/args.d.ts.map +1 -0
  9. package/build/lib/cli/args.js +263 -300
  10. package/build/lib/cli/args.js.map +1 -0
  11. package/build/lib/cli/driver-command.d.ts +102 -0
  12. package/build/lib/cli/driver-command.d.ts.map +1 -0
  13. package/build/lib/cli/driver-command.js +131 -81
  14. package/build/lib/cli/driver-command.js.map +1 -0
  15. package/build/lib/cli/extension-command.d.ts +402 -0
  16. package/build/lib/cli/extension-command.d.ts.map +1 -0
  17. package/build/lib/cli/extension-command.js +799 -383
  18. package/build/lib/cli/extension-command.js.map +1 -0
  19. package/build/lib/cli/extension.d.ts +23 -0
  20. package/build/lib/cli/extension.d.ts.map +1 -0
  21. package/build/lib/cli/extension.js +70 -68
  22. package/build/lib/cli/extension.js.map +1 -0
  23. package/build/lib/cli/parser.d.ts +84 -0
  24. package/build/lib/cli/parser.d.ts.map +1 -0
  25. package/build/lib/cli/parser.js +252 -148
  26. package/build/lib/cli/parser.js.map +1 -0
  27. package/build/lib/cli/plugin-command.d.ts +99 -0
  28. package/build/lib/cli/plugin-command.d.ts.map +1 -0
  29. package/build/lib/cli/plugin-command.js +125 -81
  30. package/build/lib/cli/plugin-command.js.map +1 -0
  31. package/build/lib/cli/utils.d.ts +29 -0
  32. package/build/lib/cli/utils.d.ts.map +1 -0
  33. package/build/lib/cli/utils.js +72 -51
  34. package/build/lib/cli/utils.js.map +1 -0
  35. package/build/lib/config-file.d.ts +100 -0
  36. package/build/lib/config-file.d.ts.map +1 -0
  37. package/build/lib/config-file.js +207 -0
  38. package/build/lib/config-file.js.map +1 -0
  39. package/build/lib/config.d.ts +49 -0
  40. package/build/lib/config.d.ts.map +1 -0
  41. package/build/lib/config.js +262 -223
  42. package/build/lib/config.js.map +1 -0
  43. package/build/lib/constants.d.ts +56 -0
  44. package/build/lib/constants.d.ts.map +1 -0
  45. package/build/lib/constants.js +73 -0
  46. package/build/lib/constants.js.map +1 -0
  47. package/build/lib/extension/driver-config.d.ts +82 -0
  48. package/build/lib/extension/driver-config.d.ts.map +1 -0
  49. package/build/lib/extension/driver-config.js +210 -0
  50. package/build/lib/extension/driver-config.js.map +1 -0
  51. package/build/lib/extension/extension-config.d.ts +270 -0
  52. package/build/lib/extension/extension-config.d.ts.map +1 -0
  53. package/build/lib/extension/extension-config.js +601 -0
  54. package/build/lib/extension/extension-config.js.map +1 -0
  55. package/build/lib/extension/index.d.ts +48 -0
  56. package/build/lib/extension/index.d.ts.map +1 -0
  57. package/build/lib/extension/index.js +105 -0
  58. package/build/lib/extension/index.js.map +1 -0
  59. package/build/lib/extension/manifest-migrations.d.ts +27 -0
  60. package/build/lib/extension/manifest-migrations.d.ts.map +1 -0
  61. package/build/lib/extension/manifest-migrations.js +134 -0
  62. package/build/lib/extension/manifest-migrations.js.map +1 -0
  63. package/build/lib/extension/manifest.d.ts +145 -0
  64. package/build/lib/extension/manifest.d.ts.map +1 -0
  65. package/build/lib/extension/manifest.js +528 -0
  66. package/build/lib/extension/manifest.js.map +1 -0
  67. package/build/lib/extension/package-changed.d.ts +11 -0
  68. package/build/lib/extension/package-changed.d.ts.map +1 -0
  69. package/build/lib/extension/package-changed.js +62 -0
  70. package/build/lib/extension/package-changed.js.map +1 -0
  71. package/build/lib/extension/plugin-config.d.ts +56 -0
  72. package/build/lib/extension/plugin-config.d.ts.map +1 -0
  73. package/build/lib/extension/plugin-config.js +102 -0
  74. package/build/lib/extension/plugin-config.js.map +1 -0
  75. package/build/lib/grid-register.d.ts +10 -0
  76. package/build/lib/grid-register.d.ts.map +1 -0
  77. package/build/lib/grid-register.js +122 -144
  78. package/build/lib/grid-register.js.map +1 -0
  79. package/build/lib/logger.d.ts +3 -0
  80. package/build/lib/logger.d.ts.map +1 -0
  81. package/build/lib/logger.js +5 -17
  82. package/build/lib/logger.js.map +1 -0
  83. package/build/lib/logsink.d.ts +4 -0
  84. package/build/lib/logsink.d.ts.map +1 -0
  85. package/build/lib/logsink.js +189 -184
  86. package/build/lib/logsink.js.map +1 -0
  87. package/build/lib/main.d.ts +62 -0
  88. package/build/lib/main.d.ts.map +1 -0
  89. package/build/lib/main.js +406 -234
  90. package/build/lib/main.js.map +1 -0
  91. package/build/lib/schema/arg-spec.d.ts +143 -0
  92. package/build/lib/schema/arg-spec.d.ts.map +1 -0
  93. package/build/lib/schema/arg-spec.js +164 -0
  94. package/build/lib/schema/arg-spec.js.map +1 -0
  95. package/build/lib/schema/cli-args.d.ts +19 -0
  96. package/build/lib/schema/cli-args.d.ts.map +1 -0
  97. package/build/lib/schema/cli-args.js +220 -0
  98. package/build/lib/schema/cli-args.js.map +1 -0
  99. package/build/lib/schema/cli-transformers.d.ts +5 -0
  100. package/build/lib/schema/cli-transformers.d.ts.map +1 -0
  101. package/build/lib/schema/cli-transformers.js +124 -0
  102. package/build/lib/schema/cli-transformers.js.map +1 -0
  103. package/build/lib/schema/index.d.ts +3 -0
  104. package/build/lib/schema/index.d.ts.map +1 -0
  105. package/build/lib/schema/index.js +19 -0
  106. package/build/lib/schema/index.js.map +1 -0
  107. package/build/lib/schema/keywords.d.ts +24 -0
  108. package/build/lib/schema/keywords.d.ts.map +1 -0
  109. package/build/lib/schema/keywords.js +128 -0
  110. package/build/lib/schema/keywords.js.map +1 -0
  111. package/build/lib/schema/schema.d.ts +260 -0
  112. package/build/lib/schema/schema.d.ts.map +1 -0
  113. package/build/lib/schema/schema.js +640 -0
  114. package/build/lib/schema/schema.js.map +1 -0
  115. package/build/lib/utils.d.ts +276 -0
  116. package/build/lib/utils.d.ts.map +1 -0
  117. package/build/lib/utils.js +372 -192
  118. package/build/lib/utils.js.map +1 -0
  119. package/build/types/cli.d.ts +134 -0
  120. package/build/types/cli.d.ts.map +1 -0
  121. package/build/types/cli.js +3 -0
  122. package/build/types/cli.js.map +1 -0
  123. package/build/types/index.d.ts +15 -0
  124. package/build/types/index.d.ts.map +1 -0
  125. package/build/types/index.js +19 -0
  126. package/build/types/index.js.map +1 -0
  127. package/build/types/manifest/base.d.ts +135 -0
  128. package/build/types/manifest/base.d.ts.map +1 -0
  129. package/build/types/manifest/base.js +3 -0
  130. package/build/types/manifest/base.js.map +1 -0
  131. package/build/types/manifest/index.d.ts +21 -0
  132. package/build/types/manifest/index.d.ts.map +1 -0
  133. package/build/types/manifest/index.js +42 -0
  134. package/build/types/manifest/index.js.map +1 -0
  135. package/build/types/manifest/v3.d.ts +139 -0
  136. package/build/types/manifest/v3.d.ts.map +1 -0
  137. package/build/types/manifest/v3.js +3 -0
  138. package/build/types/manifest/v3.js.map +1 -0
  139. package/build/types/manifest/v4.d.ts +139 -0
  140. package/build/types/manifest/v4.d.ts.map +1 -0
  141. package/build/types/manifest/v4.js +3 -0
  142. package/build/types/manifest/v4.js.map +1 -0
  143. package/driver.d.ts +1 -0
  144. package/driver.js +14 -0
  145. package/index.js +11 -0
  146. package/lib/appium.js +545 -188
  147. package/lib/cli/args.js +275 -407
  148. package/lib/cli/driver-command.js +132 -24
  149. package/lib/cli/extension-command.js +751 -272
  150. package/lib/cli/extension.js +38 -19
  151. package/lib/cli/parser.js +267 -95
  152. package/lib/cli/plugin-command.js +122 -22
  153. package/lib/cli/utils.js +24 -10
  154. package/lib/config-file.js +220 -0
  155. package/lib/config.js +243 -132
  156. package/lib/constants.js +79 -0
  157. package/lib/extension/driver-config.js +247 -0
  158. package/lib/extension/extension-config.js +709 -0
  159. package/lib/extension/index.js +116 -0
  160. package/lib/extension/manifest-migrations.js +136 -0
  161. package/lib/extension/manifest.js +580 -0
  162. package/lib/extension/package-changed.js +64 -0
  163. package/lib/extension/plugin-config.js +112 -0
  164. package/lib/grid-register.js +49 -35
  165. package/lib/logger.js +1 -2
  166. package/lib/logsink.js +59 -36
  167. package/lib/main.js +392 -104
  168. package/lib/schema/arg-spec.js +229 -0
  169. package/lib/schema/cli-args.js +241 -0
  170. package/lib/schema/cli-transformers.js +119 -0
  171. package/lib/schema/index.js +2 -0
  172. package/lib/schema/keywords.js +136 -0
  173. package/lib/schema/schema.js +725 -0
  174. package/lib/utils.js +310 -89
  175. package/package.json +84 -84
  176. package/plugin.d.ts +1 -0
  177. package/plugin.js +13 -0
  178. package/scripts/autoinstall-extensions.js +243 -0
  179. package/support.d.ts +1 -0
  180. package/support.js +13 -0
  181. package/tsconfig.json +25 -0
  182. package/types/cli.ts +193 -0
  183. package/types/index.ts +20 -0
  184. package/types/manifest/README.md +30 -0
  185. package/types/manifest/base.ts +158 -0
  186. package/types/manifest/index.ts +28 -0
  187. package/types/manifest/v3.ts +161 -0
  188. package/types/manifest/v4.ts +161 -0
  189. package/CHANGELOG.md +0 -3669
  190. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  191. package/build/lib/cli/argparse-actions.js +0 -104
  192. package/build/lib/cli/npm.js +0 -207
  193. package/build/lib/cli/parser-helpers.js +0 -93
  194. package/build/lib/driver-config.js +0 -77
  195. package/build/lib/drivers.js +0 -99
  196. package/build/lib/extension-config.js +0 -253
  197. package/build/lib/plugin-config.js +0 -59
  198. package/build/lib/plugins.js +0 -16
  199. package/build/postinstall.js +0 -90
  200. package/lib/cli/argparse-actions.js +0 -77
  201. package/lib/cli/npm.js +0 -183
  202. package/lib/cli/parser-helpers.js +0 -91
  203. package/lib/driver-config.js +0 -46
  204. package/lib/drivers.js +0 -84
  205. package/lib/extension-config.js +0 -209
  206. package/lib/plugin-config.js +0 -34
  207. package/lib/plugins.js +0 -11
  208. package/postinstall.js +0 -71
package/lib/utils.js CHANGED
@@ -1,61 +1,76 @@
1
1
  import _ from 'lodash';
2
2
  import logger from './logger';
3
- import { processCapabilities, PROTOCOLS } from 'appium-base-driver';
4
- import findRoot from 'find-root';
3
+ import {processCapabilities, PROTOCOLS, STANDARD_CAPS} from '@appium/base-driver';
4
+ import {inspect as dump} from 'util';
5
+ import {node} from '@appium/support';
6
+ import path from 'path';
7
+ import {SERVER_SUBCOMMAND, DRIVER_TYPE, PLUGIN_TYPE} from './constants';
8
+ import os from 'node:os';
5
9
 
6
10
  const W3C_APPIUM_PREFIX = 'appium';
11
+ const STANDARD_CAPS_LOWERCASE = new Set([...STANDARD_CAPS].map((cap) => cap.toLowerCase()));
12
+ export const V4_BROADCAST_IP = '0.0.0.0';
13
+ export const V6_BROADCAST_IP = '::';
7
14
 
8
- function inspectObject (args) {
9
- function getValueArray (obj, indent = ' ') {
10
- if (!_.isObject(obj)) {
11
- return [obj];
12
- }
13
15
 
14
- let strArr = ['{'];
15
- for (let [arg, value] of _.toPairs(obj)) {
16
- if (!_.isObject(value)) {
17
- strArr.push(`${indent} ${arg}: ${value}`);
18
- } else {
19
- value = getValueArray(value, `${indent} `);
20
- strArr.push(`${indent} ${arg}: ${value.shift()}`);
21
- strArr.push(...value);
22
- }
23
- }
24
- strArr.push(`${indent}}`);
25
- return strArr;
26
- }
27
- for (let [arg, value] of _.toPairs(args)) {
28
- value = getValueArray(value);
29
- logger.info(` ${arg}: ${value.shift()}`);
30
- for (let val of value) {
31
- logger.info(val);
32
- }
16
+ /**
17
+ *
18
+ * If `stdout` is a TTY, this is `true`.
19
+ *
20
+ * Used for tighter control over log output.
21
+ * @type {boolean}
22
+ */
23
+ const isStdoutTTY = process.stdout.isTTY;
24
+
25
+ /**
26
+ * Dumps to value to the console using `info` logger.
27
+ *
28
+ * @todo May want to force color to be `false` if {@link isStdoutTTY} is `false`.
29
+ */
30
+ const inspect = _.flow(
31
+ _.partialRight(
32
+ /** @type {(object: any, options: import('util').InspectOptions) => string} */ (dump),
33
+ {colors: true, depth: null, compact: !isStdoutTTY}
34
+ ),
35
+ (...args) => {
36
+ logger.info(...args);
33
37
  }
34
- }
38
+ );
35
39
 
36
40
  /**
37
41
  * Takes the caps that were provided in the request and translates them
38
42
  * into caps that can be used by the inner drivers.
39
43
  *
40
- * @param {Object} jsonwpCapabilities
41
- * @param {Object} w3cCapabilities
42
- * @param {Object} constraints
43
- * @param {Object} defaultCapabilities
44
+ * @template {Constraints} C
45
+ * @template [J=any]
46
+ * @param {J} jsonwpCapabilities
47
+ * @param {W3CCapabilities<C>} w3cCapabilities
48
+ * @param {C} constraints
49
+ * @param {NSCapabilities<C>} [defaultCapabilities]
50
+ * @returns {ParsedDriverCaps<C,J>|InvalidCaps<C,J>}
44
51
  */
45
- function parseCapsForInnerDriver (jsonwpCapabilities, w3cCapabilities, constraints = {}, defaultCapabilities = {}) {
52
+ function parseCapsForInnerDriver(
53
+ jsonwpCapabilities,
54
+ w3cCapabilities,
55
+ constraints = /** @type {C} */ ({}),
56
+ defaultCapabilities = {}
57
+ ) {
46
58
  // Check if the caller sent JSONWP caps, W3C caps, or both
47
- const hasW3CCaps = _.isPlainObject(w3cCapabilities) &&
59
+ const hasW3CCaps =
60
+ _.isPlainObject(w3cCapabilities) &&
48
61
  (_.has(w3cCapabilities, 'alwaysMatch') || _.has(w3cCapabilities, 'firstMatch'));
49
62
  const hasJSONWPCaps = _.isPlainObject(jsonwpCapabilities);
50
- let desiredCaps = {};
51
- let processedW3CCapabilities = null;
52
- let processedJsonwpCapabilities = null;
63
+ let desiredCaps = /** @type {ParsedDriverCaps<C>['desiredCaps']} */ ({});
64
+ /** @type {ParsedDriverCaps<C>['processedW3CCapabilities']} */
65
+ let processedW3CCapabilities;
66
+ /** @type {ParsedDriverCaps<C>['processedJsonwpCapabilities']} */
67
+ let processedJsonwpCapabilities;
53
68
 
54
69
  if (!hasW3CCaps) {
55
- return {
70
+ return /** @type {InvalidCaps<C>} */ ({
56
71
  protocol: PROTOCOLS.W3C,
57
72
  error: new Error('W3C capabilities should be provided'),
58
- };
73
+ });
59
74
  }
60
75
 
61
76
  const {W3C} = PROTOCOLS;
@@ -71,16 +86,23 @@ function parseCapsForInnerDriver (jsonwpCapabilities, w3cCapabilities, constrain
71
86
  for (const [defaultCapKey, defaultCapValue] of _.toPairs(defaultCapabilities)) {
72
87
  let isCapAlreadySet = false;
73
88
  // Check if the key is already present in firstMatch entries
74
- for (const firstMatchEntry of (w3cCapabilities.firstMatch || [])) {
75
- if (_.isPlainObject(firstMatchEntry)
76
- && _.has(removeAppiumPrefixes(firstMatchEntry), removeAppiumPrefix(defaultCapKey))) {
89
+ for (const firstMatchEntry of w3cCapabilities.firstMatch ?? []) {
90
+ if (
91
+ _.isPlainObject(firstMatchEntry) &&
92
+ _.has(removeAppiumPrefixes(firstMatchEntry), removeAppiumPrefix(defaultCapKey))
93
+ ) {
77
94
  isCapAlreadySet = true;
78
95
  break;
79
96
  }
80
97
  }
81
98
  // Check if the key is already present in alwaysMatch entries
82
- isCapAlreadySet = isCapAlreadySet || (_.isPlainObject(w3cCapabilities.alwaysMatch)
83
- && _.has(removeAppiumPrefixes(w3cCapabilities.alwaysMatch), removeAppiumPrefix(defaultCapKey)));
99
+ isCapAlreadySet =
100
+ isCapAlreadySet ||
101
+ (_.isPlainObject(w3cCapabilities.alwaysMatch) &&
102
+ _.has(
103
+ removeAppiumPrefixes(w3cCapabilities.alwaysMatch),
104
+ removeAppiumPrefix(defaultCapKey)
105
+ ));
84
106
  if (isCapAlreadySet) {
85
107
  // Skip if the key is already present in the provided caps
86
108
  continue;
@@ -88,14 +110,19 @@ function parseCapsForInnerDriver (jsonwpCapabilities, w3cCapabilities, constrain
88
110
 
89
111
  // Only add the default capability if it is not overridden
90
112
  if (_.isEmpty(w3cCapabilities.firstMatch)) {
91
- w3cCapabilities.firstMatch = [{[defaultCapKey]: defaultCapValue}];
113
+ w3cCapabilities.firstMatch = /** @type {W3CCapabilities<C>['firstMatch']} */ ([
114
+ {[defaultCapKey]: defaultCapValue},
115
+ ]);
92
116
  } else {
93
117
  w3cCapabilities.firstMatch[0][defaultCapKey] = defaultCapValue;
94
118
  }
95
119
  }
96
120
  }
97
121
  if (hasJSONWPCaps) {
98
- jsonwpCapabilities = Object.assign({}, removeAppiumPrefixes(defaultCapabilities), jsonwpCapabilities);
122
+ jsonwpCapabilities = {
123
+ ...removeAppiumPrefixes(defaultCapabilities),
124
+ ...jsonwpCapabilities,
125
+ };
99
126
  }
100
127
  }
101
128
 
@@ -112,13 +139,13 @@ function parseCapsForInnerDriver (jsonwpCapabilities, w3cCapabilities, constrain
112
139
  desiredCaps = processCapabilities(w3cCapabilities, constraints, true);
113
140
  } catch (error) {
114
141
  logger.info(`Could not parse W3C capabilities: ${error.message}`);
115
- return {
142
+ return /** @type {InvalidCaps<C,J>} */ ({
116
143
  desiredCaps,
117
144
  processedJsonwpCapabilities,
118
145
  processedW3CCapabilities,
119
146
  protocol,
120
147
  error,
121
- };
148
+ });
122
149
  }
123
150
 
124
151
  // Create a new w3c capabilities payload that contains only the matching caps in `alwaysMatch`
@@ -128,60 +155,112 @@ function parseCapsForInnerDriver (jsonwpCapabilities, w3cCapabilities, constrain
128
155
  };
129
156
  }
130
157
 
131
- return {desiredCaps, processedJsonwpCapabilities, processedW3CCapabilities, protocol};
158
+ return /** @type {ParsedDriverCaps<C,J>} */ ({
159
+ desiredCaps,
160
+ processedJsonwpCapabilities,
161
+ processedW3CCapabilities,
162
+ protocol,
163
+ });
132
164
  }
133
165
 
134
166
  /**
135
167
  * Takes a capabilities objects and prefixes capabilities with `appium:`
136
- * @param {Object} caps Desired capabilities object
137
- */
138
- function insertAppiumPrefixes (caps) {
139
- // Standard, non-prefixed capabilities (see https://www.w3.org/TR/webdriver/#dfn-table-of-standard-capabilities)
140
- const STANDARD_CAPS = [
141
- 'browserName',
142
- 'browserVersion',
143
- 'platformName',
144
- 'acceptInsecureCerts',
145
- 'pageLoadStrategy',
146
- 'proxy',
147
- 'setWindowRect',
148
- 'timeouts',
149
- 'unhandledPromptBehavior'
150
- ];
151
-
152
- let prefixedCaps = {};
153
- for (let [name, value] of _.toPairs(caps)) {
154
- if (STANDARD_CAPS.includes(name) || name.includes(':')) {
155
- prefixedCaps[name] = value;
156
- } else {
157
- prefixedCaps[`${W3C_APPIUM_PREFIX}:${name}`] = value;
158
- }
159
- }
160
- return prefixedCaps;
168
+ * @template {Constraints} [C={}]
169
+ * @param {Capabilities<C>} caps - Desired capabilities object
170
+ * @returns {NSCapabilities<C>}
171
+ */
172
+ function insertAppiumPrefixes(caps) {
173
+ return /** @type {NSCapabilities<C>} */ (
174
+ _.mapKeys(caps, (_, key) =>
175
+ STANDARD_CAPS_LOWERCASE.has(key.toLowerCase()) || key.includes(':')
176
+ ? key
177
+ : `${W3C_APPIUM_PREFIX}:${key}`
178
+ )
179
+ );
161
180
  }
162
181
 
163
- function removeAppiumPrefixes (caps) {
164
- if (!_.isPlainObject(caps)) {
165
- return caps;
166
- }
167
-
168
- const fixedCaps = {};
169
- for (let [name, value] of _.toPairs(caps)) {
170
- fixedCaps[removeAppiumPrefix(name)] = value;
171
- }
172
- return fixedCaps;
182
+ /**
183
+ * @template {Constraints} [C={}]
184
+ * @param {NSCapabilities<C>} caps
185
+ * @returns {Capabilities<C>}
186
+ */
187
+ function removeAppiumPrefixes(caps) {
188
+ return /** @type {Capabilities<C>} */ (_.mapKeys(caps, (_, key) => removeAppiumPrefix(key)));
173
189
  }
174
190
 
175
- function removeAppiumPrefix (key) {
191
+ /**
192
+ * @param {string} key
193
+ * @returns {string}
194
+ */
195
+ function removeAppiumPrefix(key) {
176
196
  const prefix = `${W3C_APPIUM_PREFIX}:`;
177
197
  return _.startsWith(key, prefix) ? key.substring(prefix.length) : key;
178
198
  }
179
199
 
180
- function getPackageVersion (pkgName) {
200
+ /**
201
+ *
202
+ * @param {string} pkgName
203
+ * @returns {string|undefined}
204
+ */
205
+ function getPackageVersion(pkgName) {
181
206
  const pkgInfo = require(`${pkgName}/package.json`) || {};
182
207
  return pkgInfo.version;
183
208
  }
184
209
 
210
+ /**
211
+ * Adjusts NODE_PATH environment variable,
212
+ * so drivers and plugins could load their peer dependencies.
213
+ * Read https://nodejs.org/api/modules.html#loading-from-the-global-folders
214
+ * for more details.
215
+ * @returns {void}
216
+ */
217
+ function adjustNodePath() {
218
+ const selfRoot = node.getModuleRootSync('appium', __filename);
219
+ if (!selfRoot || path.dirname(selfRoot).length >= selfRoot.length) {
220
+ return;
221
+ }
222
+ const nodeModulesRoot = path.dirname(selfRoot);
223
+
224
+ const refreshRequirePaths = () => {
225
+ try {
226
+ // ! This hack allows us to avoid modification of import
227
+ // ! statements in client modules. It uses a private API though,
228
+ // ! so it could break (maybe, eventually).
229
+ // See https://gist.github.com/branneman/8048520#7-the-hack
230
+ // @ts-ignore see above comment
231
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
232
+ require('module').Module._initPaths();
233
+ return true;
234
+ } catch (e) {
235
+ return false;
236
+ }
237
+ };
238
+
239
+ if (!process.env.NODE_PATH) {
240
+ process.env.NODE_PATH = nodeModulesRoot;
241
+ if (refreshRequirePaths()) {
242
+ process.env.APPIUM_OMIT_PEER_DEPS = '1';
243
+ } else {
244
+ delete process.env.NODE_PATH;
245
+ }
246
+ return;
247
+ }
248
+
249
+ const nodePathParts = process.env.NODE_PATH.split(path.delimiter);
250
+ if (nodePathParts.includes(nodeModulesRoot)) {
251
+ process.env.APPIUM_OMIT_PEER_DEPS = '1';
252
+ return;
253
+ }
254
+
255
+ nodePathParts.push(nodeModulesRoot);
256
+ process.env.NODE_PATH = nodePathParts.join(path.delimiter);
257
+ if (refreshRequirePaths()) {
258
+ process.env.APPIUM_OMIT_PEER_DEPS = '1';
259
+ } else {
260
+ process.env.NODE_PATH = _.without(nodePathParts, nodeModulesRoot).join(path.delimiter);
261
+ }
262
+ }
263
+
185
264
  /**
186
265
  * Pulls the initial values of Appium settings from the given capabilities argument.
187
266
  * Each setting item must satisfy the following format:
@@ -198,7 +277,7 @@ function getPackageVersion (pkgName) {
198
277
  * setting items or a dictionary containing parsed Appium setting names along with
199
278
  * their values.
200
279
  */
201
- function pullSettings (caps) {
280
+ function pullSettings(caps) {
202
281
  if (!_.isPlainObject(caps) || _.isEmpty(caps)) {
203
282
  return {};
204
283
  }
@@ -216,9 +295,151 @@ function pullSettings (caps) {
216
295
  return result;
217
296
  }
218
297
 
219
- const rootDir = findRoot(__dirname);
298
+ /**
299
+ * @template {CliCommand} [Cmd=ServerCommand]
300
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
301
+ * @param {Args<Cmd, SubCmd>} args
302
+ * @returns {args is Args<ServerCommand>}
303
+ */
304
+ export function isServerCommandArgs(args) {
305
+ return args.subcommand === SERVER_SUBCOMMAND;
306
+ }
307
+
308
+ /**
309
+ * @template {CliCommand} [Cmd=ServerCommand]
310
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
311
+ * @param {Args<Cmd, SubCmd>} args
312
+ * @returns {args is Args<CliExtensionCommand, SubCmd>}
313
+ */
314
+ export function isExtensionCommandArgs(args) {
315
+ return args.subcommand === DRIVER_TYPE || args.subcommand === PLUGIN_TYPE;
316
+ }
317
+
318
+ /**
319
+ * @template {CliCommand} Cmd
320
+ * @template {CliExtensionSubcommand} SubCmd
321
+ * @param {Args<Cmd, SubCmd>} args
322
+ * @returns {args is Args<DriverCommand, SubCmd>}
323
+ */
324
+ export function isDriverCommandArgs(args) {
325
+ return args.subcommand === DRIVER_TYPE;
326
+ }
327
+
328
+ /**
329
+ * @template {CliCommand} Cmd
330
+ * @template {CliExtensionSubcommand} SubCmd
331
+ * @param {Args<Cmd, SubCmd>} args
332
+ * @returns {args is Args<PluginCommand, SubCmd>}
333
+ */
334
+ export function isPluginCommandArgs(args) {
335
+ return args.subcommand === PLUGIN_TYPE;
336
+ }
337
+
338
+ /**
339
+ * Fetches the list of IP addresses of the current host.
340
+ *
341
+ * @param {4|6|null} family Either 4 to include ipv4 addresses only,
342
+ * 6 to include ipv6 addresses only, or null to include all of them
343
+ * @returns {string[]} The list of matched IP addresses
344
+ */
345
+ export function fetchIpAddresses (family = null) {
346
+ let familyValue = null;
347
+ // 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
348
+ if (family === 4) {
349
+ familyValue = [4, 'IPv4'];
350
+ } else if (family === 6) {
351
+ familyValue = [6, 'IPv6'];
352
+ }
353
+ return _.flatMap(_.values(os.networkInterfaces()).filter(Boolean))
354
+ // @ts-ignore The linter does not understand the above filter
355
+ .filter(({family}) => !familyValue || familyValue && familyValue.includes(family))
356
+ // @ts-ignore The linter does not understand the above filter
357
+ .map(({address}) => address);
358
+ }
220
359
 
221
360
  export {
222
- inspectObject, parseCapsForInnerDriver, insertAppiumPrefixes, rootDir,
223
- getPackageVersion, pullSettings, removeAppiumPrefixes,
361
+ inspect,
362
+ parseCapsForInnerDriver,
363
+ insertAppiumPrefixes,
364
+ getPackageVersion,
365
+ pullSettings,
366
+ removeAppiumPrefixes,
367
+ adjustNodePath,
224
368
  };
369
+
370
+ /**
371
+ * @typedef {import('@appium/types').StringRecord} StringRecord
372
+ * @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
373
+ */
374
+
375
+ /**
376
+ * @template {Constraints} [C=BaseDriverCapConstraints]
377
+ * @template [J=any]
378
+ * @typedef ParsedDriverCaps
379
+ * @property {Capabilities<C>} desiredCaps
380
+ * @property {string} protocol
381
+ * @property {J} [processedJsonwpCapabilities]
382
+ * @property {W3CCapabilities<C>} [processedW3CCapabilities]
383
+ */
384
+
385
+ /**
386
+ * @todo protocol is more specific
387
+ * @template {Constraints} [C=BaseDriverCapConstraints]
388
+ * @template [J=any]
389
+ * @typedef InvalidCaps
390
+ * @property {Error} error
391
+ * @property {string} protocol
392
+ * @property {Capabilities<C>} [desiredCaps]
393
+ * @property {J} [processedJsonwpCapabilities]
394
+ * @property {W3CCapabilities<C>} [processedW3CCapabilities]
395
+ */
396
+
397
+ /**
398
+ * @template {Constraints} C
399
+ * @typedef {import('@appium/types').Capabilities<C>} Capabilities
400
+ */
401
+
402
+ /**
403
+ * @template {Constraints} C
404
+ * @typedef {import('@appium/types').W3CCapabilities<C>} W3CCapabilities
405
+ */
406
+
407
+ /**
408
+ * @template {Constraints} C
409
+ * @typedef {import('@appium/types').NSCapabilities<C>} NSCapabilities
410
+ */
411
+
412
+ /**
413
+ * @template {Constraints} C
414
+ * @typedef {import('@appium/types').ConstraintsToCaps<C>} ConstraintsToCaps
415
+ */
416
+
417
+ /**
418
+ * @template T
419
+ * @typedef {import('type-fest').StringKeyOf<T>} StringKeyOf
420
+ */
421
+
422
+ /**
423
+ * @typedef {import('@appium/types').Constraints} Constraints
424
+ */
425
+
426
+ /**
427
+ * @typedef {import('appium/types').CliCommand} CliCommand
428
+ * @typedef {import('appium/types').CliExtensionSubcommand} CliExtensionSubcommand
429
+ * @typedef {import('appium/types').CliExtensionCommand} CliExtensionCommand
430
+ * @typedef {import('appium/types').CliCommandServer} ServerCommand
431
+ * @typedef {import('appium/types').CliCommandDriver} DriverCommand
432
+ * @typedef {import('appium/types').CliCommandPlugin} PluginCommand
433
+ */
434
+
435
+ /**
436
+ * @template {CliCommand} [Cmd=ServerCommand]
437
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
438
+ * @typedef {import('appium/types').Args<Cmd, SubCmd>} Args
439
+ */
440
+
441
+ /**
442
+ * @template {CliCommand} [Cmd=ServerCommand]
443
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
444
+ * @typedef {import('appium/types').ParsedArgs<Cmd, SubCmd>} ParsedArgs
445
+ */