appium 2.0.0-beta.45 → 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.
Files changed (138) hide show
  1. package/README.md +145 -44
  2. package/build/lib/appium.d.ts +3 -103
  3. package/build/lib/appium.d.ts.map +1 -1
  4. package/build/lib/appium.js +679 -549
  5. package/build/lib/appium.js.map +1 -1
  6. package/build/lib/cli/args.js +247 -127
  7. package/build/lib/cli/args.js.map +1 -1
  8. package/build/lib/cli/driver-command.js +63 -88
  9. package/build/lib/cli/driver-command.js.map +1 -1
  10. package/build/lib/cli/extension-command.d.ts +32 -23
  11. package/build/lib/cli/extension-command.d.ts.map +1 -1
  12. package/build/lib/cli/extension-command.js +730 -512
  13. package/build/lib/cli/extension-command.js.map +1 -1
  14. package/build/lib/cli/extension.d.ts +5 -4
  15. package/build/lib/cli/extension.d.ts.map +1 -1
  16. package/build/lib/cli/extension.js +68 -65
  17. package/build/lib/cli/extension.js.map +1 -1
  18. package/build/lib/cli/parser.d.ts +3 -3
  19. package/build/lib/cli/parser.d.ts.map +1 -1
  20. package/build/lib/cli/parser.js +234 -192
  21. package/build/lib/cli/parser.js.map +1 -1
  22. package/build/lib/cli/plugin-command.js +58 -87
  23. package/build/lib/cli/plugin-command.js.map +1 -1
  24. package/build/lib/cli/utils.js +66 -69
  25. package/build/lib/cli/utils.js.map +1 -1
  26. package/build/lib/config-file.d.ts.map +1 -1
  27. package/build/lib/config-file.js +189 -120
  28. package/build/lib/config-file.js.map +1 -1
  29. package/build/lib/config.d.ts.map +1 -1
  30. package/build/lib/config.js +254 -213
  31. package/build/lib/config.js.map +1 -1
  32. package/build/lib/constants.d.ts +5 -5
  33. package/build/lib/constants.d.ts.map +1 -1
  34. package/build/lib/constants.js +64 -59
  35. package/build/lib/constants.js.map +1 -1
  36. package/build/lib/extension/driver-config.js +199 -164
  37. package/build/lib/extension/driver-config.js.map +1 -1
  38. package/build/lib/extension/extension-config.d.ts +18 -16
  39. package/build/lib/extension/extension-config.d.ts.map +1 -1
  40. package/build/lib/extension/extension-config.js +523 -396
  41. package/build/lib/extension/extension-config.js.map +1 -1
  42. package/build/lib/extension/index.js +98 -68
  43. package/build/lib/extension/index.js.map +1 -1
  44. package/build/lib/extension/manifest-migrations.d.ts +27 -0
  45. package/build/lib/extension/manifest-migrations.d.ts.map +1 -0
  46. package/build/lib/extension/manifest-migrations.js +99 -0
  47. package/build/lib/extension/manifest-migrations.js.map +1 -0
  48. package/build/lib/extension/manifest.d.ts +7 -56
  49. package/build/lib/extension/manifest.d.ts.map +1 -1
  50. package/build/lib/extension/manifest.js +432 -240
  51. package/build/lib/extension/manifest.js.map +1 -1
  52. package/build/lib/extension/package-changed.js +57 -61
  53. package/build/lib/extension/package-changed.js.map +1 -1
  54. package/build/lib/extension/plugin-config.d.ts +2 -3
  55. package/build/lib/extension/plugin-config.d.ts.map +1 -1
  56. package/build/lib/extension/plugin-config.js +94 -70
  57. package/build/lib/extension/plugin-config.js.map +1 -1
  58. package/build/lib/grid-register.js +119 -137
  59. package/build/lib/grid-register.js.map +1 -1
  60. package/build/lib/logger.d.ts +1 -1
  61. package/build/lib/logger.d.ts.map +1 -1
  62. package/build/lib/logger.js +5 -15
  63. package/build/lib/logger.js.map +1 -1
  64. package/build/lib/logsink.d.ts.map +1 -1
  65. package/build/lib/logsink.js +189 -183
  66. package/build/lib/logsink.js.map +1 -1
  67. package/build/lib/main.d.ts +19 -12
  68. package/build/lib/main.d.ts.map +1 -1
  69. package/build/lib/main.js +330 -304
  70. package/build/lib/main.js.map +1 -1
  71. package/build/lib/schema/arg-spec.js +153 -108
  72. package/build/lib/schema/arg-spec.js.map +1 -1
  73. package/build/lib/schema/cli-args.js +203 -164
  74. package/build/lib/schema/cli-args.js.map +1 -1
  75. package/build/lib/schema/cli-transformers.js +117 -72
  76. package/build/lib/schema/cli-transformers.js.map +1 -1
  77. package/build/lib/schema/index.js +17 -32
  78. package/build/lib/schema/index.js.map +1 -1
  79. package/build/lib/schema/keywords.js +125 -67
  80. package/build/lib/schema/keywords.js.map +1 -1
  81. package/build/lib/schema/schema.d.ts.map +1 -1
  82. package/build/lib/schema/schema.js +582 -417
  83. package/build/lib/schema/schema.js.map +1 -1
  84. package/build/lib/utils.d.ts +41 -255
  85. package/build/lib/utils.d.ts.map +1 -1
  86. package/build/lib/utils.js +342 -193
  87. package/build/lib/utils.js.map +1 -1
  88. package/build/tsconfig.tsbuildinfo +1 -1
  89. package/build/types/cli.d.ts +45 -34
  90. package/build/types/cli.d.ts.map +1 -1
  91. package/build/types/cli.js +3 -0
  92. package/build/types/cli.js.map +1 -0
  93. package/build/types/index.d.ts +1 -2
  94. package/build/types/index.d.ts.map +1 -1
  95. package/build/types/index.js +19 -0
  96. package/build/types/index.js.map +1 -0
  97. package/build/types/manifest/base.d.ts +135 -0
  98. package/build/types/manifest/base.d.ts.map +1 -0
  99. package/build/types/manifest/base.js +3 -0
  100. package/build/types/manifest/base.js.map +1 -0
  101. package/build/types/manifest/index.d.ts +19 -0
  102. package/build/types/manifest/index.d.ts.map +1 -0
  103. package/build/types/manifest/index.js +40 -0
  104. package/build/types/manifest/index.js.map +1 -0
  105. package/build/types/manifest/v3.d.ts +139 -0
  106. package/build/types/manifest/v3.d.ts.map +1 -0
  107. package/build/types/manifest/v3.js +3 -0
  108. package/build/types/manifest/v3.js.map +1 -0
  109. package/lib/appium.js +1 -1
  110. package/lib/cli/args.js +1 -1
  111. package/lib/cli/extension-command.js +116 -61
  112. package/lib/cli/extension.js +9 -8
  113. package/lib/cli/parser.js +2 -2
  114. package/lib/config-file.js +2 -3
  115. package/lib/config.js +3 -2
  116. package/lib/constants.js +6 -5
  117. package/lib/extension/extension-config.js +24 -25
  118. package/lib/extension/manifest-migrations.js +99 -0
  119. package/lib/extension/manifest.js +79 -72
  120. package/lib/extension/plugin-config.js +1 -2
  121. package/lib/logsink.js +26 -5
  122. package/lib/main.js +58 -50
  123. package/lib/schema/schema.js +6 -1
  124. package/lib/utils.js +62 -0
  125. package/package.json +23 -24
  126. package/scripts/autoinstall-extensions.js +78 -26
  127. package/types/cli.ts +81 -42
  128. package/types/index.ts +1 -2
  129. package/types/manifest/README.md +30 -0
  130. package/types/manifest/base.ts +158 -0
  131. package/types/manifest/index.ts +27 -0
  132. package/types/manifest/v3.ts +161 -0
  133. package/build/types/appium-manifest.d.ts +0 -59
  134. package/build/types/appium-manifest.d.ts.map +0 -1
  135. package/build/types/extension-manifest.d.ts +0 -55
  136. package/build/types/extension-manifest.d.ts.map +0 -1
  137. package/types/appium-manifest.ts +0 -73
  138. package/types/extension-manifest.ts +0 -64
@@ -1,261 +1,453 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
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("source-map-support/register");
9
-
10
- var _bluebird = _interopRequireDefault(require("bluebird"));
11
-
12
- var _glob = _interopRequireDefault(require("glob"));
13
-
14
- var _support = require("@appium/support");
15
-
16
- var _lodash = _interopRequireDefault(require("lodash"));
17
-
18
- var _path = _interopRequireDefault(require("path"));
19
-
20
- var _yaml = _interopRequireDefault(require("yaml"));
21
-
22
- var _constants = require("../constants");
23
-
24
- var _logger = _interopRequireDefault(require("../logger"));
25
-
26
- var _extensionConfig = require("./extension-config");
27
-
28
- var _packageChanged = require("./package-changed");
29
-
30
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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
- [CONFIG_DATA_DRIVER_KEY]: Object.freeze({}),
37
- [CONFIG_DATA_PLUGIN_KEY]: Object.freeze({}),
38
- schemaRev: CONFIG_SCHEMA_REV
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
- return _lodash.default.isPlainObject(value) && _lodash.default.isPlainObject(value.appium) && _lodash.default.isString(value.name) && _lodash.default.isString(value.version);
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
- return isExtension(value) && _lodash.default.isString(_lodash.default.get(value, 'appium.driverName')) && _lodash.default.isString(_lodash.default.get(value, 'appium.automationName')) && _lodash.default.isArray(_lodash.default.get(value, 'appium.platformNames'));
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
- return isExtension(value) && _lodash.default.isString(_lodash.default.get(value, 'appium.pluginName'));
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
- _data;
55
- _appiumHome;
56
- _manifestPath;
57
- _writing;
58
- _reading;
59
-
60
- constructor(appiumHome) {
61
- this._appiumHome = appiumHome;
62
- this._data = _lodash.default.cloneDeep(INITIAL_MANIFEST_DATA);
63
- }
64
-
65
- static getInstance = _lodash.default.memoize(function _getInstance(appiumHome) {
66
- return new Manifest(appiumHome);
67
- });
68
-
69
- async syncWithInstalledExtensions() {
70
- let didChange = false;
71
-
72
- const onMatch = async filepath => {
73
- try {
74
- const pkg = JSON.parse(await _support.fs.readFile(filepath, 'utf8'));
75
-
76
- if (isDriver(pkg) || isPlugin(pkg)) {
77
- const changed = this.addExtensionFromPackage(pkg, filepath);
78
- didChange = didChange || changed;
79
- }
80
- } catch {}
81
- };
82
-
83
- const queue = [onMatch(_path.default.join(this._appiumHome, 'package.json'))];
84
- await new _bluebird.default((resolve, reject) => {
85
- (0, _glob.default)('node_modules/{*,@*/*}/package.json', {
86
- cwd: this._appiumHome,
87
- silent: true,
88
- absolute: true
89
- }, err => {
90
- if (err) {
91
- reject(err);
92
- }
93
-
94
- resolve();
95
- }).on('error', reject).on('match', filepath => {
96
- queue.push(onMatch(filepath));
97
- });
98
- });
99
- await _bluebird.default.all(queue);
100
- return didChange;
101
- }
102
-
103
- hasDriver(name) {
104
- return Boolean(this._data.drivers[name]);
105
- }
106
-
107
- hasPlugin(name) {
108
- return Boolean(this._data.plugins[name]);
109
- }
110
-
111
- addExtensionFromPackage(pkgJson, pkgPath) {
112
- var _pkgJson$peerDependen;
113
-
114
- const extensionPath = _path.default.dirname(pkgPath);
115
-
116
- const internal = {
117
- pkgName: pkgJson.name,
118
- version: pkgJson.version,
119
- appiumVersion: (_pkgJson$peerDependen = pkgJson.peerDependencies) === null || _pkgJson$peerDependen === void 0 ? void 0 : _pkgJson$peerDependen.appium,
120
- installType: _extensionConfig.INSTALL_TYPE_NPM,
121
- installSpec: `${pkgJson.name}@${pkgJson.version}`
122
- };
123
-
124
- if (isDriver(pkgJson)) {
125
- if (!this.hasDriver(pkgJson.appium.driverName)) {
126
- this.addExtension(_constants.DRIVER_TYPE, pkgJson.appium.driverName, { ..._lodash.default.omit(pkgJson.appium, 'driverName'),
127
- ...internal
128
- });
129
- return true;
130
- }
131
-
132
- return false;
133
- } else if (isPlugin(pkgJson)) {
134
- if (!this.hasPlugin(pkgJson.appium.pluginName)) {
135
- this.addExtension(_constants.PLUGIN_TYPE, pkgJson.appium.pluginName, { ..._lodash.default.omit(pkgJson.appium, 'pluginName'),
136
- ...internal
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
- return true;
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
- addExtension(extType, extName, extData) {
148
- const data = _lodash.default.clone(extData);
149
-
150
- this._data[`${extType}s`][extName] = data;
151
- return data;
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
- this._reading = (async () => {
173
- let data;
174
- let isNewFile = false;
175
- await this._setManifestPath();
176
-
177
- try {
178
- _logger.default.debug(`Reading ${this._manifestPath}...`);
179
-
180
- const yaml = await _support.fs.readFile(this._manifestPath, 'utf8');
181
- data = _yaml.default.parse(yaml);
182
-
183
- _logger.default.debug(`Parsed manifest file: ${JSON.stringify(data, null, 2)}`);
184
- } catch (err) {
185
- if (err.code === 'ENOENT') {
186
- data = _lodash.default.cloneDeep(INITIAL_MANIFEST_DATA);
187
- isNewFile = true;
188
- } else {
189
- if (this._manifestPath) {
190
- throw new Error(`Appium had trouble loading the extension installation ` + `cache file (${this._manifestPath}). It may be invalid YAML. Specific error: ${err.message}`);
191
- } else {
192
- throw new Error(`Appium encountered an unknown problem. Specific error: ${err.message}`);
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
- async _setManifestPath() {
218
- if (!this._manifestPath) {
219
- this._manifestPath = await _support.env.resolveManifestPath(this._appiumHome);
220
-
221
- if (_path.default.relative(this._appiumHome, this._manifestPath).startsWith('.')) {
222
- throw new Error(`Mismatch between location of APPIUM_HOME and manifest file. APPIUM_HOME: ${this.appiumHome}, manifest file: ${this._manifestPath}`);
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
- return this._manifestPath;
227
- }
228
-
229
- async write() {
230
- if (this._writing) {
231
- return this._writing;
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
- this._writing = (async () => {
235
- await this._setManifestPath();
236
-
237
- try {
238
- await _support.fs.mkdirp(_path.default.dirname(this._manifestPath));
239
- } catch (err) {
240
- throw new Error(`Appium could not create the directory for the manifest file: ${_path.default.dirname(this._manifestPath)}. Original error: ${err.message}`);
241
- }
242
-
243
- try {
244
- await _support.fs.writeFile(this._manifestPath, _yaml.default.stringify(this._data), 'utf8');
245
- return true;
246
- } catch (err) {
247
- throw new Error(`Appium could not write to manifest at ${this._manifestPath} using APPIUM_HOME ${this._appiumHome}. ` + `Please ensure it is writable. Original error: ${err.message}`);
248
- }
249
- })();
250
-
251
- try {
252
- return await this._writing;
253
- } finally {
254
- this._writing = undefined;
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