appium 3.2.2 → 3.3.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.
- package/build/lib/appium.d.ts +147 -205
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +169 -282
- package/build/lib/appium.js.map +1 -1
- package/build/lib/bidi-commands.d.ts.map +1 -1
- package/build/lib/bidi-commands.js +11 -11
- package/build/lib/bidi-commands.js.map +1 -1
- package/build/lib/bootstrap/appium-initializer.d.ts +21 -0
- package/build/lib/bootstrap/appium-initializer.d.ts.map +1 -0
- package/build/lib/bootstrap/appium-initializer.js +146 -0
- package/build/lib/bootstrap/appium-initializer.js.map +1 -0
- package/build/lib/bootstrap/appium-main-runner.d.ts +22 -0
- package/build/lib/bootstrap/appium-main-runner.d.ts.map +1 -0
- package/build/lib/bootstrap/appium-main-runner.js +109 -0
- package/build/lib/bootstrap/appium-main-runner.js.map +1 -0
- package/build/lib/bootstrap/config-file.d.ts +37 -0
- package/build/lib/bootstrap/config-file.d.ts.map +1 -0
- package/build/lib/{config-file.js → bootstrap/config-file.js} +62 -138
- package/build/lib/bootstrap/config-file.js.map +1 -0
- package/build/lib/bootstrap/grid-v3-register.d.ts +20 -0
- package/build/lib/bootstrap/grid-v3-register.d.ts.map +1 -0
- package/build/lib/bootstrap/grid-v3-register.js +185 -0
- package/build/lib/bootstrap/grid-v3-register.js.map +1 -0
- package/build/lib/bootstrap/init-types.d.ts +16 -0
- package/build/lib/bootstrap/init-types.d.ts.map +1 -0
- package/build/lib/bootstrap/init-types.js +3 -0
- package/build/lib/bootstrap/init-types.js.map +1 -0
- package/build/lib/bootstrap/main-helpers.d.ts +55 -0
- package/build/lib/bootstrap/main-helpers.d.ts.map +1 -0
- package/build/lib/bootstrap/main-helpers.js +187 -0
- package/build/lib/bootstrap/main-helpers.js.map +1 -0
- package/build/lib/bootstrap/node-helpers.d.ts +32 -0
- package/build/lib/bootstrap/node-helpers.d.ts.map +1 -0
- package/build/lib/bootstrap/node-helpers.js +201 -0
- package/build/lib/bootstrap/node-helpers.js.map +1 -0
- package/build/lib/bootstrap/startup-config.d.ts +22 -0
- package/build/lib/bootstrap/startup-config.d.ts.map +1 -0
- package/build/lib/bootstrap/startup-config.js +111 -0
- package/build/lib/bootstrap/startup-config.js.map +1 -0
- 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 +20 -40
- 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 +173 -377
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +387 -656
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts +10 -15
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +15 -33
- package/build/lib/cli/extension.js.map +1 -1
- package/build/lib/cli/parser.d.ts +37 -66
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +69 -104
- 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 +19 -61
- package/build/lib/cli/setup-command.js.map +1 -1
- package/build/lib/cli/utils.d.ts +33 -35
- package/build/lib/cli/utils.d.ts.map +1 -1
- package/build/lib/cli/utils.js +48 -50
- package/build/lib/cli/utils.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 +31 -62
- package/build/lib/doctor/doctor.js.map +1 -1
- package/build/lib/extension/driver-config.d.ts +18 -77
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +37 -125
- package/build/lib/extension/driver-config.js.map +1 -1
- package/build/lib/extension/extension-config.d.ts +103 -210
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +180 -342
- package/build/lib/extension/extension-config.js.map +1 -1
- package/build/lib/extension/index.d.ts +12 -29
- package/build/lib/extension/index.d.ts.map +1 -1
- package/build/lib/extension/index.js +33 -75
- package/build/lib/extension/index.js.map +1 -1
- package/build/lib/extension/manifest-migrations.d.ts +3 -20
- package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
- package/build/lib/extension/manifest-migrations.js +20 -101
- package/build/lib/extension/manifest-migrations.js.map +1 -1
- package/build/lib/extension/manifest.d.ts +61 -107
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +181 -356
- package/build/lib/extension/manifest.js.map +1 -1
- package/build/lib/extension/package-changed.d.ts +1 -3
- package/build/lib/extension/package-changed.d.ts.map +1 -1
- package/build/lib/extension/package-changed.js +8 -15
- package/build/lib/extension/package-changed.js.map +1 -1
- package/build/lib/extension/plugin-config.d.ts +10 -52
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +11 -63
- package/build/lib/extension/plugin-config.js.map +1 -1
- package/build/lib/helpers/build.d.ts +22 -0
- package/build/lib/helpers/build.d.ts.map +1 -0
- package/build/lib/helpers/build.js +109 -0
- package/build/lib/helpers/build.js.map +1 -0
- package/build/lib/helpers/capability.d.ts +38 -0
- package/build/lib/helpers/capability.d.ts.map +1 -0
- package/build/lib/helpers/capability.js +128 -0
- package/build/lib/helpers/capability.js.map +1 -0
- package/build/lib/helpers/network.d.ts +14 -0
- package/build/lib/helpers/network.d.ts.map +1 -0
- package/build/lib/helpers/network.js +35 -0
- package/build/lib/helpers/network.js.map +1 -0
- package/build/lib/insecure-features.js +6 -6
- package/build/lib/insecure-features.js.map +1 -1
- package/build/lib/inspector-commands.d.ts +6 -0
- package/build/lib/inspector-commands.d.ts.map +1 -1
- package/build/lib/inspector-commands.js +6 -0
- package/build/lib/inspector-commands.js.map +1 -1
- package/build/lib/logger.d.ts +2 -3
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +2 -3
- package/build/lib/logger.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.d.ts +15 -58
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +25 -425
- 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-guards.d.ts +34 -0
- package/build/lib/schema/cli-args-guards.d.ts.map +1 -0
- package/build/lib/schema/cli-args-guards.js +49 -0
- package/build/lib/schema/cli-args-guards.js.map +1 -0
- 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 +17 -107
- 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/format-errors.d.ts +28 -0
- package/build/lib/schema/format-errors.d.ts.map +1 -0
- package/build/lib/schema/format-errors.js +29 -0
- package/build/lib/schema/format-errors.js.map +1 -0
- package/build/lib/schema/index.d.ts +4 -2
- package/build/lib/schema/index.d.ts.map +1 -1
- package/build/lib/schema/index.js +2 -0
- 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 +88 -358
- package/build/lib/schema/schema.js.map +1 -1
- package/build/lib/utils.d.ts +7 -267
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +10 -409
- package/build/lib/utils.js.map +1 -1
- package/lib/{appium.js → appium.ts} +297 -341
- package/lib/bidi-commands.ts +10 -14
- package/lib/bootstrap/appium-initializer.ts +212 -0
- package/lib/bootstrap/appium-main-runner.ts +172 -0
- package/lib/bootstrap/config-file.ts +178 -0
- package/lib/bootstrap/grid-v3-register.ts +250 -0
- package/lib/bootstrap/init-types.ts +31 -0
- package/lib/bootstrap/main-helpers.ts +223 -0
- package/lib/bootstrap/node-helpers.ts +180 -0
- package/lib/bootstrap/startup-config.ts +143 -0
- package/lib/cli/{args.js → args.ts} +45 -56
- package/lib/cli/driver-command.ts +122 -0
- package/lib/cli/{extension-command.js → extension-command.ts} +827 -906
- package/lib/cli/extension.ts +65 -0
- package/lib/cli/{parser.js → parser.ts} +93 -116
- package/lib/cli/plugin-command.ts +117 -0
- package/lib/cli/{setup-command.js → setup-command.ts} +59 -74
- package/lib/cli/utils.ts +97 -0
- package/lib/{constants.js → constants.ts} +30 -41
- package/lib/doctor/{doctor.js → doctor.ts} +82 -92
- package/lib/extension/driver-config.ts +165 -0
- package/lib/extension/{extension-config.js → extension-config.ts} +291 -405
- package/lib/extension/index.ts +143 -0
- package/lib/extension/manifest-migrations.ts +57 -0
- package/lib/extension/manifest.ts +369 -0
- package/lib/extension/{package-changed.js → package-changed.ts} +9 -18
- package/lib/extension/plugin-config.ts +62 -0
- package/lib/helpers/build.ts +111 -0
- package/lib/helpers/capability.ts +171 -0
- package/lib/helpers/network.ts +30 -0
- package/lib/insecure-features.ts +1 -1
- package/lib/inspector-commands.ts +6 -1
- package/lib/{logger.js → logger.ts} +1 -2
- package/lib/{logsink.js → logsink.ts} +91 -137
- package/lib/main.ts +60 -0
- package/lib/schema/arg-spec.ts +131 -0
- package/lib/schema/cli-args-guards.ts +67 -0
- package/lib/schema/cli-args.ts +171 -0
- package/lib/schema/cli-transformers.ts +83 -0
- package/lib/schema/format-errors.ts +43 -0
- package/lib/schema/index.ts +4 -0
- package/lib/schema/keywords.ts +96 -0
- package/lib/schema/schema.ts +448 -0
- package/lib/utils.ts +73 -0
- package/package.json +17 -18
- package/scripts/autoinstall-extensions.js +3 -0
- package/build/lib/config-file.d.ts +0 -100
- package/build/lib/config-file.d.ts.map +0 -1
- package/build/lib/config-file.js.map +0 -1
- package/build/lib/config.d.ts +0 -70
- package/build/lib/config.d.ts.map +0 -1
- package/build/lib/config.js +0 -390
- package/build/lib/config.js.map +0 -1
- package/build/lib/grid-register.d.ts +0 -10
- package/build/lib/grid-register.d.ts.map +0 -1
- package/build/lib/grid-register.js +0 -134
- package/build/lib/grid-register.js.map +0 -1
- 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/config.js +0 -389
- package/lib/extension/driver-config.js +0 -245
- package/lib/extension/index.js +0 -169
- package/lib/extension/manifest-migrations.js +0 -136
- package/lib/extension/manifest.js +0 -550
- package/lib/extension/plugin-config.js +0 -112
- package/lib/grid-register.js +0 -146
- package/lib/main.js +0 -545
- 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/index.js +0 -2
- package/lib/schema/keywords.js +0 -136
- package/lib/schema/schema.js +0 -725
- package/lib/utils.js +0 -512
|
@@ -9,13 +9,13 @@ const support_1 = require("@appium/support");
|
|
|
9
9
|
const bluebird_1 = __importDefault(require("bluebird"));
|
|
10
10
|
const lodash_1 = __importDefault(require("lodash"));
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const node_url_1 = require("node:url");
|
|
12
13
|
const resolve_from_1 = __importDefault(require("resolve-from"));
|
|
13
14
|
const semver_1 = require("semver");
|
|
14
15
|
const extension_1 = require("../cli/extension");
|
|
15
|
-
const
|
|
16
|
-
const logger_1 =
|
|
16
|
+
const build_1 = require("../helpers/build");
|
|
17
|
+
const logger_1 = require("../logger");
|
|
17
18
|
const schema_1 = require("../schema/schema");
|
|
18
|
-
const node_url_1 = require("node:url");
|
|
19
19
|
const DEFAULT_ENTRY_POINT = 'index.js';
|
|
20
20
|
/**
|
|
21
21
|
* "npm" install type
|
|
@@ -44,7 +44,6 @@ exports.INSTALL_TYPE_GIT = 'git';
|
|
|
44
44
|
* Used when automatically detected as a working copy
|
|
45
45
|
*/
|
|
46
46
|
exports.INSTALL_TYPE_DEV = 'dev';
|
|
47
|
-
/** @type {Set<InstallType>} */
|
|
48
47
|
exports.INSTALL_TYPES = new Set([
|
|
49
48
|
exports.INSTALL_TYPE_GIT,
|
|
50
49
|
exports.INSTALL_TYPE_GITHUB,
|
|
@@ -53,68 +52,72 @@ exports.INSTALL_TYPES = new Set([
|
|
|
53
52
|
exports.INSTALL_TYPE_DEV,
|
|
54
53
|
]);
|
|
55
54
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* Subclasses should provide the generic parameter to implement.
|
|
59
|
-
* @template {ExtensionType} ExtType
|
|
55
|
+
* Shared configuration and validation for installed Appium extensions (drivers or plugins).
|
|
56
|
+
* Subclasses fix the extension kind; do not instantiate this class directly.
|
|
60
57
|
*/
|
|
61
58
|
class ExtensionConfig {
|
|
62
|
-
/**
|
|
63
|
-
* The type of extension this class is responsible for.
|
|
64
|
-
* @type {ExtType}
|
|
65
|
-
*/
|
|
66
59
|
extensionType;
|
|
67
|
-
/**
|
|
68
|
-
* Manifest data for the extensions of this type.
|
|
69
|
-
*
|
|
70
|
-
* This data should _not_ be written to by anything but {@linkcode Manifest}.
|
|
71
|
-
* @type {Readonly<ExtRecord<ExtType>>}
|
|
72
|
-
*/
|
|
73
|
-
installedExtensions;
|
|
74
|
-
/** @type {import('@appium/types').AppiumLogger} */
|
|
75
|
-
log;
|
|
76
|
-
/** @type {Manifest} */
|
|
77
60
|
manifest;
|
|
78
|
-
|
|
79
|
-
* @type {import('../cli/extension-command').ExtensionList<ExtType>|undefined}
|
|
80
|
-
*/
|
|
61
|
+
installedExtensions;
|
|
81
62
|
#listDataCache;
|
|
82
|
-
/**
|
|
83
|
-
* @protected
|
|
84
|
-
* @param {ExtType} extensionType - Type of extension
|
|
85
|
-
* @param {Manifest} manifest - `Manifest` instance
|
|
86
|
-
*/
|
|
87
63
|
constructor(extensionType, manifest) {
|
|
88
64
|
this.extensionType = extensionType;
|
|
89
|
-
this.installedExtensions = manifest.getExtensionData(extensionType);
|
|
90
65
|
this.manifest = manifest;
|
|
66
|
+
this.installedExtensions = manifest.getExtensionData(extensionType);
|
|
91
67
|
}
|
|
68
|
+
/** Path to `extensions.yaml` after the manifest has been read; otherwise undefined. */
|
|
92
69
|
get manifestPath() {
|
|
93
70
|
return this.manifest.manifestPath;
|
|
94
71
|
}
|
|
72
|
+
/** `APPIUM_HOME` directory this config is tied to. */
|
|
95
73
|
get appiumHome() {
|
|
96
74
|
return this.manifest.appiumHome;
|
|
97
75
|
}
|
|
98
76
|
/**
|
|
99
|
-
*
|
|
77
|
+
* Type guard: manifest entry includes a `schema` path or inline schema object.
|
|
78
|
+
*
|
|
79
|
+
* @param extManifest - Parsed extension metadata
|
|
80
|
+
*/
|
|
81
|
+
static extDataHasSchema(extManifest) {
|
|
82
|
+
return lodash_1.default.isString(extManifest?.schema) || lodash_1.default.isObject(extManifest?.schema);
|
|
83
|
+
}
|
|
84
|
+
static async _readExtensionSchema(appiumHome, extType, extName, extManifest) {
|
|
85
|
+
const { pkgName, schema: argSchemaPath } = extManifest;
|
|
86
|
+
if (!argSchemaPath) {
|
|
87
|
+
throw new TypeError(`No \`schema\` property found in config for ${extType} ${pkgName} -- why is this function being called?`);
|
|
88
|
+
}
|
|
89
|
+
let moduleObject;
|
|
90
|
+
if (lodash_1.default.isString(argSchemaPath)) {
|
|
91
|
+
const schemaPath = (0, resolve_from_1.default)(appiumHome, node_path_1.default.join(pkgName, argSchemaPath));
|
|
92
|
+
moduleObject = require(schemaPath);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
moduleObject = argSchemaPath;
|
|
96
|
+
}
|
|
97
|
+
// this sucks. default exports should be destroyed
|
|
98
|
+
const schema = moduleObject.__esModule ? moduleObject.default : moduleObject;
|
|
99
|
+
await (0, schema_1.registerSchema)(extType, extName, schema);
|
|
100
|
+
return schema;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Collects blocking validation issues for one extension (generic fields, type-specific rules, and schema).
|
|
100
104
|
*
|
|
101
|
-
* @param
|
|
102
|
-
* @param
|
|
103
|
-
* @returns {ExtManifestProblem[]}
|
|
105
|
+
* @param extName - Extension key as stored in the manifest
|
|
106
|
+
* @param extManifest - Manifest entry for that extension
|
|
104
107
|
*/
|
|
105
|
-
getProblems(extName, extManifest) {
|
|
108
|
+
async getProblems(extName, extManifest) {
|
|
106
109
|
return [
|
|
107
110
|
...this.getGenericConfigProblems(extManifest, extName),
|
|
108
111
|
...this.getConfigProblems(extManifest, extName),
|
|
109
|
-
...this.getSchemaProblems(extManifest, extName),
|
|
112
|
+
...(await this.getSchemaProblems(extManifest, extName)),
|
|
110
113
|
];
|
|
111
114
|
}
|
|
112
115
|
/**
|
|
113
|
-
*
|
|
116
|
+
* Collects non-fatal issues for one extension (e.g. manifest quirks, peer dependency mismatches).
|
|
117
|
+
* Warnings do not by themselves prevent loading.
|
|
114
118
|
*
|
|
115
|
-
* @param
|
|
116
|
-
* @param
|
|
117
|
-
* @returns {Promise<string[]>}
|
|
119
|
+
* @param extName - Extension key as stored in the manifest
|
|
120
|
+
* @param extManifest - Manifest entry for that extension
|
|
118
121
|
*/
|
|
119
122
|
async getWarnings(extName, extManifest) {
|
|
120
123
|
const [genericConfigWarnings, configWarnings] = await bluebird_1.default.all([
|
|
@@ -124,26 +127,12 @@ class ExtensionConfig {
|
|
|
124
127
|
return [...genericConfigWarnings, ...configWarnings];
|
|
125
128
|
}
|
|
126
129
|
/**
|
|
127
|
-
*
|
|
128
|
-
* @abstract
|
|
129
|
-
* @param {ExtManifest<ExtType>} extManifest
|
|
130
|
-
* @param {ExtName<ExtType>} extName
|
|
131
|
-
* @returns {Promise<string[]>}
|
|
132
|
-
*/
|
|
133
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
134
|
-
async getConfigWarnings(extManifest, extName) {
|
|
135
|
-
return [];
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
130
|
+
* Turns per-extension errors and warnings into human-readable log lines for console output.
|
|
138
131
|
*
|
|
139
|
-
* @param
|
|
140
|
-
* @param
|
|
132
|
+
* @param errorMap - Extension name to list of blocking problems
|
|
133
|
+
* @param warningMap - Extension name to list of warning strings
|
|
141
134
|
*/
|
|
142
135
|
getValidationResultSummaries(errorMap = new Map(), warningMap = new Map()) {
|
|
143
|
-
/**
|
|
144
|
-
* Array of computed strings
|
|
145
|
-
* @type {string[]}
|
|
146
|
-
*/
|
|
147
136
|
const errorSummaries = [];
|
|
148
137
|
for (const [extName, problems] of errorMap.entries()) {
|
|
149
138
|
if (lodash_1.default.isEmpty(problems)) {
|
|
@@ -155,7 +144,6 @@ class ExtensionConfig {
|
|
|
155
144
|
errorSummaries.push(` - ${problem.err} (Actual value: ` + `${JSON.stringify(problem.val)})`);
|
|
156
145
|
}
|
|
157
146
|
}
|
|
158
|
-
/** @type {string[]} */
|
|
159
147
|
const warningSummaries = [];
|
|
160
148
|
for (const [extName, warnings] of warningMap.entries()) {
|
|
161
149
|
if (lodash_1.default.isEmpty(warnings)) {
|
|
@@ -171,26 +159,116 @@ class ExtensionConfig {
|
|
|
171
159
|
return { errorSummaries, warningSummaries };
|
|
172
160
|
}
|
|
173
161
|
/**
|
|
174
|
-
*
|
|
162
|
+
* Records a new installed extension in the manifest and optionally persists immediately.
|
|
175
163
|
*
|
|
176
|
-
*
|
|
164
|
+
* @param extName - Manifest key for the extension
|
|
165
|
+
* @param extManifest - Full manifest payload
|
|
177
166
|
*
|
|
178
|
-
*
|
|
167
|
+
* Pass `{ write: false }` to defer flushing until a later manifest write.
|
|
168
|
+
*/
|
|
169
|
+
async addExtension(extName, extManifest, { write = true } = {}) {
|
|
170
|
+
this.manifest.setExtension(this.extensionType, extName, extManifest);
|
|
171
|
+
if (write) {
|
|
172
|
+
await this.manifest.write();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Merges new metadata into an existing extension entry and optionally writes the manifest.
|
|
177
|
+
*
|
|
178
|
+
* @param extName - Installed extension to update
|
|
179
|
+
* @param extManifest - Fields to merge over the current entry
|
|
179
180
|
*
|
|
180
|
-
*
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
* Pass `{ write: false }` to defer flushing until a later manifest write.
|
|
182
|
+
*/
|
|
183
|
+
async updateExtension(extName, extManifest, { write = true } = {}) {
|
|
184
|
+
const existing = this.installedExtensions[extName];
|
|
185
|
+
this.manifest.setExtension(this.extensionType, extName, {
|
|
186
|
+
...existing,
|
|
187
|
+
...extManifest,
|
|
188
|
+
});
|
|
189
|
+
if (write) {
|
|
190
|
+
await this.manifest.write();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Drops an extension from the manifest and optionally persists immediately.
|
|
195
|
+
*
|
|
196
|
+
* @param extName - Installed extension to remove
|
|
197
|
+
*
|
|
198
|
+
* Pass `{ write: false }` to defer flushing until a later manifest write.
|
|
199
|
+
*/
|
|
200
|
+
async removeExtension(extName, { write = true } = {}) {
|
|
201
|
+
this.manifest.deleteExtension(this.extensionType, extName);
|
|
202
|
+
if (write) {
|
|
203
|
+
await this.manifest.write();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Logs installed extensions to the console. Subclasses may use `activeNames` to annotate active plugins.
|
|
208
|
+
*/
|
|
209
|
+
print(_activeNames) {
|
|
210
|
+
void _activeNames;
|
|
211
|
+
if (lodash_1.default.isEmpty(this.installedExtensions)) {
|
|
212
|
+
logger_1.log.info(`No ${this.extensionType}s have been installed in ${this.appiumHome}. Use the "appium ${this.extensionType}" ` +
|
|
213
|
+
'command to install the one(s) you want to use.');
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
logger_1.log.info(`Available ${this.extensionType}s:`);
|
|
217
|
+
for (const [extName, extManifest] of lodash_1.default.toPairs(this.installedExtensions)) {
|
|
218
|
+
logger_1.log.info(` - ${this.extensionDesc(extName, extManifest)}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Root directory of an installed extension, preferring `installPath` and falling back to `node_modules/<pkgName>`.
|
|
223
|
+
*
|
|
224
|
+
* @param extName - Installed extension key
|
|
225
|
+
*/
|
|
226
|
+
getInstallPath(extName) {
|
|
227
|
+
return (this.installedExtensions[extName]?.installPath ??
|
|
228
|
+
node_path_1.default.join(this.appiumHome, 'node_modules', this.installedExtensions[extName].pkgName));
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Dynamically imports the extension entry point and returns the exported main class constructor.
|
|
232
|
+
*
|
|
233
|
+
* @param extName - Installed extension to load
|
|
234
|
+
*/
|
|
235
|
+
async requireAsync(extName) {
|
|
236
|
+
const [reqPath, mainClass] = await this._resolveExtension(extName);
|
|
237
|
+
logger_1.log.debug(`Requiring ${this.extensionType} at ${reqPath}`);
|
|
238
|
+
// https://github.com/nodejs/node/issues/31710
|
|
239
|
+
const importPath = support_1.system.isWindows() ? (0, node_url_1.pathToFileURL)(reqPath).href : reqPath;
|
|
240
|
+
const mod = (await import(importPath));
|
|
241
|
+
const MainClass = mod[mainClass];
|
|
242
|
+
if (!MainClass) {
|
|
243
|
+
throw new ReferenceError(`Could not find a class named "${mainClass}" exported by ${this.extensionType} "${extName}"`);
|
|
244
|
+
}
|
|
245
|
+
return MainClass;
|
|
246
|
+
}
|
|
247
|
+
/** Whether the manifest lists an extension under the given name. */
|
|
248
|
+
isInstalled(extName) {
|
|
249
|
+
return extName in this.installedExtensions;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Loads the extension’s config schema from disk or inline JSON and registers it for CLI/config validation.
|
|
253
|
+
*
|
|
254
|
+
* @param extName - Extension key
|
|
255
|
+
* @param extManifest - Manifest entry that includes `schema`
|
|
256
|
+
*/
|
|
257
|
+
async readExtensionSchema(extName, extManifest) {
|
|
258
|
+
return await ExtensionConfig._readExtensionSchema(this.appiumHome, this.extensionType, extName, extManifest);
|
|
259
|
+
}
|
|
260
|
+
/** Optional async warnings for this extension kind; override in subclasses when needed. */
|
|
261
|
+
async getConfigWarnings(_extManifest, _extName) {
|
|
262
|
+
void _extManifest;
|
|
263
|
+
void _extName;
|
|
264
|
+
return [];
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Validates all entries in `exts`, logs summaries, and removes keys that have blocking errors.
|
|
268
|
+
* Intended for subclasses’ `validate` implementation.
|
|
183
269
|
*/
|
|
184
270
|
async _validate(exts) {
|
|
185
|
-
/**
|
|
186
|
-
* Lookup of extension names to {@linkcode ExtManifestProblem ExtManifestProblems}
|
|
187
|
-
* @type {Map<ExtName<ExtType>,ExtManifestProblem[]>}
|
|
188
|
-
*/
|
|
189
271
|
const errorMap = new Map();
|
|
190
|
-
/**
|
|
191
|
-
* Lookup of extension names to warnings.
|
|
192
|
-
* @type {Map<ExtName<ExtType>,string[]>}
|
|
193
|
-
*/
|
|
194
272
|
const warningMap = new Map();
|
|
195
273
|
for (const [extName, extManifest] of lodash_1.default.toPairs(exts)) {
|
|
196
274
|
const [errors, warnings] = await bluebird_1.default.all([
|
|
@@ -205,47 +283,35 @@ class ExtensionConfig {
|
|
|
205
283
|
}
|
|
206
284
|
const { errorSummaries, warningSummaries } = this.getValidationResultSummaries(errorMap, warningMap);
|
|
207
285
|
if (!lodash_1.default.isEmpty(errorSummaries)) {
|
|
208
|
-
logger_1.
|
|
286
|
+
logger_1.log.error(`Appium encountered ${support_1.util.pluralize('error', errorMap.size, true)} while validating ${this.extensionType}s found in manifest ${this.manifestPath}`);
|
|
209
287
|
for (const summary of errorSummaries) {
|
|
210
|
-
logger_1.
|
|
288
|
+
logger_1.log.error(summary);
|
|
211
289
|
}
|
|
212
290
|
}
|
|
213
291
|
else if (!lodash_1.default.isEmpty(warningSummaries)) {
|
|
214
292
|
// only display warnings if there are no errors!
|
|
215
|
-
logger_1.
|
|
293
|
+
logger_1.log.warn(`Appium encountered ${support_1.util.pluralize('warning', warningMap.size, true)} while validating ${this.extensionType}s found in manifest ${this.manifestPath}`);
|
|
216
294
|
for (const summary of warningSummaries) {
|
|
217
|
-
logger_1.
|
|
295
|
+
logger_1.log.warn(summary);
|
|
218
296
|
}
|
|
219
297
|
}
|
|
220
298
|
return exts;
|
|
221
299
|
}
|
|
222
300
|
/**
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
* This is an expensive operation, so the result is cached. Currently, there is no
|
|
226
|
-
* use case for invalidating the cache.
|
|
227
|
-
* @protected
|
|
228
|
-
* @returns {Promise<import('../cli/extension-command').ExtensionList<ExtType>>}
|
|
301
|
+
* Fetches `appium driver|plugin list`-style data via the CLI command class; result is cached.
|
|
229
302
|
*/
|
|
230
303
|
async getListData() {
|
|
231
304
|
if (this.#listDataCache) {
|
|
232
305
|
return this.#listDataCache;
|
|
233
306
|
}
|
|
234
|
-
const CommandClass =
|
|
307
|
+
const CommandClass = extension_1.commandClasses[this.extensionType];
|
|
235
308
|
const cmd = new CommandClass({ config: this, json: true });
|
|
236
309
|
const listData = await cmd.list({ showInstalled: true, showUpdates: true });
|
|
237
310
|
this.#listDataCache = listData;
|
|
238
311
|
return listData;
|
|
239
312
|
}
|
|
240
313
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* By definition, a non-empty list of warnings does _not_ imply the extension cannot be loaded,
|
|
244
|
-
* but it may not work as expected or otherwise throw an exception at runtime.
|
|
245
|
-
*
|
|
246
|
-
* @param {ExtManifest<ExtType>} extManifest
|
|
247
|
-
* @param {ExtName<ExtType>} extName
|
|
248
|
-
* @returns {Promise<string[]>}
|
|
314
|
+
* Warnings about manifest install fields and Appium peer dependency compatibility for one extension.
|
|
249
315
|
*/
|
|
250
316
|
async getGenericConfigWarnings(extManifest, extName) {
|
|
251
317
|
const { appiumVersion, installSpec, installType, pkgName } = extManifest;
|
|
@@ -265,16 +331,10 @@ class ExtensionConfig {
|
|
|
265
331
|
`this may cause upgrades done via the \`appium\` CLI tool to fail. Please reinstall with \`appium ${this.extensionType} uninstall ` +
|
|
266
332
|
`${extName}\` and \`appium ${this.extensionType} install ${extName}\` to attempt a fix.`);
|
|
267
333
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
* @param {string} reason
|
|
271
|
-
* @returns string
|
|
272
|
-
*/
|
|
273
|
-
const createPeerWarning = (reason) => `${extTypeText} "${extName}" (package \`${pkgName}\`) may be incompatible with the current version of Appium (v${config_1.APPIUM_VER}) due to ${reason}`;
|
|
274
|
-
if (lodash_1.default.isString(appiumVersion) && !(0, semver_1.satisfies)(config_1.APPIUM_VER, appiumVersion)) {
|
|
334
|
+
const createPeerWarning = (reason) => `${extTypeText} "${extName}" (package \`${pkgName}\`) may be incompatible with the current version of Appium (v${build_1.APPIUM_VER}) due to ${reason}`;
|
|
335
|
+
if (lodash_1.default.isString(appiumVersion) && !(0, semver_1.satisfies)(build_1.APPIUM_VER, appiumVersion)) {
|
|
275
336
|
const listData = await this.getListData();
|
|
276
|
-
const extListData =
|
|
277
|
-
/** @type {import('../cli/extension-command').ExtensionListData<ExtType>} */ (listData[extName]);
|
|
337
|
+
const extListData = listData[extName];
|
|
278
338
|
if (extListData?.installed) {
|
|
279
339
|
const { updateVersion, upToDate } = extListData;
|
|
280
340
|
if (!upToDate && updateVersion) {
|
|
@@ -287,35 +347,27 @@ class ExtensionConfig {
|
|
|
287
347
|
}
|
|
288
348
|
else if (!lodash_1.default.isString(appiumVersion)) {
|
|
289
349
|
const listData = await this.getListData();
|
|
290
|
-
const extListData =
|
|
291
|
-
/** @type {import('../cli/extension-command').InstalledExtensionListData<ExtType>} */ (listData[extName]);
|
|
350
|
+
const extListData = listData[extName];
|
|
292
351
|
if (!extListData?.upToDate && extListData?.updateVersion) {
|
|
293
352
|
warnings.push(createPeerWarning(`an invalid or missing peer dependency on Appium. A newer version of \`${pkgName}\` is available; ` +
|
|
294
353
|
`please attempt to upgrade "${extName}" to v${extListData.updateVersion} or newer.`));
|
|
295
354
|
}
|
|
296
355
|
else {
|
|
297
356
|
warnings.push(createPeerWarning(`an invalid or missing peer dependency on Appium. ` +
|
|
298
|
-
`Please ask the developer of \`${pkgName}\` to add a peer dependency on \`^appium@${
|
|
357
|
+
`Please ask the developer of \`${pkgName}\` to add a peer dependency on \`^appium@${build_1.APPIUM_VER}\`.`));
|
|
299
358
|
}
|
|
300
359
|
}
|
|
301
360
|
return warnings;
|
|
302
361
|
}
|
|
303
|
-
/**
|
|
304
|
-
|
|
305
|
-
*
|
|
306
|
-
* @param {ExtManifest<ExtType>} extManifest - Extension data (from manifest)
|
|
307
|
-
* @param {ExtName<ExtType>} extName - Extension name (from manifest)
|
|
308
|
-
* @returns {ExtManifestProblem[]}
|
|
309
|
-
*/
|
|
310
|
-
getSchemaProblems(extManifest, extName) {
|
|
311
|
-
/** @type {ExtManifestProblem[]} */
|
|
362
|
+
/** Validates and registers extension CLI/config schema when the manifest defines a `schema` field. */
|
|
363
|
+
async getSchemaProblems(extManifest, extName) {
|
|
312
364
|
const problems = [];
|
|
313
365
|
const { schema: argSchemaPath } = extManifest;
|
|
314
366
|
if (ExtensionConfig.extDataHasSchema(extManifest)) {
|
|
315
367
|
if (lodash_1.default.isString(argSchemaPath)) {
|
|
316
368
|
if ((0, schema_1.isAllowedSchemaFileExtension)(argSchemaPath)) {
|
|
317
369
|
try {
|
|
318
|
-
this.readExtensionSchema(extName, extManifest);
|
|
370
|
+
await this.readExtensionSchema(extName, extManifest);
|
|
319
371
|
}
|
|
320
372
|
catch (err) {
|
|
321
373
|
problems.push({
|
|
@@ -335,7 +387,7 @@ class ExtensionConfig {
|
|
|
335
387
|
}
|
|
336
388
|
else if (lodash_1.default.isPlainObject(argSchemaPath)) {
|
|
337
389
|
try {
|
|
338
|
-
this.readExtensionSchema(extName, extManifest);
|
|
390
|
+
await this.readExtensionSchema(extName, extManifest);
|
|
339
391
|
}
|
|
340
392
|
catch (err) {
|
|
341
393
|
problems.push({
|
|
@@ -353,14 +405,9 @@ class ExtensionConfig {
|
|
|
353
405
|
}
|
|
354
406
|
return problems;
|
|
355
407
|
}
|
|
356
|
-
/**
|
|
357
|
-
* Return a list of generic unrecoverable errors for the given extension
|
|
358
|
-
* @param {ExtManifest<ExtType>} extManifest - Extension data (from manifest)
|
|
359
|
-
* @param {ExtName<ExtType>} extName - Extension name (from manifest)
|
|
360
|
-
* @returns {ExtManifestProblem[]}
|
|
361
|
-
*/
|
|
362
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
408
|
+
/** Blocking issues for required manifest fields shared by all extensions (version, package name, main class). */
|
|
363
409
|
getGenericConfigProblems(extManifest, extName) {
|
|
410
|
+
void extName;
|
|
364
411
|
const { version, pkgName, mainClass } = extManifest;
|
|
365
412
|
const problems = [];
|
|
366
413
|
if (!lodash_1.default.isString(version)) {
|
|
@@ -383,100 +430,12 @@ class ExtensionConfig {
|
|
|
383
430
|
}
|
|
384
431
|
return problems;
|
|
385
432
|
}
|
|
386
|
-
/**
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
* @returns {ExtManifestProblem[]}
|
|
391
|
-
*/
|
|
392
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
393
|
-
getConfigProblems(extManifest, extName) {
|
|
394
|
-
// should override this method if special validation is necessary for this extension type
|
|
433
|
+
/** Driver- or plugin-specific blocking validation; override in subclasses when needed. */
|
|
434
|
+
getConfigProblems(_extManifest, _extName) {
|
|
435
|
+
void _extManifest;
|
|
436
|
+
void _extName;
|
|
395
437
|
return [];
|
|
396
438
|
}
|
|
397
|
-
/**
|
|
398
|
-
* @param {string} extName
|
|
399
|
-
* @param {ExtManifest<ExtType>} extManifest
|
|
400
|
-
* @param {ExtensionConfigMutationOpts} opts
|
|
401
|
-
* @returns {Promise<void>}
|
|
402
|
-
*/
|
|
403
|
-
async addExtension(extName, extManifest, { write = true } = {}) {
|
|
404
|
-
this.manifest.setExtension(this.extensionType, extName, extManifest);
|
|
405
|
-
if (write) {
|
|
406
|
-
await this.manifest.write();
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* @param {ExtName<ExtType>} extName
|
|
411
|
-
* @param {ExtManifest<ExtType>} extManifest
|
|
412
|
-
* @param {ExtensionConfigMutationOpts} opts
|
|
413
|
-
* @returns {Promise<void>}
|
|
414
|
-
*/
|
|
415
|
-
async updateExtension(extName, extManifest, { write = true } = {}) {
|
|
416
|
-
this.manifest.setExtension(this.extensionType, extName, {
|
|
417
|
-
...this.installedExtensions[extName],
|
|
418
|
-
...extManifest,
|
|
419
|
-
});
|
|
420
|
-
if (write) {
|
|
421
|
-
await this.manifest.write();
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Remove an extension from the list of installed extensions, and optionally avoid a write to the manifest file.
|
|
426
|
-
*
|
|
427
|
-
* @param {ExtName<ExtType>} extName
|
|
428
|
-
* @param {ExtensionConfigMutationOpts} opts
|
|
429
|
-
* @returns {Promise<void>}
|
|
430
|
-
*/
|
|
431
|
-
async removeExtension(extName, { write = true } = {}) {
|
|
432
|
-
this.manifest.deleteExtension(this.extensionType, extName);
|
|
433
|
-
if (write) {
|
|
434
|
-
await this.manifest.write();
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* @param {ExtName<ExtType>[]} [activeNames]
|
|
439
|
-
* @returns {void}
|
|
440
|
-
*/
|
|
441
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
442
|
-
print(activeNames) {
|
|
443
|
-
if (lodash_1.default.isEmpty(this.installedExtensions)) {
|
|
444
|
-
logger_1.default.info(`No ${this.extensionType}s have been installed in ${this.appiumHome}. Use the "appium ${this.extensionType}" ` +
|
|
445
|
-
'command to install the one(s) you want to use.');
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
logger_1.default.info(`Available ${this.extensionType}s:`);
|
|
449
|
-
for (const [extName, extManifest] of /** @type {[string, ExtManifest<ExtType>][]} */ (lodash_1.default.toPairs(this.installedExtensions))) {
|
|
450
|
-
logger_1.default.info(` - ${this.extensionDesc(extName, extManifest)}`);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Returns a string describing the extension. Subclasses must implement.
|
|
455
|
-
* @param {ExtName<ExtType>} extName - Extension name
|
|
456
|
-
* @param {ExtManifest<ExtType>} extManifest - Extension data
|
|
457
|
-
* @returns {string}
|
|
458
|
-
* @abstract
|
|
459
|
-
*/
|
|
460
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
461
|
-
extensionDesc(extName, extManifest) {
|
|
462
|
-
throw new Error('This must be implemented in a subclass');
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Returns--with reasonable accuracy--the path on disk to the extension.
|
|
466
|
-
*
|
|
467
|
-
* If `installPath` is present in the manifest, then it is used; otherwise we just guess.
|
|
468
|
-
* @param {keyof typeof this.installedExtensions} extName
|
|
469
|
-
* @returns {string}
|
|
470
|
-
*/
|
|
471
|
-
getInstallPath(extName) {
|
|
472
|
-
return (this.installedExtensions[extName]?.installPath ??
|
|
473
|
-
node_path_1.default.join(this.appiumHome, 'node_modules', this.installedExtensions[extName].pkgName));
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
*
|
|
477
|
-
* @param {ExtName<ExtType>} extName
|
|
478
|
-
* @returns {Promise<[string, string]>}
|
|
479
|
-
*/
|
|
480
439
|
async _resolveExtension(extName) {
|
|
481
440
|
const { mainClass } = this.installedExtensions[extName];
|
|
482
441
|
const moduleRoot = this.getInstallPath(extName);
|
|
@@ -488,7 +447,6 @@ class ExtensionConfig {
|
|
|
488
447
|
catch (e) {
|
|
489
448
|
throw new ReferenceError(`Could not read the ${this.extensionType} manifest at ${packageJsonPath}: ${e.message}`);
|
|
490
449
|
}
|
|
491
|
-
/** @type {string | undefined} */
|
|
492
450
|
let entryPointRelativePath;
|
|
493
451
|
try {
|
|
494
452
|
if (extensionManifest.type === 'module' && extensionManifest.exports) {
|
|
@@ -499,97 +457,24 @@ class ExtensionConfig {
|
|
|
499
457
|
catch (e) {
|
|
500
458
|
throw new ReferenceError(`Could not find the ${this.extensionType} installed at ${moduleRoot}: ${e.message}`);
|
|
501
459
|
}
|
|
502
|
-
const entryPointFullPath = node_path_1.default.resolve(moduleRoot,
|
|
460
|
+
const entryPointFullPath = node_path_1.default.resolve(moduleRoot, entryPointRelativePath);
|
|
503
461
|
if (!await support_1.fs.exists(entryPointFullPath)) {
|
|
504
462
|
throw new ReferenceError(`Cannot find a valid ${this.extensionType} main entry point in '${packageJsonPath}'. ` +
|
|
505
463
|
`Assumed entry point: '${entryPointFullPath}'`);
|
|
506
464
|
}
|
|
507
465
|
// note: this will only reload the entry point
|
|
508
466
|
if (process.env.APPIUM_RELOAD_EXTENSIONS && require.cache[entryPointFullPath]) {
|
|
509
|
-
logger_1.
|
|
467
|
+
logger_1.log.debug(`Removing ${entryPointFullPath} from require cache`);
|
|
510
468
|
delete require.cache[entryPointFullPath];
|
|
511
469
|
}
|
|
512
470
|
return [entryPointFullPath, mainClass];
|
|
513
471
|
}
|
|
514
|
-
/**
|
|
515
|
-
* Loads extension asynchronously and returns its main class (constructor)
|
|
516
|
-
*
|
|
517
|
-
* @param {ExtName<ExtType>} extName
|
|
518
|
-
* @returns {Promise<ExtClass<ExtType>>}
|
|
519
|
-
*/
|
|
520
|
-
async requireAsync(extName) {
|
|
521
|
-
const [reqPath, mainClass] = await this._resolveExtension(extName);
|
|
522
|
-
logger_1.default.debug(`Requiring ${this.extensionType} at ${reqPath}`);
|
|
523
|
-
// https://github.com/nodejs/node/issues/31710
|
|
524
|
-
const importPath = support_1.system.isWindows() ? (0, node_url_1.pathToFileURL)(reqPath).href : reqPath;
|
|
525
|
-
const MainClass = (await import(importPath))[mainClass];
|
|
526
|
-
if (!MainClass) {
|
|
527
|
-
throw new ReferenceError(`Could not find a class named "${mainClass}" exported by ${this.extensionType} "${extName}"`);
|
|
528
|
-
}
|
|
529
|
-
return MainClass;
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* @param {string} extName
|
|
533
|
-
* @returns {boolean}
|
|
534
|
-
*/
|
|
535
|
-
isInstalled(extName) {
|
|
536
|
-
return extName in this.installedExtensions;
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Intended to be called by corresponding instance methods of subclass.
|
|
540
|
-
* @private
|
|
541
|
-
* @template {ExtensionType} ExtType
|
|
542
|
-
* @param {string} appiumHome
|
|
543
|
-
* @param {ExtType} extType
|
|
544
|
-
* @param {ExtName<ExtType>} extName - Extension name (unique to its type)
|
|
545
|
-
* @param {ExtManifestWithSchema<ExtType>} extManifest - Extension config
|
|
546
|
-
* @returns {import('ajv').SchemaObject|undefined}
|
|
547
|
-
*/
|
|
548
|
-
static _readExtensionSchema(appiumHome, extType, extName, extManifest) {
|
|
549
|
-
const { pkgName, schema: argSchemaPath } = extManifest;
|
|
550
|
-
if (!argSchemaPath) {
|
|
551
|
-
throw new TypeError(`No \`schema\` property found in config for ${extType} ${pkgName} -- why is this function being called?`);
|
|
552
|
-
}
|
|
553
|
-
let moduleObject;
|
|
554
|
-
if (lodash_1.default.isString(argSchemaPath)) {
|
|
555
|
-
const schemaPath = (0, resolve_from_1.default)(appiumHome, node_path_1.default.join(pkgName, argSchemaPath));
|
|
556
|
-
moduleObject = require(schemaPath);
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
moduleObject = argSchemaPath;
|
|
560
|
-
}
|
|
561
|
-
// this sucks. default exports should be destroyed
|
|
562
|
-
const schema = moduleObject.__esModule ? moduleObject.default : moduleObject;
|
|
563
|
-
(0, schema_1.registerSchema)(extType, extName, schema);
|
|
564
|
-
return schema;
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Returns `true` if a specific {@link ExtManifest} object has a `schema` prop.
|
|
568
|
-
* The {@link ExtManifest} object becomes a {@link ExtManifestWithSchema} object.
|
|
569
|
-
* @template {ExtensionType} ExtType
|
|
570
|
-
* @param {ExtManifest<ExtType>} extManifest
|
|
571
|
-
* @returns {extManifest is ExtManifestWithSchema<ExtType>}
|
|
572
|
-
*/
|
|
573
|
-
static extDataHasSchema(extManifest) {
|
|
574
|
-
return lodash_1.default.isString(extManifest?.schema) || lodash_1.default.isObject(extManifest?.schema);
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* If an extension provides a schema, this will load the schema and attempt to
|
|
578
|
-
* register it with the schema registrar.
|
|
579
|
-
* @param {ExtName<ExtType>} extName - Name of extension
|
|
580
|
-
* @param {ExtManifestWithSchema<ExtType>} extManifest - Extension data
|
|
581
|
-
* @returns {import('ajv').SchemaObject|undefined}
|
|
582
|
-
*/
|
|
583
|
-
readExtensionSchema(extName, extManifest) {
|
|
584
|
-
return ExtensionConfig._readExtensionSchema(this.appiumHome, this.extensionType, extName, extManifest);
|
|
585
|
-
}
|
|
586
472
|
}
|
|
587
473
|
exports.ExtensionConfig = ExtensionConfig;
|
|
588
474
|
/**
|
|
589
|
-
*
|
|
475
|
+
* Resolves a package `exports` field (string, `"."`, or `"import"`) to a relative entry path for ESM packages.
|
|
590
476
|
*
|
|
591
|
-
* @param
|
|
592
|
-
* @returns {string | undefined}
|
|
477
|
+
* @param exportsValue - `package.json` `exports` value or nested fragment
|
|
593
478
|
*/
|
|
594
479
|
function resolveEsmEntryPoint(exportsValue) {
|
|
595
480
|
if (lodash_1.default.isString(exportsValue) && exportsValue) {
|
|
@@ -598,58 +483,11 @@ function resolveEsmEntryPoint(exportsValue) {
|
|
|
598
483
|
if (!lodash_1.default.isPlainObject(exportsValue)) {
|
|
599
484
|
return;
|
|
600
485
|
}
|
|
486
|
+
const obj = exportsValue;
|
|
601
487
|
for (const key of ['.', 'import']) {
|
|
602
|
-
if (
|
|
603
|
-
return resolveEsmEntryPoint(
|
|
488
|
+
if (obj[key]) {
|
|
489
|
+
return resolveEsmEntryPoint(obj[key]);
|
|
604
490
|
}
|
|
605
491
|
}
|
|
606
492
|
}
|
|
607
|
-
/**
|
|
608
|
-
* An issue with the {@linkcode ExtManifest} for a particular extension.
|
|
609
|
-
*
|
|
610
|
-
* The existance of such an object implies that the extension cannot be loaded.
|
|
611
|
-
* @typedef ExtManifestProblem
|
|
612
|
-
* @property {string} err - Error message
|
|
613
|
-
* @property {any} val - Associated value
|
|
614
|
-
*/
|
|
615
|
-
/**
|
|
616
|
-
* An optional logging function provided to an {@link ExtensionConfig} subclass.
|
|
617
|
-
* @callback ExtensionLogFn
|
|
618
|
-
* @param {...any} args
|
|
619
|
-
* @returns {void}
|
|
620
|
-
*/
|
|
621
|
-
/**
|
|
622
|
-
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
623
|
-
* @typedef {import('./manifest').Manifest} Manifest
|
|
624
|
-
* @typedef {import('appium/types').InstallType} InstallType
|
|
625
|
-
*/
|
|
626
|
-
/**
|
|
627
|
-
* @template {ExtensionType} ExtType
|
|
628
|
-
* @typedef {import('appium/types').ExtManifest<ExtType>} ExtManifest
|
|
629
|
-
*/
|
|
630
|
-
/**
|
|
631
|
-
* @template {ExtensionType} ExtType
|
|
632
|
-
* @typedef {ExtManifest<ExtType> & {schema: NonNullable<ExtManifest<ExtType>['schema']>}} ExtManifestWithSchema
|
|
633
|
-
*/
|
|
634
|
-
/**
|
|
635
|
-
* @template {ExtensionType} ExtType
|
|
636
|
-
* @typedef {import('appium/types').ExtName<ExtType>} ExtName
|
|
637
|
-
*/
|
|
638
|
-
/**
|
|
639
|
-
* @template {ExtensionType} ExtType
|
|
640
|
-
* @typedef {import('appium/types').ExtClass<ExtType>} ExtClass
|
|
641
|
-
*/
|
|
642
|
-
/**
|
|
643
|
-
* @template {ExtensionType} ExtType
|
|
644
|
-
* @typedef {import('appium/types').ExtRecord<ExtType>} ExtRecord
|
|
645
|
-
*/
|
|
646
|
-
/**
|
|
647
|
-
* @template {ExtensionType} ExtType
|
|
648
|
-
* @typedef {import('../cli/extension').ExtCommand<ExtType>} ExtCommand
|
|
649
|
-
*/
|
|
650
|
-
/**
|
|
651
|
-
* Options for various methods in {@link ExtensionConfig}
|
|
652
|
-
* @typedef ExtensionConfigMutationOpts
|
|
653
|
-
* @property {boolean} [write=true] Whether or not to write the manifest to disk after a mutation operation
|
|
654
|
-
*/
|
|
655
493
|
//# sourceMappingURL=extension-config.js.map
|