appium 2.0.0-beta.33 → 2.0.0-beta.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/appium.d.ts +41 -52
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +32 -15
- package/build/lib/cli/args.d.ts +1 -1
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +1 -1
- package/build/lib/cli/driver-command.d.ts +5 -5
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +8 -8
- package/build/lib/cli/extension-command.d.ts +78 -51
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +135 -80
- package/build/lib/cli/extension.d.ts +9 -5
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +5 -7
- package/build/lib/cli/parser.d.ts +3 -3
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +1 -1
- package/build/lib/cli/plugin-command.d.ts +9 -15
- package/build/lib/cli/plugin-command.d.ts.map +1 -1
- package/build/lib/cli/plugin-command.js +8 -8
- package/build/lib/cli/utils.js +1 -1
- package/build/lib/config-file.d.ts.map +1 -1
- package/build/lib/config-file.js +1 -1
- package/build/lib/config.d.ts +4 -4
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +1 -1
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +1 -1
- package/build/lib/extension/driver-config.d.ts +29 -32
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +7 -20
- package/build/lib/extension/extension-config.d.ts +108 -36
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +199 -60
- package/build/lib/extension/index.d.ts +16 -7
- package/build/lib/extension/index.d.ts.map +1 -1
- package/build/lib/extension/index.js +15 -18
- package/build/lib/extension/manifest.d.ts +12 -12
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +13 -3
- package/build/lib/extension/package-changed.d.ts.map +1 -1
- package/build/lib/extension/package-changed.js +1 -1
- package/build/lib/extension/plugin-config.d.ts +19 -24
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +9 -18
- package/build/lib/grid-register.d.ts.map +1 -1
- package/build/lib/grid-register.js +1 -1
- package/build/lib/logger.d.ts +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +1 -1
- package/build/lib/logsink.d.ts.map +1 -1
- package/build/lib/logsink.js +3 -2
- package/build/lib/main.d.ts +13 -12
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +4 -4
- package/build/lib/schema/arg-spec.d.ts +4 -4
- package/build/lib/schema/arg-spec.d.ts.map +1 -1
- package/build/lib/schema/arg-spec.js +1 -1
- package/build/lib/schema/cli-args.d.ts.map +1 -1
- package/build/lib/schema/cli-args.js +1 -1
- package/build/lib/schema/cli-transformers.d.ts.map +1 -1
- package/build/lib/schema/cli-transformers.js +1 -1
- package/build/lib/schema/index.js +1 -1
- package/build/lib/schema/keywords.d.ts.map +1 -1
- package/build/lib/schema/keywords.js +1 -1
- package/build/lib/schema/schema.d.ts +2 -2
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/appium-manifest.d.ts +23 -4
- package/build/types/appium-manifest.d.ts.map +1 -1
- package/build/types/cli.d.ts.map +1 -1
- package/build/types/{external-manifest.d.ts → extension-manifest.d.ts} +15 -7
- package/build/types/extension-manifest.d.ts.map +1 -0
- package/build/types/index.d.ts +6 -5
- package/build/types/index.d.ts.map +1 -1
- package/driver.d.ts +1 -0
- package/driver.js +14 -0
- package/lib/appium.js +208 -124
- package/lib/cli/args.js +143 -93
- package/lib/cli/driver-command.js +46 -26
- package/lib/cli/extension-command.js +314 -157
- package/lib/cli/extension.js +15 -19
- package/lib/cli/parser.js +19 -31
- package/lib/cli/plugin-command.js +39 -24
- package/lib/cli/utils.js +8 -14
- package/lib/config-file.js +21 -25
- package/lib/config.js +82 -64
- package/lib/constants.js +4 -13
- package/lib/extension/driver-config.js +171 -171
- package/lib/extension/extension-config.js +347 -126
- package/lib/extension/index.js +72 -58
- package/lib/extension/manifest.js +48 -57
- package/lib/extension/package-changed.js +9 -8
- package/lib/extension/plugin-config.js +62 -62
- package/lib/grid-register.js +29 -18
- package/lib/logger.js +1 -2
- package/lib/logsink.js +29 -31
- package/lib/main.js +111 -73
- package/lib/schema/arg-spec.js +10 -13
- package/lib/schema/cli-args.js +14 -37
- package/lib/schema/cli-transformers.js +7 -14
- package/lib/schema/keywords.js +15 -13
- package/lib/schema/schema.js +58 -75
- package/lib/utils.js +50 -25
- package/package.json +27 -20
- package/plugin.d.ts +1 -0
- package/plugin.js +13 -0
- package/scripts/autoinstall-extensions.js +177 -0
- package/support.d.ts +1 -0
- package/support.js +13 -0
- package/types/appium-manifest.ts +27 -15
- package/types/cli.ts +2 -9
- package/types/{external-manifest.ts → extension-manifest.ts} +21 -15
- package/types/index.ts +12 -5
- package/build/types/extension.d.ts +0 -43
- package/build/types/extension.d.ts.map +0 -1
- package/build/types/external-manifest.d.ts.map +0 -1
- package/lib/appium-config.schema.json +0 -278
- package/scripts/postinstall.js +0 -71
- package/types/extension.ts +0 -56
package/lib/cli/extension.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
-
|
|
3
2
|
import DriverCommand from './driver-command';
|
|
4
3
|
import PluginCommand from './plugin-command';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import {DRIVER_TYPE, PLUGIN_TYPE} from '../constants';
|
|
5
|
+
import {errAndQuit, JSON_SPACES} from './utils';
|
|
7
6
|
|
|
8
|
-
const commandClasses = Object.freeze(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
export const commandClasses = Object.freeze(
|
|
8
|
+
/** @type {const} */ ({
|
|
9
|
+
[DRIVER_TYPE]: DriverCommand,
|
|
10
|
+
[PLUGIN_TYPE]: PluginCommand,
|
|
11
|
+
})
|
|
12
|
+
);
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Run a subcommand of the 'appium driver' type. Each subcommand has its own set of arguments which
|
|
@@ -17,13 +18,13 @@ const commandClasses = Object.freeze(/** @type {const} */({
|
|
|
17
18
|
* @param {Object} args - JS object where the key is the parameter name (as defined in
|
|
18
19
|
* driver-parser.js)
|
|
19
20
|
* @template {import('../extension/manifest').ExtensionType} ExtType
|
|
20
|
-
* @param {import('../extension/extension-config').ExtensionConfig<ExtType>}
|
|
21
|
+
* @param {import('../extension/extension-config').ExtensionConfig<ExtType>} config - Extension config object
|
|
21
22
|
*/
|
|
22
|
-
async function runExtensionCommand
|
|
23
|
+
async function runExtensionCommand(args, config) {
|
|
23
24
|
// TODO driver config file should be locked while any of these commands are
|
|
24
25
|
// running to prevent weird situations
|
|
25
26
|
let jsonResult = null;
|
|
26
|
-
const {extensionType: type} =
|
|
27
|
+
const {extensionType: type} = config;
|
|
27
28
|
const extCmd = args[`${type}Command`];
|
|
28
29
|
if (!extCmd) {
|
|
29
30
|
throw new TypeError(`Cannot call ${type} command without a subcommand like 'install'`);
|
|
@@ -32,10 +33,7 @@ async function runExtensionCommand (args, configObject) {
|
|
|
32
33
|
if (suppressOutput) {
|
|
33
34
|
json = true;
|
|
34
35
|
}
|
|
35
|
-
const
|
|
36
|
-
let config = configObject;
|
|
37
|
-
config.log = logFn;
|
|
38
|
-
const CommandClass = /** @type {ExtCommand<ExtType>} */(commandClasses[type]);
|
|
36
|
+
const CommandClass = /** @type {ExtCommand<ExtType>} */ (commandClasses[type]);
|
|
39
37
|
const cmd = new CommandClass({config, json});
|
|
40
38
|
try {
|
|
41
39
|
jsonResult = await cmd.execute(args);
|
|
@@ -55,11 +53,9 @@ async function runExtensionCommand (args, configObject) {
|
|
|
55
53
|
return jsonResult;
|
|
56
54
|
}
|
|
57
55
|
|
|
58
|
-
export {
|
|
59
|
-
runExtensionCommand,
|
|
60
|
-
};
|
|
56
|
+
export {runExtensionCommand};
|
|
61
57
|
|
|
62
58
|
/**
|
|
63
|
-
* @template {import('
|
|
64
|
-
* @typedef {ExtType extends import('
|
|
59
|
+
* @template {import('@appium/types').ExtensionType} ExtType
|
|
60
|
+
* @typedef {ExtType extends import('@appium/types').DriverType ? import('@appium/types').Class<DriverCommand> : ExtType extends import('@appium/types').PluginType ? import('@appium/types').Class<PluginCommand> : never} ExtCommand
|
|
65
61
|
*/
|
package/lib/cli/parser.js
CHANGED
|
@@ -1,30 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { ArgumentParser } from 'argparse';
|
|
1
|
+
import {fs} from '@appium/support';
|
|
2
|
+
import {ArgumentParser} from 'argparse';
|
|
4
3
|
import _ from 'lodash';
|
|
5
4
|
import path from 'path';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
getExtensionArgs,
|
|
11
|
-
getServerArgs
|
|
12
|
-
} from './args';
|
|
5
|
+
import {DRIVER_TYPE, PLUGIN_TYPE, SERVER_SUBCOMMAND} from '../constants';
|
|
6
|
+
import {finalizeSchema, getArgSpec, hasArgSpec} from '../schema';
|
|
7
|
+
import {rootDir} from '../config';
|
|
8
|
+
import {getExtensionArgs, getServerArgs} from './args';
|
|
13
9
|
|
|
14
10
|
/**
|
|
15
11
|
* If the parsed args do not contain any of these values, then we
|
|
16
12
|
* will automatially inject the `server` subcommand.
|
|
17
13
|
*/
|
|
18
14
|
const NON_SERVER_ARGS = Object.freeze(
|
|
19
|
-
new Set([
|
|
20
|
-
DRIVER_TYPE,
|
|
21
|
-
PLUGIN_TYPE,
|
|
22
|
-
SERVER_SUBCOMMAND,
|
|
23
|
-
'-h',
|
|
24
|
-
'--help',
|
|
25
|
-
'-v',
|
|
26
|
-
'--version'
|
|
27
|
-
])
|
|
15
|
+
new Set([DRIVER_TYPE, PLUGIN_TYPE, SERVER_SUBCOMMAND, '-h', '--help', '-v', '--version'])
|
|
28
16
|
);
|
|
29
17
|
|
|
30
18
|
const version = fs.readPackageJsonFrom(rootDir).version;
|
|
@@ -40,7 +28,7 @@ class ArgParser {
|
|
|
40
28
|
/**
|
|
41
29
|
* @param {boolean} [debug] - If true, throw instead of exit on error.
|
|
42
30
|
*/
|
|
43
|
-
constructor
|
|
31
|
+
constructor(debug = false) {
|
|
44
32
|
const prog = process.argv[1] ? path.basename(process.argv[1]) : 'appium';
|
|
45
33
|
const parser = new ArgumentParser({
|
|
46
34
|
add_help: true,
|
|
@@ -99,11 +87,11 @@ class ArgParser {
|
|
|
99
87
|
* If no subcommand is passed in, this method will inject the `server` subcommand.
|
|
100
88
|
*
|
|
101
89
|
* `ArgParser.prototype.parse_args` is an alias of this method.
|
|
102
|
-
* @template [T=import('
|
|
90
|
+
* @template [T=import('appium/types').WithServerSubcommand]
|
|
103
91
|
* @param {string[]} [args] - Array of arguments, ostensibly from `process.argv`. Gathers args from `process.argv` if not provided.
|
|
104
|
-
* @returns {import('
|
|
92
|
+
* @returns {import('appium/types').Args<T>} - The parsed arguments
|
|
105
93
|
*/
|
|
106
|
-
parseArgs
|
|
94
|
+
parseArgs(args = process.argv.slice(2)) {
|
|
107
95
|
if (!NON_SERVER_ARGS.has(args[0])) {
|
|
108
96
|
args.unshift(SERVER_SUBCOMMAND);
|
|
109
97
|
}
|
|
@@ -137,12 +125,12 @@ class ArgParser {
|
|
|
137
125
|
* @param {object} args
|
|
138
126
|
* @returns {object}
|
|
139
127
|
*/
|
|
140
|
-
static _transformParsedArgs
|
|
128
|
+
static _transformParsedArgs(args) {
|
|
141
129
|
return _.reduce(
|
|
142
130
|
args,
|
|
143
131
|
(unpacked, value, key) => {
|
|
144
132
|
if (!_.isUndefined(value) && hasArgSpec(key)) {
|
|
145
|
-
const {dest} = /** @type {import('../schema/arg-spec').ArgSpec} */(getArgSpec(key));
|
|
133
|
+
const {dest} = /** @type {import('../schema/arg-spec').ArgSpec} */ (getArgSpec(key));
|
|
146
134
|
_.set(unpacked, dest, value);
|
|
147
135
|
} else {
|
|
148
136
|
// this could be anything that _isn't_ a server arg
|
|
@@ -150,7 +138,7 @@ class ArgParser {
|
|
|
150
138
|
}
|
|
151
139
|
return unpacked;
|
|
152
140
|
},
|
|
153
|
-
{}
|
|
141
|
+
{}
|
|
154
142
|
);
|
|
155
143
|
}
|
|
156
144
|
|
|
@@ -158,7 +146,7 @@ class ArgParser {
|
|
|
158
146
|
* Patches the `exit()` method of the parser to throw an error, so we can handle it manually.
|
|
159
147
|
* @param {ArgumentParser} parser
|
|
160
148
|
*/
|
|
161
|
-
static _patchExit
|
|
149
|
+
static _patchExit(parser) {
|
|
162
150
|
parser.exit = (code, msg) => {
|
|
163
151
|
if (code) {
|
|
164
152
|
throw new Error(msg);
|
|
@@ -172,7 +160,7 @@ class ArgParser {
|
|
|
172
160
|
* @param {import('argparse').SubParser} subParser
|
|
173
161
|
* @returns {import('./args').ArgumentDefinitions}
|
|
174
162
|
*/
|
|
175
|
-
static _addServerToParser
|
|
163
|
+
static _addServerToParser(subParser) {
|
|
176
164
|
const serverParser = subParser.add_parser('server', {
|
|
177
165
|
add_help: true,
|
|
178
166
|
help: 'Run an Appium server',
|
|
@@ -194,7 +182,7 @@ class ArgParser {
|
|
|
194
182
|
* Adds extension sub-sub-commands to `driver`/`plugin` subcommands
|
|
195
183
|
* @param {import('argparse').SubParser} subParsers
|
|
196
184
|
*/
|
|
197
|
-
static _addExtensionCommandsToParser
|
|
185
|
+
static _addExtensionCommandsToParser(subParsers) {
|
|
198
186
|
for (const type of [DRIVER_TYPE, PLUGIN_TYPE]) {
|
|
199
187
|
const extParser = subParsers.add_parser(type, {
|
|
200
188
|
add_help: true,
|
|
@@ -259,10 +247,10 @@ class ArgParser {
|
|
|
259
247
|
* @param {boolean} [debug] - If `true`, throw instead of exit upon parsing error
|
|
260
248
|
* @returns {ArgParser}
|
|
261
249
|
*/
|
|
262
|
-
function getParser
|
|
250
|
+
function getParser(debug) {
|
|
263
251
|
finalizeSchema();
|
|
264
252
|
|
|
265
253
|
return new ArgParser(debug);
|
|
266
254
|
}
|
|
267
255
|
|
|
268
|
-
export {
|
|
256
|
+
export {getParser, ArgParser};
|
|
@@ -1,56 +1,71 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import ExtensionCommand from './extension-command';
|
|
3
|
-
import {
|
|
3
|
+
import {KNOWN_PLUGINS} from '../constants';
|
|
4
4
|
|
|
5
5
|
const REQ_PLUGIN_FIELDS = ['pluginName', 'mainClass'];
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @extends {ExtensionCommand<PluginType>}
|
|
9
|
+
*/
|
|
7
10
|
export default class PluginCommand extends ExtensionCommand {
|
|
8
|
-
|
|
9
11
|
/**
|
|
10
12
|
*
|
|
11
|
-
* @param {
|
|
13
|
+
* @param {import('./extension-command').ExtensionCommandOptions<PluginType>} opts
|
|
12
14
|
*/
|
|
13
|
-
constructor
|
|
15
|
+
constructor({config, json}) {
|
|
14
16
|
super({config, json});
|
|
15
17
|
this.knownExtensions = KNOWN_PLUGINS;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
async install
|
|
19
|
-
return await super._install({
|
|
20
|
+
async install({plugin, installType, packageName}) {
|
|
21
|
+
return await super._install({
|
|
22
|
+
installSpec: plugin,
|
|
23
|
+
installType,
|
|
24
|
+
packageName,
|
|
25
|
+
});
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
async uninstall
|
|
23
|
-
return await super._uninstall({
|
|
28
|
+
async uninstall({plugin}) {
|
|
29
|
+
return await super._uninstall({installSpec: plugin});
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
async update
|
|
27
|
-
return await super._update({
|
|
32
|
+
async update({plugin, unsafe}) {
|
|
33
|
+
return await super._update({installSpec: plugin, unsafe});
|
|
28
34
|
}
|
|
29
35
|
|
|
30
|
-
async run
|
|
31
|
-
return await super._run({
|
|
36
|
+
async run({plugin, scriptName}) {
|
|
37
|
+
return await super._run({installSpec: plugin, scriptName});
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
getPostInstallText
|
|
40
|
+
getPostInstallText({extName, extData}) {
|
|
35
41
|
return `Plugin ${extName}@${extData.version} successfully installed`.green;
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Validates fields in `appium` field of `driverMetadata`
|
|
46
|
+
*
|
|
47
|
+
* For any `package.json` fields which a driver requires, validate the type of
|
|
48
|
+
* those fields on the `package.json` data, throwing an error if anything is
|
|
49
|
+
* amiss.
|
|
50
|
+
* @param {import('appium/types').ExtMetadata<PluginType>} pluginMetadata
|
|
51
|
+
* @param {string} installSpec
|
|
52
|
+
* @returns {void}
|
|
53
|
+
*/
|
|
54
|
+
validateExtensionFields(pluginMetadata, installSpec) {
|
|
55
|
+
const missingFields = REQ_PLUGIN_FIELDS.reduce(
|
|
56
|
+
(acc, field) => (pluginMetadata[field] ? acc : [...acc, field]),
|
|
57
|
+
[]
|
|
58
|
+
);
|
|
42
59
|
|
|
43
60
|
if (!_.isEmpty(missingFields)) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
|
|
61
|
+
throw new Error(
|
|
62
|
+
`Installed plugin "${installSpec}" did not expose correct fields for compability ` +
|
|
63
|
+
`with Appium. Missing fields: ${JSON.stringify(missingFields)}`
|
|
64
|
+
);
|
|
46
65
|
}
|
|
47
|
-
|
|
48
66
|
}
|
|
49
|
-
|
|
50
67
|
}
|
|
51
68
|
|
|
52
69
|
/**
|
|
53
|
-
* @typedef
|
|
54
|
-
* @property {import('../extension/extension-config').ExtensionConfig<import('../extension/manifest').PluginType>} config
|
|
55
|
-
* @property {boolean} json
|
|
70
|
+
* @typedef {import('@appium/types').PluginType} PluginType
|
|
56
71
|
*/
|
package/lib/cli/utils.js
CHANGED
|
@@ -9,7 +9,7 @@ const JSON_SPACES = 4;
|
|
|
9
9
|
* @param {boolean} json - whether we should log json or text
|
|
10
10
|
* @param {any} msg - error message, object, Error instance, etc.
|
|
11
11
|
*/
|
|
12
|
-
function errAndQuit
|
|
12
|
+
function errAndQuit(json, msg) {
|
|
13
13
|
if (json) {
|
|
14
14
|
console.log(JSON.stringify({error: `${msg}`}, null, JSON_SPACES));
|
|
15
15
|
} else {
|
|
@@ -26,7 +26,7 @@ function errAndQuit (json, msg) {
|
|
|
26
26
|
* @param {boolean} json - whether we are in json mode (and should therefore not log)
|
|
27
27
|
* @param {string} msg - string to log
|
|
28
28
|
*/
|
|
29
|
-
function log
|
|
29
|
+
function log(json, msg) {
|
|
30
30
|
!json && console.log(msg);
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -36,7 +36,7 @@ function log (json, msg) {
|
|
|
36
36
|
* @param {string} msg - string to log
|
|
37
37
|
* @param {function} fn - function to wrap with spinning
|
|
38
38
|
*/
|
|
39
|
-
async function spinWith
|
|
39
|
+
async function spinWith(json, msg, fn) {
|
|
40
40
|
if (json) {
|
|
41
41
|
return await fn();
|
|
42
42
|
}
|
|
@@ -53,17 +53,17 @@ async function spinWith (json, msg, fn) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
class RingBuffer {
|
|
56
|
-
constructor
|
|
56
|
+
constructor(size = 50) {
|
|
57
57
|
this.size = size;
|
|
58
58
|
this.buffer = [];
|
|
59
59
|
}
|
|
60
|
-
getBuff
|
|
60
|
+
getBuff() {
|
|
61
61
|
return this.buffer;
|
|
62
62
|
}
|
|
63
|
-
dequeue
|
|
63
|
+
dequeue() {
|
|
64
64
|
this.buffer.shift();
|
|
65
65
|
}
|
|
66
|
-
enqueue
|
|
66
|
+
enqueue(item) {
|
|
67
67
|
if (this.buffer.length >= this.size) {
|
|
68
68
|
this.dequeue();
|
|
69
69
|
}
|
|
@@ -71,10 +71,4 @@ class RingBuffer {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export {
|
|
75
|
-
errAndQuit,
|
|
76
|
-
log,
|
|
77
|
-
spinWith,
|
|
78
|
-
JSON_SPACES,
|
|
79
|
-
RingBuffer
|
|
80
|
-
};
|
|
74
|
+
export {errAndQuit, log, spinWith, JSON_SPACES, RingBuffer};
|
package/lib/config-file.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
|
|
2
1
|
import betterAjvErrors from '@sidvind/better-ajv-errors';
|
|
3
|
-
import {
|
|
2
|
+
import {lilconfig} from 'lilconfig';
|
|
4
3
|
import _ from 'lodash';
|
|
5
4
|
import yaml from 'yaml';
|
|
6
|
-
import {
|
|
5
|
+
import {getSchema, validate} from './schema/schema';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* lilconfig loader to handle `.yaml` files
|
|
10
9
|
* @type {import('lilconfig').LoaderSync}
|
|
11
10
|
*/
|
|
12
|
-
function yamlLoader
|
|
11
|
+
function yamlLoader(filepath, content) {
|
|
13
12
|
return yaml.parse(content);
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -26,7 +25,7 @@ const rawConfig = new Map();
|
|
|
26
25
|
* If it weren't for this cache, this would be unnecessary.
|
|
27
26
|
* @type {import('lilconfig').LoaderSync}
|
|
28
27
|
*/
|
|
29
|
-
function jsonLoader
|
|
28
|
+
function jsonLoader(filepath, content) {
|
|
30
29
|
rawConfig.set(filepath, content);
|
|
31
30
|
return JSON.parse(content);
|
|
32
31
|
}
|
|
@@ -37,13 +36,15 @@ function jsonLoader (filepath, content) {
|
|
|
37
36
|
* @param {string} filepath - Path to config file
|
|
38
37
|
* @returns {Promise<import('lilconfig').LilconfigResult>}
|
|
39
38
|
*/
|
|
40
|
-
async function loadConfigFile
|
|
39
|
+
async function loadConfigFile(lc, filepath) {
|
|
41
40
|
try {
|
|
42
41
|
// removing "await" will cause any rejection to _not_ be caught in this block!
|
|
43
42
|
return await lc.load(filepath);
|
|
44
|
-
} catch (/** @type {unknown} */err) {
|
|
45
|
-
if (/** @type {NodeJS.ErrnoException} */(err).code === 'ENOENT') {
|
|
46
|
-
/** @type {NodeJS.ErrnoException} */(
|
|
43
|
+
} catch (/** @type {unknown} */ err) {
|
|
44
|
+
if (/** @type {NodeJS.ErrnoException} */ (err).code === 'ENOENT') {
|
|
45
|
+
/** @type {NodeJS.ErrnoException} */ (
|
|
46
|
+
err
|
|
47
|
+
).message = `Config file not found at user-provided path: ${filepath}`;
|
|
47
48
|
throw err;
|
|
48
49
|
} else if (err instanceof SyntaxError) {
|
|
49
50
|
// generally invalid JSON
|
|
@@ -59,7 +60,7 @@ async function loadConfigFile (lc, filepath) {
|
|
|
59
60
|
* @param {LilconfigAsyncSearcher} lc - lilconfig instance
|
|
60
61
|
* @returns {Promise<import('lilconfig').LilconfigResult>}
|
|
61
62
|
*/
|
|
62
|
-
async function searchConfigFile
|
|
63
|
+
async function searchConfigFile(lc) {
|
|
63
64
|
return await lc.search();
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -78,7 +79,7 @@ async function searchConfigFile (lc) {
|
|
|
78
79
|
* @throws {TypeError} If `errors` is empty
|
|
79
80
|
* @returns {string}
|
|
80
81
|
*/
|
|
81
|
-
export function formatErrors
|
|
82
|
+
export function formatErrors(errors = [], config = {}, opts = {}) {
|
|
82
83
|
if (errors && !errors.length) {
|
|
83
84
|
throw new TypeError('Array of errors must be non-empty');
|
|
84
85
|
}
|
|
@@ -97,7 +98,7 @@ export function formatErrors (errors = [], config = {}, opts = {}) {
|
|
|
97
98
|
* @public
|
|
98
99
|
* @returns {Promise<ReadConfigFileResult>} Contains config and filepath, if found, and any errors
|
|
99
100
|
*/
|
|
100
|
-
export async function readConfigFile
|
|
101
|
+
export async function readConfigFile(filepath, opts = {}) {
|
|
101
102
|
const lc = lilconfig('appium', {
|
|
102
103
|
loaders: {
|
|
103
104
|
'.yaml': yamlLoader,
|
|
@@ -105,12 +106,10 @@ export async function readConfigFile (filepath, opts = {}) {
|
|
|
105
106
|
'.json': jsonLoader,
|
|
106
107
|
noExt: jsonLoader,
|
|
107
108
|
},
|
|
108
|
-
packageProp: 'appiumConfig'
|
|
109
|
+
packageProp: 'appiumConfig',
|
|
109
110
|
});
|
|
110
111
|
|
|
111
|
-
const result = filepath
|
|
112
|
-
? await loadConfigFile(lc, filepath)
|
|
113
|
-
: await searchConfigFile(lc);
|
|
112
|
+
const result = filepath ? await loadConfigFile(lc, filepath) : await searchConfigFile(lc);
|
|
114
113
|
|
|
115
114
|
if (result?.filepath && !result?.isEmpty) {
|
|
116
115
|
const {pretty = true} = opts;
|
|
@@ -124,15 +123,11 @@ export async function readConfigFile (filepath, opts = {}) {
|
|
|
124
123
|
json: rawConfig.get(result.filepath),
|
|
125
124
|
pretty,
|
|
126
125
|
});
|
|
127
|
-
configResult = reason
|
|
128
|
-
? {...result, errors, reason}
|
|
129
|
-
: {...result, errors};
|
|
126
|
+
configResult = reason ? {...result, errors, reason} : {...result, errors};
|
|
130
127
|
}
|
|
131
128
|
|
|
132
129
|
// normalize (to camel case) all top-level property names of the config file
|
|
133
|
-
configResult.config = normalizeConfig(
|
|
134
|
-
/** @type {AppiumConfig} */ (configResult.config),
|
|
135
|
-
);
|
|
130
|
+
configResult.config = normalizeConfig(/** @type {AppiumConfig} */ (configResult.config));
|
|
136
131
|
|
|
137
132
|
return configResult;
|
|
138
133
|
} finally {
|
|
@@ -148,7 +143,7 @@ export async function readConfigFile (filepath, opts = {}) {
|
|
|
148
143
|
* @param {AppiumConfig} config - Configuration object
|
|
149
144
|
* @returns {NormalizedAppiumConfig} New object with camel-cased keys (or `dest` keys).
|
|
150
145
|
*/
|
|
151
|
-
export function normalizeConfig
|
|
146
|
+
export function normalizeConfig(config) {
|
|
152
147
|
const schema = getSchema();
|
|
153
148
|
/**
|
|
154
149
|
* @param {AppiumConfig} config
|
|
@@ -159,8 +154,9 @@ export function normalizeConfig (config) {
|
|
|
159
154
|
const normalize = (config, section) => {
|
|
160
155
|
const obj = _.isUndefined(section) ? config : _.get(config, section, config);
|
|
161
156
|
|
|
162
|
-
const mappedObj = _.mapKeys(
|
|
163
|
-
|
|
157
|
+
const mappedObj = _.mapKeys(
|
|
158
|
+
obj,
|
|
159
|
+
(__, prop) => schema.properties[prop]?.appiumCliDest ?? _.camelCase(prop)
|
|
164
160
|
);
|
|
165
161
|
|
|
166
162
|
return _.mapValues(mappedObj, (value, property) => {
|