appium 2.0.0-beta.46 → 2.0.0-beta.48
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.d.ts +24 -5
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +78 -88
- package/build/lib/cli/driver-command.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +33 -24
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +729 -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 +6 -5
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +65 -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 +33 -26
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +541 -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 +118 -0
- package/build/lib/extension/manifest-migrations.js.map +1 -0
- package/build/lib/extension/manifest.d.ts +35 -63
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +500 -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/driver-command.js +17 -0
- package/lib/cli/extension-command.js +119 -65
- 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 +7 -5
- package/lib/extension/extension-config.js +52 -47
- package/lib/extension/manifest-migrations.js +120 -0
- package/lib/extension/manifest.js +184 -103
- 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 +24 -25
- 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,34 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
31
|
-
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
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");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
+
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");
|
|
11
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
var _ExtensionConfig_listDataCache;
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.INSTALL_TYPES = exports.INSTALL_TYPE_GITHUB = exports.INSTALL_TYPE_LOCAL = exports.INSTALL_TYPE_GIT = exports.INSTALL_TYPE_NPM = exports.ExtensionConfig = void 0;
|
|
19
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
20
|
+
const bluebird_1 = __importDefault(require("bluebird"));
|
|
21
|
+
const path_1 = __importDefault(require("path"));
|
|
22
|
+
const resolve_from_1 = __importDefault(require("resolve-from"));
|
|
23
|
+
const semver_1 = require("semver");
|
|
24
|
+
const support_1 = require("@appium/support");
|
|
25
|
+
const extension_1 = require("../cli/extension");
|
|
26
|
+
const config_1 = require("../config");
|
|
27
|
+
const logger_1 = __importDefault(require("../logger"));
|
|
28
|
+
const schema_1 = require("../schema/schema");
|
|
32
29
|
const INSTALL_TYPE_NPM = 'npm';
|
|
33
30
|
exports.INSTALL_TYPE_NPM = INSTALL_TYPE_NPM;
|
|
34
31
|
const INSTALL_TYPE_LOCAL = 'local';
|
|
@@ -37,400 +34,548 @@ const INSTALL_TYPE_GITHUB = 'github';
|
|
|
37
34
|
exports.INSTALL_TYPE_GITHUB = INSTALL_TYPE_GITHUB;
|
|
38
35
|
const INSTALL_TYPE_GIT = 'git';
|
|
39
36
|
exports.INSTALL_TYPE_GIT = INSTALL_TYPE_GIT;
|
|
40
|
-
|
|
37
|
+
/** @type {Set<InstallType>} */
|
|
38
|
+
const INSTALL_TYPES = new Set([
|
|
39
|
+
INSTALL_TYPE_GIT,
|
|
40
|
+
INSTALL_TYPE_GITHUB,
|
|
41
|
+
INSTALL_TYPE_LOCAL,
|
|
42
|
+
INSTALL_TYPE_NPM,
|
|
43
|
+
]);
|
|
41
44
|
exports.INSTALL_TYPES = INSTALL_TYPES;
|
|
42
|
-
|
|
45
|
+
/**
|
|
46
|
+
* This class is abstract. It should not be instantiated directly.
|
|
47
|
+
*
|
|
48
|
+
* Subclasses should provide the generic parameter to implement.
|
|
49
|
+
* @template {ExtensionType} ExtType
|
|
50
|
+
*/
|
|
43
51
|
class ExtensionConfig {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
get manifestPath() {
|
|
59
|
-
return this.manifest.manifestPath;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get appiumHome() {
|
|
63
|
-
return this.manifest.appiumHome;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
getProblems(extName, extManifest) {
|
|
67
|
-
return [...this.getGenericConfigProblems(extManifest, extName), ...this.getConfigProblems(extManifest, extName), ...this.getSchemaProblems(extManifest, extName)];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async getWarnings(extName, extManifest) {
|
|
71
|
-
const [genericConfigWarnings, configWarnings] = await _bluebird.default.all([this.getGenericConfigWarnings(extManifest, extName), this.getConfigWarnings(extManifest, extName)]);
|
|
72
|
-
return [...genericConfigWarnings, ...configWarnings];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async getConfigWarnings(extManifest, extName) {
|
|
76
|
-
return [];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
getValidationResultSummaries(errorMap = new Map(), warningMap = new Map()) {
|
|
80
|
-
const errorSummaries = [];
|
|
81
|
-
|
|
82
|
-
for (const [extName, problems] of errorMap.entries()) {
|
|
83
|
-
if (_lodash.default.isEmpty(problems)) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
errorSummaries.push(`${this.extensionType} "${extName}" had ${_support.util.pluralize('error', problems.length)} and will not be available:`);
|
|
88
|
-
|
|
89
|
-
for (const problem of problems) {
|
|
90
|
-
errorSummaries.push(` - ${problem.err} (Actual value: ` + `${JSON.stringify(problem.val)})`);
|
|
91
|
-
}
|
|
52
|
+
/**
|
|
53
|
+
* @protected
|
|
54
|
+
* @param {ExtType} extensionType - Type of extension
|
|
55
|
+
* @param {Manifest} manifest - `Manifest` instance
|
|
56
|
+
*/
|
|
57
|
+
constructor(extensionType, manifest) {
|
|
58
|
+
/**
|
|
59
|
+
* @type {ExtensionListData|undefined}
|
|
60
|
+
*/
|
|
61
|
+
_ExtensionConfig_listDataCache.set(this, void 0);
|
|
62
|
+
this.extensionType = extensionType;
|
|
63
|
+
this.installedExtensions = manifest.getExtensionData(extensionType);
|
|
64
|
+
this.manifest = manifest;
|
|
92
65
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
for (const [extName, warnings] of warningMap.entries()) {
|
|
97
|
-
if (_lodash.default.isEmpty(warnings)) {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const extTypeText = _lodash.default.capitalize(this.extensionType);
|
|
102
|
-
|
|
103
|
-
const problemEnumerationText = _support.util.pluralize('potential problem', warnings.length, true);
|
|
104
|
-
|
|
105
|
-
warningSummaries.push(`${extTypeText} "${extName}" has ${problemEnumerationText}: `);
|
|
106
|
-
|
|
107
|
-
for (const warning of warnings) {
|
|
108
|
-
warningSummaries.push(` - ${warning}`);
|
|
109
|
-
}
|
|
66
|
+
get manifestPath() {
|
|
67
|
+
return this.manifest.manifestPath;
|
|
110
68
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
errorSummaries,
|
|
114
|
-
warningSummaries
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
async _validate(exts) {
|
|
119
|
-
const errorMap = new Map();
|
|
120
|
-
const warningMap = new Map();
|
|
121
|
-
|
|
122
|
-
for (const [extName, extManifest] of _lodash.default.toPairs(exts)) {
|
|
123
|
-
const [errors, warnings] = await _bluebird.default.all([this.getProblems(extName, extManifest), this.getWarnings(extName, extManifest)]);
|
|
124
|
-
|
|
125
|
-
if (errors.length) {
|
|
126
|
-
delete exts[extName];
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
errorMap.set(extName, errors);
|
|
130
|
-
warningMap.set(extName, warnings);
|
|
69
|
+
get appiumHome() {
|
|
70
|
+
return this.manifest.appiumHome;
|
|
131
71
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (!_lodash.default.isEmpty(warningSummaries)) {
|
|
146
|
-
_logger.default.warn(`Appium encountered ${_support.util.pluralize('warning', warningMap.size, true)} while validating ${this.configKey} found in manifest ${this.manifestPath}`);
|
|
147
|
-
|
|
148
|
-
for (const summary of warningSummaries) {
|
|
149
|
-
_logger.default.warn(summary);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
72
|
+
/**
|
|
73
|
+
* Returns a list of errors for a given extension.
|
|
74
|
+
*
|
|
75
|
+
* @param {ExtName<ExtType>} extName
|
|
76
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
77
|
+
* @returns {ExtManifestProblem[]}
|
|
78
|
+
*/
|
|
79
|
+
getProblems(extName, extManifest) {
|
|
80
|
+
return [
|
|
81
|
+
...this.getGenericConfigProblems(extManifest, extName),
|
|
82
|
+
...this.getConfigProblems(extManifest, extName),
|
|
83
|
+
...this.getSchemaProblems(extManifest, extName),
|
|
84
|
+
];
|
|
152
85
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Returns a list of warnings for a given extension.
|
|
88
|
+
*
|
|
89
|
+
* @param {ExtName<ExtType>} extName
|
|
90
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
91
|
+
* @returns {Promise<string[]>}
|
|
92
|
+
*/
|
|
93
|
+
async getWarnings(extName, extManifest) {
|
|
94
|
+
const [genericConfigWarnings, configWarnings] = await bluebird_1.default.all([
|
|
95
|
+
this.getGenericConfigWarnings(extManifest, extName),
|
|
96
|
+
this.getConfigWarnings(extManifest, extName),
|
|
97
|
+
]);
|
|
98
|
+
return [...genericConfigWarnings, ...configWarnings];
|
|
160
99
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
this._listDataCache = listData;
|
|
172
|
-
return listData;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
async getGenericConfigWarnings(extManifest, extName) {
|
|
176
|
-
const {
|
|
177
|
-
appiumVersion,
|
|
178
|
-
installSpec,
|
|
179
|
-
installType,
|
|
180
|
-
pkgName
|
|
181
|
-
} = extManifest;
|
|
182
|
-
const warnings = [];
|
|
183
|
-
const invalidFields = [];
|
|
184
|
-
|
|
185
|
-
if (!_lodash.default.isString(installSpec)) {
|
|
186
|
-
invalidFields.push('installSpec');
|
|
100
|
+
/**
|
|
101
|
+
* Returns a list of extension-type-specific issues. To be implemented by subclasses.
|
|
102
|
+
* @abstract
|
|
103
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
104
|
+
* @param {ExtName<ExtType>} extName
|
|
105
|
+
* @returns {Promise<string[]>}
|
|
106
|
+
*/
|
|
107
|
+
// eslint-disable-next-line no-unused-vars,require-await
|
|
108
|
+
async getConfigWarnings(extManifest, extName) {
|
|
109
|
+
return [];
|
|
187
110
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
111
|
+
/**
|
|
112
|
+
*
|
|
113
|
+
* @param {Map<ExtName<ExtType>,ExtManifestProblem[]>} [errorMap]
|
|
114
|
+
* @param {Map<ExtName<ExtType>,string[]>} [warningMap]
|
|
115
|
+
*/
|
|
116
|
+
getValidationResultSummaries(errorMap = new Map(), warningMap = new Map()) {
|
|
117
|
+
/**
|
|
118
|
+
* Array of computed strings
|
|
119
|
+
* @type {string[]}
|
|
120
|
+
*/
|
|
121
|
+
const errorSummaries = [];
|
|
122
|
+
for (const [extName, problems] of errorMap.entries()) {
|
|
123
|
+
if (lodash_1.default.isEmpty(problems)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
// remove this extension from the list since it's not valid
|
|
127
|
+
errorSummaries.push(`${this.extensionType} "${extName}" had ${support_1.util.pluralize('error', problems.length)} and will not be available:`);
|
|
128
|
+
for (const problem of problems) {
|
|
129
|
+
errorSummaries.push(` - ${problem.err} (Actual value: ` + `${JSON.stringify(problem.val)})`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** @type {string[]} */
|
|
133
|
+
const warningSummaries = [];
|
|
134
|
+
for (const [extName, warnings] of warningMap.entries()) {
|
|
135
|
+
if (lodash_1.default.isEmpty(warnings)) {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const extTypeText = lodash_1.default.capitalize(this.extensionType);
|
|
139
|
+
const problemEnumerationText = support_1.util.pluralize('potential problem', warnings.length, true);
|
|
140
|
+
warningSummaries.push(`${extTypeText} "${extName}" has ${problemEnumerationText}: `);
|
|
141
|
+
for (const warning of warnings) {
|
|
142
|
+
warningSummaries.push(` - ${warning}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return { errorSummaries, warningSummaries };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Checks extensions for problems. To be called by subclasses' `validate` method.
|
|
149
|
+
*
|
|
150
|
+
* Errors and warnings will be displayed to the user.
|
|
151
|
+
*
|
|
152
|
+
* This method mutates `exts`.
|
|
153
|
+
*
|
|
154
|
+
* @protected
|
|
155
|
+
* @param {ExtRecord<ExtType>} exts - Lookup of extension names to {@linkcode ExtManifest} objects
|
|
156
|
+
* @returns {Promise<ExtRecord<ExtType>>} The same lookup, but picking only error-free extensions
|
|
157
|
+
*/
|
|
158
|
+
async _validate(exts) {
|
|
159
|
+
/**
|
|
160
|
+
* Lookup of extension names to {@linkcode ExtManifestProblem ExtManifestProblems}
|
|
161
|
+
* @type {Map<ExtName<ExtType>,ExtManifestProblem[]>}
|
|
162
|
+
*/
|
|
163
|
+
const errorMap = new Map();
|
|
164
|
+
/**
|
|
165
|
+
* Lookup of extension names to warnings.
|
|
166
|
+
* @type {Map<ExtName<ExtType>,string[]>}
|
|
167
|
+
*/
|
|
168
|
+
const warningMap = new Map();
|
|
169
|
+
for (const [extName, extManifest] of lodash_1.default.toPairs(exts)) {
|
|
170
|
+
const [errors, warnings] = await bluebird_1.default.all([
|
|
171
|
+
this.getProblems(extName, extManifest),
|
|
172
|
+
this.getWarnings(extName, extManifest),
|
|
173
|
+
]);
|
|
174
|
+
if (errors.length) {
|
|
175
|
+
delete exts[extName];
|
|
176
|
+
}
|
|
177
|
+
errorMap.set(extName, errors);
|
|
178
|
+
warningMap.set(extName, warnings);
|
|
179
|
+
}
|
|
180
|
+
const { errorSummaries, warningSummaries } = this.getValidationResultSummaries(errorMap, warningMap);
|
|
181
|
+
if (!lodash_1.default.isEmpty(errorSummaries)) {
|
|
182
|
+
logger_1.default.error(`Appium encountered ${support_1.util.pluralize('error', errorMap.size, true)} while validating ${this.extensionType}s found in manifest ${this.manifestPath}`);
|
|
183
|
+
for (const summary of errorSummaries) {
|
|
184
|
+
logger_1.default.error(summary);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
// only display warnings if there are no errors!
|
|
189
|
+
if (!lodash_1.default.isEmpty(warningSummaries)) {
|
|
190
|
+
logger_1.default.warn(`Appium encountered ${support_1.util.pluralize('warning', warningMap.size, true)} while validating ${this.extensionType}s found in manifest ${this.manifestPath}`);
|
|
191
|
+
for (const summary of warningSummaries) {
|
|
192
|
+
logger_1.default.warn(summary);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return exts;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Retrieves listing data for extensions via command class.
|
|
200
|
+
*
|
|
201
|
+
* This is an expensive operation, so the result is cached. Currently, there is no
|
|
202
|
+
* use case for invalidating the cache.
|
|
203
|
+
* @protected
|
|
204
|
+
* @returns {Promise<ExtensionListData>}
|
|
205
|
+
*/
|
|
206
|
+
async getListData() {
|
|
207
|
+
if (__classPrivateFieldGet(this, _ExtensionConfig_listDataCache, "f")) {
|
|
208
|
+
return __classPrivateFieldGet(this, _ExtensionConfig_listDataCache, "f");
|
|
209
|
+
}
|
|
210
|
+
const CommandClass = /** @type {ExtCommand<ExtType>} */ (extension_1.commandClasses[this.extensionType]);
|
|
211
|
+
const cmd = new CommandClass({ config: this, json: true });
|
|
212
|
+
const listData = await cmd.list({ showInstalled: true, showUpdates: true });
|
|
213
|
+
__classPrivateFieldSet(this, _ExtensionConfig_listDataCache, listData, "f");
|
|
214
|
+
return listData;
|
|
191
215
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
216
|
+
/**
|
|
217
|
+
* Returns a list of warnings for a particular extension.
|
|
218
|
+
*
|
|
219
|
+
* By definition, a non-empty list of warnings does _not_ imply the extension cannot be loaded,
|
|
220
|
+
* but it may not work as expected or otherwise throw an exception at runtime.
|
|
221
|
+
*
|
|
222
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
223
|
+
* @param {ExtName<ExtType>} extName
|
|
224
|
+
* @returns {Promise<string[]>}
|
|
225
|
+
*/
|
|
226
|
+
async getGenericConfigWarnings(extManifest, extName) {
|
|
227
|
+
const { appiumVersion, installSpec, installType, pkgName } = extManifest;
|
|
228
|
+
const warnings = [];
|
|
229
|
+
const invalidFields = [];
|
|
230
|
+
if (!lodash_1.default.isString(installSpec)) {
|
|
231
|
+
invalidFields.push('installSpec');
|
|
232
|
+
}
|
|
233
|
+
if (!INSTALL_TYPES.has(installType)) {
|
|
234
|
+
invalidFields.push('installType');
|
|
235
|
+
}
|
|
236
|
+
const extTypeText = lodash_1.default.capitalize(this.extensionType);
|
|
237
|
+
if (invalidFields.length) {
|
|
238
|
+
const invalidFieldsEnumerationText = support_1.util.pluralize('invalid or missing field', invalidFields.length, true);
|
|
239
|
+
const invalidFieldsText = invalidFields.map((field) => `"${field}"`).join(', ');
|
|
240
|
+
warnings.push(`${extTypeText} "${extName}" (package \`${pkgName}\`) has ${invalidFieldsEnumerationText} (${invalidFieldsText}) in \`extensions.yaml\`; this may cause upgrades done via the \`appium\` CLI tool to fail. Please reinstall with \`appium ${this.extensionType} uninstall ${extName}\` and \`appium ${this.extensionType} install ${extName}\` to attempt a fix.`);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Helps concatenate warning messages related to peer dependencies
|
|
244
|
+
* @param {string} reason
|
|
245
|
+
* @returns string
|
|
246
|
+
*/
|
|
247
|
+
const createPeerWarning = (reason) => `${extTypeText} "${extName}" (package \`${pkgName}\`) may be incompatible with the current version of Appium (v${config_1.APPIUM_VER}) due to ${reason}`;
|
|
248
|
+
if (lodash_1.default.isString(appiumVersion) && !(0, semver_1.satisfies)(config_1.APPIUM_VER, appiumVersion)) {
|
|
249
|
+
const listData = await this.getListData();
|
|
250
|
+
const extListData = /** @type {InstalledExtensionListData} */ (listData[extName]);
|
|
251
|
+
if (extListData?.installed) {
|
|
252
|
+
const { updateVersion, upToDate } = extListData;
|
|
253
|
+
if (!upToDate) {
|
|
254
|
+
warnings.push(createPeerWarning(`its peer dependency on older Appium v${appiumVersion}. Please upgrade \`${pkgName}\` to v${updateVersion} or newer.`));
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
warnings.push(createPeerWarning(`its peer dependency on older Appium v${appiumVersion}. Please ask the developer of \`${pkgName}\` to update the peer dependency on Appium to v${config_1.APPIUM_VER}.`));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else if (!lodash_1.default.isString(appiumVersion)) {
|
|
262
|
+
const listData = await this.getListData();
|
|
263
|
+
const extListData = /** @type {InstalledExtensionListData} */ (listData[extName]);
|
|
264
|
+
if (!extListData?.upToDate && extListData?.updateVersion) {
|
|
265
|
+
warnings.push(createPeerWarning(`an invalid or missing peer dependency on Appium. A newer version of \`${pkgName}\` is available; please attempt to upgrade "${extName}" to v${extListData.updateVersion} or newer.`));
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
warnings.push(createPeerWarning(`an invalid or missing peer dependency on Appium. Please ask the developer of \`${pkgName}\` to add a peer dependency on \`^appium@${config_1.APPIUM_VER}\`.`));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return warnings;
|
|
200
272
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
273
|
+
/**
|
|
274
|
+
* Returns list of unrecoverable errors (if any) for the given extension _if_ it has a `schema` property.
|
|
275
|
+
*
|
|
276
|
+
* @param {ExtManifest<ExtType>} extManifest - Extension data (from manifest)
|
|
277
|
+
* @param {ExtName<ExtType>} extName - Extension name (from manifest)
|
|
278
|
+
* @returns {ExtManifestProblem[]}
|
|
279
|
+
*/
|
|
280
|
+
getSchemaProblems(extManifest, extName) {
|
|
281
|
+
/** @type {ExtManifestProblem[]} */
|
|
282
|
+
const problems = [];
|
|
283
|
+
const { schema: argSchemaPath } = extManifest;
|
|
284
|
+
if (ExtensionConfig.extDataHasSchema(extManifest)) {
|
|
285
|
+
if (lodash_1.default.isString(argSchemaPath)) {
|
|
286
|
+
if ((0, schema_1.isAllowedSchemaFileExtension)(argSchemaPath)) {
|
|
287
|
+
try {
|
|
288
|
+
this.readExtensionSchema(extName, extManifest);
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
problems.push({
|
|
292
|
+
err: `Unable to register schema at path ${argSchemaPath}; ${err.message}`,
|
|
293
|
+
val: argSchemaPath,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
problems.push({
|
|
299
|
+
err: `Schema file has unsupported extension. Allowed: ${[
|
|
300
|
+
...schema_1.ALLOWED_SCHEMA_EXTENSIONS,
|
|
301
|
+
].join(', ')}`,
|
|
302
|
+
val: argSchemaPath,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else if (lodash_1.default.isPlainObject(argSchemaPath)) {
|
|
307
|
+
try {
|
|
308
|
+
this.readExtensionSchema(extName, extManifest);
|
|
309
|
+
}
|
|
310
|
+
catch (err) {
|
|
311
|
+
problems.push({
|
|
312
|
+
err: `Unable to register embedded schema; ${err.message}`,
|
|
313
|
+
val: argSchemaPath,
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
problems.push({
|
|
319
|
+
err: 'Incorrectly formatted schema field; must be a path to a schema file or a schema object.',
|
|
320
|
+
val: argSchemaPath,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
218
323
|
}
|
|
219
|
-
|
|
220
|
-
} else if (!_lodash.default.isString(appiumVersion)) {
|
|
221
|
-
const listData = await this.getListData();
|
|
222
|
-
const extListData = listData[extName];
|
|
223
|
-
|
|
224
|
-
if (!(extListData !== null && extListData !== void 0 && extListData.upToDate) && extListData !== null && extListData !== void 0 && extListData.updateVersion) {
|
|
225
|
-
warnings.push(createPeerWarning(`an invalid or missing peer dependency on Appium. A newer version of \`${pkgName}\` is available; please attempt to upgrade "${extName}" to v${extListData.updateVersion} or newer.`));
|
|
226
|
-
} else {
|
|
227
|
-
warnings.push(createPeerWarning(`an invalid or missing peer dependency on Appium. Please ask the developer of \`${pkgName}\` to add a peer dependency on \`^appium@${_config.APPIUM_VER}\`.`));
|
|
228
|
-
}
|
|
324
|
+
return problems;
|
|
229
325
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (_lodash.default.isString(argSchemaPath)) {
|
|
242
|
-
if ((0, _schema.isAllowedSchemaFileExtension)(argSchemaPath)) {
|
|
243
|
-
try {
|
|
244
|
-
this.readExtensionSchema(extName, extManifest);
|
|
245
|
-
} catch (err) {
|
|
326
|
+
/**
|
|
327
|
+
* Return a list of generic unrecoverable errors for the given extension
|
|
328
|
+
* @param {ExtManifest<ExtType>} extManifest - Extension data (from manifest)
|
|
329
|
+
* @param {ExtName<ExtType>} extName - Extension name (from manifest)
|
|
330
|
+
* @returns {ExtManifestProblem[]}
|
|
331
|
+
*/
|
|
332
|
+
// eslint-disable-next-line no-unused-vars
|
|
333
|
+
getGenericConfigProblems(extManifest, extName) {
|
|
334
|
+
const { version, pkgName, mainClass } = extManifest;
|
|
335
|
+
const problems = [];
|
|
336
|
+
if (!lodash_1.default.isString(version)) {
|
|
246
337
|
problems.push({
|
|
247
|
-
|
|
248
|
-
|
|
338
|
+
err: `Invalid or missing \`version\` field in my \`package.json\` and/or \`extensions.yaml\` (must be a string)`,
|
|
339
|
+
val: version,
|
|
249
340
|
});
|
|
250
|
-
}
|
|
251
|
-
} else {
|
|
252
|
-
problems.push({
|
|
253
|
-
err: `Schema file has unsupported extension. Allowed: ${[..._schema.ALLOWED_SCHEMA_EXTENSIONS].join(', ')}`,
|
|
254
|
-
val: argSchemaPath
|
|
255
|
-
});
|
|
256
341
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
err: `Unable to register embedded schema; ${err.message}`,
|
|
263
|
-
val: argSchemaPath
|
|
264
|
-
});
|
|
342
|
+
if (!lodash_1.default.isString(pkgName)) {
|
|
343
|
+
problems.push({
|
|
344
|
+
err: `Invalid or missing \`name\` field in my \`package.json\` and/or \`extensions.yaml\` (must be a string)`,
|
|
345
|
+
val: pkgName,
|
|
346
|
+
});
|
|
265
347
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return problems;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
getGenericConfigProblems(extManifest, extName) {
|
|
278
|
-
const {
|
|
279
|
-
version,
|
|
280
|
-
pkgName,
|
|
281
|
-
mainClass
|
|
282
|
-
} = extManifest;
|
|
283
|
-
const problems = [];
|
|
284
|
-
|
|
285
|
-
if (!_lodash.default.isString(version)) {
|
|
286
|
-
problems.push({
|
|
287
|
-
err: `Invalid or missing \`version\` field in my \`package.json\` and/or \`extensions.yaml\` (must be a string)`,
|
|
288
|
-
val: version
|
|
289
|
-
});
|
|
348
|
+
if (!lodash_1.default.isString(mainClass)) {
|
|
349
|
+
problems.push({
|
|
350
|
+
err: `Invalid or missing \`appium.mainClass\` field in my \`package.json\` and/or \`mainClass\` field in \`extensions.yaml\` (must be a string)`,
|
|
351
|
+
val: mainClass,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
return problems;
|
|
290
355
|
}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
356
|
+
/**
|
|
357
|
+
* @abstract
|
|
358
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
359
|
+
* @param {ExtName<ExtType>} extName
|
|
360
|
+
* @returns {ExtManifestProblem[]}
|
|
361
|
+
*/
|
|
362
|
+
// eslint-disable-next-line no-unused-vars
|
|
363
|
+
getConfigProblems(extManifest, extName) {
|
|
364
|
+
// shoud override this method if special validation is necessary for this extension type
|
|
365
|
+
return [];
|
|
297
366
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
367
|
+
/**
|
|
368
|
+
* @param {string} extName
|
|
369
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
370
|
+
* @param {ExtensionConfigMutationOpts} [opts]
|
|
371
|
+
* @returns {Promise<void>}
|
|
372
|
+
*/
|
|
373
|
+
async addExtension(extName, extManifest, { write = true } = {}) {
|
|
374
|
+
this.manifest.setExtension(this.extensionType, extName, extManifest);
|
|
375
|
+
if (write) {
|
|
376
|
+
await this.manifest.write();
|
|
377
|
+
}
|
|
304
378
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
await this.manifest.write();
|
|
379
|
+
/**
|
|
380
|
+
* @param {ExtName<ExtType>} extName
|
|
381
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
382
|
+
* @param {ExtensionConfigMutationOpts} [opts]
|
|
383
|
+
* @returns {Promise<void>}
|
|
384
|
+
*/
|
|
385
|
+
async updateExtension(extName, extManifest, { write = true } = {}) {
|
|
386
|
+
this.manifest.setExtension(this.extensionType, extName, {
|
|
387
|
+
...this.installedExtensions[extName],
|
|
388
|
+
...extManifest,
|
|
389
|
+
});
|
|
390
|
+
if (write) {
|
|
391
|
+
await this.manifest.write();
|
|
392
|
+
}
|
|
320
393
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Remove an extension from the list of installed extensions, and optionally avoid a write to the manifest file.
|
|
396
|
+
*
|
|
397
|
+
* @param {ExtName<ExtType>} extName
|
|
398
|
+
* @param {ExtensionConfigMutationOpts} [opts]
|
|
399
|
+
* @returns {Promise<void>}
|
|
400
|
+
*/
|
|
401
|
+
async removeExtension(extName, { write = true } = {}) {
|
|
402
|
+
this.manifest.deleteExtension(this.extensionType, extName);
|
|
403
|
+
if (write) {
|
|
404
|
+
await this.manifest.write();
|
|
405
|
+
}
|
|
332
406
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
407
|
+
/**
|
|
408
|
+
* @param {ExtName<ExtType>[]} [activeNames]
|
|
409
|
+
* @returns {void}
|
|
410
|
+
*/
|
|
411
|
+
// eslint-disable-next-line no-unused-vars
|
|
412
|
+
print(activeNames) {
|
|
413
|
+
if (lodash_1.default.isEmpty(this.installedExtensions)) {
|
|
414
|
+
logger_1.default.info(`No ${this.extensionType}s have been installed in ${this.appiumHome}. Use the "appium ${this.extensionType}" ` +
|
|
415
|
+
'command to install the one(s) you want to use.');
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
logger_1.default.info(`Available ${this.extensionType}s:`);
|
|
419
|
+
for (const [extName, extManifest] of /** @type {[string, ExtManifest<ExtType>][]} */ (lodash_1.default.toPairs(this.installedExtensions))) {
|
|
420
|
+
logger_1.default.info(` - ${this.extensionDesc(extName, extManifest)}`);
|
|
421
|
+
}
|
|
342
422
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
423
|
+
/**
|
|
424
|
+
* Returns a string describing the extension. Subclasses must implement.
|
|
425
|
+
* @param {ExtName<ExtType>} extName - Extension name
|
|
426
|
+
* @param {ExtManifest<ExtType>} extManifest - Extension data
|
|
427
|
+
* @returns {string}
|
|
428
|
+
* @abstract
|
|
429
|
+
*/
|
|
430
|
+
// eslint-disable-next-line no-unused-vars
|
|
431
|
+
extensionDesc(extName, extManifest) {
|
|
432
|
+
throw new Error('This must be implemented in a subclass');
|
|
350
433
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
434
|
+
/**
|
|
435
|
+
* Returns--with reasonable accuracy--the path on disk to the extension.
|
|
436
|
+
*
|
|
437
|
+
* If `installPath` is present in the manifest, then it is used; otherwise we just guess.
|
|
438
|
+
* @param {keyof typeof this.installedExtensions} extName
|
|
439
|
+
* @returns {string}
|
|
440
|
+
*/
|
|
441
|
+
getInstallPath(extName) {
|
|
442
|
+
return (this.installedExtensions[extName]?.installPath ??
|
|
443
|
+
path_1.default.join(this.appiumHome, 'node_modules', this.installedExtensions[extName].pkgName));
|
|
356
444
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
445
|
+
/**
|
|
446
|
+
* Loads extension and returns its main class (constructor)
|
|
447
|
+
* @param {ExtName<ExtType>} extName
|
|
448
|
+
* @returns {ExtClass<ExtType>}
|
|
449
|
+
*/
|
|
450
|
+
require(extName) {
|
|
451
|
+
const { mainClass } = this.installedExtensions[extName];
|
|
452
|
+
const reqPath = this.getInstallPath(extName);
|
|
453
|
+
/** @type {string} */
|
|
454
|
+
let reqResolved;
|
|
455
|
+
try {
|
|
456
|
+
reqResolved = require.resolve(reqPath);
|
|
457
|
+
}
|
|
458
|
+
catch (err) {
|
|
459
|
+
throw new ReferenceError(`Could not find a ${this.extensionType} installed at ${reqPath}`);
|
|
460
|
+
}
|
|
461
|
+
// note: this will only reload the entry point
|
|
462
|
+
if (process.env.APPIUM_RELOAD_EXTENSIONS && require.cache[reqResolved]) {
|
|
463
|
+
logger_1.default.debug(`Removing ${reqResolved} from require cache`);
|
|
464
|
+
delete require.cache[reqResolved];
|
|
465
|
+
}
|
|
466
|
+
logger_1.default.debug(`Requiring ${this.extensionType} at ${reqPath}`);
|
|
467
|
+
const MainClass = require(reqPath)[mainClass];
|
|
468
|
+
if (!MainClass) {
|
|
469
|
+
throw new ReferenceError(`Could not find a class named "${mainClass}" exported by ${this.extensionType} "${extName}"`);
|
|
470
|
+
}
|
|
471
|
+
return MainClass;
|
|
378
472
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
473
|
+
/**
|
|
474
|
+
* @param {string} extName
|
|
475
|
+
* @returns {boolean}
|
|
476
|
+
*/
|
|
477
|
+
isInstalled(extName) {
|
|
478
|
+
return extName in this.installedExtensions;
|
|
384
479
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
480
|
+
/**
|
|
481
|
+
* Intended to be called by corresponding instance methods of subclass.
|
|
482
|
+
* @private
|
|
483
|
+
* @template {ExtensionType} ExtType
|
|
484
|
+
* @param {string} appiumHome
|
|
485
|
+
* @param {ExtType} extType
|
|
486
|
+
* @param {ExtName<ExtType>} extName - Extension name (unique to its type)
|
|
487
|
+
* @param {ExtManifestWithSchema<ExtType>} extManifest - Extension config
|
|
488
|
+
* @returns {import('ajv').SchemaObject|undefined}
|
|
489
|
+
*/
|
|
490
|
+
static _readExtensionSchema(appiumHome, extType, extName, extManifest) {
|
|
491
|
+
const { pkgName, schema: argSchemaPath } = extManifest;
|
|
492
|
+
if (!argSchemaPath) {
|
|
493
|
+
throw new TypeError(`No \`schema\` property found in config for ${extType} ${pkgName} -- why is this function being called?`);
|
|
494
|
+
}
|
|
495
|
+
let moduleObject;
|
|
496
|
+
if (lodash_1.default.isString(argSchemaPath)) {
|
|
497
|
+
const schemaPath = (0, resolve_from_1.default)(appiumHome, path_1.default.join(pkgName, argSchemaPath));
|
|
498
|
+
moduleObject = require(schemaPath);
|
|
499
|
+
}
|
|
500
|
+
else {
|
|
501
|
+
moduleObject = argSchemaPath;
|
|
502
|
+
}
|
|
503
|
+
// this sucks. default exports should be destroyed
|
|
504
|
+
const schema = moduleObject.__esModule ? moduleObject.default : moduleObject;
|
|
505
|
+
(0, schema_1.registerSchema)(extType, extName, schema);
|
|
506
|
+
return schema;
|
|
392
507
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
const {
|
|
403
|
-
pkgName,
|
|
404
|
-
schema: argSchemaPath
|
|
405
|
-
} = extManifest;
|
|
406
|
-
|
|
407
|
-
if (!argSchemaPath) {
|
|
408
|
-
throw new TypeError(`No \`schema\` property found in config for ${extType} ${pkgName} -- why is this function being called?`);
|
|
508
|
+
/**
|
|
509
|
+
* Returns `true` if a specific {@link ExtManifest} object has a `schema` prop.
|
|
510
|
+
* The {@link ExtManifest} object becomes a {@link ExtManifestWithSchema} object.
|
|
511
|
+
* @template {ExtensionType} ExtType
|
|
512
|
+
* @param {ExtManifest<ExtType>} extManifest
|
|
513
|
+
* @returns {extManifest is ExtManifestWithSchema<ExtType>}
|
|
514
|
+
*/
|
|
515
|
+
static extDataHasSchema(extManifest) {
|
|
516
|
+
return lodash_1.default.isString(extManifest?.schema) || lodash_1.default.isObject(extManifest?.schema);
|
|
409
517
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
518
|
+
/**
|
|
519
|
+
* If an extension provides a schema, this will load the schema and attempt to
|
|
520
|
+
* register it with the schema registrar.
|
|
521
|
+
* @param {ExtName<ExtType>} extName - Name of extension
|
|
522
|
+
* @param {ExtManifestWithSchema<ExtType>} extManifest - Extension data
|
|
523
|
+
* @returns {import('ajv').SchemaObject|undefined}
|
|
524
|
+
*/
|
|
525
|
+
readExtensionSchema(extName, extManifest) {
|
|
526
|
+
return ExtensionConfig._readExtensionSchema(this.appiumHome, this.extensionType, extName, extManifest);
|
|
418
527
|
}
|
|
419
|
-
|
|
420
|
-
const schema = moduleObject.__esModule ? moduleObject.default : moduleObject;
|
|
421
|
-
(0, _schema.registerSchema)(extType, extName, schema);
|
|
422
|
-
return schema;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
static extDataHasSchema(extManifest) {
|
|
426
|
-
return _lodash.default.isString(extManifest === null || extManifest === void 0 ? void 0 : extManifest.schema) || _lodash.default.isObject(extManifest === null || extManifest === void 0 ? void 0 : extManifest.schema);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
readExtensionSchema(extName, extManifest) {
|
|
430
|
-
return ExtensionConfig._readExtensionSchema(this.appiumHome, this.extensionType, extName, extManifest);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
528
|
}
|
|
434
|
-
|
|
435
529
|
exports.ExtensionConfig = ExtensionConfig;
|
|
436
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJJTlNUQUxMX1RZUEVfTlBNIiwiSU5TVEFMTF9UWVBFX0xPQ0FMIiwiSU5TVEFMTF9UWVBFX0dJVEhVQiIsIklOU1RBTExfVFlQRV9HSVQiLCJJTlNUQUxMX1RZUEVTIiwiU2V0IiwiRXh0ZW5zaW9uQ29uZmlnIiwiZXh0ZW5zaW9uVHlwZSIsImNvbmZpZ0tleSIsImluc3RhbGxlZEV4dGVuc2lvbnMiLCJsb2ciLCJtYW5pZmVzdCIsIl9saXN0RGF0YUNhY2hlIiwiY29uc3RydWN0b3IiLCJnZXRFeHRlbnNpb25EYXRhIiwibWFuaWZlc3RQYXRoIiwiYXBwaXVtSG9tZSIsImdldFByb2JsZW1zIiwiZXh0TmFtZSIsImV4dE1hbmlmZXN0IiwiZ2V0R2VuZXJpY0NvbmZpZ1Byb2JsZW1zIiwiZ2V0Q29uZmlnUHJvYmxlbXMiLCJnZXRTY2hlbWFQcm9ibGVtcyIsImdldFdhcm5pbmdzIiwiZ2VuZXJpY0NvbmZpZ1dhcm5pbmdzIiwiY29uZmlnV2FybmluZ3MiLCJCIiwiYWxsIiwiZ2V0R2VuZXJpY0NvbmZpZ1dhcm5pbmdzIiwiZ2V0Q29uZmlnV2FybmluZ3MiLCJnZXRWYWxpZGF0aW9uUmVzdWx0U3VtbWFyaWVzIiwiZXJyb3JNYXAiLCJNYXAiLCJ3YXJuaW5nTWFwIiwiZXJyb3JTdW1tYXJpZXMiLCJwcm9ibGVtcyIsImVudHJpZXMiLCJfIiwiaXNFbXB0eSIsInB1c2giLCJ1dGlsIiwicGx1cmFsaXplIiwibGVuZ3RoIiwicHJvYmxlbSIsImVyciIsIkpTT04iLCJzdHJpbmdpZnkiLCJ2YWwiLCJ3YXJuaW5nU3VtbWFyaWVzIiwid2FybmluZ3MiLCJleHRUeXBlVGV4dCIsImNhcGl0YWxpemUiLCJwcm9ibGVtRW51bWVyYXRpb25UZXh0Iiwid2FybmluZyIsIl92YWxpZGF0ZSIsImV4dHMiLCJ0b1BhaXJzIiwiZXJyb3JzIiwic2V0IiwiZXJyb3IiLCJzaXplIiwic3VtbWFyeSIsIndhcm4iLCJnZXRMaXN0RGF0YSIsIkNvbW1hbmRDbGFzcyIsImNvbW1hbmRDbGFzc2VzIiwiY21kIiwiY29uZmlnIiwianNvbiIsImxpc3REYXRhIiwibGlzdCIsInNob3dJbnN0YWxsZWQiLCJzaG93VXBkYXRlcyIsImFwcGl1bVZlcnNpb24iLCJpbnN0YWxsU3BlYyIsImluc3RhbGxUeXBlIiwicGtnTmFtZSIsImludmFsaWRGaWVsZHMiLCJpc1N0cmluZyIsImhhcyIsImludmFsaWRGaWVsZHNFbnVtZXJhdGlvblRleHQiLCJpbnZhbGlkRmllbGRzVGV4dCIsIm1hcCIsImZpZWxkIiwiam9pbiIsImNyZWF0ZVBlZXJXYXJuaW5nIiwicmVhc29uIiwiQVBQSVVNX1ZFUiIsInNhdGlzZmllcyIsImV4dExpc3REYXRhIiwiaW5zdGFsbGVkIiwidXBkYXRlVmVyc2lvbiIsInVwVG9EYXRlIiwic2NoZW1hIiwiYXJnU2NoZW1hUGF0aCIsImV4dERhdGFIYXNTY2hlbWEiLCJpc0FsbG93ZWRTY2hlbWFGaWxlRXh0ZW5zaW9uIiwicmVhZEV4dGVuc2lvblNjaGVtYSIsIm1lc3NhZ2UiLCJBTExPV0VEX1NDSEVNQV9FWFRFTlNJT05TIiwiaXNQbGFpbk9iamVjdCIsInZlcnNpb24iLCJtYWluQ2xhc3MiLCJhZGRFeHRlbnNpb24iLCJ3cml0ZSIsInVwZGF0ZUV4dGVuc2lvbiIsInJlbW92ZUV4dGVuc2lvbiIsInByaW50IiwiYWN0aXZlTmFtZXMiLCJpbmZvIiwiZXh0ZW5zaW9uRGVzYyIsIkVycm9yIiwiZ2V0SW5zdGFsbFBhdGgiLCJwYXRoIiwicmVxdWlyZSIsInJlcVBhdGgiLCJyZXFSZXNvbHZlZCIsInJlc29sdmUiLCJSZWZlcmVuY2VFcnJvciIsInByb2Nlc3MiLCJlbnYiLCJBUFBJVU1fUkVMT0FEX0VYVEVOU0lPTlMiLCJjYWNoZSIsImRlYnVnIiwiTWFpbkNsYXNzIiwiaXNJbnN0YWxsZWQiLCJpbmNsdWRlcyIsIk9iamVjdCIsImtleXMiLCJfcmVhZEV4dGVuc2lvblNjaGVtYSIsImV4dFR5cGUiLCJUeXBlRXJyb3IiLCJtb2R1bGVPYmplY3QiLCJzY2hlbWFQYXRoIiwicmVzb2x2ZUZyb20iLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsInJlZ2lzdGVyU2NoZW1hIiwiaXNPYmplY3QiXSwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZXh0ZW5zaW9uL2V4dGVuc2lvbi1jb25maWcuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBCIGZyb20gJ2JsdWViaXJkJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHJlc29sdmVGcm9tIGZyb20gJ3Jlc29sdmUtZnJvbSc7XG5pbXBvcnQge3NhdGlzZmllc30gZnJvbSAnc2VtdmVyJztcbmltcG9ydCB7dXRpbH0gZnJvbSAnQGFwcGl1bS9zdXBwb3J0JztcbmltcG9ydCB7Y29tbWFuZENsYXNzZXN9IGZyb20gJy4uL2NsaS9leHRlbnNpb24nO1xuaW1wb3J0IHtBUFBJVU1fVkVSfSBmcm9tICcuLi9jb25maWcnO1xuaW1wb3J0IGxvZyBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHtcbiAgQUxMT1dFRF9TQ0hFTUFfRVhURU5TSU9OUyxcbiAgaXNBbGxvd2VkU2NoZW1hRmlsZUV4dGVuc2lvbixcbiAgcmVnaXN0ZXJTY2hlbWEsXG59IGZyb20gJy4uL3NjaGVtYS9zY2hlbWEnO1xuXG5jb25zdCBJTlNUQUxMX1RZUEVfTlBNID0gJ25wbSc7XG5jb25zdCBJTlNUQUxMX1RZUEVfTE9DQUwgPSAnbG9jYWwnO1xuY29uc3QgSU5TVEFMTF9UWVBFX0dJVEhVQiA9ICdnaXRodWInO1xuY29uc3QgSU5TVEFMTF9UWVBFX0dJVCA9ICdnaXQnO1xuXG4vKiogQHR5cGUge1NldDxJbnN0YWxsVHlwZT59ICovXG5jb25zdCBJTlNUQUxMX1RZUEVTID0gbmV3IFNldChbXG4gIElOU1RBTExfVFlQRV9HSVQsXG4gIElOU1RBTExfVFlQRV9HSVRIVUIsXG4gIElOU1RBTExfVFlQRV9MT0NBTCxcbiAgSU5TVEFMTF9UWVBFX05QTSxcbl0pO1xuXG4vKipcbiAqIFRoaXMgY2xhc3MgaXMgYWJzdHJhY3QuIEl0IHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LlxuICpcbiAqIFN1YmNsYXNzZXMgc2hvdWxkIHByb3ZpZGUgdGhlIGdlbmVyaWMgcGFyYW1ldGVyIHRvIGltcGxlbWVudC5cbiAqIEB0ZW1wbGF0ZSB7RXh0ZW5zaW9uVHlwZX0gRXh0VHlwZVxuICovXG5leHBvcnQgY2xhc3MgRXh0ZW5zaW9uQ29uZmlnIHtcbiAgLyoqIEB0eXBlIHtFeHRUeXBlfSAqL1xuICBleHRlbnNpb25UeXBlO1xuXG4gIC8qKiBAdHlwZSB7YCR7RXh0VHlwZX1zYH0gKi9cbiAgY29uZmlnS2V5O1xuXG4gIC8qKiBAdHlwZSB7RXh0UmVjb3JkPEV4dFR5cGU+fSAqL1xuICBpbnN0YWxsZWRFeHRlbnNpb25zO1xuXG4gIC8qKiBAdHlwZSB7aW1wb3J0KCdAYXBwaXVtL3R5cGVzJykuQXBwaXVtTG9nZ2VyfSAqL1xuICBsb2c7XG5cbiAgLyoqIEB0eXBlIHtNYW5pZmVzdH0gKi9cbiAgbWFuaWZlc3Q7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtFeHRlbnNpb25MaXN0RGF0YX1cbiAgICovXG4gIF9saXN0RGF0YUNhY2hlO1xuXG4gIC8qKlxuICAgKiBAcHJvdGVjdGVkXG4gICAqIEBwYXJhbSB7RXh0VHlwZX0gZXh0ZW5zaW9uVHlwZSAtIFR5cGUgb2YgZXh0ZW5zaW9uXG4gICAqIEBwYXJhbSB7TWFuaWZlc3R9IG1hbmlmZXN0IC0gYE1hbmlmZXN0YCBpbnN0YW5jZVxuICAgKi9cbiAgY29uc3RydWN0b3IoZXh0ZW5zaW9uVHlwZSwgbWFuaWZlc3QpIHtcbiAgICB0aGlzLmV4dGVuc2lvblR5cGUgPSBleHRlbnNpb25UeXBlO1xuICAgIHRoaXMuY29uZmlnS2V5ID0gYCR7ZXh0ZW5zaW9uVHlwZX1zYDtcbiAgICB0aGlzLmluc3RhbGxlZEV4dGVuc2lvbnMgPSBtYW5pZmVzdC5nZXRFeHRlbnNpb25EYXRhKGV4dGVuc2lvblR5cGUpO1xuICAgIHRoaXMubWFuaWZlc3QgPSBtYW5pZmVzdDtcbiAgfVxuXG4gIGdldCBtYW5pZmVzdFBhdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFuaWZlc3QubWFuaWZlc3RQYXRoO1xuICB9XG5cbiAgZ2V0IGFwcGl1bUhvbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFuaWZlc3QuYXBwaXVtSG9tZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBlcnJvcnMgZm9yIGEgZ2l2ZW4gZXh0ZW5zaW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge0V4dE5hbWU8RXh0VHlwZT59IGV4dE5hbWVcbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gZXh0TWFuaWZlc3RcbiAgICogQHJldHVybnMge0V4dE1hbmlmZXN0UHJvYmxlbVtdfVxuICAgKi9cbiAgZ2V0UHJvYmxlbXMoZXh0TmFtZSwgZXh0TWFuaWZlc3QpIHtcbiAgICByZXR1cm4gW1xuICAgICAgLi4udGhpcy5nZXRHZW5lcmljQ29uZmlnUHJvYmxlbXMoZXh0TWFuaWZlc3QsIGV4dE5hbWUpLFxuICAgICAgLi4udGhpcy5nZXRDb25maWdQcm9ibGVtcyhleHRNYW5pZmVzdCwgZXh0TmFtZSksXG4gICAgICAuLi50aGlzLmdldFNjaGVtYVByb2JsZW1zKGV4dE1hbmlmZXN0LCBleHROYW1lKSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBsaXN0IG9mIHdhcm5pbmdzIGZvciBhIGdpdmVuIGV4dGVuc2lvbi5cbiAgICpcbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lXG4gICAqIEBwYXJhbSB7RXh0TWFuaWZlc3Q8RXh0VHlwZT59IGV4dE1hbmlmZXN0XG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn1cbiAgICovXG4gIGFzeW5jIGdldFdhcm5pbmdzKGV4dE5hbWUsIGV4dE1hbmlmZXN0KSB7XG4gICAgY29uc3QgW2dlbmVyaWNDb25maWdXYXJuaW5ncywgY29uZmlnV2FybmluZ3NdID0gYXdhaXQgQi5hbGwoW1xuICAgICAgdGhpcy5nZXRHZW5lcmljQ29uZmlnV2FybmluZ3MoZXh0TWFuaWZlc3QsIGV4dE5hbWUpLFxuICAgICAgdGhpcy5nZXRDb25maWdXYXJuaW5ncyhleHRNYW5pZmVzdCwgZXh0TmFtZSksXG4gICAgXSk7XG5cbiAgICByZXR1cm4gWy4uLmdlbmVyaWNDb25maWdXYXJuaW5ncywgLi4uY29uZmlnV2FybmluZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBsaXN0IG9mIGV4dGVuc2lvbi10eXBlLXNwZWNpZmljIGlzc3Vlcy4gVG8gYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3Nlcy5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7RXh0TWFuaWZlc3Q8RXh0VHlwZT59IGV4dE1hbmlmZXN0XG4gICAqIEBwYXJhbSB7RXh0TmFtZTxFeHRUeXBlPn0gZXh0TmFtZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59XG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMscmVxdWlyZS1hd2FpdFxuICBhc3luYyBnZXRDb25maWdXYXJuaW5ncyhleHRNYW5pZmVzdCwgZXh0TmFtZSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0ge01hcDxFeHROYW1lPEV4dFR5cGU+LEV4dE1hbmlmZXN0UHJvYmxlbVtdPn0gW2Vycm9yTWFwXVxuICAgKiBAcGFyYW0ge01hcDxFeHROYW1lPEV4dFR5cGU+LHN0cmluZ1tdPn0gW3dhcm5pbmdNYXBdXG4gICAqL1xuICBnZXRWYWxpZGF0aW9uUmVzdWx0U3VtbWFyaWVzKGVycm9yTWFwID0gbmV3IE1hcCgpLCB3YXJuaW5nTWFwID0gbmV3IE1hcCgpKSB7XG4gICAgLyoqXG4gICAgICogQXJyYXkgb2YgY29tcHV0ZWQgc3RyaW5nc1xuICAgICAqIEB0eXBlIHtzdHJpbmdbXX1cbiAgICAgKi9cbiAgICBjb25zdCBlcnJvclN1bW1hcmllcyA9IFtdO1xuICAgIGZvciAoY29uc3QgW2V4dE5hbWUsIHByb2JsZW1zXSBvZiBlcnJvck1hcC5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChfLmlzRW1wdHkocHJvYmxlbXMpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgLy8gcmVtb3ZlIHRoaXMgZXh0ZW5zaW9uIGZyb20gdGhlIGxpc3Qgc2luY2UgaXQncyBub3QgdmFsaWRcbiAgICAgIGVycm9yU3VtbWFyaWVzLnB1c2goXG4gICAgICAgIGAke3RoaXMuZXh0ZW5zaW9uVHlwZX0gXCIke2V4dE5hbWV9XCIgaGFkICR7dXRpbC5wbHVyYWxpemUoXG4gICAgICAgICAgJ2Vycm9yJyxcbiAgICAgICAgICBwcm9ibGVtcy5sZW5ndGhcbiAgICAgICAgKX0gYW5kIHdpbGwgbm90IGJlIGF2YWlsYWJsZTpgXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBwcm9ibGVtIG9mIHByb2JsZW1zKSB7XG4gICAgICAgIGVycm9yU3VtbWFyaWVzLnB1c2goXG4gICAgICAgICAgYCAgLSAke3Byb2JsZW0uZXJyfSAoQWN0dWFsIHZhbHVlOiBgICsgYCR7SlNPTi5zdHJpbmdpZnkocHJvYmxlbS52YWwpfSlgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3Qgd2FybmluZ1N1bW1hcmllcyA9IFtdO1xuICAgIGZvciAoY29uc3QgW2V4dE5hbWUsIHdhcm5pbmdzXSBvZiB3YXJuaW5nTWFwLmVudHJpZXMoKSkge1xuICAgICAgaWYgKF8uaXNFbXB0eSh3YXJuaW5ncykpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBleHRUeXBlVGV4dCA9IF8uY2FwaXRhbGl6ZSh0aGlzLmV4dGVuc2lvblR5cGUpO1xuICAgICAgY29uc3QgcHJvYmxlbUVudW1lcmF0aW9uVGV4dCA9IHV0aWwucGx1cmFsaXplKCdwb3RlbnRpYWwgcHJvYmxlbScsIHdhcm5pbmdzLmxlbmd0aCwgdHJ1ZSk7XG4gICAgICB3YXJuaW5nU3VtbWFyaWVzLnB1c2goYCR7ZXh0VHlwZVRleHR9IFwiJHtleHROYW1lfVwiIGhhcyAke3Byb2JsZW1FbnVtZXJhdGlvblRleHR9OiBgKTtcbiAgICAgIGZvciAoY29uc3Qgd2FybmluZyBvZiB3YXJuaW5ncykge1xuICAgICAgICB3YXJuaW5nU3VtbWFyaWVzLnB1c2goYCAgLSAke3dhcm5pbmd9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtlcnJvclN1bW1hcmllcywgd2FybmluZ1N1bW1hcmllc307XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGV4dGVuc2lvbnMgZm9yIHByb2JsZW1zLiAgVG8gYmUgY2FsbGVkIGJ5IHN1YmNsYXNzZXMnIGB2YWxpZGF0ZWAgbWV0aG9kLlxuICAgKlxuICAgKiBFcnJvcnMgYW5kIHdhcm5pbmdzIHdpbGwgYmUgZGlzcGxheWVkIHRvIHRoZSB1c2VyLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBleHRzYC5cbiAgICpcbiAgICogQHByb3RlY3RlZFxuICAgKiBAcGFyYW0ge0V4dFJlY29yZDxFeHRUeXBlPn0gZXh0cyAtIExvb2t1cCBvZiBleHRlbnNpb24gbmFtZXMgdG8ge0BsaW5rY29kZSBFeHRNYW5pZmVzdH0gb2JqZWN0c1xuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxFeHRSZWNvcmQ8RXh0VHlwZT4+fSBUaGUgc2FtZSBsb29rdXAsIGJ1dCBwaWNraW5nIG9ubHkgZXJyb3ItZnJlZSBleHRlbnNpb25zXG4gICAqL1xuICBhc3luYyBfdmFsaWRhdGUoZXh0cykge1xuICAgIC8qKlxuICAgICAqIExvb2t1cCBvZiBleHRlbnNpb24gbmFtZXMgdG8ge0BsaW5rY29kZSBFeHRNYW5pZmVzdFByb2JsZW0gRXh0TWFuaWZlc3RQcm9ibGVtc31cbiAgICAgKiBAdHlwZSB7TWFwPEV4dE5hbWU8RXh0VHlwZT4sRXh0TWFuaWZlc3RQcm9ibGVtW10+fVxuICAgICAqL1xuICAgIGNvbnN0IGVycm9yTWFwID0gbmV3IE1hcCgpO1xuICAgIC8qKlxuICAgICAqIExvb2t1cCBvZiBleHRlbnNpb24gbmFtZXMgdG8gd2FybmluZ3MuXG4gICAgICogQHR5cGUge01hcDxFeHROYW1lPEV4dFR5cGU+LHN0cmluZ1tdPn1cbiAgICAgKi9cbiAgICBjb25zdCB3YXJuaW5nTWFwID0gbmV3IE1hcCgpO1xuXG4gICAgZm9yIChjb25zdCBbZXh0TmFtZSwgZXh0TWFuaWZlc3RdIG9mIF8udG9QYWlycyhleHRzKSkge1xuICAgICAgY29uc3QgW2Vycm9ycywgd2FybmluZ3NdID0gYXdhaXQgQi5hbGwoW1xuICAgICAgICB0aGlzLmdldFByb2JsZW1zKGV4dE5hbWUsIGV4dE1hbmlmZXN0KSxcbiAgICAgICAgdGhpcy5nZXRXYXJuaW5ncyhleHROYW1lLCBleHRNYW5pZmVzdCksXG4gICAgICBdKTtcbiAgICAgIGlmIChlcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgIGRlbGV0ZSBleHRzW2V4dE5hbWVdO1xuICAgICAgfVxuICAgICAgZXJyb3JNYXAuc2V0KGV4dE5hbWUsIGVycm9ycyk7XG4gICAgICB3YXJuaW5nTWFwLnNldChleHROYW1lLCB3YXJuaW5ncyk7XG4gICAgfVxuXG4gICAgY29uc3Qge2Vycm9yU3VtbWFyaWVzLCB3YXJuaW5nU3VtbWFyaWVzfSA9IHRoaXMuZ2V0VmFsaWRhdGlvblJlc3VsdFN1bW1hcmllcyhcbiAgICAgIGVycm9yTWFwLFxuICAgICAgd2FybmluZ01hcFxuICAgICk7XG5cbiAgICBpZiAoIV8uaXNFbXB0eShlcnJvclN1bW1hcmllcykpIHtcbiAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgYEFwcGl1bSBlbmNvdW50ZXJlZCAke3V0aWwucGx1cmFsaXplKCdlcnJvcicsIGVycm9yTWFwLnNpemUsIHRydWUpfSB3aGlsZSB2YWxpZGF0aW5nICR7XG4gICAgICAgICAgdGhpcy5jb25maWdLZXlcbiAgICAgICAgfSBmb3VuZCBpbiBtYW5pZmVzdCAke3RoaXMubWFuaWZlc3RQYXRofWBcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IHN1bW1hcnkgb2YgZXJyb3JTdW1tYXJpZXMpIHtcbiAgICAgICAgbG9nLmVycm9yKHN1bW1hcnkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBvbmx5IGRpc3BsYXkgd2FybmluZ3MgaWYgdGhlcmUgYXJlIG5vIGVycm9ycyFcblxuICAgICAgaWYgKCFfLmlzRW1wdHkod2FybmluZ1N1bW1hcmllcykpIHtcbiAgICAgICAgbG9nLndhcm4oXG4gICAgICAgICAgYEFwcGl1bSBlbmNvdW50ZXJlZCAke3V0aWwucGx1cmFsaXplKFxuICAgICAgICAgICAgJ3dhcm5pbmcnLFxuICAgICAgICAgICAgd2FybmluZ01hcC5zaXplLFxuICAgICAgICAgICAgdHJ1ZVxuICAgICAgICAgICl9IHdoaWxlIHZhbGlkYXRpbmcgJHt0aGlzLmNvbmZpZ0tleX0gZm91bmQgaW4gbWFuaWZlc3QgJHt0aGlzLm1hbmlmZXN0UGF0aH1gXG4gICAgICAgICk7XG4gICAgICAgIGZvciAoY29uc3Qgc3VtbWFyeSBvZiB3YXJuaW5nU3VtbWFyaWVzKSB7XG4gICAgICAgICAgbG9nLndhcm4oc3VtbWFyeSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGV4dHM7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGxpc3RpbmcgZGF0YSBmb3IgZXh0ZW5zaW9ucyB2aWEgY29tbWFuZCBjbGFzcy5cbiAgICogQ2FjaGVzIHRoZSByZXN1bHQgaW4ge0BsaW5rY29kZSBFeHRlbnNpb25Db25maWcuX2xpc3REYXRhQ2FjaGV9XG4gICAqIEBwcm90ZWN0ZWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RXh0ZW5zaW9uTGlzdERhdGE+fVxuICAgKi9cbiAgYXN5bmMgZ2V0TGlzdERhdGEoKSB7XG4gICAgaWYgKHRoaXMuX2xpc3REYXRhQ2FjaGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9saXN0RGF0YUNhY2hlO1xuICAgIH1cbiAgICBjb25zdCBDb21tYW5kQ2xhc3MgPSAvKiogQHR5cGUge0V4dENvbW1hbmQ8RXh0VHlwZT59ICovIChjb21tYW5kQ2xhc3Nlc1t0aGlzLmV4dGVuc2lvblR5cGVdKTtcbiAgICBjb25zdCBjbWQgPSBuZXcgQ29tbWFuZENsYXNzKHtjb25maWc6IHRoaXMsIGpzb246IHRydWV9KTtcbiAgICBjb25zdCBsaXN0RGF0YSA9IGF3YWl0IGNtZC5saXN0KHtzaG93SW5zdGFsbGVkOiB0cnVlLCBzaG93VXBkYXRlczogdHJ1ZX0pO1xuICAgIHRoaXMuX2xpc3REYXRhQ2FjaGUgPSBsaXN0RGF0YTtcbiAgICByZXR1cm4gbGlzdERhdGE7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2Ygd2FybmluZ3MgZm9yIGEgcGFydGljdWxhciBleHRlbnNpb24uXG4gICAqXG4gICAqIEJ5IGRlZmluaXRpb24sIGEgbm9uLWVtcHR5IGxpc3Qgb2Ygd2FybmluZ3MgZG9lcyBfbm90XyBpbXBseSB0aGUgZXh0ZW5zaW9uIGNhbm5vdCBiZSBsb2FkZWQsXG4gICAqIGJ1dCBpdCBtYXkgbm90IHdvcmsgYXMgZXhwZWN0ZWQgb3Igb3RoZXJ3aXNlIHRocm93IGFuIGV4Y2VwdGlvbiBhdCBydW50aW1lLlxuICAgKlxuICAgKiBAcGFyYW0ge0V4dE1hbmlmZXN0PEV4dFR5cGU+fSBleHRNYW5pZmVzdFxuICAgKiBAcGFyYW0ge0V4dE5hbWU8RXh0VHlwZT59IGV4dE5hbWVcbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fVxuICAgKi9cbiAgYXN5bmMgZ2V0R2VuZXJpY0NvbmZpZ1dhcm5pbmdzKGV4dE1hbmlmZXN0LCBleHROYW1lKSB7XG4gICAgY29uc3Qge2FwcGl1bVZlcnNpb24sIGluc3RhbGxTcGVjLCBpbnN0YWxsVHlwZSwgcGtnTmFtZX0gPSBleHRNYW5pZmVzdDtcbiAgICBjb25zdCB3YXJuaW5ncyA9IFtdO1xuXG4gICAgY29uc3QgaW52YWxpZEZpZWxkcyA9IFtdO1xuICAgIGlmICghXy5pc1N0cmluZyhpbnN0YWxsU3BlYykpIHtcbiAgICAgIGludmFsaWRGaWVsZHMucHVzaCgnaW5zdGFsbFNwZWMnKTtcbiAgICB9XG5cbiAgICBpZiAoIUlOU1RBTExfVFlQRVMuaGFzKGluc3RhbGxUeXBlKSkge1xuICAgICAgaW52YWxpZEZpZWxkcy5wdXNoKCdpbnN0YWxsVHlwZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGV4dFR5cGVUZXh0ID0gXy5jYXBpdGFsaXplKHRoaXMuZXh0ZW5zaW9uVHlwZSk7XG5cbiAgICBpZiAoaW52YWxpZEZpZWxkcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRGaWVsZHNFbnVtZXJhdGlvblRleHQgPSB1dGlsLnBsdXJhbGl6ZShcbiAgICAgICAgJ2ludmFsaWQgb3IgbWlzc2luZyBmaWVsZCcsXG4gICAgICAgIGludmFsaWRGaWVsZHMubGVuZ3RoLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuICAgICAgY29uc3QgaW52YWxpZEZpZWxkc1RleHQgPSBpbnZhbGlkRmllbGRzLm1hcCgoZmllbGQpID0+IGBcIiR7ZmllbGR9XCJgKS5qb2luKCcsICcpO1xuXG4gICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICBgJHtleHRUeXBlVGV4dH0gXCIke2V4dE5hbWV9XCIgKHBhY2thZ2UgXFxgJHtwa2dOYW1lfVxcYCkgaGFzICR7aW52YWxpZEZpZWxkc0VudW1lcmF0aW9uVGV4dH0gKCR7aW52YWxpZEZpZWxkc1RleHR9KSBpbiBcXGBleHRlbnNpb25zLnlhbWxcXGA7IHRoaXMgbWF5IGNhdXNlIHVwZ3JhZGVzIGRvbmUgdmlhIHRoZSBcXGBhcHBpdW1cXGAgQ0xJIHRvb2wgdG8gZmFpbC4gUGxlYXNlIHJlaW5zdGFsbCB3aXRoIFxcYGFwcGl1bSAke3RoaXMuZXh0ZW5zaW9uVHlwZX0gdW5pbnN0YWxsICR7ZXh0TmFtZX1cXGAgYW5kIFxcYGFwcGl1bSAke3RoaXMuZXh0ZW5zaW9uVHlwZX0gaW5zdGFsbCAke2V4dE5hbWV9XFxgIHRvIGF0dGVtcHQgYSBmaXguYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIZWxwcyBjb25jYXRlbmF0ZSB3YXJuaW5nIG1lc3NhZ2VzIHJlbGF0ZWQgdG8gcGVlciBkZXBlbmRlbmNpZXNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uXG4gICAgICogQHJldHVybnMgc3RyaW5nXG4gICAgICovXG4gICAgY29uc3QgY3JlYXRlUGVlcldhcm5pbmcgPSAocmVhc29uKSA9PlxuICAgICAgYCR7ZXh0VHlwZVRleHR9IFwiJHtleHROYW1lfVwiIChwYWNrYWdlIFxcYCR7cGtnTmFtZX1cXGApIG1heSBiZSBpbmNvbXBhdGlibGUgd2l0aCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIEFwcGl1bSAodiR7QVBQSVVNX1ZFUn0pIGR1ZSB0byAke3JlYXNvbn1gO1xuXG4gICAgaWYgKF8uaXNTdHJpbmcoYXBwaXVtVmVyc2lvbikgJiYgIXNhdGlzZmllcyhBUFBJVU1fVkVSLCBhcHBpdW1WZXJzaW9uKSkge1xuICAgICAgY29uc3QgbGlzdERhdGEgPSBhd2FpdCB0aGlzLmdldExpc3REYXRhKCk7XG4gICAgICBjb25zdCBleHRMaXN0RGF0YSA9IC8qKiBAdHlwZSB7SW5zdGFsbGVkRXh0ZW5zaW9uTGlzdERhdGF9ICovIChsaXN0RGF0YVtleHROYW1lXSk7XG4gICAgICBpZiAoZXh0TGlzdERhdGE/Lmluc3RhbGxlZCkge1xuICAgICAgICBjb25zdCB7dXBkYXRlVmVyc2lvbiwgdXBUb0RhdGV9ID0gZXh0TGlzdERhdGE7XG4gICAgICAgIGlmICghdXBUb0RhdGUpIHtcbiAgICAgICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICAgICAgY3JlYXRlUGVlcldhcm5pbmcoXG4gICAgICAgICAgICAgIGBpdHMgcGVlciBkZXBlbmRlbmN5IG9uIG9sZGVyIEFwcGl1bSB2JHthcHBpdW1WZXJzaW9ufS4gUGxlYXNlIHVwZ3JhZGUgXFxgJHtwa2dOYW1lfVxcYCB0byB2JHt1cGRhdGVWZXJzaW9ufSBvciBuZXdlci5gXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICAgICAgY3JlYXRlUGVlcldhcm5pbmcoXG4gICAgICAgICAgICAgIGBpdHMgcGVlciBkZXBlbmRlbmN5IG9uIG9sZGVyIEFwcGl1bSB2JHthcHBpdW1WZXJzaW9ufS4gUGxlYXNlIGFzayB0aGUgZGV2ZWxvcGVyIG9mIFxcYCR7cGtnTmFtZX1cXGAgdG8gdXBkYXRlIHRoZSBwZWVyIGRlcGVuZGVuY3kgb24gQXBwaXVtIHRvIHYke0FQUElVTV9WRVJ9LmBcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghXy5pc1N0cmluZyhhcHBpdW1WZXJzaW9uKSkge1xuICAgICAgY29uc3QgbGlzdERhdGEgPSBhd2FpdCB0aGlzLmdldExpc3REYXRhKCk7XG4gICAgICBjb25zdCBleHRMaXN0RGF0YSA9IC8qKiBAdHlwZSB7SW5zdGFsbGVkRXh0ZW5zaW9uTGlzdERhdGF9ICovIChsaXN0RGF0YVtleHROYW1lXSk7XG4gICAgICBpZiAoIWV4dExpc3REYXRhPy51cFRvRGF0ZSAmJiBleHRMaXN0RGF0YT8udXBkYXRlVmVyc2lvbikge1xuICAgICAgICB3YXJuaW5ncy5wdXNoKFxuICAgICAgICAgIGNyZWF0ZVBlZXJXYXJuaW5nKFxuICAgICAgICAgICAgYGFuIGludmFsaWQgb3IgbWlzc2luZyBwZWVyIGRlcGVuZGVuY3kgb24gQXBwaXVtLiBBIG5ld2VyIHZlcnNpb24gb2YgXFxgJHtwa2dOYW1lfVxcYCBpcyBhdmFpbGFibGU7IHBsZWFzZSBhdHRlbXB0IHRvIHVwZ3JhZGUgXCIke2V4dE5hbWV9XCIgdG8gdiR7ZXh0TGlzdERhdGEudXBkYXRlVmVyc2lvbn0gb3IgbmV3ZXIuYFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdhcm5pbmdzLnB1c2goXG4gICAgICAgICAgY3JlYXRlUGVlcldhcm5pbmcoXG4gICAgICAgICAgICBgYW4gaW52YWxpZCBvciBtaXNzaW5nIHBlZXIgZGVwZW5kZW5jeSBvbiBBcHBpdW0uIFBsZWFzZSBhc2sgdGhlIGRldmVsb3BlciBvZiBcXGAke3BrZ05hbWV9XFxgIHRvIGFkZCBhIHBlZXIgZGVwZW5kZW5jeSBvbiBcXGBeYXBwaXVtQCR7QVBQSVVNX1ZFUn1cXGAuYFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHdhcm5pbmdzO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIGxpc3Qgb2YgdW5yZWNvdmVyYWJsZSBlcnJvcnMgKGlmIGFueSkgZm9yIHRoZSBnaXZlbiBleHRlbnNpb24gX2lmXyBpdCBoYXMgYSBgc2NoZW1hYCBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gZXh0TWFuaWZlc3QgLSBFeHRlbnNpb24gZGF0YSAoZnJvbSBtYW5pZmVzdClcbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lIC0gRXh0ZW5zaW9uIG5hbWUgKGZyb20gbWFuaWZlc3QpXG4gICAqIEByZXR1cm5zIHtFeHRNYW5pZmVzdFByb2JsZW1bXX1cbiAgICovXG4gIGdldFNjaGVtYVByb2JsZW1zKGV4dE1hbmlmZXN0LCBleHROYW1lKSB7XG4gICAgLyoqIEB0eXBlIHtFeHRNYW5pZmVzdFByb2JsZW1bXX0gKi9cbiAgICBjb25zdCBwcm9ibGVtcyA9IFtdO1xuICAgIGNvbnN0IHtzY2hlbWE6IGFyZ1NjaGVtYVBhdGh9ID0gZXh0TWFuaWZlc3Q7XG4gICAgaWYgKEV4dGVuc2lvbkNvbmZpZy5leHREYXRhSGFzU2NoZW1hKGV4dE1hbmlmZXN0KSkge1xuICAgICAgaWYgKF8uaXNTdHJpbmcoYXJnU2NoZW1hUGF0aCkpIHtcbiAgICAgICAgaWYgKGlzQWxsb3dlZFNjaGVtYUZpbGVFeHRlbnNpb24oYXJnU2NoZW1hUGF0aCkpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5yZWFkRXh0ZW5zaW9uU2NoZW1hKGV4dE5hbWUsIGV4dE1hbmlmZXN0KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHByb2JsZW1zLnB1c2goe1xuICAgICAgICAgICAgICBlcnI6IGBVbmFibGUgdG8gcmVnaXN0ZXIgc2NoZW1hIGF0IHBhdGggJHthcmdTY2hlbWFQYXRofTsgJHtlcnIubWVzc2FnZX1gLFxuICAgICAgICAgICAgICB2YWw6IGFyZ1NjaGVtYVBhdGgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJvYmxlbXMucHVzaCh7XG4gICAgICAgICAgICBlcnI6IGBTY2hlbWEgZmlsZSBoYXMgdW5zdXBwb3J0ZWQgZXh0ZW5zaW9uLiBBbGxvd2VkOiAke1tcbiAgICAgICAgICAgICAgLi4uQUxMT1dFRF9TQ0hFTUFfRVhURU5TSU9OUyxcbiAgICAgICAgICAgIF0uam9pbignLCAnKX1gLFxuICAgICAgICAgICAgdmFsOiBhcmdTY2hlbWFQYXRoLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKF8uaXNQbGFpbk9iamVjdChhcmdTY2hlbWFQYXRoKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMucmVhZEV4dGVuc2lvblNjaGVtYShleHROYW1lLCBleHRNYW5pZmVzdCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIHByb2JsZW1zLnB1c2goe1xuICAgICAgICAgICAgZXJyOiBgVW5hYmxlIHRvIHJlZ2lzdGVyIGVtYmVkZGVkIHNjaGVtYTsgJHtlcnIubWVzc2FnZX1gLFxuICAgICAgICAgICAgdmFsOiBhcmdTY2hlbWFQYXRoLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcm9ibGVtcy5wdXNoKHtcbiAgICAgICAgICBlcnI6ICdJbmNvcnJlY3RseSBmb3JtYXR0ZWQgc2NoZW1hIGZpZWxkOyBtdXN0IGJlIGEgcGF0aCB0byBhIHNjaGVtYSBmaWxlIG9yIGEgc2NoZW1hIG9iamVjdC4nLFxuICAgICAgICAgIHZhbDogYXJnU2NoZW1hUGF0aCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9ibGVtcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBsaXN0IG9mIGdlbmVyaWMgdW5yZWNvdmVyYWJsZSBlcnJvcnMgZm9yIHRoZSBnaXZlbiBleHRlbnNpb25cbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gZXh0TWFuaWZlc3QgLSBFeHRlbnNpb24gZGF0YSAoZnJvbSBtYW5pZmVzdClcbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lIC0gRXh0ZW5zaW9uIG5hbWUgKGZyb20gbWFuaWZlc3QpXG4gICAqIEByZXR1cm5zIHtFeHRNYW5pZmVzdFByb2JsZW1bXX1cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBnZXRHZW5lcmljQ29uZmlnUHJvYmxlbXMoZXh0TWFuaWZlc3QsIGV4dE5hbWUpIHtcbiAgICBjb25zdCB7dmVyc2lvbiwgcGtnTmFtZSwgbWFpbkNsYXNzfSA9IGV4dE1hbmlmZXN0O1xuICAgIGNvbnN0IHByb2JsZW1zID0gW107XG5cbiAgICBpZiAoIV8uaXNTdHJpbmcodmVyc2lvbikpIHtcbiAgICAgIHByb2JsZW1zLnB1c2goe1xuICAgICAgICBlcnI6IGBJbnZhbGlkIG9yIG1pc3NpbmcgXFxgdmVyc2lvblxcYCBmaWVsZCBpbiBteSBcXGBwYWNrYWdlLmpzb25cXGAgYW5kL29yIFxcYGV4dGVuc2lvbnMueWFtbFxcYCAobXVzdCBiZSBhIHN0cmluZylgLFxuICAgICAgICB2YWw6IHZlcnNpb24sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIV8uaXNTdHJpbmcocGtnTmFtZSkpIHtcbiAgICAgIHByb2JsZW1zLnB1c2goe1xuICAgICAgICBlcnI6IGBJbnZhbGlkIG9yIG1pc3NpbmcgXFxgbmFtZVxcYCBmaWVsZCBpbiBteSBcXGBwYWNrYWdlLmpzb25cXGAgYW5kL29yIFxcYGV4dGVuc2lvbnMueWFtbFxcYCAobXVzdCBiZSBhIHN0cmluZylgLFxuICAgICAgICB2YWw6IHBrZ05hbWUsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIV8uaXNTdHJpbmcobWFpbkNsYXNzKSkge1xuICAgICAgcHJvYmxlbXMucHVzaCh7XG4gICAgICAgIGVycjogYEludmFsaWQgb3IgbWlzc2luZyBcXGBhcHBpdW0ubWFpbkNsYXNzXFxgIGZpZWxkIGluIG15IFxcYHBhY2thZ2UuanNvblxcYCBhbmQvb3IgXFxgbWFpbkNsYXNzXFxgIGZpZWxkIGluIFxcYGV4dGVuc2lvbnMueWFtbFxcYCAobXVzdCBiZSBhIHN0cmluZylgLFxuICAgICAgICB2YWw6IG1haW5DbGFzcyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9ibGVtcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gZXh0TWFuaWZlc3RcbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lXG4gICAqIEByZXR1cm5zIHtFeHRNYW5pZmVzdFByb2JsZW1bXX1cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBnZXRDb25maWdQcm9ibGVtcyhleHRNYW5pZmVzdCwgZXh0TmFtZSkge1xuICAgIC8vIHNob3VkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGlmIHNwZWNpYWwgdmFsaWRhdGlvbiBpcyBuZWNlc3NhcnkgZm9yIHRoaXMgZXh0ZW5zaW9uIHR5cGVcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV4dE5hbWVcbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gZXh0TWFuaWZlc3RcbiAgICogQHBhcmFtIHtFeHRlbnNpb25Db25maWdNdXRhdGlvbk9wdHN9IFtvcHRzXVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGFkZEV4dGVuc2lvbihleHROYW1lLCBleHRNYW5pZmVzdCwge3dyaXRlID0gdHJ1ZX0gPSB7fSkge1xuICAgIHRoaXMubWFuaWZlc3QuYWRkRXh0ZW5zaW9uKHRoaXMuZXh0ZW5zaW9uVHlwZSwgZXh0TmFtZSwgZXh0TWFuaWZlc3QpO1xuICAgIGlmICh3cml0ZSkge1xuICAgICAgYXdhaXQgdGhpcy5tYW5pZmVzdC53cml0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0V4dE5hbWU8RXh0VHlwZT59IGV4dE5hbWVcbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPnxpbXBvcnQoJy4uL2NsaS9leHRlbnNpb24tY29tbWFuZCcpLkV4dGVuc2lvbkZpZWxkczxFeHRUeXBlPn0gZXh0TWFuaWZlc3RcbiAgICogQHBhcmFtIHtFeHRlbnNpb25Db25maWdNdXRhdGlvbk9wdHN9IFtvcHRzXVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHVwZGF0ZUV4dGVuc2lvbihleHROYW1lLCBleHRNYW5pZmVzdCwge3dyaXRlID0gdHJ1ZX0gPSB7fSkge1xuICAgIHRoaXMuaW5zdGFsbGVkRXh0ZW5zaW9uc1tleHROYW1lXSA9IHtcbiAgICAgIC4uLnRoaXMuaW5zdGFsbGVkRXh0ZW5zaW9uc1tleHROYW1lXSxcbiAgICAgIC4uLmV4dE1hbmlmZXN0LFxuICAgIH07XG4gICAgaWYgKHdyaXRlKSB7XG4gICAgICBhd2FpdCB0aGlzLm1hbmlmZXN0LndyaXRlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBleHRlbnNpb24gZnJvbSB0aGUgbGlzdCBvZiBpbnN0YWxsZWQgZXh0ZW5zaW9ucywgYW5kIG9wdGlvbmFsbHkgYXZvaWQgYSB3cml0ZSB0byB0aGUgbWFuaWZlc3QgZmlsZS5cbiAgICpcbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lXG4gICAqIEBwYXJhbSB7RXh0ZW5zaW9uQ29uZmlnTXV0YXRpb25PcHRzfSBbb3B0c11cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyByZW1vdmVFeHRlbnNpb24oZXh0TmFtZSwge3dyaXRlID0gdHJ1ZX0gPSB7fSkge1xuICAgIGRlbGV0ZSB0aGlzLmluc3RhbGxlZEV4dGVuc2lvbnNbZXh0TmFtZV07XG4gICAgaWYgKHdyaXRlKSB7XG4gICAgICBhd2FpdCB0aGlzLm1hbmlmZXN0LndyaXRlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RXh0TmFtZTxFeHRUeXBlPltdfSBbYWN0aXZlTmFtZXNdXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIHByaW50KGFjdGl2ZU5hbWVzKSB7XG4gICAgaWYgKF8uaXNFbXB0eSh0aGlzLmluc3RhbGxlZEV4dGVuc2lvbnMpKSB7XG4gICAgICBsb2cuaW5mbyhcbiAgICAgICAgYE5vICR7dGhpcy5jb25maWdLZXl9IGhhdmUgYmVlbiBpbnN0YWxsZWQgaW4gJHt0aGlzLmFwcGl1bUhvbWV9LiBVc2UgdGhlIFwiYXBwaXVtICR7dGhpcy5leHRlbnNpb25UeXBlfVwiIGAgK1xuICAgICAgICAgICdjb21tYW5kIHRvIGluc3RhbGwgdGhlIG9uZShzKSB5b3Ugd2FudCB0byB1c2UuJ1xuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2cuaW5mbyhgQXZhaWxhYmxlICR7dGhpcy5jb25maWdLZXl9OmApO1xuICAgIGZvciAoY29uc3QgW2V4dE5hbWUsIGV4dE1hbmlmZXN0XSBvZiAvKiogQHR5cGUge1tzdHJpbmcsIEV4dE1hbmlmZXN0PEV4dFR5cGU+XVtdfSAqLyAoXG4gICAgICBfLnRvUGFpcnModGhpcy5pbnN0YWxsZWRFeHRlbnNpb25zKVxuICAgICkpIHtcbiAgICAgIGxvZy5pbmZvKGAgIC0gJHt0aGlzLmV4dGVuc2lvbkRlc2MoZXh0TmFtZSwgZXh0TWFuaWZlc3QpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgc3RyaW5nIGRlc2NyaWJpbmcgdGhlIGV4dGVuc2lvbi4gU3ViY2xhc3NlcyBtdXN0IGltcGxlbWVudC5cbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lIC0gRXh0ZW5zaW9uIG5hbWVcbiAgICogQHBhcmFtIHtFeHRNYW5pZmVzdDxFeHRUeXBlPn0gZXh0TWFuaWZlc3QgLSBFeHRlbnNpb24gZGF0YVxuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKiBAYWJzdHJhY3RcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBleHRlbnNpb25EZXNjKGV4dE5hbWUsIGV4dE1hbmlmZXN0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIG11c3QgYmUgaW1wbGVtZW50ZWQgaW4gYSBzdWJjbGFzcycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBleHROYW1lXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICBnZXRJbnN0YWxsUGF0aChleHROYW1lKSB7XG4gICAgcmV0dXJuIHBhdGguam9pbih0aGlzLmFwcGl1bUhvbWUsICdub2RlX21vZHVsZXMnLCB0aGlzLmluc3RhbGxlZEV4dGVuc2lvbnNbZXh0TmFtZV0ucGtnTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgZXh0ZW5zaW9uIGFuZCByZXR1cm5zIGl0cyBtYWluIGNsYXNzIChjb25zdHJ1Y3RvcilcbiAgICogQHBhcmFtIHtFeHROYW1lPEV4dFR5cGU+fSBleHROYW1lXG4gICAqIEByZXR1cm5zIHtFeHRDbGFzczxFeHRUeXBlPn1cbiAgICovXG4gIHJlcXVpcmUoZXh0TmFtZSkge1xuICAgIGNvbnN0IHttYWluQ2xhc3N9ID0gdGhpcy5pbnN0YWxsZWRFeHRlbnNpb25zW2V4dE5hbWVdO1xuICAgIGNvbnN0IHJlcVBhdGggPSB0aGlzLmdldEluc3RhbGxQYXRoKGV4dE5hbWUpO1xuICAgIC8qKiBAdHlwZSB7c3RyaW5nfSAqL1xuICAgIGxldCByZXFSZXNvbHZlZDtcbiAgICB0cnkge1xuICAgICAgcmVxUmVzb2x2ZWQgPSByZXF1aXJlLnJlc29sdmUocmVxUGF0aCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoYENvdWxkIG5vdCBmaW5kIGEgJHt0aGlzLmV4dGVuc2lvblR5cGV9IGluc3RhbGxlZCBhdCAke3JlcVBhdGh9YCk7XG4gICAgfVxuICAgIC8vIG5vdGU6IHRoaXMgd2lsbCBvbmx5IHJlbG9hZCB0aGUgZW50cnkgcG9pbnRcbiAgICBpZiAocHJvY2Vzcy5lbnYuQVBQSVVNX1JFTE9BRF9FWFRFTlNJT05TICYmIHJlcXVpcmUuY2FjaGVbcmVxUmVzb2x2ZWRdKSB7XG4gICAgICBsb2cuZGVidWcoYFJlbW92aW5nICR7cmVxUmVzb2x2ZWR9IGZyb20gcmVxdWlyZSBjYWNoZWApO1xuICAgICAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbcmVxUmVzb2x2ZWRdO1xuICAgIH1cbiAgICBsb2cuZGVidWcoYFJlcXVpcmluZyAke3RoaXMuZXh0ZW5zaW9uVHlwZX0gYXQgJHtyZXFQYXRofWApO1xuICAgIGNvbnN0IE1haW5DbGFzcyA9IHJlcXVpcmUocmVxUGF0aClbbWFpbkNsYXNzXTtcbiAgICBpZiAoIU1haW5DbGFzcykge1xuICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgYSBjbGFzcyBuYW1lZCBcIiR7bWFpbkNsYXNzfVwiIGV4cG9ydGVkIGJ5ICR7dGhpcy5leHRlbnNpb25UeXBlfSBcIiR7ZXh0TmFtZX1cImBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBNYWluQ2xhc3M7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV4dE5hbWVcbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBpc0luc3RhbGxlZChleHROYW1lKSB7XG4gICAgcmV0dXJuIF8uaW5jbHVkZXMoT2JqZWN0LmtleXModGhpcy5pbnN0YWxsZWRFeHRlbnNpb25zKSwgZXh0TmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogSW50ZW5kZWQgdG8gYmUgY2FsbGVkIGJ5IGNvcnJlc3BvbmRpbmcgaW5zdGFuY2UgbWV0aG9kcyBvZiBzdWJjbGFzcy5cbiAgICogQHByaXZhdGVcbiAgICogQHRlbXBsYXRlIHtFeHRlbnNpb25UeXBlfSBFeHRUeXBlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcHBpdW1Ib21lXG4gICAqIEBwYXJhbSB7RXh0VHlwZX0gZXh0VHlwZVxuICAgKiBAcGFyYW0ge0V4dE5hbWU8RXh0VHlwZT59IGV4dE5hbWUgLSBFeHRlbnNpb24gbmFtZSAodW5pcXVlIHRvIGl0cyB0eXBlKVxuICAgKiBAcGFyYW0ge0V4dE1hbmlmZXN0V2l0aFNjaGVtYTxFeHRUeXBlPn0gZXh0TWFuaWZlc3QgLSBFeHRlbnNpb24gY29uZmlnXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoJ2FqdicpLlNjaGVtYU9iamVjdHx1bmRlZmluZWR9XG4gICAqL1xuICBzdGF0aWMgX3JlYWRFeHRlbnNpb25TY2hlbWEoYXBwaXVtSG9tZSwgZXh0VHlwZSwgZXh0TmFtZSwgZXh0TWFuaWZlc3QpIHtcbiAgICBjb25zdCB7cGtnTmFtZSwgc2NoZW1hOiBhcmdTY2hlbWFQYXRofSA9IGV4dE1hbmlmZXN0O1xuICAgIGlmICghYXJnU2NoZW1hUGF0aCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgYE5vIFxcYHNjaGVtYVxcYCBwcm9wZXJ0eSBmb3VuZCBpbiBjb25maWcgZm9yICR7ZXh0VHlwZX0gJHtwa2dOYW1lfSAtLSB3aHkgaXMgdGhpcyBmdW5jdGlvbiBiZWluZyBjYWxsZWQ/YFxuICAgICAgKTtcbiAgICB9XG4gICAgbGV0IG1vZHVsZU9iamVjdDtcbiAgICBpZiAoXy5pc1N0cmluZyhhcmdTY2hlbWFQYXRoKSkge1xuICAgICAgY29uc3Qgc2NoZW1hUGF0aCA9IHJlc29sdmVGcm9tKGFwcGl1bUhvbWUsIHBhdGguam9pbihwa2dOYW1lLCBhcmdTY2hlbWFQYXRoKSk7XG4gICAgICBtb2R1bGVPYmplY3QgPSByZXF1aXJlKHNjaGVtYVBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb2R1bGVPYmplY3QgPSBhcmdTY2hlbWFQYXRoO1xuICAgIH1cbiAgICAvLyB0aGlzIHN1Y2tzLiBkZWZhdWx0IGV4cG9ydHMgc2hvdWxkIGJlIGRlc3Ryb3llZFxuICAgIGNvbnN0IHNjaGVtYSA9IG1vZHVsZU9iamVjdC5fX2VzTW9kdWxlID8gbW9kdWxlT2JqZWN0LmRlZmF1bHQgOiBtb2R1bGVPYmplY3Q7XG4gICAgcmVnaXN0ZXJTY2hlbWEoZXh0VHlwZSwgZXh0TmFtZSwgc2NoZW1hKTtcbiAgICByZXR1cm4gc2NoZW1hO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYHRydWVgIGlmIGEgc3BlY2lmaWMge0BsaW5rIEV4dE1hbmlmZXN0fSBvYmplY3QgaGFzIGEgYHNjaGVtYWAgcHJvcC5cbiAgICogVGhlIHtAbGluayBFeHRNYW5pZmVzdH0gb2JqZWN0IGJlY29tZXMgYSB7QGxpbmsgRXh0TWFuaWZlc3RXaXRoU2NoZW1hfSBvYmplY3QuXG4gICAqIEB0ZW1wbGF0ZSB7RXh0ZW5zaW9uVHlwZX0gRXh0VHlwZVxuICAgKiBAcGFyYW0ge0V4dE1hbmlmZXN0PEV4dFR5cGU+fSBleHRNYW5pZmVzdFxuICAgKiBAcmV0dXJucyB7ZXh0TWFuaWZlc3QgaXMgRXh0TWFuaWZlc3RXaXRoU2NoZW1hPEV4dFR5cGU+fVxuICAgKi9cbiAgc3RhdGljIGV4dERhdGFIYXNTY2hlbWEoZXh0TWFuaWZlc3QpIHtcbiAgICByZXR1cm4gXy5pc1N0cmluZyhleHRNYW5pZmVzdD8uc2NoZW1hKSB8fCBfLmlzT2JqZWN0KGV4dE1hbmlmZXN0Py5zY2hlbWEpO1xuICB9XG5cbiAgLyoqXG4gICAqIElmIGFuIGV4dGVuc2lvbiBwcm92aWRlcyBhIHNjaGVtYSwgdGhpcyB3aWxsIGxvYWQgdGhlIHNjaGVtYSBhbmQgYXR0ZW1wdCB0b1xuICAgKiByZWdpc3RlciBpdCB3aXRoIHRoZSBzY2hlbWEgcmVnaXN0cmFyLlxuICAgKiBAcGFyYW0ge0V4dE5hbWU8RXh0VHlwZT59IGV4dE5hbWUgLSBOYW1lIG9mIGV4dGVuc2lvblxuICAgKiBAcGFyYW0ge0V4dE1hbmlmZXN0V2l0aFNjaGVtYTxFeHRUeXBlPn0gZXh0TWFuaWZlc3QgLSBFeHRlbnNpb24gZGF0YVxuICAgKiBAcmV0dXJucyB7aW1wb3J0KCdhanYnKS5TY2hlbWFPYmplY3R8dW5kZWZpbmVkfVxuICAgKi9cbiAgcmVhZEV4dGVuc2lvblNjaGVtYShleHROYW1lLCBleHRNYW5pZmVzdCkge1xuICAgIHJldHVybiBFeHRlbnNpb25Db25maWcuX3JlYWRFeHRlbnNpb25TY2hlbWEoXG4gICAgICB0aGlzLmFwcGl1bUhvbWUsXG4gICAgICB0aGlzLmV4dGVuc2lvblR5cGUsXG4gICAgICBleHROYW1lLFxuICAgICAgZXh0TWFuaWZlc3RcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCB7SU5TVEFMTF9UWVBFX05QTSwgSU5TVEFMTF9UWVBFX0dJVCwgSU5TVEFMTF9UWVBFX0xPQ0FMLCBJTlNUQUxMX1RZUEVfR0lUSFVCLCBJTlNUQUxMX1RZUEVTfTtcblxuLyoqXG4gKiBBbiBpc3N1ZSB3aXRoIHRoZSB7QGxpbmtjb2RlIEV4dE1hbmlmZXN0fSBmb3IgYSBwYXJ0aWN1bGFyIGV4dGVuc2lvbi5cbiAqXG4gKiBUaGUgZXhpc3RhbmNlIG9mIHN1Y2ggYW4gb2JqZWN0IGltcGxpZXMgdGhhdCB0aGUgZXh0ZW5zaW9uIGNhbm5vdCBiZSBsb2FkZWQuXG4gKiBAdHlwZWRlZiBFeHRNYW5pZmVzdFByb2JsZW1cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBlcnIgLSBFcnJvciBtZXNzYWdlXG4gKiBAcHJvcGVydHkge2FueX0gdmFsIC0gQXNzb2NpYXRlZCB2YWx1ZVxuICovXG5cbi8qKlxuICogQW4gb3B0aW9uYWwgbG9nZ2luZyBmdW5jdGlvbiBwcm92aWRlZCB0byBhbiB7QGxpbmsgRXh0ZW5zaW9uQ29uZmlnfSBzdWJjbGFzcy5cbiAqIEBjYWxsYmFjayBFeHRlbnNpb25Mb2dGblxuICogQHBhcmFtIHsuLi5hbnl9IGFyZ3NcbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge2ltcG9ydCgnQGFwcGl1bS90eXBlcycpLkV4dGVuc2lvblR5cGV9IEV4dGVuc2lvblR5cGVcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4vbWFuaWZlc3QnKS5NYW5pZmVzdH0gTWFuaWZlc3RcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHBpdW0vdHlwZXMnKS5FeHRNYW5pZmVzdDxUPn0gRXh0TWFuaWZlc3RcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHBpdW0vdHlwZXMnKS5FeHRNYW5pZmVzdFdpdGhTY2hlbWE8VD59IEV4dE1hbmlmZXN0V2l0aFNjaGVtYVxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJ2FwcGl1bS90eXBlcycpLkV4dE5hbWU8VD59IEV4dE5hbWVcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHBpdW0vdHlwZXMnKS5FeHRDbGFzczxUPn0gRXh0Q2xhc3NcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7aW1wb3J0KCdhcHBpdW0vdHlwZXMnKS5FeHRSZWNvcmQ8VD59IEV4dFJlY29yZFxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uL2NsaS9leHRlbnNpb24nKS5FeHRDb21tYW5kPFQ+fSBFeHRDb21tYW5kXG4gKi9cblxuLyoqXG4gKiBPcHRpb25zIGZvciB2YXJpb3VzIG1ldGhvZHMgaW4ge0BsaW5rIEV4dGVuc2lvbkNvbmZpZ31cbiAqIEB0eXBlZGVmIEV4dGVuc2lvbkNvbmZpZ011dGF0aW9uT3B0c1xuICogQHByb3BlcnR5IHtib29sZWFufSBbd3JpdGU9dHJ1ZV0gV2hldGhlciBvciBub3QgdG8gd3JpdGUgdGhlIG1hbmlmZXN0IHRvIGRpc2sgYWZ0ZXIgYSBtdXRhdGlvbiBvcGVyYXRpb25cbiAqL1xuXG4vKipcbiAqIEEgdmFsaWQgaW5zdGFsbCB0eXBlXG4gKiBAdHlwZWRlZiB7dHlwZW9mIElOU1RBTExfVFlQRV9OUE0gfCB0eXBlb2YgSU5TVEFMTF9UWVBFX0dJVCB8IHR5cGVvZiBJTlNUQUxMX1RZUEVfTE9DQUwgfCB0eXBlb2YgSU5TVEFMTF9UWVBFX0dJVEhVQn0gSW5zdGFsbFR5cGVcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uL2NsaS9leHRlbnNpb24tY29tbWFuZCcpLkV4dGVuc2lvbkxpc3REYXRhfSBFeHRlbnNpb25MaXN0RGF0YVxuICogQHR5cGVkZWYge2ltcG9ydCgnLi4vY2xpL2V4dGVuc2lvbi1jb21tYW5kJykuSW5zdGFsbGVkRXh0ZW5zaW9uTGlzdERhdGF9IEluc3RhbGxlZEV4dGVuc2lvbkxpc3REYXRhXG4gKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFNQSxNQUFNQSxnQkFBZ0IsR0FBRyxLQUF6Qjs7QUFDQSxNQUFNQyxrQkFBa0IsR0FBRyxPQUEzQjs7QUFDQSxNQUFNQyxtQkFBbUIsR0FBRyxRQUE1Qjs7QUFDQSxNQUFN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
|
|
530
|
+
_ExtensionConfig_listDataCache = new WeakMap();
|
|
531
|
+
/**
|
|
532
|
+
* An issue with the {@linkcode ExtManifest} for a particular extension.
|
|
533
|
+
*
|
|
534
|
+
* The existance of such an object implies that the extension cannot be loaded.
|
|
535
|
+
* @typedef ExtManifestProblem
|
|
536
|
+
* @property {string} err - Error message
|
|
537
|
+
* @property {any} val - Associated value
|
|
538
|
+
*/
|
|
539
|
+
/**
|
|
540
|
+
* An optional logging function provided to an {@link ExtensionConfig} subclass.
|
|
541
|
+
* @callback ExtensionLogFn
|
|
542
|
+
* @param {...any} args
|
|
543
|
+
* @returns {void}
|
|
544
|
+
*/
|
|
545
|
+
/**
|
|
546
|
+
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
547
|
+
* @typedef {import('./manifest').Manifest} Manifest
|
|
548
|
+
* @typedef {import('../cli/extension-command').ExtensionListData} ExtensionListData
|
|
549
|
+
* @typedef {import('../cli/extension-command').InstalledExtensionListData} InstalledExtensionListData
|
|
550
|
+
* @typedef {import('appium/types').InstallType} InstallType
|
|
551
|
+
*/
|
|
552
|
+
/**
|
|
553
|
+
* @template {ExtensionType} ExtType
|
|
554
|
+
* @typedef {import('appium/types').ExtManifest<ExtType>} ExtManifest
|
|
555
|
+
*/
|
|
556
|
+
/**
|
|
557
|
+
* @template {ExtensionType} ExtType
|
|
558
|
+
* @typedef {ExtManifest<ExtType> & {schema: NonNullable<ExtManifest<ExtType>['schema']>}} ExtManifestWithSchema
|
|
559
|
+
*/
|
|
560
|
+
/**
|
|
561
|
+
* @template {ExtensionType} ExtType
|
|
562
|
+
* @typedef {import('appium/types').ExtName<ExtType>} ExtName
|
|
563
|
+
*/
|
|
564
|
+
/**
|
|
565
|
+
* @template {ExtensionType} ExtType
|
|
566
|
+
* @typedef {import('appium/types').ExtClass<ExtType>} ExtClass
|
|
567
|
+
*/
|
|
568
|
+
/**
|
|
569
|
+
* @template {ExtensionType} ExtType
|
|
570
|
+
* @typedef {import('appium/types').ExtRecord<ExtType>} ExtRecord
|
|
571
|
+
*/
|
|
572
|
+
/**
|
|
573
|
+
* @template {ExtensionType} ExtType
|
|
574
|
+
* @typedef {import('../cli/extension').ExtCommand<ExtType>} ExtCommand
|
|
575
|
+
*/
|
|
576
|
+
/**
|
|
577
|
+
* Options for various methods in {@link ExtensionConfig}
|
|
578
|
+
* @typedef ExtensionConfigMutationOpts
|
|
579
|
+
* @property {boolean} [write=true] Whether or not to write the manifest to disk after a mutation operation
|
|
580
|
+
*/
|
|
581
|
+
//# sourceMappingURL=extension-config.js.map
|