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

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/build/lib/main.js CHANGED
@@ -1,248 +1,420 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
-
4
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
5
-
6
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
7
-
8
- Object.defineProperty(exports, "__esModule", {
9
- value: true
10
- });
11
- exports.main = main;
12
-
13
- require("source-map-support/register");
14
-
15
- var _logsink = require("./logsink");
16
-
17
- var _logger = _interopRequireDefault(require("./logger"));
18
-
19
- var _lodash = _interopRequireDefault(require("lodash"));
20
-
21
- var _appiumBaseDriver = require("appium-base-driver");
22
-
23
- var _asyncbox = require("asyncbox");
24
-
25
- var _parser = _interopRequireWildcard(require("./cli/parser"));
26
-
27
- var _args = require("./cli/args");
28
-
29
- var _appiumSupport = require("appium-support");
30
-
31
- var _config = require("./config");
32
-
33
- var _driverConfig = _interopRequireDefault(require("./driver-config"));
34
-
35
- var _pluginConfig = _interopRequireDefault(require("./plugin-config"));
36
-
37
- var _extensionConfig = require("./extension-config");
38
-
39
- var _extension = require("./cli/extension");
40
-
41
- var _appium = require("./appium");
42
-
43
- var _gridRegister = _interopRequireDefault(require("./grid-register"));
44
-
45
- var _utils = require("./utils");
46
-
47
- async function preflightChecks({
48
- parser,
49
- args,
50
- driverConfig,
51
- pluginConfig,
52
- throwInsteadOfExit = false
53
- }) {
54
- try {
55
- (0, _config.checkNodeOk)();
56
-
57
- if (args.longStacktrace) {
58
- require('longjohn').async_trace_limit = -1;
59
- }
60
-
61
- if (args.showConfig) {
62
- await (0, _config.showConfig)();
63
- process.exit(0);
64
- }
65
-
66
- (0, _config.warnNodeDeprecations)();
67
- (0, _config.validateServerArgs)(parser, args);
68
- await driverConfig.read();
69
- await pluginConfig.read();
70
-
71
- if (args.tmpDir) {
72
- await (0, _config.validateTmpDir)(args.tmpDir);
73
- }
74
- } catch (err) {
75
- _logger.default.error(err.message.red);
76
-
77
- if (throwInsteadOfExit) {
78
- throw err;
79
- }
80
-
81
- process.exit(1);
82
- }
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.resolveAppiumHome = exports.init = exports.main = exports.validate = exports.getSchema = exports.finalizeSchema = exports.readConfigFile = void 0;
8
+ const logsink_1 = require("./logsink"); // this import needs to come first since it sets up global npmlog
9
+ const logger_1 = __importDefault(require("./logger")); // logger needs to remain second
10
+ const base_driver_1 = require("@appium/base-driver");
11
+ const support_1 = require("@appium/support");
12
+ const asyncbox_1 = require("asyncbox");
13
+ const lodash_1 = __importDefault(require("lodash"));
14
+ const appium_1 = require("./appium");
15
+ const extension_1 = require("./cli/extension");
16
+ const parser_1 = require("./cli/parser");
17
+ const config_1 = require("./config");
18
+ const config_file_1 = require("./config-file");
19
+ const extension_2 = require("./extension");
20
+ const constants_1 = require("./constants");
21
+ const grid_register_1 = __importDefault(require("./grid-register"));
22
+ const schema_1 = require("./schema/schema");
23
+ const utils_1 = require("./utils");
24
+ const node_os_1 = __importDefault(require("node:os"));
25
+ const { resolveAppiumHome } = support_1.env;
26
+ exports.resolveAppiumHome = resolveAppiumHome;
27
+ /**
28
+ *
29
+ * @param {ParsedArgs} args
30
+ * @param {boolean} [throwInsteadOfExit]
31
+ */
32
+ async function preflightChecks(args, throwInsteadOfExit = false) {
33
+ try {
34
+ (0, config_1.checkNodeOk)();
35
+ await (0, config_1.checkNpmOk)();
36
+ if (args.longStacktrace) {
37
+ Error.stackTraceLimit = constants_1.LONG_STACKTRACE_LIMIT;
38
+ }
39
+ if (args.showBuildInfo) {
40
+ await (0, config_1.showBuildInfo)();
41
+ process.exit(0);
42
+ }
43
+ (0, config_1.warnNodeDeprecations)();
44
+ (0, schema_1.validate)(args);
45
+ if (args.tmpDir) {
46
+ await (0, config_1.validateTmpDir)(args.tmpDir);
47
+ }
48
+ }
49
+ catch (err) {
50
+ logger_1.default.error(err.message.red);
51
+ if (throwInsteadOfExit) {
52
+ throw err;
53
+ }
54
+ process.exit(1);
55
+ }
83
56
  }
84
-
57
+ /**
58
+ * @param {Args} args
59
+ */
85
60
  function logNonDefaultArgsWarning(args) {
86
- _logger.default.info('Non-default server args:');
87
-
88
- (0, _utils.inspectObject)(args);
61
+ logger_1.default.info('Non-default server args:');
62
+ (0, utils_1.inspect)(args);
89
63
  }
90
-
64
+ /**
65
+ * @param {Args['defaultCapabilities']} caps
66
+ */
91
67
  function logDefaultCapabilitiesWarning(caps) {
92
- _logger.default.info('Default capabilities, which will be added to each request ' + 'unless overridden by desired capabilities:');
93
-
94
- (0, _utils.inspectObject)(caps);
68
+ logger_1.default.info('Default capabilities, which will be added to each request ' +
69
+ 'unless overridden by desired capabilities:');
70
+ (0, utils_1.inspect)(caps);
95
71
  }
96
-
97
- async function logStartupInfo(parser, args) {
98
- let welcome = `Welcome to Appium v${_config.APPIUM_VER}`;
99
- let appiumRev = await (0, _config.getGitRev)();
100
-
101
- if (appiumRev) {
102
- welcome += ` (REV ${appiumRev})`;
103
- }
104
-
105
- _logger.default.info(welcome);
106
-
107
- let showArgs = (0, _config.getNonDefaultArgs)(parser, args);
108
-
109
- if (_lodash.default.size(showArgs)) {
110
- logNonDefaultArgsWarning(showArgs);
111
- }
112
-
113
- if (!_lodash.default.isEmpty(args.defaultCapabilities)) {
114
- logDefaultCapabilitiesWarning(args.defaultCapabilities);
115
- }
72
+ /**
73
+ * @param {ParsedArgs} args
74
+ */
75
+ async function logStartupInfo(args) {
76
+ let welcome = `Welcome to Appium v${config_1.APPIUM_VER}`;
77
+ let appiumRev = await (0, config_1.getGitRev)();
78
+ if (appiumRev) {
79
+ welcome += ` (REV ${appiumRev})`;
80
+ }
81
+ logger_1.default.info(welcome);
82
+ let showArgs = (0, config_1.getNonDefaultServerArgs)(args);
83
+ if (lodash_1.default.size(showArgs)) {
84
+ logNonDefaultArgsWarning(showArgs);
85
+ }
86
+ if (!lodash_1.default.isEmpty(args.defaultCapabilities)) {
87
+ logDefaultCapabilitiesWarning(args.defaultCapabilities);
88
+ }
89
+ // TODO: bring back loglevel reporting below once logger is flushed out
90
+ // logger.info('Console LogLevel: ' + logger.transports.console.level);
91
+ // if (logger.transports.file) {
92
+ // logger.info('File LogLevel: ' + logger.transports.file.level);
93
+ // }
116
94
  }
117
-
118
- function logServerPort(address, port) {
119
- let logMessage = `Appium REST http interface listener started on ` + `${address}:${port}`;
120
-
121
- _logger.default.info(logMessage);
95
+ /**
96
+ * Gets a list of `updateServer` functions from all extensions
97
+ * @param {DriverNameMap} driverClasses
98
+ * @param {PluginNameMap} pluginClasses
99
+ * @returns {import('@appium/types').UpdateServerCallback[]}
100
+ */
101
+ function getServerUpdaters(driverClasses, pluginClasses) {
102
+ return lodash_1.default.compact(lodash_1.default.map([...driverClasses.keys(), ...pluginClasses.keys()], 'updateServer'));
122
103
  }
123
-
124
- async function main(args = null) {
125
- let parser = (0, _parser.default)();
126
- let throwInsteadOfExit = false;
127
-
128
- if (args) {
129
- args = Object.assign({}, (0, _parser.getDefaultServerArgs)(), args);
130
-
131
- if (args.throwInsteadOfExit) {
132
- throwInsteadOfExit = true;
133
- delete args.throwInsteadOfExit;
134
- }
135
- } else {
136
- args = parser.parse_args();
137
- }
138
-
139
- await (0, _logsink.init)(args);
140
-
141
- if (args.subcommand === _extensionConfig.DRIVER_TYPE || args.subcommand === _extensionConfig.PLUGIN_TYPE) {
142
- await (0, _extension.runExtensionCommand)(args, args.subcommand);
143
- process.exit();
144
- }
145
-
146
- if (args.logFilters) {
147
- const {
148
- issues,
149
- rules
150
- } = await _appiumSupport.logger.loadSecureValuesPreprocessingRules(args.logFilters);
151
-
152
- if (!_lodash.default.isEmpty(issues)) {
153
- throw new Error(`The log filtering rules config '${args.logFilters}' has issues: ` + JSON.stringify(issues, null, 2));
154
- }
155
-
156
- if (_lodash.default.isEmpty(rules)) {
157
- _logger.default.warn(`Found no log filtering rules in '${args.logFilters}'. Is that expected?`);
158
- } else {
159
- _logger.default.info(`Loaded ${_appiumSupport.util.pluralize('filtering rule', rules.length, true)} from '${args.logFilters}'`);
160
- }
161
- }
162
-
163
- let appiumDriver = new _appium.AppiumDriver(args);
164
- const driverConfig = new _driverConfig.default(args.appiumHome);
165
- const pluginConfig = new _pluginConfig.default(args.appiumHome);
166
- appiumDriver.driverConfig = driverConfig;
167
- await preflightChecks({
168
- parser,
169
- args,
170
- driverConfig,
171
- pluginConfig,
172
- throwInsteadOfExit
173
- });
174
- await logStartupInfo(parser, args);
175
- let routeConfiguringFunction = (0, _appiumBaseDriver.routeConfiguringFunction)(appiumDriver);
176
- const plugins = Object.keys(pluginConfig.installedExtensions).filter(pluginName => _lodash.default.includes(args.plugins, pluginName) || args.plugins.length === 1 && args.plugins[0] === _args.USE_ALL_PLUGINS).map(pluginName => {
104
+ /**
105
+ * Makes a big `MethodMap` from all the little `MethodMap`s in the extensions
106
+ * @param {DriverNameMap} driverClasses
107
+ * @param {PluginNameMap} pluginClasses
108
+ * @returns {import('@appium/types').MethodMap<import('@appium/types').Driver>}
109
+ */
110
+ function getExtraMethodMap(driverClasses, pluginClasses) {
111
+ return [...driverClasses.keys(), ...pluginClasses.keys()].reduce((map, klass) => ({
112
+ ...map,
113
+ ...(klass.newMethodMap ?? {}),
114
+ }), {});
115
+ }
116
+ /**
117
+ * Prepares and validates appium home path folder
118
+ *
119
+ * @param {string} name The name of the appium home source (needed for error messages)
120
+ * @param {string} appiumHome The actual value to be verified
121
+ * @returns {Promise<string>} Same appiumHome value
122
+ * @throws {Error} If the validation has failed
123
+ */
124
+ async function prepareAppiumHome(name, appiumHome) {
125
+ let stat;
126
+ try {
127
+ stat = await support_1.fs.stat(appiumHome);
128
+ }
129
+ catch (e) {
130
+ let err = e;
131
+ if (e.code === 'ENOENT') {
132
+ try {
133
+ await support_1.fs.mkdir(appiumHome, { recursive: true });
134
+ return appiumHome;
135
+ }
136
+ catch (e1) {
137
+ err = e1;
138
+ }
139
+ }
140
+ throw new Error(`The path '${appiumHome}' provided in the ${name} must point ` +
141
+ `to a valid folder writeable for the current user account '${node_os_1.default.userInfo().username}'. ` +
142
+ `Original error: ${err.message}`);
143
+ }
144
+ if (!stat.isDirectory()) {
145
+ throw new Error(`The path '${appiumHome}' provided in the ${name} must point to a valid folder`);
146
+ }
177
147
  try {
178
- const PluginClass = pluginConfig.require(pluginName);
179
-
180
- return new PluginClass(pluginName);
181
- } catch (err) {
182
- _logger.default.error(`Could not load plugin '${pluginName}', so it will not be available. Error ` + `in loading the plugin was: ${err}`);
183
-
184
- return false;
185
- }
186
- }).filter(Boolean);
187
- appiumDriver.plugins = plugins;
188
- const serverOpts = {
189
- routeConfiguringFunction,
190
- port: args.port,
191
- hostname: args.address,
192
- allowCors: args.allowCors,
193
- basePath: args.basePath,
194
- plugins
195
- };
196
-
197
- if (args.keepAliveTimeout) {
198
- serverOpts.keepAliveTimeout = args.keepAliveTimeout * 1000;
199
- }
200
-
201
- let server = await (0, _appiumBaseDriver.server)(serverOpts);
202
-
203
- if (args.allowCors) {
204
- _logger.default.warn('You have enabled CORS requests from any host. Be careful not ' + 'to visit sites which could maliciously try to start Appium ' + 'sessions on your machine');
205
- }
206
-
207
- appiumDriver.server = server;
208
-
209
- try {
210
- if (args.nodeconfig !== null) {
211
- await (0, _gridRegister.default)(args.nodeconfig, args.address, args.port, args.basePath);
212
- }
213
- } catch (err) {
214
- await server.close();
215
- throw err;
216
- }
217
-
218
- for (const signal of ['SIGINT', 'SIGTERM']) {
219
- process.once(signal, async function onSignal() {
220
- _logger.default.info(`Received ${signal} - shutting down`);
221
-
222
- try {
223
- await appiumDriver.deleteAllSessions({
224
- force: true,
225
- reason: `The process has received ${signal} signal`
148
+ await support_1.fs.access(appiumHome, support_1.fs.constants.W_OK);
149
+ }
150
+ catch (e) {
151
+ throw new Error(`The folder path '${appiumHome}' provided in the ${name} must be ` +
152
+ `writeable for the current user account '${node_os_1.default.userInfo().username}. ` +
153
+ `Original error: ${e.message}`);
154
+ }
155
+ return appiumHome;
156
+ }
157
+ /**
158
+ * Initializes Appium, but does not start the server.
159
+ *
160
+ * Use this to get at the configuration schema.
161
+ *
162
+ * If `args` contains a non-empty `subcommand` which is not `server`, this function will return an empty object.
163
+ *
164
+ * @template {CliCommand} [Cmd=ServerCommand]
165
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
166
+ * @param {Args<Cmd, SubCmd>} [args] - Partial args (progammatic usage only)
167
+ * @returns {Promise<InitResult<Cmd>>}
168
+ * @example
169
+ * import {init, getSchema} from 'appium';
170
+ * const options = {}; // config object
171
+ * await init(options);
172
+ * const schema = getSchema(); // entire config schema including plugins and drivers
173
+ */
174
+ async function init(args) {
175
+ const appiumHome = args?.appiumHome ?? (await resolveAppiumHome());
176
+ let appiumHomeSourceName = 'autodetected appium home path';
177
+ if (!lodash_1.default.isNil(args?.appiumHome)) {
178
+ appiumHomeSourceName = 'appiumHome config value';
179
+ }
180
+ else if (process.env.APPIUM_HOME) {
181
+ appiumHomeSourceName = 'APPIUM_HOME environment variable';
182
+ }
183
+ await prepareAppiumHome(appiumHomeSourceName, appiumHome);
184
+ (0, utils_1.adjustNodePath)();
185
+ const { driverConfig, pluginConfig } = await (0, extension_2.loadExtensions)(appiumHome);
186
+ const parser = (0, parser_1.getParser)();
187
+ let throwInsteadOfExit = false;
188
+ /** @type {Args<Cmd, SubCmd>} */
189
+ let preConfigArgs;
190
+ if (args) {
191
+ // if we have a containing package instead of running as a CLI process,
192
+ // that package might not appreciate us calling 'process.exit' willy-
193
+ // nilly, so give it the option to have us throw instead of exit
194
+ if (args.throwInsteadOfExit) {
195
+ throwInsteadOfExit = true;
196
+ // but remove it since it's not a real server arg per se
197
+ delete args.throwInsteadOfExit;
198
+ }
199
+ preConfigArgs = { ...args, subcommand: args.subcommand ?? constants_1.SERVER_SUBCOMMAND };
200
+ }
201
+ else {
202
+ // otherwise parse from CLI
203
+ preConfigArgs = /** @type {Args<Cmd, SubCmd>} */ (parser.parseArgs());
204
+ }
205
+ const configResult = await (0, config_file_1.readConfigFile)(preConfigArgs.configFile);
206
+ if (!lodash_1.default.isEmpty(configResult.errors)) {
207
+ throw new Error(`Errors in config file ${configResult.filepath}:\n ${configResult.reason ?? configResult.errors}`);
208
+ }
209
+ // merge config and apply defaults.
210
+ // the order of precendece is:
211
+ // 1. command line args
212
+ // 2. config file
213
+ // 3. defaults from config file.
214
+ if ((0, utils_1.isServerCommandArgs)(preConfigArgs)) {
215
+ const defaults = (0, schema_1.getDefaultsForSchema)(false);
216
+ /** @type {ParsedArgs} */
217
+ const serverArgs = lodash_1.default.defaultsDeep({}, preConfigArgs, configResult.config?.server, defaults);
218
+ if (preConfigArgs.showConfig) {
219
+ (0, config_1.showConfig)((0, config_1.getNonDefaultServerArgs)(preConfigArgs), configResult, defaults, serverArgs);
220
+ return /** @type {InitResult<Cmd>} */ ({});
221
+ }
222
+ await (0, logsink_1.init)(serverArgs);
223
+ if (serverArgs.logFilters) {
224
+ const { issues, rules } = await support_1.logger.loadSecureValuesPreprocessingRules(serverArgs.logFilters);
225
+ if (!lodash_1.default.isEmpty(issues)) {
226
+ throw new Error(`The log filtering rules config '${serverArgs.logFilters}' has issues: ` +
227
+ JSON.stringify(issues, null, 2));
228
+ }
229
+ if (lodash_1.default.isEmpty(rules)) {
230
+ logger_1.default.warn(`Found no log filtering rules in '${serverArgs.logFilters}'. Is that expected?`);
231
+ }
232
+ else {
233
+ logger_1.default.info(`Loaded ${support_1.util.pluralize('filtering rule', rules.length, true)} from '${serverArgs.logFilters}'`);
234
+ }
235
+ }
236
+ const appiumDriver = new appium_1.AppiumDriver(
237
+ /** @type {import('@appium/types').DriverOpts<import('./appium').AppiumDriverConstraints>} */ (serverArgs));
238
+ // set the config on the umbrella driver so it can match drivers to caps
239
+ appiumDriver.driverConfig = driverConfig;
240
+ await preflightChecks(serverArgs, throwInsteadOfExit);
241
+ return /** @type {InitResult<Cmd>} */ ({
242
+ appiumDriver,
243
+ parsedArgs: serverArgs,
244
+ driverConfig,
245
+ pluginConfig,
226
246
  });
247
+ }
248
+ else {
249
+ if ((0, utils_1.isExtensionCommandArgs)(preConfigArgs)) {
250
+ // if the user has requested the 'driver' CLI, don't run the normal server,
251
+ // but instead pass control to the driver CLI
252
+ if ((0, utils_1.isDriverCommandArgs)(preConfigArgs)) {
253
+ await (0, extension_1.runExtensionCommand)(preConfigArgs, driverConfig);
254
+ }
255
+ if ((0, utils_1.isPluginCommandArgs)(preConfigArgs)) {
256
+ await (0, extension_1.runExtensionCommand)(preConfigArgs, pluginConfig);
257
+ }
258
+ }
259
+ return /** @type {InitResult<Cmd>} */ ({});
260
+ }
261
+ }
262
+ exports.init = init;
263
+ /**
264
+ * Prints the actual server address and the list of URLs that
265
+ * could be used to connect to the current server.
266
+ * Properly replaces broadcast addresses in client URLs.
267
+ *
268
+ * @param {string} url The URL the server is listening on
269
+ */
270
+ function logServerAddress(url) {
271
+ logger_1.default.info(`Appium REST http interface listener started on ${url}`);
272
+ const urlObj = new URL(url);
273
+ if (![utils_1.V4_BROADCAST_IP, utils_1.V6_BROADCAST_IP].includes(urlObj.hostname)) {
274
+ return;
275
+ }
276
+ const ips = (0, utils_1.fetchIpAddresses)(urlObj.hostname === utils_1.V4_BROADCAST_IP ? 4 : 6);
277
+ logger_1.default.info(`You can provide the following ${support_1.util.pluralize('URL', ips.length, false)} ` +
278
+ `in your client code to connect to this server:\n` +
279
+ ips.map((x) => `\t${urlObj.href.replace(urlObj.hostname, x)}`).join('\n'));
280
+ }
281
+ /**
282
+ * Initializes Appium's config. Starts server if appropriate and resolves the
283
+ * server instance if so; otherwise resolves w/ `undefined`.
284
+ * @template {CliCommand} [Cmd=ServerCommand]
285
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
286
+ * @param {Args<Cmd, SubCmd>} [args] - Arguments from CLI or otherwise
287
+ * @returns {Promise<Cmd extends ServerCommand ? import('@appium/types').AppiumServer : void>}
288
+ */
289
+ async function main(args) {
290
+ const initResult = await init(args);
291
+ if (lodash_1.default.isEmpty(initResult)) {
292
+ // if this branch is taken, we've run a different subcommand, so there's nothing
293
+ // left to do here.
294
+ return /** @type {Cmd extends ServerCommand ? import('@appium/types').AppiumServer : void} */ (undefined);
295
+ }
296
+ const { appiumDriver, pluginConfig, driverConfig, parsedArgs } =
297
+ /** @type {InitResult<ServerCommand>} */ (initResult);
298
+ const pluginClasses = (0, extension_2.getActivePlugins)(pluginConfig, parsedArgs.usePlugins);
299
+ // set the active plugins on the umbrella driver so it can use them for commands
300
+ appiumDriver.pluginClasses = pluginClasses;
301
+ await logStartupInfo(parsedArgs);
302
+ let routeConfiguringFunction = (0, base_driver_1.routeConfiguringFunction)(appiumDriver);
303
+ const driverClasses = (0, extension_2.getActiveDrivers)(driverConfig, parsedArgs.useDrivers);
304
+ const serverUpdaters = getServerUpdaters(driverClasses, pluginClasses);
305
+ const extraMethodMap = getExtraMethodMap(driverClasses, pluginClasses);
306
+ /** @type {import('@appium/base-driver').ServerOpts} */
307
+ const serverOpts = {
308
+ routeConfiguringFunction,
309
+ port: parsedArgs.port,
310
+ hostname: parsedArgs.address,
311
+ allowCors: parsedArgs.allowCors,
312
+ basePath: parsedArgs.basePath,
313
+ serverUpdaters,
314
+ extraMethodMap,
315
+ cliArgs: parsedArgs,
316
+ };
317
+ if (parsedArgs.keepAliveTimeout) {
318
+ serverOpts.keepAliveTimeout = parsedArgs.keepAliveTimeout * 1000;
319
+ }
320
+ let server;
321
+ try {
322
+ server = await (0, base_driver_1.server)(serverOpts);
323
+ }
324
+ catch (err) {
325
+ logger_1.default.error(`Could not configure Appium server. It's possible that a driver or plugin tried ` +
326
+ `to update the server and failed. Original error: ${err.message}`);
327
+ logger_1.default.debug(err.stack);
328
+ return process.exit(1);
329
+ }
330
+ if (parsedArgs.allowCors) {
331
+ logger_1.default.warn('You have enabled CORS requests from any host. Be careful not ' +
332
+ 'to visit sites which could maliciously try to start Appium ' +
333
+ 'sessions on your machine');
334
+ }
335
+ appiumDriver.server = server;
336
+ try {
337
+ // configure as node on grid, if necessary
338
+ // falsy values should not cause this to run
339
+ if (parsedArgs.nodeconfig) {
340
+ await (0, grid_register_1.default)(parsedArgs.nodeconfig, parsedArgs.address, parsedArgs.port, parsedArgs.basePath);
341
+ }
342
+ }
343
+ catch (err) {
227
344
  await server.close();
228
- process.exit(0);
229
- } catch (e) {
230
- _logger.default.warn(e);
231
-
232
- process.exit(1);
233
- }
234
- });
235
- }
236
-
237
- logServerPort(args.address, args.port);
238
- driverConfig.print();
239
- pluginConfig.print(plugins);
240
- return server;
345
+ throw err;
346
+ }
347
+ for (const signal of ['SIGINT', 'SIGTERM']) {
348
+ process.once(signal, async function onSignal() {
349
+ logger_1.default.info(`Received ${signal} - shutting down`);
350
+ try {
351
+ await appiumDriver.deleteAllSessions({
352
+ force: true,
353
+ reason: `The process has received ${signal} signal`,
354
+ });
355
+ await server.close();
356
+ process.exit(0);
357
+ }
358
+ catch (e) {
359
+ logger_1.default.warn(e);
360
+ process.exit(1);
361
+ }
362
+ });
363
+ }
364
+ logServerAddress(`http://${parsedArgs.address}:${parsedArgs.port}${parsedArgs.basePath}`);
365
+ driverConfig.print();
366
+ pluginConfig.print([...pluginClasses.values()]);
367
+ return /** @type {Cmd extends ServerCommand ? import('@appium/types').AppiumServer : void} */ (server);
241
368
  }
242
-
369
+ exports.main = main;
370
+ // NOTE: this is here for backwards compat for any scripts referencing `main.js` directly
371
+ // (more specifically, `build/lib/main.js`)
372
+ // the executable is now `../index.js`, so that module will typically be `require.main`.
243
373
  if (require.main === module) {
244
- (0, _asyncbox.asyncify)(main);
245
- }require('source-map-support').install();
246
-
247
-
248
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9tYWluLmpzIl0sIm5hbWVzIjpbInByZWZsaWdodENoZWNrcyIsInBhcnNlciIsImFyZ3MiLCJkcml2ZXJDb25maWciLCJwbHVnaW5Db25maWciLCJ0aHJvd0luc3RlYWRPZkV4aXQiLCJsb25nU3RhY2t0cmFjZSIsInJlcXVpcmUiLCJhc3luY190cmFjZV9saW1pdCIsInNob3dDb25maWciLCJwcm9jZXNzIiwiZXhpdCIsInJlYWQiLCJ0bXBEaXIiLCJlcnIiLCJsb2dnZXIiLCJlcnJvciIsIm1lc3NhZ2UiLCJyZWQiLCJsb2dOb25EZWZhdWx0QXJnc1dhcm5pbmciLCJpbmZvIiwibG9nRGVmYXVsdENhcGFiaWxpdGllc1dhcm5pbmciLCJjYXBzIiwibG9nU3RhcnR1cEluZm8iLCJ3ZWxjb21lIiwiQVBQSVVNX1ZFUiIsImFwcGl1bVJldiIsInNob3dBcmdzIiwiXyIsInNpemUiLCJpc0VtcHR5IiwiZGVmYXVsdENhcGFiaWxpdGllcyIsImxvZ1NlcnZlclBvcnQiLCJhZGRyZXNzIiwicG9ydCIsImxvZ01lc3NhZ2UiLCJtYWluIiwiT2JqZWN0IiwiYXNzaWduIiwicGFyc2VfYXJncyIsInN1YmNvbW1hbmQiLCJEUklWRVJfVFlQRSIsIlBMVUdJTl9UWVBFIiwibG9nRmlsdGVycyIsImlzc3VlcyIsInJ1bGVzIiwibG9nRmFjdG9yeSIsImxvYWRTZWN1cmVWYWx1ZXNQcmVwcm9jZXNzaW5nUnVsZXMiLCJFcnJvciIsIkpTT04iLCJzdHJpbmdpZnkiLCJ3YXJuIiwidXRpbCIsInBsdXJhbGl6ZSIsImxlbmd0aCIsImFwcGl1bURyaXZlciIsIkFwcGl1bURyaXZlciIsIkRyaXZlckNvbmZpZyIsImFwcGl1bUhvbWUiLCJQbHVnaW5Db25maWciLCJyb3V0ZUNvbmZpZ3VyaW5nRnVuY3Rpb24iLCJwbHVnaW5zIiwia2V5cyIsImluc3RhbGxlZEV4dGVuc2lvbnMiLCJmaWx0ZXIiLCJwbHVnaW5OYW1lIiwiaW5jbHVkZXMiLCJVU0VfQUxMX1BMVUdJTlMiLCJtYXAiLCJQbHVnaW5DbGFzcyIsIkJvb2xlYW4iLCJzZXJ2ZXJPcHRzIiwiaG9zdG5hbWUiLCJhbGxvd0NvcnMiLCJiYXNlUGF0aCIsImtlZXBBbGl2ZVRpbWVvdXQiLCJzZXJ2ZXIiLCJub2RlY29uZmlnIiwiY2xvc2UiLCJzaWduYWwiLCJvbmNlIiwib25TaWduYWwiLCJkZWxldGVBbGxTZXNzaW9ucyIsImZvcmNlIiwicmVhc29uIiwiZSIsInByaW50IiwibW9kdWxlIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7QUFHQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFLQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFHQSxlQUFlQSxlQUFmLENBQWdDO0FBQUNDLEVBQUFBLE1BQUQ7QUFBU0MsRUFBQUEsSUFBVDtBQUFlQyxFQUFBQSxZQUFmO0FBQTZCQyxFQUFBQSxZQUE3QjtBQUEyQ0MsRUFBQUEsa0JBQWtCLEdBQUc7QUFBaEUsQ0FBaEMsRUFBd0c7QUFDdEcsTUFBSTtBQUNGOztBQUNBLFFBQUlILElBQUksQ0FBQ0ksY0FBVCxFQUF5QjtBQUN2QkMsTUFBQUEsT0FBTyxDQUFDLFVBQUQsQ0FBUCxDQUFvQkMsaUJBQXBCLEdBQXdDLENBQUMsQ0FBekM7QUFDRDs7QUFDRCxRQUFJTixJQUFJLENBQUNPLFVBQVQsRUFBcUI7QUFDbkIsWUFBTSx5QkFBTjtBQUNBQyxNQUFBQSxPQUFPLENBQUNDLElBQVIsQ0FBYSxDQUFiO0FBQ0Q7O0FBQ0Q7QUFDQSxvQ0FBbUJWLE1BQW5CLEVBQTJCQyxJQUEzQjtBQUNBLFVBQU1DLFlBQVksQ0FBQ1MsSUFBYixFQUFOO0FBQ0EsVUFBTVIsWUFBWSxDQUFDUSxJQUFiLEVBQU47O0FBQ0EsUUFBSVYsSUFBSSxDQUFDVyxNQUFULEVBQWlCO0FBQ2YsWUFBTSw0QkFBZVgsSUFBSSxDQUFDVyxNQUFwQixDQUFOO0FBQ0Q7QUFDRixHQWhCRCxDQWdCRSxPQUFPQyxHQUFQLEVBQVk7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Q2dDLElBQXBCLENBQWI7QUFDQS9CLEVBQUFBLFlBQVksQ0FBQ21GLEtBQWI7QUFDQWxGLEVBQUFBLFlBQVksQ0FBQ2tGLEtBQWIsQ0FBbUJ6QixPQUFuQjtBQUVBLFNBQU9lLE1BQVA7QUFDRDs7QUFFRCxJQUFJckUsT0FBTyxDQUFDNkIsSUFBUixLQUFpQm1ELE1BQXJCLEVBQTZCO0FBQzNCLDBCQUFTbkQsSUFBVDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuLy8gdHJhbnNwaWxlOm1haW5cblxuaW1wb3J0IHsgaW5pdCBhcyBsb2dzaW5rSW5pdCB9IGZyb20gJy4vbG9nc2luayc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vbG9nZ2VyJzsgLy8gbG9nZ2VyIG5lZWRzIHRvIHJlbWFpbiBmaXJzdCBvZiBpbXBvcnRzXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgc2VydmVyIGFzIGJhc2VTZXJ2ZXIsIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiBhcyBtYWtlUm91dGVyIH0gZnJvbSAnYXBwaXVtLWJhc2UtZHJpdmVyJztcbmltcG9ydCB7IGFzeW5jaWZ5IH0gZnJvbSAnYXN5bmNib3gnO1xuaW1wb3J0IHsgZGVmYXVsdCBhcyBnZXRQYXJzZXIsIGdldERlZmF1bHRTZXJ2ZXJBcmdzIH0gZnJvbSAnLi9jbGkvcGFyc2VyJztcbmltcG9ydCB7IFVTRV9BTExfUExVR0lOUyB9IGZyb20gJy4vY2xpL2FyZ3MnO1xuaW1wb3J0IHsgbG9nZ2VyIGFzIGxvZ0ZhY3RvcnksIHV0aWwgfSBmcm9tICdhcHBpdW0tc3VwcG9ydCc7XG5pbXBvcnQge1xuICBzaG93Q29uZmlnLCBjaGVja05vZGVPaywgdmFsaWRhdGVTZXJ2ZXJBcmdzLFxuICB3YXJuTm9kZURlcHJlY2F0aW9ucywgdmFsaWRhdGVUbXBEaXIsIGdldE5vbkRlZmF1bHRBcmdzLFxuICBnZXRHaXRSZXYsIEFQUElVTV9WRVJcbn0gZnJvbSAnLi9jb25maWcnO1xuaW1wb3J0IERyaXZlckNvbmZpZyBmcm9tICcuL2RyaXZlci1jb25maWcnO1xuaW1wb3J0IFBsdWdpbkNvbmZpZyBmcm9tICcuL3BsdWdpbi1jb25maWcnO1xuaW1wb3J0IHsgRFJJVkVSX1RZUEUsIFBMVUdJTl9UWVBFIH0gZnJvbSAnLi9leHRlbnNpb24tY29uZmlnJztcbmltcG9ydCB7IHJ1bkV4dGVuc2lvbkNvbW1hbmQgfSBmcm9tICcuL2NsaS9leHRlbnNpb24nO1xuaW1wb3J0IHsgQXBwaXVtRHJpdmVyIH0gZnJvbSAnLi9hcHBpdW0nO1xuaW1wb3J0IHJlZ2lzdGVyTm9kZSBmcm9tICcuL2dyaWQtcmVnaXN0ZXInO1xuaW1wb3J0IHsgaW5zcGVjdE9iamVjdCB9IGZyb20gJy4vdXRpbHMnO1xuXG5cbmFzeW5jIGZ1bmN0aW9uIHByZWZsaWdodENoZWNrcyAoe3BhcnNlciwgYXJncywgZHJpdmVyQ29uZmlnLCBwbHVnaW5Db25maWcsIHRocm93SW5zdGVhZE9mRXhpdCA9IGZhbHNlfSkge1xuICB0cnkge1xuICAgIGNoZWNrTm9kZU9rKCk7XG4gICAgaWYgKGFyZ3MubG9uZ1N0YWNrdHJhY2UpIHtcbiAgICAgIHJlcXVpcmUoJ2xvbmdqb2huJykuYXN5bmNfdHJhY2VfbGltaXQgPSAtMTtcbiAgICB9XG4gICAgaWYgKGFyZ3Muc2hvd0NvbmZpZykge1xuICAgICAgYXdhaXQgc2hvd0NvbmZpZygpO1xuICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgIH1cbiAgICB3YXJuTm9kZURlcHJlY2F0aW9ucygpO1xuICAgIHZhbGlkYXRlU2VydmVyQXJncyhwYXJzZXIsIGFyZ3MpO1xuICAgIGF3YWl0IGRyaXZlckNvbmZpZy5yZWFkKCk7XG4gICAgYXdhaXQgcGx1Z2luQ29uZmlnLnJlYWQoKTtcbiAgICBpZiAoYXJncy50bXBEaXIpIHtcbiAgICAgIGF3YWl0IHZhbGlkYXRlVG1wRGlyKGFyZ3MudG1wRGlyKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5lcnJvcihlcnIubWVzc2FnZS5yZWQpO1xuICAgIGlmICh0aHJvd0luc3RlYWRPZkV4aXQpIHtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG5cbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9nTm9uRGVmYXVsdEFyZ3NXYXJuaW5nIChhcmdzKSB7XG4gIGxvZ2dlci5pbmZvKCdOb24tZGVmYXVsdCBzZXJ2ZXIgYXJnczonKTtcbiAgaW5zcGVjdE9iamVjdChhcmdzKTtcbn1cblxuZnVuY3Rpb24gbG9nRGVmYXVsdENhcGFiaWxpdGllc1dhcm5pbmcgKGNhcHMpIHtcbiAgbG9nZ2VyLmluZm8oJ0RlZmF1bHQgY2FwYWJpbGl0aWVzLCB3aGljaCB3aWxsIGJlIGFkZGVkIHRvIGVhY2ggcmVxdWVzdCAnICtcbiAgICAgICAgICAgICAgJ3VubGVzcyBvdmVycmlkZGVuIGJ5IGRlc2lyZWQgY2FwYWJpbGl0aWVzOicpO1xuICBpbnNwZWN0T2JqZWN0KGNhcHMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBsb2dTdGFydHVwSW5mbyAocGFyc2VyLCBhcmdzKSB7XG4gIGxldCB3ZWxjb21lID0gYFdlbGNvbWUgdG8gQXBwaXVtIHYke0FQUElVTV9WRVJ9YDtcbiAgbGV0IGFwcGl1bVJldiA9IGF3YWl0IGdldEdpdFJldigpO1xuICBpZiAoYXBwaXVtUmV2KSB7XG4gICAgd2VsY29tZSArPSBgIChSRVYgJHthcHBpdW1SZXZ9KWA7XG4gIH1cbiAgbG9nZ2VyLmluZm8od2VsY29tZSk7XG5cbiAgbGV0IHNob3dBcmdzID0gZ2V0Tm9uRGVmYXVsdEFyZ3MocGFyc2VyLCBhcmdzKTtcbiAgaWYgKF8uc2l6ZShzaG93QXJncykpIHtcbiAgICBsb2dOb25EZWZhdWx0QXJnc1dhcm5pbmcoc2hvd0FyZ3MpO1xuICB9XG4gIGlmICghXy5pc0VtcHR5KGFyZ3MuZGVmYXVsdENhcGFiaWxpdGllcykpIHtcbiAgICBsb2dEZWZhdWx0Q2FwYWJpbGl0aWVzV2FybmluZyhhcmdzLmRlZmF1bHRDYXBhYmlsaXRpZXMpO1xuICB9XG4gIC8vIFRPRE86IGJyaW5nIGJhY2sgbG9nbGV2ZWwgcmVwb3J0aW5nIGJlbG93IG9uY2UgbG9nZ2VyIGlzIGZsdXNoZWQgb3V0XG4gIC8vIGxvZ2dlci5pbmZvKCdDb25zb2xlIExvZ0xldmVsOiAnICsgbG9nZ2VyLnRyYW5zcG9ydHMuY29uc29sZS5sZXZlbCk7XG4gIC8vIGlmIChsb2dnZXIudHJhbnNwb3J0cy5maWxlKSB7XG4gIC8vICAgbG9nZ2VyLmluZm8oJ0ZpbGUgTG9nTGV2ZWw6ICcgKyBsb2dnZXIudHJhbnNwb3J0cy5maWxlLmxldmVsKTtcbiAgLy8gfVxufVxuXG5mdW5jdGlvbiBsb2dTZXJ2ZXJQb3J0IChhZGRyZXNzLCBwb3J0KSB7XG4gIGxldCBsb2dNZXNzYWdlID0gYEFwcGl1bSBSRVNUIGh0dHAgaW50ZXJmYWNlIGxpc3RlbmVyIHN0YXJ0ZWQgb24gYCArXG4gICAgICAgICAgICAgICAgICAgYCR7YWRkcmVzc306JHtwb3J0fWA7XG4gIGxvZ2dlci5pbmZvKGxvZ01lc3NhZ2UpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBtYWluIChhcmdzID0gbnVsbCkge1xuICBsZXQgcGFyc2VyID0gZ2V0UGFyc2VyKCk7XG4gIGxldCB0aHJvd0luc3RlYWRPZkV4aXQgPSBmYWxzZTtcbiAgaWYgKGFyZ3MpIHtcbiAgICAvLyBhIGNvbnRhaW5pbmcgcGFja2FnZSBwYXNzZWQgaW4gdGhlaXIgb3duIGFyZ3MsIGxldCdzIGZpbGwgdGhlbSBvdXRcbiAgICAvLyB3aXRoIGRlZmF1bHRzXG4gICAgYXJncyA9IE9iamVjdC5hc3NpZ24oe30sIGdldERlZmF1bHRTZXJ2ZXJBcmdzKCksIGFyZ3MpO1xuXG4gICAgLy8gaWYgd2UgaGF2ZSBhIGNvbnRhaW5pbmcgcGFja2FnZSBpbnN0ZWFkIG9mIHJ1bm5pbmcgYXMgYSBDTEkgcHJvY2VzcyxcbiAgICAvLyB0aGF0IHBhY2thZ2UgbWlnaHQgbm90IGFwcHJlY2lhdGUgdXMgY2FsbGluZyAncHJvY2Vzcy5leGl0JyB3aWxseS1cbiAgICAvLyBuaWxseSwgc28gZ2l2ZSBpdCB0aGUgb3B0aW9uIHRvIGhhdmUgdXMgdGhyb3cgaW5zdGVhZCBvZiBleGl0XG4gICAgaWYgKGFyZ3MudGhyb3dJbnN0ZWFkT2ZFeGl0KSB7XG4gICAgICB0aHJvd0luc3RlYWRPZkV4aXQgPSB0cnVlO1xuICAgICAgLy8gYnV0IHJlbW92ZSBpdCBzaW5jZSBpdCdzIG5vdCBhIHJlYWwgc2VydmVyIGFyZyBwZXIgc2VcbiAgICAgIGRlbGV0ZSBhcmdzLnRocm93SW5zdGVhZE9mRXhpdDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gb3RoZXJ3aXNlIHBhcnNlIGZyb20gQ0xJXG4gICAgYXJncyA9IHBhcnNlci5wYXJzZV9hcmdzKCk7XG4gIH1cbiAgYXdhaXQgbG9nc2lua0luaXQoYXJncyk7XG5cbiAgLy8gaWYgdGhlIHVzZXIgaGFzIHJlcXVlc3RlZCB0aGUgJ2RyaXZlcicgQ0xJLCBkb24ndCBydW4gdGhlIG5vcm1hbCBzZXJ2ZXIsXG4gIC8vIGJ1dCBpbnN0ZWFkIHBhc3MgY29udHJvbCB0byB0aGUgZHJpdmVyIENMSVxuICBpZiAoYXJncy5zdWJjb21tYW5kID09PSBEUklWRVJfVFlQRSB8fCBhcmdzLnN1YmNvbW1hbmQgPT09IFBMVUdJTl9UWVBFKSB7XG4gICAgYXdhaXQgcnVuRXh0ZW5zaW9uQ29tbWFuZChhcmdzLCBhcmdzLnN1YmNvbW1hbmQpO1xuICAgIHByb2Nlc3MuZXhpdCgpO1xuICB9XG5cbiAgaWYgKGFyZ3MubG9nRmlsdGVycykge1xuICAgIGNvbnN0IHtpc3N1ZXMsIHJ1bGVzfSA9IGF3YWl0IGxvZ0ZhY3RvcnkubG9hZFNlY3VyZVZhbHVlc1ByZXByb2Nlc3NpbmdSdWxlcyhhcmdzLmxvZ0ZpbHRlcnMpO1xuICAgIGlmICghXy5pc0VtcHR5KGlzc3VlcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGxvZyBmaWx0ZXJpbmcgcnVsZXMgY29uZmlnICcke2FyZ3MubG9nRmlsdGVyc30nIGhhcyBpc3N1ZXM6IGAgK1xuICAgICAgICBKU09OLnN0cmluZ2lmeShpc3N1ZXMsIG51bGwsIDIpKTtcbiAgICB9XG4gICAgaWYgKF8uaXNFbXB0eShydWxlcykpIHtcbiAgICAgIGxvZ2dlci53YXJuKGBGb3VuZCBubyBsb2cgZmlsdGVyaW5nIHJ1bGVzIGluICcke2FyZ3MubG9nRmlsdGVyc30nLiBJcyB0aGF0IGV4cGVjdGVkP2ApO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIuaW5mbyhgTG9hZGVkICR7dXRpbC5wbHVyYWxpemUoJ2ZpbHRlcmluZyBydWxlJywgcnVsZXMubGVuZ3RoLCB0cnVlKX0gZnJvbSAnJHthcmdzLmxvZ0ZpbHRlcnN9J2ApO1xuICAgIH1cbiAgfVxuXG4gIGxldCBhcHBpdW1Ecml2ZXIgPSBuZXcgQXBwaXVtRHJpdmVyKGFyZ3MpO1xuICBjb25zdCBkcml2ZXJDb25maWcgPSBuZXcgRHJpdmVyQ29uZmlnKGFyZ3MuYXBwaXVtSG9tZSk7XG4gIGNvbnN0IHBsdWdpbkNvbmZpZyA9IG5ldyBQbHVnaW5Db25maWcoYXJncy5hcHBpdW1Ib21lKTtcbiAgYXBwaXVtRHJpdmVyLmRyaXZlckNvbmZpZyA9IGRyaXZlckNvbmZpZztcbiAgYXdhaXQgcHJlZmxpZ2h0Q2hlY2tzKHtwYXJzZXIsIGFyZ3MsIGRyaXZlckNvbmZpZywgcGx1Z2luQ29uZmlnLCB0aHJvd0luc3RlYWRPZkV4aXR9KTtcbiAgYXdhaXQgbG9nU3RhcnR1cEluZm8ocGFyc2VyLCBhcmdzKTtcbiAgbGV0IHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbiA9IG1ha2VSb3V0ZXIoYXBwaXVtRHJpdmVyKTtcblxuICAvLyBmaW5kIGFueSBwbHVnaW4gbmFtZSB3aGljaCBoYXMgYmVlbiBpbnN0YWxsZWQsIGFuZCB3aGljaCBoYXMgYmVlbiByZXF1ZXN0ZWQgZm9yIGFjdGl2YXRpb24gYnlcbiAgLy8gdXNpbmcgdGhlIC0tcGx1Z2lucyBmbGFnLCBhbmQgdHVybiBlYWNoIG9uZSBpbnRvIGFuIGluc3RhbnRpYXRlZCBwbHVnaW4gb2JqZWN0LCBzbyB3ZSBjYW4gc2VuZFxuICAvLyB0aGVtIGFzIG9iamVjdHMgdG8gdGhlIHNlcnZlciBpbml0LiB3ZSBhbHNvIHdhbnQgdG8gc2VuZC9hc3NpZ24gdGhlbSB0byB0aGUgdW1icmVsbGEgZHJpdmVyIHNvXG4gIC8vIGl0IGNhbiB1c2UgdGhlbSB0byB3cmFwIGNvbW1hbmQgZXhlY3V0aW9uXG4gIGNvbnN0IHBsdWdpbnMgPSBPYmplY3Qua2V5cyhwbHVnaW5Db25maWcuaW5zdGFsbGVkRXh0ZW5zaW9ucykuZmlsdGVyKChwbHVnaW5OYW1lKSA9PlxuICAgIF8uaW5jbHVkZXMoYXJncy5wbHVnaW5zLCBwbHVnaW5OYW1lKSB8fFxuICAgIChhcmdzLnBsdWdpbnMubGVuZ3RoID09PSAxICYmIGFyZ3MucGx1Z2luc1swXSA9PT0gVVNFX0FMTF9QTFVHSU5TKVxuICApLm1hcCgocGx1Z2luTmFtZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBQbHVnaW5DbGFzcyA9IHBsdWdpbkNvbmZpZy5yZXF1aXJlKHBsdWdpbk5hbWUpO1xuICAgICAgcmV0dXJuIG5ldyBQbHVnaW5DbGFzcyhwbHVnaW5OYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgQ291bGQgbm90IGxvYWQgcGx1Z2luICcke3BsdWdpbk5hbWV9Jywgc28gaXQgd2lsbCBub3QgYmUgYXZhaWxhYmxlLiBFcnJvciBgICtcbiAgICAgICAgICAgICAgICAgICBgaW4gbG9hZGluZyB0aGUgcGx1Z2luIHdhczogJHtlcnJ9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KS5maWx0ZXIoQm9vbGVhbik7XG4gIGFwcGl1bURyaXZlci5wbHVnaW5zID0gcGx1Z2lucztcblxuICBjb25zdCBzZXJ2ZXJPcHRzID0ge1xuICAgIHJvdXRlQ29uZmlndXJpbmdGdW5jdGlvbixcbiAgICBwb3J0OiBhcmdzLnBvcnQsXG4gICAgaG9zdG5hbWU6IGFyZ3MuYWRkcmVzcyxcbiAgICBhbGxvd0NvcnM6IGFyZ3MuYWxsb3dDb3JzLFxuICAgIGJhc2VQYXRoOiBhcmdzLmJhc2VQYXRoLFxuICAgIHBsdWdpbnMsXG4gIH07XG4gIGlmIChhcmdzLmtlZXBBbGl2ZVRpbWVvdXQpIHtcbiAgICBzZXJ2ZXJPcHRzLmtlZXBBbGl2ZVRpbWVvdXQgPSBhcmdzLmtlZXBBbGl2ZVRpbWVvdXQgKiAxMDAwO1xuICB9XG4gIGxldCBzZXJ2ZXIgPSBhd2FpdCBiYXNlU2VydmVyKHNlcnZlck9wdHMpO1xuICBpZiAoYXJncy5hbGxvd0NvcnMpIHtcbiAgICBsb2dnZXIud2FybignWW91IGhhdmUgZW5hYmxlZCBDT1JTIHJlcXVlc3RzIGZyb20gYW55IGhvc3QuIEJlIGNhcmVmdWwgbm90ICcgK1xuICAgICAgICAgICAgICAgICd0byB2aXNpdCBzaXRlcyB3aGljaCBjb3VsZCBtYWxpY2lvdXNseSB0cnkgdG8gc3RhcnQgQXBwaXVtICcgK1xuICAgICAgICAgICAgICAgICdzZXNzaW9ucyBvbiB5b3VyIG1hY2hpbmUnKTtcbiAgfVxuICBhcHBpdW1Ecml2ZXIuc2VydmVyID0gc2VydmVyO1xuICB0cnkge1xuICAgIC8vIFRPRE8gcHJlbGF1bmNoIGlmIGFyZ3MubGF1bmNoIGlzIHNldFxuICAgIC8vIFRPRE86IHN0YXJ0QWxlcnRTb2NrZXQoc2VydmVyLCBhcHBpdW1TZXJ2ZXIpO1xuXG4gICAgLy8gY29uZmlndXJlIGFzIG5vZGUgb24gZ3JpZCwgaWYgbmVjZXNzYXJ5XG4gICAgaWYgKGFyZ3Mubm9kZWNvbmZpZyAhPT0gbnVsbCkge1xuICAgICAgYXdhaXQgcmVnaXN0ZXJOb2RlKGFyZ3Mubm9kZWNvbmZpZywgYXJncy5hZGRyZXNzLCBhcmdzLnBvcnQsIGFyZ3MuYmFzZVBhdGgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgdGhyb3cgZXJyO1xuICB9XG5cbiAgZm9yIChjb25zdCBzaWduYWwgb2YgWydTSUdJTlQnLCAnU0lHVEVSTSddKSB7XG4gICAgcHJvY2Vzcy5vbmNlKHNpZ25hbCwgYXN5bmMgZnVuY3Rpb24gb25TaWduYWwgKCkge1xuICAgICAgbG9nZ2VyLmluZm8oYFJlY2VpdmVkICR7c2lnbmFsfSAtIHNodXR0aW5nIGRvd25gKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGFwcGl1bURyaXZlci5kZWxldGVBbGxTZXNzaW9ucyh7XG4gICAgICAgICAgZm9yY2U6IHRydWUsXG4gICAgICAgICAgcmVhc29uOiBgVGhlIHByb2Nlc3MgaGFzIHJlY2VpdmVkICR7c2lnbmFsfSBzaWduYWxgLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oZSk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGxvZ1NlcnZlclBvcnQoYXJncy5hZGRyZXNzLCBhcmdzLnBvcnQpO1xuICBkcml2ZXJDb25maWcucHJpbnQoKTtcbiAgcGx1Z2luQ29uZmlnLnByaW50KHBsdWdpbnMpO1xuXG4gIHJldHVybiBzZXJ2ZXI7XG59XG5cbmlmIChyZXF1aXJlLm1haW4gPT09IG1vZHVsZSkge1xuICBhc3luY2lmeShtYWluKTtcbn1cblxuZXhwb3J0IHsgbWFpbiB9O1xuIl0sImZpbGUiOiJsaWIvbWFpbi5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLiJ9
374
+ (0, asyncbox_1.asyncify)(main);
375
+ }
376
+ // everything below here is intended to be a public API.
377
+ var config_file_2 = require("./config-file");
378
+ Object.defineProperty(exports, "readConfigFile", { enumerable: true, get: function () { return config_file_2.readConfigFile; } });
379
+ var schema_2 = require("./schema/schema");
380
+ Object.defineProperty(exports, "finalizeSchema", { enumerable: true, get: function () { return schema_2.finalizeSchema; } });
381
+ Object.defineProperty(exports, "getSchema", { enumerable: true, get: function () { return schema_2.getSchema; } });
382
+ Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return schema_2.validate; } });
383
+ /**
384
+ * @typedef {import('@appium/types').DriverType} DriverType
385
+ * @typedef {import('@appium/types').PluginType} PluginType
386
+ * @typedef {import('@appium/types').DriverClass} DriverClass
387
+ * @typedef {import('@appium/types').PluginClass} PluginClass
388
+ * @typedef {import('appium/types').CliCommand} CliCommand
389
+ * @typedef {import('appium/types').CliExtensionSubcommand} CliExtensionSubcommand
390
+ * @typedef {import('appium/types').CliExtensionCommand} CliExtensionCommand
391
+ * @typedef {import('appium/types').CliCommandServer} ServerCommand
392
+ * @typedef {import('appium/types').CliCommandDriver} DriverCommand
393
+ * @typedef {import('appium/types').CliCommandPlugin} PluginCommand
394
+ * @typedef {import('./extension').DriverNameMap} DriverNameMap
395
+ * @typedef {import('./extension').PluginNameMap} PluginNameMap
396
+ */
397
+ /**
398
+ * Literally an empty object
399
+ * @typedef { {} } ExtCommandInitResult
400
+ */
401
+ /**
402
+ * @typedef ServerInitData
403
+ * @property {import('./appium').AppiumDriver} appiumDriver - The Appium driver
404
+ * @property {import('appium/types').ParsedArgs} parsedArgs - The parsed arguments
405
+ */
406
+ /**
407
+ * @template {CliCommand} Cmd
408
+ * @typedef {Cmd extends ServerCommand ? ServerInitData & import('./extension').ExtensionConfigs : ExtCommandInitResult} InitResult
409
+ */
410
+ /**
411
+ * @template {CliCommand} [Cmd=ServerCommand]
412
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
413
+ * @typedef {import('appium/types').Args<Cmd, SubCmd>} Args
414
+ */
415
+ /**
416
+ * @template {CliCommand} [Cmd=ServerCommand]
417
+ * @template {CliExtensionSubcommand|void} [SubCmd=void]
418
+ * @typedef {import('appium/types').ParsedArgs<Cmd, SubCmd>} ParsedArgs
419
+ */
420
+ //# sourceMappingURL=main.js.map