appium 3.2.2 → 3.3.0
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/cli/args.d.ts +16 -12
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +15 -35
- package/build/lib/cli/args.js.map +1 -1
- package/build/lib/cli/driver-command.d.ts +51 -93
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +11 -66
- package/build/lib/cli/driver-command.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +211 -415
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +384 -653
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts +11 -16
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +10 -28
- package/build/lib/cli/extension.js.map +1 -1
- package/build/lib/cli/parser.d.ts +40 -69
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +24 -59
- package/build/lib/cli/parser.js.map +1 -1
- package/build/lib/cli/plugin-command.d.ts +50 -90
- package/build/lib/cli/plugin-command.d.ts.map +1 -1
- package/build/lib/cli/plugin-command.js +11 -63
- package/build/lib/cli/plugin-command.js.map +1 -1
- package/build/lib/cli/setup-command.d.ts +21 -26
- package/build/lib/cli/setup-command.d.ts.map +1 -1
- package/build/lib/cli/setup-command.js +13 -55
- package/build/lib/cli/setup-command.js.map +1 -1
- package/build/lib/cli/utils.d.ts +27 -29
- package/build/lib/cli/utils.d.ts.map +1 -1
- package/build/lib/cli/utils.js +29 -31
- package/build/lib/cli/utils.js.map +1 -1
- package/build/lib/config-file.d.ts +24 -67
- package/build/lib/config-file.d.ts.map +1 -1
- package/build/lib/config-file.js +56 -115
- package/build/lib/config-file.js.map +1 -1
- package/build/lib/config.d.ts +42 -44
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +75 -107
- package/build/lib/config.js.map +1 -1
- package/build/lib/constants.d.ts +23 -23
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +10 -15
- package/build/lib/constants.js.map +1 -1
- package/build/lib/doctor/doctor.d.ts +40 -57
- package/build/lib/doctor/doctor.d.ts.map +1 -1
- package/build/lib/doctor/doctor.js +29 -60
- package/build/lib/doctor/doctor.js.map +1 -1
- package/build/lib/grid-register.d.ts +32 -7
- package/build/lib/grid-register.d.ts.map +1 -1
- package/build/lib/grid-register.js +84 -48
- package/build/lib/grid-register.js.map +1 -1
- package/build/lib/logsink.d.ts +13 -22
- package/build/lib/logsink.d.ts.map +1 -1
- package/build/lib/logsink.js +48 -103
- package/build/lib/logsink.js.map +1 -1
- package/build/lib/main.js +1 -1
- package/build/lib/main.js.map +1 -1
- package/build/lib/schema/arg-spec.d.ts +32 -107
- package/build/lib/schema/arg-spec.d.ts.map +1 -1
- package/build/lib/schema/arg-spec.js +11 -107
- package/build/lib/schema/arg-spec.js.map +1 -1
- package/build/lib/schema/cli-args.d.ts +3 -15
- package/build/lib/schema/cli-args.d.ts.map +1 -1
- package/build/lib/schema/cli-args.js +15 -105
- package/build/lib/schema/cli-args.js.map +1 -1
- package/build/lib/schema/cli-transformers.d.ts +15 -12
- package/build/lib/schema/cli-transformers.d.ts.map +1 -1
- package/build/lib/schema/cli-transformers.js +15 -45
- package/build/lib/schema/cli-transformers.js.map +1 -1
- package/build/lib/schema/index.d.ts +2 -2
- package/build/lib/schema/index.d.ts.map +1 -1
- package/build/lib/schema/index.js.map +1 -1
- package/build/lib/schema/keywords.d.ts +12 -20
- package/build/lib/schema/keywords.d.ts.map +1 -1
- package/build/lib/schema/keywords.js +6 -51
- package/build/lib/schema/keywords.js.map +1 -1
- package/build/lib/schema/schema.d.ts +106 -231
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +75 -345
- package/build/lib/schema/schema.js.map +1 -1
- package/build/lib/utils.d.ts +59 -238
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +55 -207
- package/build/lib/utils.js.map +1 -1
- package/lib/cli/{args.js → args.ts} +40 -51
- package/lib/cli/driver-command.ts +122 -0
- package/lib/cli/{extension-command.js → extension-command.ts} +610 -689
- package/lib/cli/extension.ts +65 -0
- package/lib/cli/{parser.js → parser.ts} +48 -71
- package/lib/cli/plugin-command.ts +117 -0
- package/lib/cli/{setup-command.js → setup-command.ts} +57 -72
- package/lib/cli/utils.ts +97 -0
- package/lib/config-file.ts +212 -0
- package/lib/{config.js → config.ts} +129 -141
- package/lib/{constants.js → constants.ts} +30 -41
- package/lib/doctor/{doctor.js → doctor.ts} +81 -91
- package/lib/grid-register.ts +250 -0
- package/lib/{logsink.js → logsink.ts} +91 -137
- package/lib/main.js +1 -1
- package/lib/schema/arg-spec.ts +131 -0
- package/lib/schema/cli-args.ts +171 -0
- package/lib/schema/cli-transformers.ts +83 -0
- package/lib/schema/keywords.ts +96 -0
- package/lib/schema/schema.ts +449 -0
- package/lib/utils.ts +404 -0
- package/package.json +16 -16
- package/lib/cli/driver-command.js +0 -174
- package/lib/cli/extension.js +0 -74
- package/lib/cli/plugin-command.js +0 -164
- package/lib/cli/utils.js +0 -91
- package/lib/config-file.js +0 -228
- package/lib/grid-register.js +0 -146
- package/lib/schema/arg-spec.js +0 -229
- package/lib/schema/cli-args.js +0 -254
- package/lib/schema/cli-transformers.js +0 -113
- package/lib/schema/keywords.js +0 -136
- package/lib/schema/schema.js +0 -725
- package/lib/utils.js +0 -512
- /package/lib/schema/{index.js → index.ts} +0 -0
|
@@ -4,36 +4,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.isAllowedSchemaFileExtension = exports.getDefaultsForExtension = exports.getDefaultsForSchema = exports.flattenSchema = exports.getSchema = exports.validate = exports.resetSchema = exports.finalizeSchema = exports.isFinalized = exports.hasArgSpec = exports.getArgSpec = exports.getAllArgSpecs = exports.registerSchema = exports.SchemaUnsupportedSchemaError = exports.SchemaUnknownSchemaError = exports.SchemaNameConflictError = exports.SchemaFinalizationError = exports.ALLOWED_SCHEMA_EXTENSIONS = exports.RoachHotelMap = void 0;
|
|
7
|
-
const ajv_1 = require("ajv");
|
|
7
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
8
8
|
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
9
9
|
const lodash_1 = __importDefault(require("lodash"));
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
-
const constants_1 = require("../constants");
|
|
12
11
|
const schema_1 = require("@appium/schema");
|
|
12
|
+
const constants_1 = require("../constants");
|
|
13
13
|
const arg_spec_1 = require("./arg-spec");
|
|
14
14
|
const keywords_1 = require("./keywords");
|
|
15
15
|
/**
|
|
16
16
|
* Key/value pairs go in... but they don't come out.
|
|
17
|
-
*
|
|
18
|
-
* @template K,V
|
|
19
|
-
* @extends {Map<K,V>}
|
|
20
17
|
*/
|
|
21
18
|
class RoachHotelMap extends Map {
|
|
22
|
-
/**
|
|
23
|
-
* @param {K} key
|
|
24
|
-
* @param {V} value
|
|
25
|
-
*/
|
|
26
19
|
set(key, value) {
|
|
27
20
|
if (this.has(key)) {
|
|
28
|
-
throw new Error(`${key} is already set`);
|
|
21
|
+
throw new Error(`${String(key)} is already set`);
|
|
29
22
|
}
|
|
30
23
|
return super.set(key, value);
|
|
31
24
|
}
|
|
32
|
-
/**
|
|
33
|
-
* @param {K} key
|
|
34
|
-
*/
|
|
35
25
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
36
|
-
delete(
|
|
26
|
+
delete(_key) {
|
|
37
27
|
return false;
|
|
38
28
|
}
|
|
39
29
|
clear() {
|
|
@@ -41,66 +31,22 @@ class RoachHotelMap extends Map {
|
|
|
41
31
|
}
|
|
42
32
|
}
|
|
43
33
|
exports.RoachHotelMap = RoachHotelMap;
|
|
44
|
-
|
|
45
|
-
* Extensions that an extension schema file can have.
|
|
46
|
-
*/
|
|
47
|
-
exports.ALLOWED_SCHEMA_EXTENSIONS = Object.freeze(new Set(/** @type {AllowedSchemaExtension[]} */ (['.json', '.js', '.cjs'])));
|
|
34
|
+
exports.ALLOWED_SCHEMA_EXTENSIONS = Object.freeze(new Set(['.json', '.js', '.cjs']));
|
|
48
35
|
const SCHEMA_KEY = '$schema';
|
|
49
|
-
/**
|
|
50
|
-
* A wrapper around Ajv and schema-related functions.
|
|
51
|
-
*
|
|
52
|
-
* Should have been named Highlander, because _there can only be one_
|
|
53
|
-
*/
|
|
54
36
|
class AppiumSchema {
|
|
55
|
-
/**
|
|
56
|
-
* A mapping of unique argument IDs to their corresponding {@link ArgSpec}s.
|
|
57
|
-
*
|
|
58
|
-
* An "argument" is a CLI argument or a config property.
|
|
59
|
-
*
|
|
60
|
-
* Used to provide easy lookups of argument metadata when converting between different representations of those arguments.
|
|
61
|
-
* @type {RoachHotelMap<string,ArgSpec>}
|
|
62
|
-
*/
|
|
63
37
|
#argSpecs = new RoachHotelMap();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
* are stored here in memory until the instance is _finalized_.
|
|
69
|
-
* @type {Record<ExtensionType,Map<string,SchemaObject>>}
|
|
70
|
-
*/
|
|
71
|
-
#registeredSchemas = { [constants_1.DRIVER_TYPE]: new Map(), [constants_1.PLUGIN_TYPE]: new Map() };
|
|
72
|
-
/**
|
|
73
|
-
* Ajv instance
|
|
74
|
-
*
|
|
75
|
-
* @type {Ajv}
|
|
76
|
-
*/
|
|
38
|
+
#registeredSchemas = {
|
|
39
|
+
[constants_1.DRIVER_TYPE]: new Map(),
|
|
40
|
+
[constants_1.PLUGIN_TYPE]: new Map(),
|
|
41
|
+
};
|
|
77
42
|
#ajv;
|
|
78
|
-
/**
|
|
79
|
-
* Singleton instance.
|
|
80
|
-
* @type {AppiumSchema}
|
|
81
|
-
*/
|
|
82
43
|
static #instance;
|
|
83
|
-
/**
|
|
84
|
-
* Lookup of schema IDs to finalized schemas.
|
|
85
|
-
*
|
|
86
|
-
* This does not include references, but rather the root schemas themselves.
|
|
87
|
-
* @type {Record<string,StrictSchemaObject>?}
|
|
88
|
-
*/
|
|
89
44
|
#finalizedSchemas = null;
|
|
90
|
-
/**
|
|
91
|
-
* Initializes Ajv, adds standard formats and our custom keywords.
|
|
92
|
-
* @see https://npm.im/ajv-formats
|
|
93
|
-
* @private
|
|
94
|
-
*/
|
|
95
45
|
constructor() {
|
|
96
46
|
this.#ajv = AppiumSchema._instantiateAjv();
|
|
97
47
|
}
|
|
98
48
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* Returns a singleton instance if one exists, otherwise creates a new one.
|
|
102
|
-
* Binds public methods to the instance.
|
|
103
|
-
* @returns {AppiumSchema}
|
|
49
|
+
* Returns a singleton instance.
|
|
104
50
|
*/
|
|
105
51
|
static create() {
|
|
106
52
|
if (!AppiumSchema.#instance) {
|
|
@@ -125,97 +71,57 @@ class AppiumSchema {
|
|
|
125
71
|
return AppiumSchema.#instance;
|
|
126
72
|
}
|
|
127
73
|
/**
|
|
128
|
-
* Returns `true` if a schema has been registered
|
|
129
|
-
*
|
|
130
|
-
* This does not depend on whether or not the instance has been _finalized_.
|
|
131
|
-
* @param {ExtensionType} extType - Extension type
|
|
132
|
-
* @param {string} extName - Name
|
|
133
|
-
* @returns {boolean} If registered
|
|
74
|
+
* Returns `true` if a schema has been registered for extension type/name.
|
|
134
75
|
*/
|
|
135
76
|
hasRegisteredSchema(extType, extName) {
|
|
136
77
|
return this.#registeredSchemas[extType].has(extName);
|
|
137
78
|
}
|
|
138
79
|
/**
|
|
139
|
-
*
|
|
140
|
-
* successfully and {@link AppiumSchema.reset reset} has not been called since.
|
|
141
|
-
* @returns {boolean} If finalized
|
|
80
|
+
* Returns `true` if this instance has been finalized.
|
|
142
81
|
*/
|
|
143
82
|
isFinalized() {
|
|
144
83
|
return Boolean(this.#finalizedSchemas);
|
|
145
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns map of known argument specs.
|
|
87
|
+
*/
|
|
146
88
|
getAllArgSpecs() {
|
|
147
89
|
return this.#argSpecs;
|
|
148
90
|
}
|
|
149
91
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* This does three things:
|
|
153
|
-
* 1. It combines all schemas from extensions into the Appium config schema,
|
|
154
|
-
* then adds the result to the `Ajv` instance.
|
|
155
|
-
* 2. It adds schemas for _each_ argument/property for validation purposes.
|
|
156
|
-
* The CLI uses these schemas to validate specific arguments.
|
|
157
|
-
* 3. The schemas are validated against JSON schema draft-07 (which is the
|
|
158
|
-
* only one supported at this time)
|
|
159
|
-
*
|
|
160
|
-
* Any method in this instance that needs to interact with the `Ajv` instance
|
|
161
|
-
* will throw if this method has not been called.
|
|
162
|
-
*
|
|
163
|
-
* If the instance has already been finalized, this is a no-op.
|
|
164
|
-
* @public
|
|
165
|
-
* @throws {Error} If the schema is not valid
|
|
166
|
-
* @returns {Readonly<Record<string,StrictSchemaObject>>} Record of schema IDs to full schema objects
|
|
92
|
+
* Finalizes all registered schemas into Ajv and generates arg-spec lookups.
|
|
167
93
|
*/
|
|
168
94
|
finalize() {
|
|
169
95
|
if (this.isFinalized()) {
|
|
170
|
-
return
|
|
96
|
+
return this.#finalizedSchemas;
|
|
171
97
|
}
|
|
172
98
|
const ajv = this.#ajv;
|
|
173
|
-
// Ajv will _mutate_ the schema, so we need to clone it.
|
|
174
99
|
const baseSchema = lodash_1.default.cloneDeep(schema_1.AppiumConfigJsonSchema);
|
|
175
|
-
/**
|
|
176
|
-
*
|
|
177
|
-
* @param {SchemaObject} schema
|
|
178
|
-
* @param {ExtensionType} [extType]
|
|
179
|
-
* @param {string} [extName]
|
|
180
|
-
*/
|
|
181
100
|
const addArgSpecs = (schema, extType, extName) => {
|
|
182
|
-
for (
|
|
101
|
+
for (const [propName, propSchema] of Object.entries(schema)) {
|
|
183
102
|
const argSpec = arg_spec_1.ArgSpec.create(propName, {
|
|
184
103
|
dest: propSchema.appiumCliDest,
|
|
185
104
|
defaultValue: propSchema.default,
|
|
186
105
|
extType,
|
|
187
106
|
extName,
|
|
188
107
|
});
|
|
189
|
-
|
|
190
|
-
this.#argSpecs.set(arg, argSpec);
|
|
108
|
+
this.#argSpecs.set(argSpec.arg, argSpec);
|
|
191
109
|
}
|
|
192
110
|
};
|
|
193
111
|
addArgSpecs(lodash_1.default.omit(baseSchema.properties.server.properties, [constants_1.DRIVER_TYPE, constants_1.PLUGIN_TYPE]));
|
|
194
|
-
/**
|
|
195
|
-
* @type {Record<string,StrictSchemaObject>}
|
|
196
|
-
*/
|
|
197
112
|
const finalizedSchemas = {};
|
|
198
|
-
const finalSchema = lodash_1.default.reduce(this.#registeredSchemas,
|
|
199
|
-
/**
|
|
200
|
-
* @param {typeof baseSchema} baseSchema
|
|
201
|
-
* @param {Map<string,SchemaObject>} extensionSchemas
|
|
202
|
-
* @param {ExtensionType} extType
|
|
203
|
-
*/
|
|
204
|
-
(baseSchema, extensionSchemas, extType) => {
|
|
113
|
+
const finalSchema = lodash_1.default.reduce(this.#registeredSchemas, (base, extensionSchemas, extType) => {
|
|
205
114
|
extensionSchemas.forEach((schema, extName) => {
|
|
206
115
|
const $ref = arg_spec_1.ArgSpec.toSchemaBaseRef(extType, extName);
|
|
207
116
|
schema.$id = $ref;
|
|
208
|
-
schema.additionalProperties = false;
|
|
209
|
-
|
|
210
|
-
$ref,
|
|
211
|
-
$comment: extName,
|
|
212
|
-
};
|
|
117
|
+
schema.additionalProperties = false;
|
|
118
|
+
base.properties.server.properties[extType].properties[extName] = { $ref, $comment: extName };
|
|
213
119
|
ajv.validateSchema(schema, true);
|
|
214
120
|
addArgSpecs(schema.properties, extType, extName);
|
|
215
121
|
ajv.addSchema(schema, $ref);
|
|
216
|
-
finalizedSchemas[$ref] =
|
|
122
|
+
finalizedSchemas[$ref] = schema;
|
|
217
123
|
});
|
|
218
|
-
return
|
|
124
|
+
return base;
|
|
219
125
|
}, baseSchema);
|
|
220
126
|
ajv.addSchema(finalSchema, arg_spec_1.APPIUM_CONFIG_SCHEMA_ID);
|
|
221
127
|
finalizedSchemas[arg_spec_1.APPIUM_CONFIG_SCHEMA_ID] = finalSchema;
|
|
@@ -224,56 +130,19 @@ class AppiumSchema {
|
|
|
224
130
|
return Object.freeze(finalizedSchemas);
|
|
225
131
|
}
|
|
226
132
|
/**
|
|
227
|
-
*
|
|
228
|
-
* @private
|
|
229
|
-
* @returns {Ajv}
|
|
230
|
-
*/
|
|
231
|
-
static _instantiateAjv() {
|
|
232
|
-
const ajv = (0, ajv_formats_1.default)(new ajv_1.Ajv({
|
|
233
|
-
// without this not much validation actually happens
|
|
234
|
-
allErrors: true,
|
|
235
|
-
}));
|
|
236
|
-
// add custom keywords to ajv. see schema-keywords.js
|
|
237
|
-
lodash_1.default.forEach(keywords_1.keywords, (keyword) => {
|
|
238
|
-
ajv.addKeyword(keyword);
|
|
239
|
-
});
|
|
240
|
-
return ajv;
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Resets this instance to its original state.
|
|
244
|
-
*
|
|
245
|
-
* - Removes all added schemas from the `Ajv` instance
|
|
246
|
-
* - Resets the map of {@link ArgSpec ArgSpecs}
|
|
247
|
-
* - Resets the map of registered schemas
|
|
248
|
-
* - Sets the {@link AppiumSchema._finalized _finalized} flag to `false`
|
|
249
|
-
*
|
|
250
|
-
* If you need to call {@link AppiumSchema.finalize} again, you'll want to call this first.
|
|
251
|
-
* @returns {void}
|
|
133
|
+
* Resets this instance to initial state.
|
|
252
134
|
*/
|
|
253
135
|
reset() {
|
|
254
136
|
for (const schemaId of Object.keys(this.#finalizedSchemas ?? {})) {
|
|
255
137
|
this.#ajv.removeSchema(schemaId);
|
|
256
138
|
}
|
|
257
139
|
this.#argSpecs = new RoachHotelMap();
|
|
258
|
-
this.#registeredSchemas = {
|
|
259
|
-
[constants_1.DRIVER_TYPE]: new Map(),
|
|
260
|
-
[constants_1.PLUGIN_TYPE]: new Map(),
|
|
261
|
-
};
|
|
140
|
+
this.#registeredSchemas = { [constants_1.DRIVER_TYPE]: new Map(), [constants_1.PLUGIN_TYPE]: new Map() };
|
|
262
141
|
this.#finalizedSchemas = null;
|
|
263
|
-
// Ajv seems to have an over-eager cache, so we have to dump the object entirely.
|
|
264
142
|
this.#ajv = AppiumSchema._instantiateAjv();
|
|
265
143
|
}
|
|
266
144
|
/**
|
|
267
|
-
* Registers
|
|
268
|
-
*
|
|
269
|
-
* This is "fail-fast" in that the schema will immediately be validated against JSON schema draft-07 _or_ whatever the value of the schema's `$schema` prop is.
|
|
270
|
-
*
|
|
271
|
-
* Does _not_ add the schema to the `ajv` instance (this is done by {@link AppiumSchema.finalize}).
|
|
272
|
-
* @param {ExtensionType} extType - Extension type
|
|
273
|
-
* @param {string} extName - Unique extension name for `type`
|
|
274
|
-
* @param {SchemaObject} schema - Schema object
|
|
275
|
-
* @throws {SchemaNameConflictError} If the schema is an invalid
|
|
276
|
-
* @returns {void}
|
|
145
|
+
* Registers an extension schema.
|
|
277
146
|
*/
|
|
278
147
|
registerSchema(extType, extName, schema) {
|
|
279
148
|
if (!(extType && extName) || lodash_1.default.isUndefined(schema)) {
|
|
@@ -293,49 +162,24 @@ class AppiumSchema {
|
|
|
293
162
|
this.#registeredSchemas[extType].set(normalizedExtName, schema);
|
|
294
163
|
}
|
|
295
164
|
/**
|
|
296
|
-
* Returns
|
|
297
|
-
* @param {string} name - CLI argument name
|
|
298
|
-
* @param {ExtensionType} [extType] - Extension type
|
|
299
|
-
* @param {string} [extName] - Extension name
|
|
300
|
-
* @returns {ArgSpec|undefined} ArgSpec or `undefined` if not found
|
|
165
|
+
* Returns an `ArgSpec` for argument name/ext context, if present.
|
|
301
166
|
*/
|
|
302
167
|
getArgSpec(name, extType, extName) {
|
|
303
168
|
return this.#argSpecs.get(arg_spec_1.ArgSpec.toArg(name, extType, extName));
|
|
304
169
|
}
|
|
305
170
|
/**
|
|
306
|
-
* Returns `true` if
|
|
307
|
-
* @param {string} name - CLI argument name
|
|
308
|
-
* @param {ExtensionType} [extType] - Extension type
|
|
309
|
-
* @param {string} [extName] - Extension name
|
|
310
|
-
* @returns {boolean} `true` if such an {@link ArgSpec} exists
|
|
171
|
+
* Returns `true` if an `ArgSpec` exists for argument name/ext context.
|
|
311
172
|
*/
|
|
312
173
|
hasArgSpec(name, extType, extName) {
|
|
313
174
|
return this.#argSpecs.has(arg_spec_1.ArgSpec.toArg(name, extType, extName));
|
|
314
175
|
}
|
|
315
176
|
/**
|
|
316
|
-
* Returns
|
|
317
|
-
*
|
|
318
|
-
* The "dest" string is the property name in object returned by
|
|
319
|
-
* `argparse.ArgumentParser['parse_args']`.
|
|
320
|
-
* @template {boolean|undefined} Flattened
|
|
321
|
-
* @param {Flattened} [flatten=true] - If `true`, flattens the returned object
|
|
322
|
-
* using "keypath"-style keys of the format `<extType>.<extName>.<argName>`.
|
|
323
|
-
* Otherwise, returns a nested object using `extType` and `extName` as
|
|
324
|
-
* properties. Base arguments (server arguments) are always at the top level.
|
|
325
|
-
* @returns {DefaultValues<Flattened>}
|
|
177
|
+
* Returns default values for all args, flattened or nested.
|
|
326
178
|
*/
|
|
327
|
-
getDefaults(flatten =
|
|
179
|
+
getDefaults(flatten = true) {
|
|
328
180
|
if (!this.isFinalized()) {
|
|
329
181
|
throw new SchemaFinalizationError();
|
|
330
182
|
}
|
|
331
|
-
/**
|
|
332
|
-
* @private
|
|
333
|
-
* @callback DefaultReducer
|
|
334
|
-
* @param {DefaultValues<Flattened>} defaults
|
|
335
|
-
* @param {ArgSpec} argSpec
|
|
336
|
-
* @returns {DefaultValues<Flattened>}
|
|
337
|
-
*/
|
|
338
|
-
/** @type {DefaultReducer} */
|
|
339
183
|
const reducer = flatten
|
|
340
184
|
? (defaults, { defaultValue, dest }) => {
|
|
341
185
|
if (!lodash_1.default.isUndefined(defaultValue)) {
|
|
@@ -349,16 +193,11 @@ class AppiumSchema {
|
|
|
349
193
|
}
|
|
350
194
|
return defaults;
|
|
351
195
|
};
|
|
352
|
-
/** @type {DefaultValues<Flattened>} */
|
|
353
196
|
const retval = {};
|
|
354
197
|
return [...this.#argSpecs.values()].reduce(reducer, retval);
|
|
355
198
|
}
|
|
356
199
|
/**
|
|
357
|
-
* Returns
|
|
358
|
-
* be of format `<argName>`.
|
|
359
|
-
* @param {ExtensionType} extType - Extension type
|
|
360
|
-
* @param {string} extName - Extension name
|
|
361
|
-
* @returns {Record<string,ArgSpecDefaultValue>}
|
|
200
|
+
* Returns flattened defaults for a specific extension.
|
|
362
201
|
*/
|
|
363
202
|
getDefaultsForExtension(extType, extName) {
|
|
364
203
|
if (!this.isFinalized()) {
|
|
@@ -373,27 +212,14 @@ class AppiumSchema {
|
|
|
373
212
|
}, {});
|
|
374
213
|
}
|
|
375
214
|
/**
|
|
376
|
-
*
|
|
377
|
-
* {@link ArgSpec ArgSpecs}.
|
|
378
|
-
*
|
|
379
|
-
* Converts nested extension schemas to keys based on the extension type and
|
|
380
|
-
* name. Used when translating to `argparse` options or getting the list of
|
|
381
|
-
* default values (see {@link AppiumSchema.getDefaults}) for CLI or otherwise.
|
|
382
|
-
*
|
|
383
|
-
* The return value is an intermediate representation used by `cli-args`
|
|
384
|
-
* module's `toParserArgs`, which converts the finalized schema to parameters
|
|
385
|
-
* used by `argparse`.
|
|
386
|
-
* @throws If {@link AppiumSchema.finalize} has not been called yet.
|
|
387
|
-
* @returns {FlattenedSchema}
|
|
215
|
+
* Flattens finalized schemas into schema + argSpec tuples.
|
|
388
216
|
*/
|
|
389
217
|
flatten() {
|
|
390
218
|
const schema = this.getSchema();
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
219
|
+
const stack = [
|
|
220
|
+
{ properties: schema.properties, prefix: [] },
|
|
221
|
+
];
|
|
394
222
|
const flattened = [];
|
|
395
|
-
// this bit is a recursive algorithm rewritten as a for loop.
|
|
396
|
-
// when we find something we want to traverse, we add it to `stack`
|
|
397
223
|
for (const { properties, prefix } of stack) {
|
|
398
224
|
const pairs = lodash_1.default.toPairs(properties);
|
|
399
225
|
for (const [key, value] of pairs) {
|
|
@@ -402,10 +228,7 @@ class AppiumSchema {
|
|
|
402
228
|
}
|
|
403
229
|
const { properties, $ref } = value;
|
|
404
230
|
if (properties) {
|
|
405
|
-
stack.push({
|
|
406
|
-
properties,
|
|
407
|
-
prefix: key === arg_spec_1.SERVER_PROP_NAME ? [] : [...prefix, key],
|
|
408
|
-
});
|
|
231
|
+
stack.push({ properties, prefix: key === arg_spec_1.SERVER_PROP_NAME ? [] : [...prefix, key] });
|
|
409
232
|
}
|
|
410
233
|
else if ($ref) {
|
|
411
234
|
let refSchema;
|
|
@@ -413,24 +236,18 @@ class AppiumSchema {
|
|
|
413
236
|
refSchema = this.getSchema($ref);
|
|
414
237
|
}
|
|
415
238
|
catch {
|
|
416
|
-
// this can happen if an extension schema supplies a $ref to a non-existent schema
|
|
417
239
|
throw new SchemaUnknownSchemaError($ref);
|
|
418
240
|
}
|
|
419
241
|
const { normalizedExtName } = arg_spec_1.ArgSpec.extensionInfoFromRootSchemaId($ref);
|
|
420
242
|
if (!normalizedExtName) {
|
|
421
|
-
/* istanbul ignore next */
|
|
422
243
|
throw new ReferenceError(`Could not determine extension name from schema ID ${$ref}. This is a bug.`);
|
|
423
244
|
}
|
|
424
|
-
stack.push({
|
|
425
|
-
properties: refSchema.properties,
|
|
426
|
-
prefix: [...prefix, key, normalizedExtName],
|
|
427
|
-
});
|
|
245
|
+
stack.push({ properties: refSchema.properties, prefix: [...prefix, key, normalizedExtName] });
|
|
428
246
|
}
|
|
429
247
|
else if (key !== constants_1.DRIVER_TYPE && key !== constants_1.PLUGIN_TYPE) {
|
|
430
248
|
const [extType, extName] = prefix;
|
|
431
|
-
const argSpec = this.getArgSpec(key,
|
|
249
|
+
const argSpec = this.getArgSpec(key, extType, extName);
|
|
432
250
|
if (!argSpec) {
|
|
433
|
-
/* istanbul ignore next */
|
|
434
251
|
throw new ReferenceError(`Unknown argument with key ${key}, extType ${extType} and extName ${extName}. This is a bug.`);
|
|
435
252
|
}
|
|
436
253
|
flattened.push({ schema: lodash_1.default.cloneDeep(value), argSpec });
|
|
@@ -440,71 +257,58 @@ class AppiumSchema {
|
|
|
440
257
|
return flattened;
|
|
441
258
|
}
|
|
442
259
|
/**
|
|
443
|
-
*
|
|
444
|
-
* @public
|
|
445
|
-
* @param {string} [ref] - Schema ID
|
|
446
|
-
* @throws If the schema has not yet been finalized
|
|
447
|
-
* @returns {SchemaObject}
|
|
260
|
+
* Returns schema by ID (default: base Appium schema).
|
|
448
261
|
*/
|
|
449
262
|
getSchema(ref = arg_spec_1.APPIUM_CONFIG_SCHEMA_ID) {
|
|
450
|
-
return
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Retrieves schema validator function from Ajv
|
|
454
|
-
* @param {string} [id] - Schema ID
|
|
455
|
-
* @private
|
|
456
|
-
* @returns {import('ajv').ValidateFunction}
|
|
457
|
-
*/
|
|
458
|
-
_getValidator(id = arg_spec_1.APPIUM_CONFIG_SCHEMA_ID) {
|
|
459
|
-
const validator = this.#ajv.getSchema(id);
|
|
460
|
-
if (!validator) {
|
|
461
|
-
if (id === arg_spec_1.APPIUM_CONFIG_SCHEMA_ID) {
|
|
462
|
-
throw new SchemaFinalizationError();
|
|
463
|
-
}
|
|
464
|
-
else {
|
|
465
|
-
throw new SchemaUnknownSchemaError(id);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
return validator;
|
|
263
|
+
return this._getValidator(ref).schema;
|
|
469
264
|
}
|
|
470
265
|
/**
|
|
471
|
-
*
|
|
472
|
-
* If errors occur, the returned array will be non-empty.
|
|
473
|
-
* @param {any} value - The value (hopefully an object) to validate against the schema
|
|
474
|
-
* @param {string} [ref] - Schema ID or ref.
|
|
475
|
-
* @public
|
|
476
|
-
* @returns {import('ajv').ErrorObject[]} Array of errors, if any.
|
|
266
|
+
* Validates a value against schema by ID/reference.
|
|
477
267
|
*/
|
|
478
268
|
validate(value, ref = arg_spec_1.APPIUM_CONFIG_SCHEMA_ID) {
|
|
479
269
|
const validator = this._getValidator(ref);
|
|
480
270
|
return !validator(value) && lodash_1.default.isArray(validator.errors) ? [...validator.errors] : [];
|
|
481
271
|
}
|
|
482
272
|
/**
|
|
483
|
-
* Returns `true` if
|
|
484
|
-
* @param {import('type-fest').LiteralUnion<AllowedSchemaExtension, string>} filename
|
|
485
|
-
* @returns {boolean}
|
|
273
|
+
* Returns `true` if filename extension is an allowed schema extension.
|
|
486
274
|
*/
|
|
487
275
|
static isAllowedSchemaFileExtension(filename) {
|
|
488
|
-
return exports.ALLOWED_SCHEMA_EXTENSIONS.has(
|
|
489
|
-
/** @type {AllowedSchemaExtension} */ (node_path_1.default.extname(filename)));
|
|
276
|
+
return exports.ALLOWED_SCHEMA_EXTENSIONS.has(node_path_1.default.extname(filename));
|
|
490
277
|
}
|
|
491
278
|
/**
|
|
492
|
-
* Returns `true` if
|
|
493
|
-
* @param {any} schema - Schema to check
|
|
494
|
-
* @returns {schema is SchemaObject}
|
|
279
|
+
* Returns `true` if schema is a plain object and not async.
|
|
495
280
|
*/
|
|
496
281
|
static isSupportedSchemaType(schema) {
|
|
497
282
|
return lodash_1.default.isPlainObject(schema) && schema.$async !== true;
|
|
498
283
|
}
|
|
499
|
-
}
|
|
500
|
-
/**
|
|
501
|
-
* Thrown when the {@link AppiumSchema} instance has not yet been finalized, but
|
|
502
|
-
* the method called requires it.
|
|
503
|
-
*/
|
|
504
|
-
class SchemaFinalizationError extends Error {
|
|
505
284
|
/**
|
|
506
|
-
*
|
|
285
|
+
* Configures and creates an Ajv instance.
|
|
286
|
+
*/
|
|
287
|
+
static _instantiateAjv() {
|
|
288
|
+
const ajv = (0, ajv_formats_1.default)(new ajv_1.default({
|
|
289
|
+
// without this not much validation actually happens
|
|
290
|
+
allErrors: true,
|
|
291
|
+
}));
|
|
292
|
+
lodash_1.default.forEach(keywords_1.keywords, (keyword) => {
|
|
293
|
+
ajv.addKeyword(keyword);
|
|
294
|
+
});
|
|
295
|
+
return ajv;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Retrieves schema validator function from Ajv.
|
|
507
299
|
*/
|
|
300
|
+
_getValidator(id = arg_spec_1.APPIUM_CONFIG_SCHEMA_ID) {
|
|
301
|
+
const validator = this.#ajv.getSchema(id);
|
|
302
|
+
if (!validator) {
|
|
303
|
+
if (id === arg_spec_1.APPIUM_CONFIG_SCHEMA_ID) {
|
|
304
|
+
throw new SchemaFinalizationError();
|
|
305
|
+
}
|
|
306
|
+
throw new SchemaUnknownSchemaError(id);
|
|
307
|
+
}
|
|
308
|
+
return validator;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
class SchemaFinalizationError extends Error {
|
|
508
312
|
code = 'APPIUMERR_SCHEMA_FINALIZATION';
|
|
509
313
|
constructor() {
|
|
510
314
|
super('Schema not yet finalized; `finalize()` must be called first.');
|
|
@@ -512,23 +316,11 @@ class SchemaFinalizationError extends Error {
|
|
|
512
316
|
}
|
|
513
317
|
exports.SchemaFinalizationError = SchemaFinalizationError;
|
|
514
318
|
/**
|
|
515
|
-
* Thrown when a
|
|
516
|
-
*
|
|
517
|
-
* This is likely going to be caused by attempting to register the same schema twice.
|
|
319
|
+
* Thrown when a unique extension schema name conflicts with an existing one.
|
|
518
320
|
*/
|
|
519
321
|
class SchemaNameConflictError extends Error {
|
|
520
|
-
/**
|
|
521
|
-
* @type {Readonly<string>}
|
|
522
|
-
*/
|
|
523
322
|
code = 'APPIUMERR_SCHEMA_NAME_CONFLICT';
|
|
524
|
-
/**
|
|
525
|
-
* @type {Readonly<{extType: ExtensionType, extName: string}>}
|
|
526
|
-
*/
|
|
527
323
|
data;
|
|
528
|
-
/**
|
|
529
|
-
* @param {ExtensionType} extType
|
|
530
|
-
* @param {string} extName
|
|
531
|
-
*/
|
|
532
324
|
constructor(extType, extName) {
|
|
533
325
|
super(`Name for ${extType} schema "${extName}" conflicts with an existing schema`);
|
|
534
326
|
this.data = { extType, extName };
|
|
@@ -536,20 +328,11 @@ class SchemaNameConflictError extends Error {
|
|
|
536
328
|
}
|
|
537
329
|
exports.SchemaNameConflictError = SchemaNameConflictError;
|
|
538
330
|
/**
|
|
539
|
-
* Thrown when
|
|
331
|
+
* Thrown when requested schema ID is unknown to Ajv.
|
|
540
332
|
*/
|
|
541
333
|
class SchemaUnknownSchemaError extends ReferenceError {
|
|
542
|
-
/**
|
|
543
|
-
* @type {Readonly<string>}
|
|
544
|
-
*/
|
|
545
334
|
code = 'APPIUMERR_SCHEMA_UNKNOWN_SCHEMA';
|
|
546
|
-
/**
|
|
547
|
-
* @type {Readonly<{schemaId: string}>}
|
|
548
|
-
*/
|
|
549
335
|
data;
|
|
550
|
-
/**
|
|
551
|
-
* @param {string} schemaId
|
|
552
|
-
*/
|
|
553
336
|
constructor(schemaId) {
|
|
554
337
|
super(`Unknown schema: "${schemaId}"`);
|
|
555
338
|
this.data = { schemaId };
|
|
@@ -557,29 +340,14 @@ class SchemaUnknownSchemaError extends ReferenceError {
|
|
|
557
340
|
}
|
|
558
341
|
exports.SchemaUnknownSchemaError = SchemaUnknownSchemaError;
|
|
559
342
|
/**
|
|
560
|
-
* Thrown when
|
|
561
|
-
*
|
|
562
|
-
* "Valid" schemas which are unsupported include boolean schemas and async schemas
|
|
563
|
-
* (having a `true` `$async` property).
|
|
343
|
+
* Thrown when provided schema type is unsupported (boolean/async/non-object).
|
|
564
344
|
*/
|
|
565
345
|
class SchemaUnsupportedSchemaError extends TypeError {
|
|
566
|
-
/**
|
|
567
|
-
* @type {Readonly<string>}
|
|
568
|
-
*/
|
|
569
346
|
code = 'APPIUMERR_SCHEMA_UNSUPPORTED_SCHEMA';
|
|
570
|
-
/**
|
|
571
|
-
* @type {Readonly<{schema: any, extType: ExtensionType, extName: string}>}
|
|
572
|
-
*/
|
|
573
347
|
data;
|
|
574
|
-
/**
|
|
575
|
-
* @param {any} schema
|
|
576
|
-
* @param {ExtensionType} extType
|
|
577
|
-
* @param {string} extName
|
|
578
|
-
*/
|
|
579
348
|
constructor(schema, extType, extName) {
|
|
580
|
-
// https://github.com/Microsoft/TypeScript/issues/8277
|
|
581
349
|
super((() => {
|
|
582
|
-
|
|
350
|
+
const msg = `Unsupported schema from ${extType} "${extName}":`;
|
|
583
351
|
if (lodash_1.default.isBoolean(schema)) {
|
|
584
352
|
return `${msg} schema cannot be a boolean`;
|
|
585
353
|
}
|
|
@@ -587,7 +355,6 @@ class SchemaUnsupportedSchemaError extends TypeError {
|
|
|
587
355
|
if (schema.$async) {
|
|
588
356
|
return `${msg} schema cannot be an async schema`;
|
|
589
357
|
}
|
|
590
|
-
/* istanbul ignore next */
|
|
591
358
|
throw new TypeError(`schema IS supported; this error should not be thrown (this is a bug). value of schema: ${JSON.stringify(schema)}`);
|
|
592
359
|
}
|
|
593
360
|
return `${msg} schema must be a plain object without a true "$async" property`;
|
|
@@ -599,41 +366,4 @@ exports.SchemaUnsupportedSchemaError = SchemaUnsupportedSchemaError;
|
|
|
599
366
|
const appiumSchema = AppiumSchema.create();
|
|
600
367
|
exports.registerSchema = appiumSchema.registerSchema, exports.getAllArgSpecs = appiumSchema.getAllArgSpecs, exports.getArgSpec = appiumSchema.getArgSpec, exports.hasArgSpec = appiumSchema.hasArgSpec, exports.isFinalized = appiumSchema.isFinalized, exports.finalizeSchema = appiumSchema.finalize, exports.resetSchema = appiumSchema.reset, exports.validate = appiumSchema.validate, exports.getSchema = appiumSchema.getSchema, exports.flattenSchema = appiumSchema.flatten, exports.getDefaultsForSchema = appiumSchema.getDefaults, exports.getDefaultsForExtension = appiumSchema.getDefaultsForExtension;
|
|
601
368
|
exports.isAllowedSchemaFileExtension = AppiumSchema.isAllowedSchemaFileExtension;
|
|
602
|
-
/**
|
|
603
|
-
* Appium only supports schemas that are plain objects; not arrays.
|
|
604
|
-
* @typedef {import('ajv').SchemaObject & {[key: number]: never}} SchemaObject
|
|
605
|
-
*/
|
|
606
|
-
/**
|
|
607
|
-
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
608
|
-
*/
|
|
609
|
-
/**
|
|
610
|
-
* An object having property `additionalProperties: false`
|
|
611
|
-
* @typedef StrictProp
|
|
612
|
-
* @property {false} additionalProperties
|
|
613
|
-
*/
|
|
614
|
-
/**
|
|
615
|
-
* A {@link SchemaObject} with `additionalProperties: false`
|
|
616
|
-
* @typedef {SchemaObject & StrictProp} StrictSchemaObject
|
|
617
|
-
*/
|
|
618
|
-
/**
|
|
619
|
-
* A list of schemas associated with properties and their corresponding {@link ArgSpec} objects.
|
|
620
|
-
*
|
|
621
|
-
* Intermediate data structure used when converting the entire schema down to CLI arguments.
|
|
622
|
-
* @typedef { {schema: SchemaObject, argSpec: ArgSpec}[] } FlattenedSchema
|
|
623
|
-
*/
|
|
624
|
-
/**
|
|
625
|
-
* @typedef {ArgSpec['defaultValue']} ArgSpecDefaultValue
|
|
626
|
-
*/
|
|
627
|
-
/**
|
|
628
|
-
* e.g. `{driver: {foo: 'bar'}}` where `foo` is the arg name and `bar` is the default value.
|
|
629
|
-
* @typedef {Record<string,Record<string,ArgSpecDefaultValue>>} NestedArgSpecDefaultValue
|
|
630
|
-
*/
|
|
631
|
-
/**
|
|
632
|
-
* Helper type for the return value of {@link AppiumSchema.getDefaults}
|
|
633
|
-
* @template {boolean|undefined} Flattened
|
|
634
|
-
* @typedef {Record<string,Flattened extends true ? ArgSpecDefaultValue : ArgSpecDefaultValue | NestedArgSpecDefaultValue>} DefaultValues
|
|
635
|
-
*/
|
|
636
|
-
/**
|
|
637
|
-
* @typedef {'.json'|'.js'|'.cjs'} AllowedSchemaExtension
|
|
638
|
-
*/
|
|
639
369
|
//# sourceMappingURL=schema.js.map
|