appium 2.0.0-beta.46 → 2.0.0-beta.47
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/README.md +145 -44
- package/build/lib/appium.d.ts +3 -103
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +679 -549
- package/build/lib/appium.js.map +1 -1
- package/build/lib/cli/args.js +247 -127
- package/build/lib/cli/args.js.map +1 -1
- package/build/lib/cli/driver-command.js +63 -88
- package/build/lib/cli/driver-command.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +32 -23
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +730 -512
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts +7 -6
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +68 -65
- package/build/lib/cli/extension.js.map +1 -1
- 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 +234 -192
- package/build/lib/cli/parser.js.map +1 -1
- package/build/lib/cli/plugin-command.js +58 -87
- package/build/lib/cli/plugin-command.js.map +1 -1
- package/build/lib/cli/utils.js +66 -69
- package/build/lib/cli/utils.js.map +1 -1
- package/build/lib/config-file.d.ts.map +1 -1
- package/build/lib/config-file.js +189 -120
- package/build/lib/config-file.js.map +1 -1
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +254 -213
- package/build/lib/config.js.map +1 -1
- package/build/lib/constants.d.ts +5 -5
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +64 -59
- package/build/lib/constants.js.map +1 -1
- package/build/lib/extension/driver-config.js +199 -164
- package/build/lib/extension/driver-config.js.map +1 -1
- package/build/lib/extension/extension-config.d.ts +18 -16
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +523 -396
- package/build/lib/extension/extension-config.js.map +1 -1
- package/build/lib/extension/index.js +98 -68
- package/build/lib/extension/index.js.map +1 -1
- package/build/lib/extension/manifest-migrations.d.ts +27 -0
- package/build/lib/extension/manifest-migrations.d.ts.map +1 -0
- package/build/lib/extension/manifest-migrations.js +99 -0
- package/build/lib/extension/manifest-migrations.js.map +1 -0
- package/build/lib/extension/manifest.d.ts +7 -56
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +432 -240
- package/build/lib/extension/manifest.js.map +1 -1
- package/build/lib/extension/package-changed.js +57 -61
- package/build/lib/extension/package-changed.js.map +1 -1
- package/build/lib/extension/plugin-config.d.ts +2 -3
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +94 -70
- package/build/lib/extension/plugin-config.js.map +1 -1
- package/build/lib/grid-register.js +119 -137
- package/build/lib/grid-register.js.map +1 -1
- package/build/lib/logger.d.ts +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +5 -15
- package/build/lib/logger.js.map +1 -1
- package/build/lib/logsink.d.ts.map +1 -1
- package/build/lib/logsink.js +189 -183
- package/build/lib/logsink.js.map +1 -1
- package/build/lib/main.d.ts +19 -12
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +330 -304
- package/build/lib/main.js.map +1 -1
- package/build/lib/schema/arg-spec.js +153 -108
- package/build/lib/schema/arg-spec.js.map +1 -1
- package/build/lib/schema/cli-args.js +203 -164
- package/build/lib/schema/cli-args.js.map +1 -1
- package/build/lib/schema/cli-transformers.js +117 -72
- package/build/lib/schema/cli-transformers.js.map +1 -1
- package/build/lib/schema/index.js +17 -32
- package/build/lib/schema/index.js.map +1 -1
- package/build/lib/schema/keywords.js +125 -67
- package/build/lib/schema/keywords.js.map +1 -1
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +582 -417
- package/build/lib/schema/schema.js.map +1 -1
- package/build/lib/utils.d.ts +41 -255
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +342 -193
- package/build/lib/utils.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/cli.d.ts +45 -34
- package/build/types/cli.d.ts.map +1 -1
- package/build/types/cli.js +3 -0
- package/build/types/cli.js.map +1 -0
- package/build/types/index.d.ts +1 -2
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js +19 -0
- package/build/types/index.js.map +1 -0
- package/build/types/manifest/base.d.ts +135 -0
- package/build/types/manifest/base.d.ts.map +1 -0
- package/build/types/manifest/base.js +3 -0
- package/build/types/manifest/base.js.map +1 -0
- package/build/types/manifest/index.d.ts +19 -0
- package/build/types/manifest/index.d.ts.map +1 -0
- package/build/types/manifest/index.js +40 -0
- package/build/types/manifest/index.js.map +1 -0
- package/build/types/manifest/v3.d.ts +139 -0
- package/build/types/manifest/v3.d.ts.map +1 -0
- package/build/types/manifest/v3.js +3 -0
- package/build/types/manifest/v3.js.map +1 -0
- package/lib/appium.js +1 -1
- package/lib/cli/args.js +1 -1
- package/lib/cli/extension-command.js +116 -61
- package/lib/cli/extension.js +9 -8
- package/lib/cli/parser.js +2 -2
- package/lib/config-file.js +2 -3
- package/lib/config.js +3 -2
- package/lib/constants.js +6 -5
- package/lib/extension/extension-config.js +24 -25
- package/lib/extension/manifest-migrations.js +99 -0
- package/lib/extension/manifest.js +79 -72
- package/lib/extension/plugin-config.js +1 -2
- package/lib/logsink.js +26 -5
- package/lib/main.js +58 -50
- package/lib/schema/schema.js +6 -1
- package/lib/utils.js +62 -0
- package/package.json +23 -24
- package/scripts/autoinstall-extensions.js +78 -26
- package/types/cli.ts +81 -42
- package/types/index.ts +1 -2
- package/types/manifest/README.md +30 -0
- package/types/manifest/base.ts +158 -0
- package/types/manifest/index.ts +27 -0
- package/types/manifest/v3.ts +161 -0
- package/build/types/appium-manifest.d.ts +0 -59
- package/build/types/appium-manifest.d.ts.map +0 -1
- package/build/types/extension-manifest.d.ts +0 -55
- package/build/types/extension-manifest.d.ts.map +0 -1
- package/types/appium-manifest.ts +0 -73
- package/types/extension-manifest.ts +0 -64
|
@@ -1,261 +1,453 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Module containing {@link Manifest} which handles reading & writing of extension config files.
|
|
4
|
+
*/
|
|
5
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
6
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
7
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
8
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
9
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
10
|
+
};
|
|
11
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
12
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
13
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
var _Manifest_instances, _Manifest_data, _Manifest_appiumHome, _Manifest_manifestPath, _Manifest_writing, _Manifest_reading, _Manifest_setManifestPath;
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
21
|
exports.Manifest = void 0;
|
|
7
|
-
|
|
8
|
-
require("
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const CONFIG_SCHEMA_REV = 2;
|
|
33
|
-
const CONFIG_DATA_DRIVER_KEY = `${_constants.DRIVER_TYPE}s`;
|
|
34
|
-
const CONFIG_DATA_PLUGIN_KEY = `${_constants.PLUGIN_TYPE}s`;
|
|
22
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
23
|
+
const glob_1 = __importDefault(require("glob"));
|
|
24
|
+
const support_1 = require("@appium/support");
|
|
25
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
26
|
+
const path_1 = __importDefault(require("path"));
|
|
27
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
28
|
+
const constants_1 = require("../constants");
|
|
29
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
30
|
+
const extension_config_1 = require("./extension-config");
|
|
31
|
+
const package_changed_1 = require("./package-changed");
|
|
32
|
+
const manifest_migrations_1 = require("./manifest-migrations");
|
|
33
|
+
/**
|
|
34
|
+
* The name of the prop (`drivers`) used in `extensions.yaml` for drivers.
|
|
35
|
+
* @type {`${typeof DRIVER_TYPE}s`}
|
|
36
|
+
*/
|
|
37
|
+
const CONFIG_DATA_DRIVER_KEY = `${constants_1.DRIVER_TYPE}s`;
|
|
38
|
+
/**
|
|
39
|
+
* The name of the prop (`plugins`) used in `extensions.yaml` for plugins.
|
|
40
|
+
* @type {`${typeof PLUGIN_TYPE}s`}
|
|
41
|
+
*/
|
|
42
|
+
const CONFIG_DATA_PLUGIN_KEY = `${constants_1.PLUGIN_TYPE}s`;
|
|
43
|
+
/**
|
|
44
|
+
* @type {Readonly<ManifestData>}
|
|
45
|
+
*/
|
|
35
46
|
const INITIAL_MANIFEST_DATA = Object.freeze({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
[CONFIG_DATA_DRIVER_KEY]: Object.freeze({}),
|
|
48
|
+
[CONFIG_DATA_PLUGIN_KEY]: Object.freeze({}),
|
|
49
|
+
schemaRev: constants_1.CURRENT_SCHEMA_REV,
|
|
39
50
|
});
|
|
40
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Given a `package.json` return `true` if it represents an Appium Extension (either a driver or plugin).
|
|
53
|
+
*
|
|
54
|
+
* The `package.json` must have an `appium` property which is an object.
|
|
55
|
+
* @param {any} value
|
|
56
|
+
* @returns {value is ExtPackageJson<ExtensionType>}
|
|
57
|
+
*/
|
|
41
58
|
function isExtension(value) {
|
|
42
|
-
|
|
59
|
+
return (lodash_1.default.isPlainObject(value) &&
|
|
60
|
+
lodash_1.default.isPlainObject(value.appium) &&
|
|
61
|
+
lodash_1.default.isString(value.name) &&
|
|
62
|
+
lodash_1.default.isString(value.version));
|
|
43
63
|
}
|
|
44
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Given a `package.json`, return `true` if it represents an Appium Driver.
|
|
66
|
+
*
|
|
67
|
+
* To be considered a driver, a `package.json` must have a fields
|
|
68
|
+
* `appium.driverName`, `appium.automationName` and `appium.platformNames`.
|
|
69
|
+
* @param {any} value - Value to test
|
|
70
|
+
* @returns {value is ExtPackageJson<DriverType>}
|
|
71
|
+
*/
|
|
45
72
|
function isDriver(value) {
|
|
46
|
-
|
|
73
|
+
return (isExtension(value) &&
|
|
74
|
+
lodash_1.default.isString(lodash_1.default.get(value, 'appium.driverName')) &&
|
|
75
|
+
lodash_1.default.isString(lodash_1.default.get(value, 'appium.automationName')) &&
|
|
76
|
+
lodash_1.default.isArray(lodash_1.default.get(value, 'appium.platformNames')));
|
|
47
77
|
}
|
|
48
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Given a `package.json`, return `true` if it represents an Appium Plugin.
|
|
80
|
+
*
|
|
81
|
+
* To be considered a plugin, a `package.json` must have an `appium.pluginName` field.
|
|
82
|
+
* @param {any} value - Value to test
|
|
83
|
+
* @returns {value is ExtPackageJson<PluginType>}
|
|
84
|
+
*/
|
|
49
85
|
function isPlugin(value) {
|
|
50
|
-
|
|
86
|
+
return isExtension(value) && lodash_1.default.isString(lodash_1.default.get(value, 'appium.pluginName'));
|
|
51
87
|
}
|
|
52
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Handles reading & writing of extension config files.
|
|
90
|
+
*
|
|
91
|
+
* Only one instance of this class exists per value of `APPIUM_HOME`.
|
|
92
|
+
*/
|
|
53
93
|
class Manifest {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Sets internal data to a fresh clone of {@link INITIAL_MANIFEST_DATA}
|
|
96
|
+
*
|
|
97
|
+
* Use {@link Manifest.getInstance} instead.
|
|
98
|
+
* @param {string} appiumHome
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
constructor(appiumHome) {
|
|
102
|
+
_Manifest_instances.add(this);
|
|
103
|
+
/**
|
|
104
|
+
* The entire contents of a parsed YAML extension config file.
|
|
105
|
+
*
|
|
106
|
+
* Contains proxies for automatic persistence on disk
|
|
107
|
+
* @type {ManifestData}
|
|
108
|
+
*/
|
|
109
|
+
_Manifest_data.set(this, void 0);
|
|
110
|
+
/**
|
|
111
|
+
* Path to `APPIUM_HOME`.
|
|
112
|
+
* @type {Readonly<string>}
|
|
113
|
+
*/
|
|
114
|
+
_Manifest_appiumHome.set(this, void 0);
|
|
115
|
+
/**
|
|
116
|
+
* Path to `extensions.yaml`
|
|
117
|
+
* @type {string}
|
|
118
|
+
* Not set until {@link Manifest.read} is called.
|
|
119
|
+
*/
|
|
120
|
+
_Manifest_manifestPath.set(this, void 0);
|
|
121
|
+
/**
|
|
122
|
+
* Helps avoid writing multiple times.
|
|
123
|
+
*
|
|
124
|
+
* If this is `undefined`, calling {@link Manifest.write} will cause it to be
|
|
125
|
+
* set to a `Promise`. When the call to `write()` is complete, the `Promise`
|
|
126
|
+
* will resolve and then this value will be set to `undefined`. Concurrent calls
|
|
127
|
+
* made while this value is a `Promise` will return the `Promise` itself.
|
|
128
|
+
* @type {Promise<boolean>|undefined}
|
|
129
|
+
*/
|
|
130
|
+
_Manifest_writing.set(this, void 0);
|
|
131
|
+
/**
|
|
132
|
+
* Helps avoid reading multiple times.
|
|
133
|
+
*
|
|
134
|
+
* If this is `undefined`, calling {@link Manifest.read} will cause it to be
|
|
135
|
+
* set to a `Promise`. When the call to `read()` is complete, the `Promise`
|
|
136
|
+
* will resolve and then this value will be set to `undefined`. Concurrent calls
|
|
137
|
+
* made while this value is a `Promise` will return the `Promise` itself.
|
|
138
|
+
* @type {Promise<void>|undefined}
|
|
139
|
+
*/
|
|
140
|
+
_Manifest_reading.set(this, void 0);
|
|
141
|
+
__classPrivateFieldSet(this, _Manifest_appiumHome, appiumHome, "f");
|
|
142
|
+
__classPrivateFieldSet(this, _Manifest_data, lodash_1.default.cloneDeep(INITIAL_MANIFEST_DATA), "f");
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Searches `APPIUM_HOME` for installed extensions and adds them to the manifest.
|
|
146
|
+
* @returns {Promise<boolean>} `true` if any extensions were added, `false` otherwise.
|
|
147
|
+
*/
|
|
148
|
+
async syncWithInstalledExtensions() {
|
|
149
|
+
// this could be parallelized, but we can't use fs.walk as an async iterator
|
|
150
|
+
let didChange = false;
|
|
151
|
+
/**
|
|
152
|
+
* Listener for the `match` event of a `glob` instance
|
|
153
|
+
* @param {string} filepath - Path to a `package.json`
|
|
154
|
+
* @returns {Promise<void>}
|
|
155
|
+
*/
|
|
156
|
+
const onMatch = async (filepath) => {
|
|
157
|
+
try {
|
|
158
|
+
const pkg = JSON.parse(await support_1.fs.readFile(filepath, 'utf8'));
|
|
159
|
+
if (isDriver(pkg) || isPlugin(pkg)) {
|
|
160
|
+
const changed = this.addExtensionFromPackage(pkg, filepath);
|
|
161
|
+
didChange = didChange || changed;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch { }
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* A list of `Promise`s which read `package.json` files looking for Appium extensions.
|
|
168
|
+
* @type {Promise<void>[]}
|
|
169
|
+
*/
|
|
170
|
+
const queue = [
|
|
171
|
+
// look at `package.json` in `APPIUM_HOME` only
|
|
172
|
+
onMatch(path_1.default.join(__classPrivateFieldGet(this, _Manifest_appiumHome, "f"), 'package.json')),
|
|
173
|
+
];
|
|
174
|
+
// add dependencies to the queue
|
|
175
|
+
await new bluebird_1.default((resolve, reject) => {
|
|
176
|
+
(0, glob_1.default)('node_modules/{*,@*/*}/package.json', { cwd: __classPrivateFieldGet(this, _Manifest_appiumHome, "f"), silent: true, absolute: true },
|
|
177
|
+
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
178
|
+
(err) => {
|
|
179
|
+
if (err) {
|
|
180
|
+
reject(err);
|
|
181
|
+
}
|
|
182
|
+
resolve();
|
|
183
|
+
})
|
|
184
|
+
.on('error', reject)
|
|
185
|
+
.on('match', (filepath) => {
|
|
186
|
+
queue.push(onMatch(filepath));
|
|
187
|
+
});
|
|
137
188
|
});
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return false;
|
|
142
|
-
} else {
|
|
143
|
-
throw new TypeError(`The extension in ${extensionPath} is neither a valid driver nor a valid plugin.`);
|
|
189
|
+
// wait for everything to finish
|
|
190
|
+
await bluebird_1.default.all(queue);
|
|
191
|
+
return didChange;
|
|
144
192
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
get appiumHome() {
|
|
155
|
-
return this._appiumHome;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
get manifestPath() {
|
|
159
|
-
return this._manifestPath;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
getExtensionData(extType) {
|
|
163
|
-
return this._data[`${extType}s`];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async read() {
|
|
167
|
-
if (this._reading) {
|
|
168
|
-
await this._reading;
|
|
169
|
-
return this._data;
|
|
193
|
+
/**
|
|
194
|
+
* Returns `true` if driver with name `name` is registered.
|
|
195
|
+
* @param {string} name - Driver name
|
|
196
|
+
* @returns {boolean}
|
|
197
|
+
*/
|
|
198
|
+
hasDriver(name) {
|
|
199
|
+
return Boolean(__classPrivateFieldGet(this, _Manifest_data, "f").drivers[name]);
|
|
170
200
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
201
|
+
/**
|
|
202
|
+
* Returns `true` if plugin with name `name` is registered.
|
|
203
|
+
* @param {string} name - Plugin name
|
|
204
|
+
* @returns {boolean}
|
|
205
|
+
*/
|
|
206
|
+
hasPlugin(name) {
|
|
207
|
+
return Boolean(__classPrivateFieldGet(this, _Manifest_data, "f").plugins[name]);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Given a path to a `package.json`, add it as either a driver or plugin to the manifest.
|
|
211
|
+
*
|
|
212
|
+
* Will _not_ overwrite existing entries.
|
|
213
|
+
* @template {ExtensionType} ExtType
|
|
214
|
+
* @param {ExtPackageJson<ExtType>} pkgJson
|
|
215
|
+
* @param {string} pkgPath
|
|
216
|
+
* @returns {boolean} - `true` upon success, `false` if the extension is already registered.
|
|
217
|
+
*/
|
|
218
|
+
addExtensionFromPackage(pkgJson, pkgPath) {
|
|
219
|
+
const extensionPath = path_1.default.dirname(pkgPath);
|
|
220
|
+
/**
|
|
221
|
+
* @type {InternalMetadata}
|
|
222
|
+
*/
|
|
223
|
+
const internal = {
|
|
224
|
+
pkgName: pkgJson.name,
|
|
225
|
+
version: pkgJson.version,
|
|
226
|
+
appiumVersion: pkgJson.peerDependencies?.appium,
|
|
227
|
+
installType: extension_config_1.INSTALL_TYPE_NPM,
|
|
228
|
+
installSpec: `${pkgJson.name}@${pkgJson.version}`,
|
|
229
|
+
installPath: extensionPath,
|
|
230
|
+
};
|
|
231
|
+
if (isDriver(pkgJson)) {
|
|
232
|
+
if (!this.hasDriver(pkgJson.appium.driverName)) {
|
|
233
|
+
this.addExtension(constants_1.DRIVER_TYPE, pkgJson.appium.driverName, {
|
|
234
|
+
...lodash_1.default.omit(pkgJson.appium, 'driverName'),
|
|
235
|
+
...internal,
|
|
236
|
+
});
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
else if (isPlugin(pkgJson)) {
|
|
242
|
+
if (!this.hasPlugin(pkgJson.appium.pluginName)) {
|
|
243
|
+
this.addExtension(constants_1.PLUGIN_TYPE, pkgJson.appium.pluginName, {
|
|
244
|
+
...lodash_1.default.omit(pkgJson.appium, 'pluginName'),
|
|
245
|
+
...internal,
|
|
246
|
+
});
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
throw new TypeError(`The extension in ${extensionPath} is neither a valid driver nor a valid plugin.`);
|
|
194
253
|
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
this._data = data;
|
|
198
|
-
let installedExtensionsChanged = false;
|
|
199
|
-
|
|
200
|
-
if ((await _support.env.hasAppiumDependency(this.appiumHome)) && (await (0, _packageChanged.packageDidChange)(this.appiumHome))) {
|
|
201
|
-
installedExtensionsChanged = await this.syncWithInstalledExtensions();
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (isNewFile || installedExtensionsChanged) {
|
|
205
|
-
await this.write();
|
|
206
|
-
}
|
|
207
|
-
})();
|
|
208
|
-
|
|
209
|
-
try {
|
|
210
|
-
await this._reading;
|
|
211
|
-
return this._data;
|
|
212
|
-
} finally {
|
|
213
|
-
this._reading = undefined;
|
|
214
254
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
255
|
+
/**
|
|
256
|
+
* Adds an extension to the manifest as was installed by the `appium` CLI. The
|
|
257
|
+
* `extData`, `extType`, and `extName` have already been determined.
|
|
258
|
+
*
|
|
259
|
+
* See {@link Manifest.addExtensionFromPackage} for adding an extension from an on-disk package.
|
|
260
|
+
* @template {ExtensionType} ExtType
|
|
261
|
+
* @param {ExtType} extType - `driver` or `plugin`
|
|
262
|
+
* @param {string} extName - Name of extension
|
|
263
|
+
* @param {ExtManifest<ExtType>} extData - Extension metadata
|
|
264
|
+
* @returns {ExtManifest<ExtType>} A clone of `extData`, potentially with a mutated `appiumVersion` field
|
|
265
|
+
*/
|
|
266
|
+
addExtension(extType, extName, extData) {
|
|
267
|
+
const data = lodash_1.default.clone(extData);
|
|
268
|
+
__classPrivateFieldGet(this, _Manifest_data, "f")[`${extType}s`][extName] = data;
|
|
269
|
+
return data;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Returns the `APPIUM_HOME` path
|
|
273
|
+
*/
|
|
274
|
+
get appiumHome() {
|
|
275
|
+
return __classPrivateFieldGet(this, _Manifest_appiumHome, "f");
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Returns the path to the manifest file (`extensions.yaml`)
|
|
279
|
+
*/
|
|
280
|
+
get manifestPath() {
|
|
281
|
+
return __classPrivateFieldGet(this, _Manifest_manifestPath, "f");
|
|
224
282
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
283
|
+
/**
|
|
284
|
+
* Returns extension data for a particular type.
|
|
285
|
+
*
|
|
286
|
+
* @template {ExtensionType} ExtType
|
|
287
|
+
* @param {ExtType} extType
|
|
288
|
+
* @returns {ExtRecord<ExtType>}
|
|
289
|
+
*/
|
|
290
|
+
getExtensionData(extType) {
|
|
291
|
+
return __classPrivateFieldGet(this, _Manifest_data, "f")[ /** @type {string} */(`${extType}s`)];
|
|
232
292
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Reads manifest from disk and _overwrites_ the internal data.
|
|
295
|
+
*
|
|
296
|
+
* If the manifest does not exist on disk, an {@link INITIAL_MANIFEST_DATA "empty"} manifest file will be created.
|
|
297
|
+
*
|
|
298
|
+
* If `APPIUM_HOME` contains a `package.json` with an `appium` dependency, then a hash of the `package.json` will be taken. If this hash differs from the last hash, the contents of `APPIUM_HOME/node_modules` will be scanned for extensions that may have been installed outside of the `appium` CLI. Any found extensions will be added to the manifest file, and if so, the manifest file will be written to disk.
|
|
299
|
+
*
|
|
300
|
+
* Only one read operation should happen at a time.
|
|
301
|
+
* @returns {Promise<ManifestData>} The data
|
|
302
|
+
*/
|
|
303
|
+
async read() {
|
|
304
|
+
if (__classPrivateFieldGet(this, _Manifest_reading, "f")) {
|
|
305
|
+
await __classPrivateFieldGet(this, _Manifest_reading, "f");
|
|
306
|
+
return __classPrivateFieldGet(this, _Manifest_data, "f");
|
|
307
|
+
}
|
|
308
|
+
__classPrivateFieldSet(this, _Manifest_reading, (async () => {
|
|
309
|
+
/** @type {ManifestData} */
|
|
310
|
+
let data;
|
|
311
|
+
let isNewFile = false;
|
|
312
|
+
await __classPrivateFieldGet(this, _Manifest_instances, "m", _Manifest_setManifestPath).call(this);
|
|
313
|
+
try {
|
|
314
|
+
logger_1.default.debug(`Reading ${__classPrivateFieldGet(this, _Manifest_manifestPath, "f")}...`);
|
|
315
|
+
const yaml = await support_1.fs.readFile(__classPrivateFieldGet(this, _Manifest_manifestPath, "f"), 'utf8');
|
|
316
|
+
data = yaml_1.default.parse(yaml);
|
|
317
|
+
logger_1.default.debug(`Parsed manifest file: ${JSON.stringify(data, null, 2)}`);
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
if (err.code === 'ENOENT') {
|
|
321
|
+
data = lodash_1.default.cloneDeep(INITIAL_MANIFEST_DATA);
|
|
322
|
+
isNewFile = true;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
if (__classPrivateFieldGet(this, _Manifest_manifestPath, "f")) {
|
|
326
|
+
throw new Error(`Appium had trouble loading the extension installation ` +
|
|
327
|
+
`cache file (${__classPrivateFieldGet(this, _Manifest_manifestPath, "f")}). It may be invalid YAML. Specific error: ${err.message}`);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
throw new Error(`Appium encountered an unknown problem. Specific error: ${err.message}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
__classPrivateFieldSet(this, _Manifest_data, data, "f");
|
|
335
|
+
let shouldWrite = false;
|
|
336
|
+
if ((data.schemaRev ?? 0) < constants_1.CURRENT_SCHEMA_REV) {
|
|
337
|
+
logger_1.default.debug(`Updating manifest schema from rev ${data.schemaRev ?? '(none)'} to ${constants_1.CURRENT_SCHEMA_REV}`);
|
|
338
|
+
shouldWrite = await (0, manifest_migrations_1.migrate)(this, __classPrivateFieldGet(this, _Manifest_data, "f"));
|
|
339
|
+
}
|
|
340
|
+
if (shouldWrite ||
|
|
341
|
+
((await support_1.env.hasAppiumDependency(this.appiumHome)) &&
|
|
342
|
+
(await (0, package_changed_1.packageDidChange)(this.appiumHome)))) {
|
|
343
|
+
shouldWrite = await this.syncWithInstalledExtensions();
|
|
344
|
+
}
|
|
345
|
+
if (isNewFile || shouldWrite) {
|
|
346
|
+
await this.write();
|
|
347
|
+
}
|
|
348
|
+
})(), "f");
|
|
349
|
+
try {
|
|
350
|
+
await __classPrivateFieldGet(this, _Manifest_reading, "f");
|
|
351
|
+
return __classPrivateFieldGet(this, _Manifest_data, "f");
|
|
352
|
+
}
|
|
353
|
+
finally {
|
|
354
|
+
__classPrivateFieldSet(this, _Manifest_reading, undefined, "f");
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Writes the data if it need s writing.
|
|
359
|
+
*
|
|
360
|
+
* If the `schemaRev` prop needs updating, the file will be written.
|
|
361
|
+
*
|
|
362
|
+
* @todo If this becomes too much of a bottleneck, throttle it.
|
|
363
|
+
* @returns {Promise<boolean>} Whether the data was written
|
|
364
|
+
*/
|
|
365
|
+
async write() {
|
|
366
|
+
if (__classPrivateFieldGet(this, _Manifest_writing, "f")) {
|
|
367
|
+
return __classPrivateFieldGet(this, _Manifest_writing, "f");
|
|
368
|
+
}
|
|
369
|
+
__classPrivateFieldSet(this, _Manifest_writing, (async () => {
|
|
370
|
+
await __classPrivateFieldGet(this, _Manifest_instances, "m", _Manifest_setManifestPath).call(this);
|
|
371
|
+
try {
|
|
372
|
+
await support_1.fs.mkdirp(path_1.default.dirname(__classPrivateFieldGet(this, _Manifest_manifestPath, "f")));
|
|
373
|
+
}
|
|
374
|
+
catch (err) {
|
|
375
|
+
throw new Error(`Appium could not create the directory for the manifest file: ${path_1.default.dirname(__classPrivateFieldGet(this, _Manifest_manifestPath, "f"))}. Original error: ${err.message}`);
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
await support_1.fs.writeFile(__classPrivateFieldGet(this, _Manifest_manifestPath, "f"), yaml_1.default.stringify(__classPrivateFieldGet(this, _Manifest_data, "f")), 'utf8');
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
catch (err) {
|
|
382
|
+
throw new Error(`Appium could not write to manifest at ${__classPrivateFieldGet(this, _Manifest_manifestPath, "f")} using APPIUM_HOME ${__classPrivateFieldGet(this, _Manifest_appiumHome, "f")}. Please ensure it is writable. Original error: ${err.message}`);
|
|
383
|
+
}
|
|
384
|
+
})(), "f");
|
|
385
|
+
try {
|
|
386
|
+
return await __classPrivateFieldGet(this, _Manifest_writing, "f");
|
|
387
|
+
}
|
|
388
|
+
finally {
|
|
389
|
+
__classPrivateFieldSet(this, _Manifest_writing, undefined, "f");
|
|
390
|
+
}
|
|
255
391
|
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
392
|
}
|
|
259
|
-
|
|
260
393
|
exports.Manifest = Manifest;
|
|
261
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDT05GSUdfU0NIRU1BX1JFViIsIkNPTkZJR19EQVRBX0RSSVZFUl9LRVkiLCJEUklWRVJfVFlQRSIsIkNPTkZJR19EQVRBX1BMVUdJTl9LRVkiLCJQTFVHSU5fVFlQRSIsIklOSVRJQUxfTUFOSUZFU1RfREFUQSIsIk9iamVjdCIsImZyZWV6ZSIsInNjaGVtYVJldiIsImlzRXh0ZW5zaW9uIiwidmFsdWUiLCJfIiwiaXNQbGFpbk9iamVjdCIsImFwcGl1bSIsImlzU3RyaW5nIiwibmFtZSIsInZlcnNpb24iLCJpc0RyaXZlciIsImdldCIsImlzQXJyYXkiLCJpc1BsdWdpbiIsIk1hbmlmZXN0IiwiX2RhdGEiLCJfYXBwaXVtSG9tZSIsIl9tYW5pZmVzdFBhdGgiLCJfd3JpdGluZyIsIl9yZWFkaW5nIiwiY29uc3RydWN0b3IiLCJhcHBpdW1Ib21lIiwiY2xvbmVEZWVwIiwiZ2V0SW5zdGFuY2UiLCJtZW1vaXplIiwiX2dldEluc3RhbmNlIiwic3luY1dpdGhJbnN0YWxsZWRFeHRlbnNpb25zIiwiZGlkQ2hhbmdlIiwib25NYXRjaCIsImZpbGVwYXRoIiwicGtnIiwiSlNPTiIsInBhcnNlIiwiZnMiLCJyZWFkRmlsZSIsImNoYW5nZWQiLCJhZGRFeHRlbnNpb25Gcm9tUGFja2FnZSIsInF1ZXVlIiwicGF0aCIsImpvaW4iLCJCIiwicmVzb2x2ZSIsInJlamVjdCIsImdsb2IiLCJjd2QiLCJzaWxlbnQiLCJhYnNvbHV0ZSIsImVyciIsIm9uIiwicHVzaCIsImFsbCIsImhhc0RyaXZlciIsIkJvb2xlYW4iLCJkcml2ZXJzIiwiaGFzUGx1Z2luIiwicGx1Z2lucyIsInBrZ0pzb24iLCJwa2dQYXRoIiwiZXh0ZW5zaW9uUGF0aCIsImRpcm5hbWUiLCJpbnRlcm5hbCIsInBrZ05hbWUiLCJhcHBpdW1WZXJzaW9uIiwicGVlckRlcGVuZGVuY2llcyIsImluc3RhbGxUeXBlIiwiSU5TVEFMTF9UWVBFX05QTSIsImluc3RhbGxTcGVjIiwiZHJpdmVyTmFtZSIsImFkZEV4dGVuc2lvbiIsIm9taXQiLCJwbHVnaW5OYW1lIiwiVHlwZUVycm9yIiwiZXh0VHlwZSIsImV4dE5hbWUiLCJleHREYXRhIiwiZGF0YSIsImNsb25lIiwibWFuaWZlc3RQYXRoIiwiZ2V0RXh0ZW5zaW9uRGF0YSIsInJlYWQiLCJpc05ld0ZpbGUiLCJfc2V0TWFuaWZlc3RQYXRoIiwibG9nIiwiZGVidWciLCJ5YW1sIiwiWUFNTCIsInN0cmluZ2lmeSIsImNvZGUiLCJFcnJvciIsIm1lc3NhZ2UiLCJpbnN0YWxsZWRFeHRlbnNpb25zQ2hhbmdlZCIsImVudiIsImhhc0FwcGl1bURlcGVuZGVuY3kiLCJwYWNrYWdlRGlkQ2hhbmdlIiwid3JpdGUiLCJ1bmRlZmluZWQiLCJyZXNvbHZlTWFuaWZlc3RQYXRoIiwicmVsYXRpdmUiLCJzdGFydHNXaXRoIiwibWtkaXJwIiwid3JpdGVGaWxlIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2V4dGVuc2lvbi9tYW5pZmVzdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE1vZHVsZSBjb250YWluaW5nIHtAbGluayBNYW5pZmVzdH0gd2hpY2ggaGFuZGxlcyByZWFkaW5nICYgd3JpdGluZyBvZiBleHRlbnNpb24gY29uZmlnIGZpbGVzLlxuICovXG5cbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBnbG9iIGZyb20gJ2dsb2InO1xuaW1wb3J0IHtlbnYsIGZzfSBmcm9tICdAYXBwaXVtL3N1cHBvcnQnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IFlBTUwgZnJvbSAneWFtbCc7XG5pbXBvcnQge0RSSVZFUl9UWVBFLCBQTFVHSU5fVFlQRX0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCBsb2cgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCB7SU5TVEFMTF9UWVBFX05QTX0gZnJvbSAnLi9leHRlbnNpb24tY29uZmlnJztcbmltcG9ydCB7cGFja2FnZURpZENoYW5nZX0gZnJvbSAnLi9wYWNrYWdlLWNoYW5nZWQnO1xuXG4vKipcbiAqIEN1cnJlbnQgY29uZmlndXJhdGlvbiBzY2hlbWEgcmV2aXNpb24hXG4gKi9cbmNvbnN0IENPTkZJR19TQ0hFTUFfUkVWID0gMjtcblxuLyoqXG4gKiBUaGUgbmFtZSBvZiB0aGUgcHJvcCAoYGRyaXZlcnNgKSB1c2VkIGluIGBleHRlbnNpb25zLnlhbWxgIGZvciBkcml2ZXJzLlxuICogQHR5cGUge2Ake3R5cGVvZiBEUklWRVJfVFlQRX1zYH1cbiAqL1xuY29uc3QgQ09ORklHX0RBVEFfRFJJVkVSX0tFWSA9IGAke0RSSVZFUl9UWVBFfXNgO1xuXG4vKipcbiAqIFRoZSBuYW1lIG9mIHRoZSBwcm9wIChgcGx1Z2luc2ApIHVzZWQgaW4gYGV4dGVuc2lvbnMueWFtbGAgZm9yIHBsdWdpbnMuXG4gKiBAdHlwZSB7YCR7dHlwZW9mIFBMVUdJTl9UWVBFfXNgfVxuICovXG5jb25zdCBDT05GSUdfREFUQV9QTFVHSU5fS0VZID0gYCR7UExVR0lOX1RZUEV9c2A7XG5cbi8qKlxuICogQHR5cGUge1JlYWRvbmx5PE1hbmlmZXN0RGF0YT59XG4gKi9cbmNvbnN0IElOSVRJQUxfTUFOSUZFU1RfREFUQSA9IE9iamVjdC5mcmVlemUoe1xuICBbQ09ORklHX0RBVEFfRFJJVkVSX0tFWV06IE9iamVjdC5mcmVlemUoe30pLFxuICBbQ09ORklHX0RBVEFfUExVR0lOX0tFWV06IE9iamVjdC5mcmVlemUoe30pLFxuICBzY2hlbWFSZXY6IENPTkZJR19TQ0hFTUFfUkVWLFxufSk7XG5cbi8qKlxuICogR2l2ZW4gYSBgcGFja2FnZS5qc29uYCByZXR1cm4gYHRydWVgIGlmIGl0IHJlcHJlc2VudHMgYW4gQXBwaXVtIEV4dGVuc2lvbiAoZWl0aGVyIGEgZHJpdmVyIG9yIHBsdWdpbikuXG4gKlxuICogVGhlIGBwYWNrYWdlLmpzb25gIG11c3QgaGF2ZSBhbiBgYXBwaXVtYCBwcm9wZXJ0eSB3aGljaCBpcyBhbiBvYmplY3QuXG4gKiBAcGFyYW0ge2FueX0gdmFsdWVcbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBFeHRQYWNrYWdlSnNvbjxFeHRlbnNpb25UeXBlPn1cbiAqL1xuZnVuY3Rpb24gaXNFeHRlbnNpb24odmFsdWUpIHtcbiAgcmV0dXJuIChcbiAgICBfLmlzUGxhaW5PYmplY3QodmFsdWUpICYmXG4gICAgXy5pc1BsYWluT2JqZWN0KHZhbHVlLmFwcGl1bSkgJiZcbiAgICBfLmlzU3RyaW5nKHZhbHVlLm5hbWUpICYmXG4gICAgXy5pc1N0cmluZyh2YWx1ZS52ZXJzaW9uKVxuICApO1xufVxuLyoqXG4gKiBHaXZlbiBhIGBwYWNrYWdlLmpzb25gLCByZXR1cm4gYHRydWVgIGlmIGl0IHJlcHJlc2VudHMgYW4gQXBwaXVtIERyaXZlci5cbiAqXG4gKiBUbyBiZSBjb25zaWRlcmVkIGEgZHJpdmVyLCBhIGBwYWNrYWdlLmpzb25gIG11c3QgaGF2ZSBhIGZpZWxkc1xuICogYGFwcGl1bS5kcml2ZXJOYW1lYCwgYGFwcGl1bS5hdXRvbWF0aW9uTmFtZWAgYW5kIGBhcHBpdW0ucGxhdGZvcm1OYW1lc2AuXG4gKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBWYWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7dmFsdWUgaXMgRXh0UGFja2FnZUpzb248RHJpdmVyVHlwZT59XG4gKi9cbmZ1bmN0aW9uIGlzRHJpdmVyKHZhbHVlKSB7XG4gIHJldHVybiAoXG4gICAgaXNFeHRlbnNpb24odmFsdWUpICYmXG4gICAgXy5pc1N0cmluZyhfLmdldCh2YWx1ZSwgJ2FwcGl1bS5kcml2ZXJOYW1lJykpICYmXG4gICAgXy5pc1N0cmluZyhfLmdldCh2YWx1ZSwgJ2FwcGl1bS5hdXRvbWF0aW9uTmFtZScpKSAmJlxuICAgIF8uaXNBcnJheShfLmdldCh2YWx1ZSwgJ2FwcGl1bS5wbGF0Zm9ybU5hbWVzJykpXG4gICk7XG59XG5cbi8qKlxuICogR2l2ZW4gYSBgcGFja2FnZS5qc29uYCwgcmV0dXJuIGB0cnVlYCBpZiBpdCByZXByZXNlbnRzIGFuIEFwcGl1bSBQbHVnaW4uXG4gKlxuICogVG8gYmUgY29uc2lkZXJlZCBhIHBsdWdpbiwgYSBgcGFja2FnZS5qc29uYCBtdXN0IGhhdmUgYW4gYGFwcGl1bS5wbHVnaW5OYW1lYCBmaWVsZC5cbiAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBFeHRQYWNrYWdlSnNvbjxQbHVnaW5UeXBlPn1cbiAqL1xuZnVuY3Rpb24gaXNQbHVnaW4odmFsdWUpIHtcbiAgcmV0dXJuIGlzRXh0ZW5zaW9uKHZhbHVlKSAmJiBfLmlzU3RyaW5nKF8uZ2V0KHZhbHVlLCAnYXBwaXVtLnBsdWdpbk5hbWUnKSk7XG59XG5cbi8qKlxuICogSGFuZGxlcyByZWFkaW5nICYgd3JpdGluZyBvZiBleHRlbnNpb24gY29uZmlnIGZpbGVzLlxuICpcbiAqIE9ubHkgb25lIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgZXhpc3RzIHBlciB2YWx1ZSBvZiBgQVBQSVVNX0hPTUVgLlxuICovXG5leHBvcnQgY2xhc3MgTWFuaWZlc3Qge1xuICAvKipcbiAgICogVGhlIGVudGlyZSBjb250ZW50cyBvZiBhIHBhcnNlZCBZQU1MIGV4dGVuc2lvbiBjb25maWcgZmlsZS5cbiAgICpcbiAgICogQ29udGFpbnMgcHJveGllcyBmb3IgYXV0b21hdGljIHBlcnNpc3RlbmNlIG9uIGRpc2tcbiAgICogQHR5cGUge01hbmlmZXN0RGF0YX1cbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9kYXRhO1xuXG4gIC8qKlxuICAgKiBQYXRoIHRvIGBBUFBJVU1fSE9NRWAuXG4gICAqIEBwcml2YXRlXG4gICAqIEB0eXBlIHtSZWFkb25seTxzdHJpbmc+fVxuICAgKi9cbiAgX2FwcGl1bUhvbWU7XG5cbiAgLyoqXG4gICAqIFBhdGggdG8gYGV4dGVuc2lvbnMueWFtbGBcbiAgICogQHR5cGUge3N0cmluZ31cbiAgICogTm90IHNldCB1bnRpbCB7QGxpbmsgTWFuaWZlc3QucmVhZH0gaXMgY2FsbGVkLlxuICAgKi9cbiAgX21hbmlmZXN0UGF0aDtcblxuICAvKipcbiAgICogSGVscHMgYXZvaWQgd3JpdGluZyBtdWx0aXBsZSB0aW1lcy5cbiAgICpcbiAgICogSWYgdGhpcyBpcyBgdW5kZWZpbmVkYCwgY2FsbGluZyB7QGxpbmsgTWFuaWZlc3Qud3JpdGV9IHdpbGwgY2F1c2UgaXQgdG8gYmVcbiAgICogc2V0IHRvIGEgYFByb21pc2VgLiBXaGVuIHRoZSBjYWxsIHRvIGB3cml0ZSgpYCBpcyBjb21wbGV0ZSwgdGhlIGBQcm9taXNlYFxuICAgKiB3aWxsIHJlc29sdmUgYW5kIHRoZW4gdGhpcyB2YWx1ZSB3aWxsIGJlIHNldCB0byBgdW5kZWZpbmVkYC4gIENvbmN1cnJlbnQgY2FsbHNcbiAgICogbWFkZSB3aGlsZSB0aGlzIHZhbHVlIGlzIGEgYFByb21pc2VgIHdpbGwgcmV0dXJuIHRoZSBgUHJvbWlzZWAgaXRzZWxmLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAdHlwZSB7UHJvbWlzZTxib29sZWFuPnx1bmRlZmluZWR9XG4gICAqL1xuICBfd3JpdGluZztcblxuICAvKipcbiAgICogSGVscHMgYXZvaWQgcmVhZGluZyBtdWx0aXBsZSB0aW1lcy5cbiAgICpcbiAgICogSWYgdGhpcyBpcyBgdW5kZWZpbmVkYCwgY2FsbGluZyB7QGxpbmsgTWFuaWZlc3QucmVhZH0gd2lsbCBjYXVzZSBpdCB0byBiZVxuICAgKiBzZXQgdG8gYSBgUHJvbWlzZWAuIFdoZW4gdGhlIGNhbGwgdG8gYHJlYWQoKWAgaXMgY29tcGxldGUsIHRoZSBgUHJvbWlzZWBcbiAgICogd2lsbCByZXNvbHZlIGFuZCB0aGVuIHRoaXMgdmFsdWUgd2lsbCBiZSBzZXQgdG8gYHVuZGVmaW5lZGAuICBDb25jdXJyZW50IGNhbGxzXG4gICAqIG1hZGUgd2hpbGUgdGhpcyB2YWx1ZSBpcyBhIGBQcm9taXNlYCB3aWxsIHJldHVybiB0aGUgYFByb21pc2VgIGl0c2VsZi5cbiAgICogQHByaXZhdGVcbiAgICogQHR5cGUge1Byb21pc2U8dm9pZD58dW5kZWZpbmVkfVxuICAgKi9cbiAgX3JlYWRpbmc7XG5cbiAgLyoqXG4gICAqIFNldHMgaW50ZXJuYWwgZGF0YSB0byBhIGZyZXNoIGNsb25lIG9mIHtAbGluayBJTklUSUFMX01BTklGRVNUX0RBVEF9XG4gICAqXG4gICAqIFVzZSB7QGxpbmsgTWFuaWZlc3QuZ2V0SW5zdGFuY2V9IGluc3RlYWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcHBpdW1Ib21lXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhcHBpdW1Ib21lKSB7XG4gICAgdGhpcy5fYXBwaXVtSG9tZSA9IGFwcGl1bUhvbWU7XG4gICAgdGhpcy5fZGF0YSA9IF8uY2xvbmVEZWVwKElOSVRJQUxfTUFOSUZFU1RfREFUQSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIG5ldyBvciBleGlzdGluZyB7QGxpbmsgTWFuaWZlc3R9IGluc3RhbmNlLCBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgYGFwcGl1bUhvbWVgLlxuICAgKlxuICAgKiBNYWludGFpbnMgb25lIGluc3RhbmNlIHBlciB2YWx1ZSBvZiBgYXBwaXVtSG9tZWAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcHBpdW1Ib21lIC0gUGF0aCB0byBgQVBQSVVNX0hPTUVgXG4gICAqIEByZXR1cm5zIHtNYW5pZmVzdH1cbiAgICovXG4gIHN0YXRpYyBnZXRJbnN0YW5jZSA9IF8ubWVtb2l6ZShmdW5jdGlvbiBfZ2V0SW5zdGFuY2UoYXBwaXVtSG9tZSkge1xuICAgIHJldHVybiBuZXcgTWFuaWZlc3QoYXBwaXVtSG9tZSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBTZWFyY2hlcyBgQVBQSVVNX0hPTUVgIGZvciBpbnN0YWxsZWQgZXh0ZW5zaW9ucyBhbmQgYWRkcyB0aGVtIHRvIHRoZSBtYW5pZmVzdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IGB0cnVlYCBpZiBhbnkgZXh0ZW5zaW9ucyB3ZXJlIGFkZGVkLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICovXG4gIGFzeW5jIHN5bmNXaXRoSW5zdGFsbGVkRXh0ZW5zaW9ucygpIHtcbiAgICAvLyB0aGlzIGNvdWxkIGJlIHBhcmFsbGVsaXplZCwgYnV0IHdlIGNhbid0IHVzZSBmcy53YWxrIGFzIGFuIGFzeW5jIGl0ZXJhdG9yXG4gICAgbGV0IGRpZENoYW5nZSA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogTGlzdGVuZXIgZm9yIHRoZSBgbWF0Y2hgIGV2ZW50IG9mIGEgYGdsb2JgIGluc3RhbmNlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVwYXRoIC0gUGF0aCB0byBhIGBwYWNrYWdlLmpzb25gXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgY29uc3Qgb25NYXRjaCA9IGFzeW5jIChmaWxlcGF0aCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGtnID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShmaWxlcGF0aCwgJ3V0ZjgnKSk7XG4gICAgICAgIGlmIChpc0RyaXZlcihwa2cpIHx8IGlzUGx1Z2luKHBrZykpIHtcbiAgICAgICAgICBjb25zdCBjaGFuZ2VkID0gdGhpcy5hZGRFeHRlbnNpb25Gcm9tUGFja2FnZShwa2csIGZpbGVwYXRoKTtcbiAgICAgICAgICBkaWRDaGFuZ2UgPSBkaWRDaGFuZ2UgfHwgY2hhbmdlZDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7fVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBIGxpc3Qgb2YgYFByb21pc2VgcyB3aGljaCByZWFkIGBwYWNrYWdlLmpzb25gIGZpbGVzIGxvb2tpbmcgZm9yIEFwcGl1bSBleHRlbnNpb25zLlxuICAgICAqIEB0eXBlIHtQcm9taXNlPHZvaWQ+W119XG4gICAgICovXG4gICAgY29uc3QgcXVldWUgPSBbXG4gICAgICAvLyBsb29rIGF0IGBwYWNrYWdlLmpzb25gIGluIGBBUFBJVU1fSE9NRWAgb25seVxuICAgICAgb25NYXRjaChwYXRoLmpvaW4odGhpcy5fYXBwaXVtSG9tZSwgJ3BhY2thZ2UuanNvbicpKSxcbiAgICBdO1xuXG4gICAgLy8gYWRkIGRlcGVuZGVuY2llcyB0byB0aGUgcXVldWVcbiAgICBhd2FpdCBuZXcgQigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBnbG9iKFxuICAgICAgICAnbm9kZV9tb2R1bGVzL3sqLEAqLyp9L3BhY2thZ2UuanNvbicsXG4gICAgICAgIHtjd2Q6IHRoaXMuX2FwcGl1bUhvbWUsIHNpbGVudDogdHJ1ZSwgYWJzb2x1dGU6IHRydWV9LFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJvbWlzZS9wcmVmZXItYXdhaXQtdG8tY2FsbGJhY2tzXG4gICAgICAgIChlcnIpID0+IHtcbiAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAgIC5vbignZXJyb3InLCByZWplY3QpXG4gICAgICAgIC5vbignbWF0Y2gnLCAoZmlsZXBhdGgpID0+IHtcbiAgICAgICAgICBxdWV1ZS5wdXNoKG9uTWF0Y2goZmlsZXBhdGgpKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyB3YWl0IGZvciBldmVyeXRoaW5nIHRvIGZpbmlzaFxuICAgIGF3YWl0IEIuYWxsKHF1ZXVlKTtcblxuICAgIHJldHVybiBkaWRDaGFuZ2U7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBgdHJ1ZWAgaWYgZHJpdmVyIHdpdGggbmFtZSBgbmFtZWAgaXMgcmVnaXN0ZXJlZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBEcml2ZXIgbmFtZVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIGhhc0RyaXZlcihuYW1lKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4odGhpcy5fZGF0YS5kcml2ZXJzW25hbWVdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGB0cnVlYCBpZiBwbHVnaW4gd2l0aCBuYW1lIGBuYW1lYCBpcyByZWdpc3RlcmVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFBsdWdpbiBuYW1lXG4gICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgKi9cbiAgaGFzUGx1Z2luKG5hbWUpIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLl9kYXRhLnBsdWdpbnNbbmFtZV0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdpdmVuIGEgcGF0aCB0byBhIGBwYWNrYWdlLmpzb25gLCBhZGQgaXQgYXMgZWl0aGVyIGEgZHJpdmVyIG9yIHBsdWdpbiB0byB0aGUgbWFuaWZlc3QuXG4gICAqXG4gICAqIFdpbGwgX25vdF8gb3ZlcndyaXRlIGV4aXN0aW5nIGVudHJpZXMuXG4gICAqIEB0ZW1wbGF0ZSB7RXh0ZW5zaW9uVHlwZX0gRXh0VHlwZVxuICAgKiBAcGFyYW0ge0V4dFBhY2thZ2VKc29uPEV4dFR5cGU+fSBwa2dKc29uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwa2dQYXRoXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIGB0cnVlYCB1cG9uIHN1Y2Nlc3MsIGBmYWxzZWAgaWYgdGhlIGV4dGVuc2lvbiBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuXG4gICAqL1xuICBhZGRFeHRlbnNpb25Gcm9tUGFja2FnZShwa2dKc29uLCBwa2dQYXRoKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uUGF0aCA9IHBhdGguZGlybmFtZShwa2dQYXRoKTtcblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtJbnRlcm5hbE1ldGFkYXRhfVxuICAgICAqL1xuICAgIGNvbnN0IGludGVybmFsID0ge1xuICAgICAgcGtnTmFtZTogcGtnSnNvbi5uYW1lLFxuICAgICAgdmVyc2lvbjogcGtnSnNvbi52ZXJzaW9uLFxuICAgICAgYXBwaXVtVmVyc2lvbjogcGtnSnNvbi5wZWVyRGVwZW5kZW5jaWVzPy5hcHBpdW0sXG4gICAgICBpbnN0YWxsVHlwZTogSU5TVEFMTF9UWVBFX05QTSxcbiAgICAgIGluc3RhbGxTcGVjOiBgJHtwa2dKc29uLm5hbWV9QCR7cGtnSnNvbi52ZXJzaW9ufWAsXG4gICAgfTtcblxuICAgIGlmIChpc0RyaXZlcihwa2dKc29uKSkge1xuICAgICAgaWYgKCF0aGlzLmhhc0RyaXZlcihwa2dKc29uLmFwcGl1bS5kcml2ZXJOYW1lKSkge1xuICAgICAgICB0aGlzLmFkZEV4dGVuc2lvbihEUklWRVJfVFlQRSwgcGtnSnNvbi5hcHBpdW0uZHJpdmVyTmFtZSwge1xuICAgICAgICAgIC4uLl8ub21pdChwa2dKc29uLmFwcGl1bSwgJ2RyaXZlck5hbWUnKSxcbiAgICAgICAgICAuLi5pbnRlcm5hbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoaXNQbHVnaW4ocGtnSnNvbikpIHtcbiAgICAgIGlmICghdGhpcy5oYXNQbHVnaW4ocGtnSnNvbi5hcHBpdW0ucGx1Z2luTmFtZSkpIHtcbiAgICAgICAgdGhpcy5hZGRFeHRlbnNpb24oUExVR0lOX1RZUEUsIHBrZ0pzb24uYXBwaXVtLnBsdWdpbk5hbWUsIHtcbiAgICAgICAgICAuLi5fLm9taXQocGtnSnNvbi5hcHBpdW0sICdwbHVnaW5OYW1lJyksXG4gICAgICAgICAgLi4uaW50ZXJuYWwsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgYFRoZSBleHRlbnNpb24gaW4gJHtleHRlbnNpb25QYXRofSBpcyBuZWl0aGVyIGEgdmFsaWQgZHJpdmVyIG5vciBhIHZhbGlkIHBsdWdpbi5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIGV4dGVuc2lvbiB0byB0aGUgbWFuaWZlc3QgYXMgd2FzIGluc3RhbGxlZCBieSB0aGUgYGFwcGl1bWAgQ0xJLiAgVGhlXG4gICAqIGBleHREYXRhYCwgYGV4dFR5cGVgLCBhbmQgYGV4dE5hbWVgIGhhdmUgYWxyZWFkeSBiZWVuIGRldGVybWluZWQuXG4gICAqXG4gICAqIFNlZSB7QGxpbmsgTWFuaWZlc3QuYWRkRXh0ZW5zaW9uRnJvbVBhY2thZ2V9IGZvciBhZGRpbmcgYW4gZXh0ZW5zaW9uIGZyb20gYW4gb24tZGlzayBwYWNrYWdlLlxuICAgKiBAdGVtcGxhdGUge0V4dGVuc2lvblR5cGV9IEV4dFR5cGVcbiAgICogQHBhcmFtIHtFeHRUeXBlfSBleHRUeXBlIC0gYGRyaXZlcmAgb3IgYHBsdWdpbmBcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV4dE5hbWUgLSBOYW1lIG9mIGV4dGVuc2lvblxuICAgKiBAcGFyYW0ge0V4dE1hbmlmZXN0PEV4dFR5cGU+fSBleHREYXRhIC0gRXh0ZW5zaW9uIG1ldGFkYXRhXG4gICAqIEByZXR1cm5zIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gQSBjbG9uZSBvZiBgZXh0RGF0YWAsIHBvdGVudGlhbGx5IHdpdGggYSBtdXRhdGVkIGBhcHBpdW1WZXJzaW9uYCBmaWVsZFxuICAgKi9cbiAgYWRkRXh0ZW5zaW9uKGV4dFR5cGUsIGV4dE5hbWUsIGV4dERhdGEpIHtcbiAgICBjb25zdCBkYXRhID0gXy5jbG9uZShleHREYXRhKTtcbiAgICB0aGlzLl9kYXRhW2Ake2V4dFR5cGV9c2BdW2V4dE5hbWVdID0gZGF0YTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBBUFBJVU1fSE9NRSBwYXRoXG4gICAqL1xuICBnZXQgYXBwaXVtSG9tZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fYXBwaXVtSG9tZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwYXRoIHRvIHRoZSBtYW5pZmVzdCBmaWxlXG4gICAqL1xuICBnZXQgbWFuaWZlc3RQYXRoKCkge1xuICAgIHJldHVybiB0aGlzLl9tYW5pZmVzdFBhdGg7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBleHRlbnNpb24gZGF0YSBmb3IgYSBwYXJ0aWN1bGFyIHR5cGUuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSB7RXh0ZW5zaW9uVHlwZX0gRXh0VHlwZVxuICAgKiBAcGFyYW0ge0V4dFR5cGV9IGV4dFR5cGVcbiAgICogQHJldHVybnMge0V4dFJlY29yZDxFeHRUeXBlPn1cbiAgICovXG4gIGdldEV4dGVuc2lvbkRhdGEoZXh0VHlwZSkge1xuICAgIHJldHVybiB0aGlzLl9kYXRhWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoYCR7ZXh0VHlwZX1zYCldO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIG1hbmlmZXN0IGZyb20gZGlzayBhbmQgX292ZXJ3cml0ZXNfIHRoZSBpbnRlcm5hbCBkYXRhLlxuICAgKlxuICAgKiBJZiB0aGUgbWFuaWZlc3QgZG9lcyBub3QgZXhpc3Qgb24gZGlzaywgYW4ge0BsaW5rIElOSVRJQUxfTUFOSUZFU1RfREFUQSBcImVtcHR5XCJ9IG1hbmlmZXN0IGZpbGUgd2lsbCBiZSBjcmVhdGVkLlxuICAgKlxuICAgKiBJZiBgQVBQSVVNX0hPTUVgIGNvbnRhaW5zIGEgYHBhY2thZ2UuanNvbmAgd2l0aCBhbiBgYXBwaXVtYCBkZXBlbmRlbmN5LCB0aGVuIGEgaGFzaCBvZiB0aGUgYHBhY2thZ2UuanNvbmAgd2lsbCBiZSB0YWtlbi4gSWYgdGhpcyBoYXNoIGRpZmZlcnMgZnJvbSB0aGUgbGFzdCBoYXNoLCB0aGUgY29udGVudHMgb2YgYEFQUElVTV9IT01FL25vZGVfbW9kdWxlc2Agd2lsbCBiZSBzY2FubmVkIGZvciBleHRlbnNpb25zIHRoYXQgbWF5IGhhdmUgYmVlbiBpbnN0YWxsZWQgb3V0c2lkZSBvZiB0aGUgYGFwcGl1bWAgQ0xJLiAgQW55IGZvdW5kIGV4dGVuc2lvbnMgd2lsbCBiZSBhZGRlZCB0byB0aGUgbWFuaWZlc3QgZmlsZSwgYW5kIGlmIHNvLCB0aGUgbWFuaWZlc3QgZmlsZSB3aWxsIGJlIHdyaXR0ZW4gdG8gZGlzay5cbiAgICpcbiAgICogT25seSBvbmUgcmVhZCBvcGVyYXRpb24gc2hvdWxkIGhhcHBlbiBhdCBhIHRpbWUuICBUaGlzIGlzIGNvbnRyb2xsZWQgdmlhIHRoZSB7QGxpbmsgTWFuaWZlc3QuX3JlYWRpbmd9IHByb3BlcnR5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNYW5pZmVzdERhdGE+fSBUaGUgZGF0YVxuICAgKi9cbiAgYXN5bmMgcmVhZCgpIHtcbiAgICBpZiAodGhpcy5fcmVhZGluZykge1xuICAgICAgYXdhaXQgdGhpcy5fcmVhZGluZztcbiAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgIH1cblxuICAgIHRoaXMuX3JlYWRpbmcgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgLyoqIEB0eXBlIHtNYW5pZmVzdERhdGF9ICovXG4gICAgICBsZXQgZGF0YTtcbiAgICAgIGxldCBpc05ld0ZpbGUgPSBmYWxzZTtcbiAgICAgIGF3YWl0IHRoaXMuX3NldE1hbmlmZXN0UGF0aCgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgbG9nLmRlYnVnKGBSZWFkaW5nICR7dGhpcy5fbWFuaWZlc3RQYXRofS4uLmApO1xuICAgICAgICBjb25zdCB5YW1sID0gYXdhaXQgZnMucmVhZEZpbGUodGhpcy5fbWFuaWZlc3RQYXRoLCAndXRmOCcpO1xuICAgICAgICBkYXRhID0gWUFNTC5wYXJzZSh5YW1sKTtcbiAgICAgICAgbG9nLmRlYnVnKGBQYXJzZWQgbWFuaWZlc3QgZmlsZTogJHtKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKX1gKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09ICdFTk9FTlQnKSB7XG4gICAgICAgICAgZGF0YSA9IF8uY2xvbmVEZWVwKElOSVRJQUxfTUFOSUZFU1RfREFUQSk7XG4gICAgICAgICAgaXNOZXdGaWxlID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAodGhpcy5fbWFuaWZlc3RQYXRoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGBBcHBpdW0gaGFkIHRyb3VibGUgbG9hZGluZyB0aGUgZXh0ZW5zaW9uIGluc3RhbGxhdGlvbiBgICtcbiAgICAgICAgICAgICAgICBgY2FjaGUgZmlsZSAoJHt0aGlzLl9tYW5pZmVzdFBhdGh9KS4gSXQgbWF5IGJlIGludmFsaWQgWUFNTC4gU3BlY2lmaWMgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgQXBwaXVtIGVuY291bnRlcmVkIGFuIHVua25vd24gcHJvYmxlbS4gU3BlY2lmaWMgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICBsZXQgaW5zdGFsbGVkRXh0ZW5zaW9uc0NoYW5nZWQgPSBmYWxzZTtcbiAgICAgIGlmIChcbiAgICAgICAgKGF3YWl0IGVudi5oYXNBcHBpdW1EZXBlbmRlbmN5KHRoaXMuYXBwaXVtSG9tZSkpICYmXG4gICAgICAgIChhd2FpdCBwYWNrYWdlRGlkQ2hhbmdlKHRoaXMuYXBwaXVtSG9tZSkpXG4gICAgICApIHtcbiAgICAgICAgaW5zdGFsbGVkRXh0ZW5zaW9uc0NoYW5nZWQgPSBhd2FpdCB0aGlzLnN5bmNXaXRoSW5zdGFsbGVkRXh0ZW5zaW9ucygpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNOZXdGaWxlIHx8IGluc3RhbGxlZEV4dGVuc2lvbnNDaGFuZ2VkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMud3JpdGUoKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9yZWFkaW5nO1xuICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX3JlYWRpbmcgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMge0BsaW5rIE1hbmlmZXN0Ll9tYW5pZmVzdFBhdGh9IGlzIHNldC5cbiAgICpcbiAgICogQ3JlYXRlcyB0aGUgZGlyZWN0b3J5IGlmIG5lY2Vzc2FyeS5cbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn1cbiAgICovXG4gIGFzeW5jIF9zZXRNYW5pZmVzdFBhdGgoKSB7XG4gICAgaWYgKCF0aGlzLl9tYW5pZmVzdFBhdGgpIHtcbiAgICAgIHRoaXMuX21hbmlmZXN0UGF0aCA9IGF3YWl0IGVudi5yZXNvbHZlTWFuaWZlc3RQYXRoKHRoaXMuX2FwcGl1bUhvbWUpO1xuXG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgIGlmIChwYXRoLnJlbGF0aXZlKHRoaXMuX2FwcGl1bUhvbWUsIHRoaXMuX21hbmlmZXN0UGF0aCkuc3RhcnRzV2l0aCgnLicpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgTWlzbWF0Y2ggYmV0d2VlbiBsb2NhdGlvbiBvZiBBUFBJVU1fSE9NRSBhbmQgbWFuaWZlc3QgZmlsZS4gQVBQSVVNX0hPTUU6ICR7dGhpcy5hcHBpdW1Ib21lfSwgbWFuaWZlc3QgZmlsZTogJHt0aGlzLl9tYW5pZmVzdFBhdGh9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9tYW5pZmVzdFBhdGg7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIHRoZSBkYXRhIGlmIGl0IG5lZWQgcyB3cml0aW5nLlxuICAgKlxuICAgKiBJZiB0aGUgYHNjaGVtYVJldmAgcHJvcCBuZWVkcyB1cGRhdGluZywgdGhlIGZpbGUgd2lsbCBiZSB3cml0dGVuLlxuICAgKlxuICAgKiBAdG9kbyBJZiB0aGlzIGJlY29tZXMgdG9vIG11Y2ggb2YgYSBib3R0bGVuZWNrLCB0aHJvdHRsZSBpdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgdGhlIGRhdGEgd2FzIHdyaXR0ZW5cbiAgICovXG4gIGFzeW5jIHdyaXRlKCkge1xuICAgIGlmICh0aGlzLl93cml0aW5nKSB7XG4gICAgICByZXR1cm4gdGhpcy5fd3JpdGluZztcbiAgICB9XG4gICAgdGhpcy5fd3JpdGluZyA9IChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLl9zZXRNYW5pZmVzdFBhdGgoKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLm1rZGlycChwYXRoLmRpcm5hbWUodGhpcy5fbWFuaWZlc3RQYXRoKSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBBcHBpdW0gY291bGQgbm90IGNyZWF0ZSB0aGUgZGlyZWN0b3J5IGZvciB0aGUgbWFuaWZlc3QgZmlsZTogJHtwYXRoLmRpcm5hbWUoXG4gICAgICAgICAgICB0aGlzLl9tYW5pZmVzdFBhdGhcbiAgICAgICAgICApfS4gT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHRoaXMuX21hbmlmZXN0UGF0aCwgWUFNTC5zdHJpbmdpZnkodGhpcy5fZGF0YSksICd1dGY4Jyk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgQXBwaXVtIGNvdWxkIG5vdCB3cml0ZSB0byBtYW5pZmVzdCBhdCAke3RoaXMuX21hbmlmZXN0UGF0aH0gdXNpbmcgQVBQSVVNX0hPTUUgJHt0aGlzLl9hcHBpdW1Ib21lfS4gYCArXG4gICAgICAgICAgICBgUGxlYXNlIGVuc3VyZSBpdCBpcyB3cml0YWJsZS4gT3JpZ2luYWwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pKCk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLl93cml0aW5nO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLl93cml0aW5nID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFR5cGUgb2YgdGhlIHN0cmluZyByZWZlcnJpbmcgdG8gYSBkcml2ZXIgKHR5cGljYWxseSBhcyBhIGtleSBvciB0eXBlIHN0cmluZylcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5Ecml2ZXJUeXBlfSBEcml2ZXJUeXBlXG4gKi9cblxuLyoqXG4gKiBUeXBlIG9mIHRoZSBzdHJpbmcgcmVmZXJyaW5nIHRvIGEgcGx1Z2luICh0eXBpY2FsbHkgYXMgYSBrZXkgb3IgdHlwZSBzdHJpbmcpXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuUGx1Z2luVHlwZX0gUGx1Z2luVHlwZVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgU3luY1dpdGhJbnN0YWxsZWRFeHRlbnNpb25zT3B0c1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZXB0aExpbWl0XSAtIE1heGltdW0gZGVwdGggdG8gcmVjdXJzZSBpbnRvIHN1YmRpcmVjdG9yaWVzXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHBpdW0vdHlwZXMnKS5NYW5pZmVzdERhdGF9IE1hbmlmZXN0RGF0YVxuICogQHR5cGVkZWYge2ltcG9ydCgnYXBwaXVtL3R5cGVzJykuSW50ZXJuYWxNZXRhZGF0YX0gSW50ZXJuYWxNZXRhZGF0YVxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2FwcGl1bS90eXBlcycpLkV4dFBhY2thZ2VKc29uPFQ+fSBFeHRQYWNrYWdlSnNvblxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2FwcGl1bS90eXBlcycpLkV4dE1hbmlmZXN0PFQ+fSBFeHRNYW5pZmVzdFxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2FwcGl1bS90eXBlcycpLkV4dFJlY29yZDxUPn0gRXh0UmVjb3JkXG4gKi9cblxuLyoqXG4gKiBFaXRoZXIgYGRyaXZlcmAgb3IgYHBsdWdpbmAgcm5cbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ0BhcHBpdW0vdHlwZXMnKS5FeHRlbnNpb25UeXBlfSBFeHRlbnNpb25UeXBlXG4gKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBSUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFLQSxNQUFNQSxpQkFBaUIsR0FBRyxDQUExQjtBQU1BLE1BQU1DLHNCQUFzQixHQUFJLEdBQUVDLHNCQUFZLEdBQTlDO0FBTUEsTUFBTUMsc0JBQXNCLEdBQUksR0FBRUMsc0JBQVksR0FBOUM7QUFLQSxNQUFNQyxxQkFBcUIsR0FBR0MsTUFBTSxDQUFDQyxNQUFQLENBQWM7RUFDMUMsQ0FBQ04sc0JBQUQsR0FBMEJLLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLEVBQWQsQ0FEZ0I7RUFFMUMsQ0FBQ0osc0JBQUQsR0FBMEJHLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLEVBQWQsQ0FGZ0I7RUFHMUNDLFNBQVMsRUFBRVI7QUFIK0IsQ0FBZCxDQUE5Qjs7QUFhQSxTQUFTUyxXQUFULENBQXFCQyxLQUFyQixFQUE0QjtFQUMxQixPQUNFQyxlQUFBLENBQUVDLGFBQUYsQ0FBZ0JGLEtBQWhCLEtBQ0FDLGVBQUEsQ0FBRUMsYUFBRixDQUFnQkYsS0FBSyxDQUFDRyxNQUF0QixDQURBLElBRUFGLGVBQUEsQ0FBRUcsUUFBRixDQUFXSixLQUFLLENBQUNLLElBQWpCLENBRkEsSUFHQUosZUFBQSxDQUFFRyxRQUFGLENBQVdKLEtBQUssQ0FBQ00sT0FBakIsQ0FKRjtBQU1EOztBQVNELFNBQVNDLFFBQVQsQ0FBa0JQLEtBQWxCLEVBQXlCO0VBQ3ZCLE9B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
|
|
394
|
+
_Manifest_data = new WeakMap(), _Manifest_appiumHome = new WeakMap(), _Manifest_manifestPath = new WeakMap(), _Manifest_writing = new WeakMap(), _Manifest_reading = new WeakMap(), _Manifest_instances = new WeakSet(), _Manifest_setManifestPath =
|
|
395
|
+
/**
|
|
396
|
+
* Ensures the internal manifest path is set.
|
|
397
|
+
*
|
|
398
|
+
* Creates the directory if necessary.
|
|
399
|
+
* @returns {Promise<string>}
|
|
400
|
+
*/
|
|
401
|
+
async function _Manifest_setManifestPath() {
|
|
402
|
+
if (!__classPrivateFieldGet(this, _Manifest_manifestPath, "f")) {
|
|
403
|
+
__classPrivateFieldSet(this, _Manifest_manifestPath, await support_1.env.resolveManifestPath(__classPrivateFieldGet(this, _Manifest_appiumHome, "f")), "f");
|
|
404
|
+
/* istanbul ignore if */
|
|
405
|
+
if (path_1.default.relative(__classPrivateFieldGet(this, _Manifest_appiumHome, "f"), __classPrivateFieldGet(this, _Manifest_manifestPath, "f")).startsWith('.')) {
|
|
406
|
+
throw new Error(`Mismatch between location of APPIUM_HOME and manifest file. APPIUM_HOME: ${this.appiumHome}, manifest file: ${__classPrivateFieldGet(this, _Manifest_manifestPath, "f")}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return __classPrivateFieldGet(this, _Manifest_manifestPath, "f");
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* Returns a new or existing {@link Manifest} instance, based on the value of `appiumHome`.
|
|
413
|
+
*
|
|
414
|
+
* Maintains one instance per value of `appiumHome`.
|
|
415
|
+
* @param {string} appiumHome - Path to `APPIUM_HOME`
|
|
416
|
+
* @returns {Manifest}
|
|
417
|
+
*/
|
|
418
|
+
Manifest.getInstance = lodash_1.default.memoize(function _getInstance(appiumHome) {
|
|
419
|
+
return new Manifest(appiumHome);
|
|
420
|
+
});
|
|
421
|
+
/**
|
|
422
|
+
* Type of the string referring to a driver (typically as a key or type string)
|
|
423
|
+
* @typedef {import('@appium/types').DriverType} DriverType
|
|
424
|
+
*/
|
|
425
|
+
/**
|
|
426
|
+
* Type of the string referring to a plugin (typically as a key or type string)
|
|
427
|
+
* @typedef {import('@appium/types').PluginType} PluginType
|
|
428
|
+
*/
|
|
429
|
+
/**
|
|
430
|
+
* @typedef SyncWithInstalledExtensionsOpts
|
|
431
|
+
* @property {number} [depthLimit] - Maximum depth to recurse into subdirectories
|
|
432
|
+
*/
|
|
433
|
+
/**
|
|
434
|
+
* @typedef {import('appium/types').ManifestData} ManifestData
|
|
435
|
+
* @typedef {import('appium/types').InternalMetadata} InternalMetadata
|
|
436
|
+
*/
|
|
437
|
+
/**
|
|
438
|
+
* @template {ExtensionType} ExtType
|
|
439
|
+
* @typedef {import('appium/types').ExtPackageJson<ExtType>} ExtPackageJson
|
|
440
|
+
*/
|
|
441
|
+
/**
|
|
442
|
+
* @template {ExtensionType} ExtType
|
|
443
|
+
* @typedef {import('appium/types').ExtManifest<ExtType>} ExtManifest
|
|
444
|
+
*/
|
|
445
|
+
/**
|
|
446
|
+
* @template {ExtensionType} ExtType
|
|
447
|
+
* @typedef {import('appium/types').ExtRecord<ExtType>} ExtRecord
|
|
448
|
+
*/
|
|
449
|
+
/**
|
|
450
|
+
* Either `driver` or `plugin` rn
|
|
451
|
+
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
452
|
+
*/
|
|
453
|
+
//# sourceMappingURL=manifest.js.map
|