appium 2.0.0-beta.25 → 2.0.0-beta.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/appium.d.ts +215 -0
- package/build/lib/appium.d.ts.map +1 -0
- package/build/lib/appium.js +94 -101
- package/build/lib/cli/args.d.ts +20 -0
- package/build/lib/cli/args.d.ts.map +1 -0
- package/build/lib/cli/args.js +19 -39
- package/build/lib/cli/driver-command.d.ts +36 -0
- package/build/lib/cli/driver-command.d.ts.map +1 -0
- package/build/lib/cli/driver-command.js +10 -13
- package/build/lib/cli/extension-command.d.ts +345 -0
- package/build/lib/cli/extension-command.d.ts.map +1 -0
- package/build/lib/cli/extension-command.js +117 -94
- package/build/lib/cli/extension.d.ts +14 -0
- package/build/lib/cli/extension.d.ts.map +1 -0
- package/build/lib/cli/extension.js +14 -22
- package/build/lib/cli/parser.d.ts +79 -0
- package/build/lib/cli/parser.d.ts.map +1 -0
- package/build/lib/cli/parser.js +9 -19
- package/build/lib/cli/plugin-command.d.ts +39 -0
- package/build/lib/cli/plugin-command.d.ts.map +1 -0
- package/build/lib/cli/plugin-command.js +9 -14
- package/build/lib/cli/utils.d.ts +29 -0
- package/build/lib/cli/utils.d.ts.map +1 -0
- package/build/lib/cli/utils.js +2 -4
- package/build/lib/config-file.d.ts +100 -0
- package/build/lib/config-file.d.ts.map +1 -0
- package/build/lib/config-file.js +2 -4
- package/build/lib/config.d.ts +40 -0
- package/build/lib/config.d.ts.map +1 -0
- package/build/lib/config.js +8 -7
- package/build/lib/constants.d.ts +48 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +60 -0
- package/build/lib/extension/driver-config.d.ts +84 -0
- package/build/lib/extension/driver-config.d.ts.map +1 -0
- package/build/lib/extension/driver-config.js +190 -0
- package/build/lib/extension/extension-config.d.ts +170 -0
- package/build/lib/extension/extension-config.d.ts.map +1 -0
- package/build/lib/extension/extension-config.js +297 -0
- package/build/lib/extension/index.d.ts +39 -0
- package/build/lib/extension/index.d.ts.map +1 -0
- package/build/lib/extension/index.js +77 -0
- package/build/lib/extension/manifest.d.ts +174 -0
- package/build/lib/extension/manifest.d.ts.map +1 -0
- package/build/lib/extension/manifest.js +246 -0
- package/build/lib/extension/package-changed.d.ts +11 -0
- package/build/lib/extension/package-changed.d.ts.map +1 -0
- package/build/lib/extension/package-changed.js +68 -0
- package/build/lib/extension/plugin-config.d.ts +62 -0
- package/build/lib/extension/plugin-config.d.ts.map +1 -0
- package/build/lib/extension/plugin-config.js +87 -0
- package/build/lib/grid-register.d.ts +10 -0
- package/build/lib/grid-register.d.ts.map +1 -0
- package/build/lib/grid-register.js +2 -4
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +2 -4
- package/build/lib/logsink.d.ts +4 -0
- package/build/lib/logsink.d.ts.map +1 -0
- package/build/lib/logsink.js +2 -4
- package/build/lib/main.d.ts +51 -0
- package/build/lib/main.d.ts.map +1 -0
- package/build/lib/main.js +40 -68
- package/build/lib/schema/arg-spec.d.ts +143 -0
- package/build/lib/schema/arg-spec.d.ts.map +1 -0
- package/build/lib/schema/arg-spec.js +11 -14
- package/build/lib/schema/cli-args.d.ts +19 -0
- package/build/lib/schema/cli-args.d.ts.map +1 -0
- package/build/lib/schema/cli-args.js +2 -4
- package/build/lib/schema/cli-transformers.d.ts +5 -0
- package/build/lib/schema/cli-transformers.d.ts.map +1 -0
- package/build/lib/schema/cli-transformers.js +2 -4
- package/build/lib/schema/index.d.ts +3 -0
- package/build/lib/schema/index.d.ts.map +1 -0
- package/build/lib/schema/index.js +2 -4
- package/build/lib/schema/keywords.d.ts +24 -0
- package/build/lib/schema/keywords.d.ts.map +1 -0
- package/build/lib/schema/keywords.js +2 -4
- package/build/lib/schema/schema.d.ts +259 -0
- package/build/lib/schema/schema.d.ts.map +1 -0
- package/build/lib/schema/schema.js +57 -39
- package/build/lib/utils.d.ts +66 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +6 -35
- package/build/tsconfig.tsbuildinfo +1 -0
- package/lib/appium.js +188 -117
- package/lib/cli/args.js +19 -24
- package/lib/cli/driver-command.js +19 -8
- package/lib/cli/extension-command.js +314 -184
- package/lib/cli/extension.js +18 -16
- package/lib/cli/parser.js +7 -16
- package/lib/cli/plugin-command.js +16 -7
- package/lib/cli/utils.js +1 -1
- package/lib/config-file.js +6 -7
- package/lib/config.js +17 -12
- package/lib/constants.js +78 -0
- package/lib/extension/driver-config.js +249 -0
- package/lib/extension/extension-config.js +458 -0
- package/lib/extension/index.js +102 -0
- package/lib/extension/manifest.js +486 -0
- package/lib/extension/package-changed.js +63 -0
- package/lib/extension/plugin-config.js +113 -0
- package/lib/grid-register.js +4 -4
- package/lib/logsink.js +4 -0
- package/lib/main.js +54 -92
- package/lib/schema/arg-spec.js +11 -7
- package/lib/schema/cli-args.js +1 -1
- package/lib/schema/cli-transformers.js +0 -1
- package/lib/schema/keywords.js +1 -2
- package/lib/schema/schema.js +62 -31
- package/lib/utils.js +48 -45
- package/package.json +30 -24
- package/{postinstall.js → scripts/postinstall.js} +1 -1
- package/types/appium-manifest.d.ts +61 -0
- package/types/cli.d.ts +134 -0
- package/types/extension.d.ts +56 -0
- package/types/external-manifest.d.ts +58 -0
- package/types/index.d.ts +7 -0
- package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
- package/build/check-npm-pack-files.js +0 -23
- package/build/commands-yml/parse.js +0 -319
- package/build/commands-yml/validator.js +0 -130
- package/build/index.js +0 -19
- package/build/lib/appium-config.schema.json +0 -0
- package/build/lib/cli/npm.js +0 -220
- package/build/lib/driver-config.js +0 -100
- package/build/lib/drivers.js +0 -100
- package/build/lib/ext-config-io.js +0 -165
- package/build/lib/extension-config.js +0 -320
- package/build/lib/plugin-config.js +0 -69
- package/build/lib/plugins.js +0 -18
- package/build/lib/schema/appium-config-schema.js +0 -253
- package/build/postinstall.js +0 -90
- package/build/test/cli/cli-e2e-specs.js +0 -221
- package/build/test/cli/cli-helpers.js +0 -86
- package/build/test/cli/cli-specs.js +0 -71
- package/build/test/cli/fixtures/test-driver/package.json +0 -27
- package/build/test/cli/schema-args-specs.js +0 -48
- package/build/test/cli/schema-e2e-specs.js +0 -47
- package/build/test/config-e2e-specs.js +0 -112
- package/build/test/config-file-e2e-specs.js +0 -191
- package/build/test/config-file-specs.js +0 -281
- package/build/test/config-specs.js +0 -258
- package/build/test/driver-e2e-specs.js +0 -435
- package/build/test/driver-specs.js +0 -386
- package/build/test/ext-config-io-specs.js +0 -181
- package/build/test/extension-config-specs.js +0 -365
- package/build/test/fixtures/allow-feat.txt +0 -5
- package/build/test/fixtures/caps.json +0 -3
- package/build/test/fixtures/config/allow-insecure.txt +0 -3
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
- package/build/test/fixtures/config/appium.config.bad.json +0 -32
- package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
- package/build/test/fixtures/config/appium.config.good.js +0 -40
- package/build/test/fixtures/config/appium.config.good.json +0 -33
- package/build/test/fixtures/config/appium.config.good.yaml +0 -30
- package/build/test/fixtures/config/appium.config.invalid.json +0 -31
- package/build/test/fixtures/config/appium.config.security-array.json +0 -5
- package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
- package/build/test/fixtures/config/appium.config.security-path.json +0 -5
- package/build/test/fixtures/config/driver-fake.config.json +0 -8
- package/build/test/fixtures/config/nodeconfig.json +0 -3
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +0 -35
- package/build/test/fixtures/deny-feat.txt +0 -5
- package/build/test/fixtures/driver.schema.js +0 -20
- package/build/test/fixtures/extensions.yaml +0 -27
- package/build/test/fixtures/flattened-schema.js +0 -532
- package/build/test/fixtures/plugin.schema.js +0 -20
- package/build/test/fixtures/schema-with-extensions.js +0 -28
- package/build/test/grid-register-specs.js +0 -74
- package/build/test/helpers.js +0 -75
- package/build/test/logger-specs.js +0 -76
- package/build/test/npm-specs.js +0 -20
- package/build/test/parser-specs.js +0 -319
- package/build/test/plugin-e2e-specs.js +0 -316
- package/build/test/schema/arg-spec-specs.js +0 -70
- package/build/test/schema/cli-args-specs.js +0 -408
- package/build/test/schema/schema-specs.js +0 -407
- package/build/test/utils-specs.js +0 -288
- package/lib/cli/npm.js +0 -251
- package/lib/driver-config.js +0 -101
- package/lib/drivers.js +0 -84
- package/lib/ext-config-io.js +0 -287
- package/lib/extension-config.js +0 -366
- package/lib/plugin-config.js +0 -63
- package/lib/plugins.js +0 -13
- package/lib/schema/appium-config-schema.js +0 -287
- package/types/appium-config.d.ts +0 -197
- package/types/types.d.ts +0 -206
|
@@ -1,51 +1,66 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
|
-
import NPM from './npm';
|
|
5
4
|
import path from 'path';
|
|
6
|
-
import { fs, util } from '@appium/support';
|
|
5
|
+
import { npm, fs, util, env } from '@appium/support';
|
|
7
6
|
import { log, spinWith, RingBuffer } from './utils';
|
|
8
|
-
import { SubProcess} from 'teen_process';
|
|
7
|
+
import { SubProcess } from 'teen_process';
|
|
9
8
|
import { INSTALL_TYPE_NPM, INSTALL_TYPE_GIT, INSTALL_TYPE_GITHUB,
|
|
10
|
-
INSTALL_TYPE_LOCAL } from '../extension-config';
|
|
9
|
+
INSTALL_TYPE_LOCAL } from '../extension/extension-config';
|
|
10
|
+
import { packageDidChange } from '../extension/package-changed';
|
|
11
11
|
|
|
12
12
|
const UPDATE_ALL = 'installed';
|
|
13
13
|
|
|
14
14
|
class NotUpdatableError extends Error {}
|
|
15
15
|
class NoUpdatesAvailableError extends Error {}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @template {ExtensionType} ExtType
|
|
19
|
+
*/
|
|
20
|
+
class ExtensionCommand {
|
|
21
|
+
/**
|
|
22
|
+
* This is the `DriverConfig` or `PluginConfig`, depending on `ExtType`.
|
|
23
|
+
* @type {ExtensionConfig<ExtType>}
|
|
24
|
+
*/
|
|
25
|
+
config;
|
|
18
26
|
|
|
19
27
|
/**
|
|
20
|
-
* @
|
|
21
|
-
* @
|
|
22
|
-
* @property {boolean} json - whether the output of this command should be JSON or text
|
|
23
|
-
* @property {string} type - DRIVER_TYPE or PLUGIN_TYPE
|
|
28
|
+
* {@linkcode Record} of official plugins or drivers.
|
|
29
|
+
* @type {KnownExtensions<ExtType>}
|
|
24
30
|
*/
|
|
31
|
+
knownExtensions;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* If `true`, command output has been requested as JSON.
|
|
35
|
+
* @type {boolean}
|
|
36
|
+
*/
|
|
37
|
+
isJsonOutput;
|
|
25
38
|
|
|
26
39
|
/**
|
|
27
40
|
* Build an ExtensionCommand
|
|
28
|
-
*
|
|
29
|
-
* @param {ExtensionCommandConstructor} opts
|
|
30
|
-
* @return {ExtensionCommand}
|
|
41
|
+
* @param {ExtensionCommandOptions<ExtType>} opts
|
|
31
42
|
*/
|
|
32
|
-
constructor ({config, json
|
|
43
|
+
constructor ({config, json}) {
|
|
33
44
|
this.config = config;
|
|
34
|
-
this.type = type;
|
|
35
45
|
this.isJsonOutput = json;
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* `driver` or `plugin`, depending on the `ExtensionConfig`.
|
|
50
|
+
*/
|
|
51
|
+
get type () {
|
|
52
|
+
return this.config.extensionType;
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
/**
|
|
41
56
|
* Take a CLI parse and run an extension command based on its type
|
|
42
57
|
*
|
|
43
58
|
* @param {object} args - a key/value object with CLI flags and values
|
|
44
|
-
* @return {object} the result of the specific command which is executed
|
|
59
|
+
* @return {Promise<object>} the result of the specific command which is executed
|
|
45
60
|
*/
|
|
46
61
|
async execute (args) {
|
|
47
62
|
const cmd = args[`${this.type}Command`];
|
|
48
|
-
if (!_.isFunction(
|
|
63
|
+
if (!_.isFunction(this[cmd])) {
|
|
49
64
|
throw new Error(`Cannot handle ${this.type} command ${cmd}`);
|
|
50
65
|
}
|
|
51
66
|
const executeCmd = this[cmd].bind(this);
|
|
@@ -53,7 +68,7 @@ export default class ExtensionCommand {
|
|
|
53
68
|
}
|
|
54
69
|
|
|
55
70
|
/**
|
|
56
|
-
* @typedef
|
|
71
|
+
* @typedef ListOptions
|
|
57
72
|
* @property {boolean} showInstalled - whether should show only installed extensions
|
|
58
73
|
* @property {boolean} showUpdates - whether should show available updates
|
|
59
74
|
*/
|
|
@@ -61,8 +76,8 @@ export default class ExtensionCommand {
|
|
|
61
76
|
/**
|
|
62
77
|
* List extensions
|
|
63
78
|
*
|
|
64
|
-
* @param {
|
|
65
|
-
* @return {
|
|
79
|
+
* @param {ListOptions} opts
|
|
80
|
+
* @return {Promise<ExtensionListData>} map of extension names to extension data
|
|
66
81
|
*/
|
|
67
82
|
async list ({showInstalled, showUpdates}) {
|
|
68
83
|
const lsMsg = `Listing ${showInstalled ? 'installed' : 'available'} ${this.type}s`;
|
|
@@ -77,7 +92,12 @@ export default class ExtensionCommand {
|
|
|
77
92
|
}
|
|
78
93
|
}
|
|
79
94
|
return acc;
|
|
80
|
-
},
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* This accumulator contains either {@linkcode UninstalledExtensionLIstData} _or_
|
|
98
|
+
* {@linkcode InstalledExtensionListData} without upgrade information (which is added by the below code block)
|
|
99
|
+
* @type {Record<string,Partial<InstalledExtensionListData>|UninstalledExtensionListData>}
|
|
100
|
+
*/({}));
|
|
81
101
|
|
|
82
102
|
// if we want to show whether updates are available, put that behind a spinner
|
|
83
103
|
await spinWith(this.isJsonOutput, lsMsg, async () => {
|
|
@@ -85,8 +105,7 @@ export default class ExtensionCommand {
|
|
|
85
105
|
return;
|
|
86
106
|
}
|
|
87
107
|
for (const [ext, data] of _.toPairs(exts)) {
|
|
88
|
-
|
|
89
|
-
if (!installed || installType !== INSTALL_TYPE_NPM) {
|
|
108
|
+
if (!data.installed || data.installType !== INSTALL_TYPE_NPM) {
|
|
90
109
|
// don't need to check for updates on exts that aren't installed
|
|
91
110
|
// also don't need to check for updates on non-npm exts
|
|
92
111
|
continue;
|
|
@@ -98,63 +117,64 @@ export default class ExtensionCommand {
|
|
|
98
117
|
}
|
|
99
118
|
});
|
|
100
119
|
|
|
120
|
+
const listData = /** @type {ExtensionListData} */(exts);
|
|
121
|
+
|
|
101
122
|
// if we're just getting the data, short circuit return here since we don't need to do any
|
|
102
123
|
// formatting logic
|
|
103
124
|
if (this.isJsonOutput) {
|
|
104
|
-
return
|
|
125
|
+
return listData;
|
|
105
126
|
}
|
|
106
127
|
|
|
107
128
|
for (const [
|
|
108
129
|
name,
|
|
109
|
-
|
|
110
|
-
] of _.toPairs(
|
|
111
|
-
let
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
data
|
|
131
|
+
] of _.toPairs(listData)) {
|
|
132
|
+
let installTxt = ' [not installed]'.grey;
|
|
133
|
+
let updateTxt = '';
|
|
134
|
+
let upToDateTxt = '';
|
|
135
|
+
let unsafeUpdateTxt = '';
|
|
136
|
+
if (data.installed) {
|
|
137
|
+
const {installType, installSpec, updateVersion, unsafeUpdateVersion, version, upToDate} = data;
|
|
138
|
+
let typeTxt;
|
|
139
|
+
switch (installType) {
|
|
140
|
+
case INSTALL_TYPE_GIT:
|
|
141
|
+
case INSTALL_TYPE_GITHUB:
|
|
142
|
+
typeTxt = `(cloned from ${installSpec})`.yellow;
|
|
143
|
+
break;
|
|
144
|
+
case INSTALL_TYPE_LOCAL:
|
|
145
|
+
typeTxt = `(linked from ${installSpec})`.magenta;
|
|
146
|
+
break;
|
|
147
|
+
default:
|
|
148
|
+
typeTxt = '(NPM)';
|
|
149
|
+
}
|
|
150
|
+
installTxt = `@${version.yellow} ${('[installed ' + typeTxt + ']').green}`;
|
|
151
|
+
|
|
152
|
+
if (showUpdates) {
|
|
153
|
+
if (updateVersion) {
|
|
154
|
+
updateTxt = ` [${updateVersion} available]`.magenta;
|
|
155
|
+
}
|
|
156
|
+
if (upToDate) {
|
|
157
|
+
upToDateTxt = ` [Up to date]`.green;
|
|
158
|
+
}
|
|
159
|
+
if (unsafeUpdateVersion) {
|
|
160
|
+
unsafeUpdateTxt = ` [${unsafeUpdateVersion} available (potentially unsafe)]`.cyan;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
122
163
|
}
|
|
123
|
-
const installTxt = installed ?
|
|
124
|
-
`@${version.yellow} ${('[installed ' + typeTxt + ']').green}` :
|
|
125
|
-
' [not installed]'.grey;
|
|
126
|
-
const updateTxt = showUpdates && updateVersion ?
|
|
127
|
-
` [${updateVersion} available]`.magenta :
|
|
128
|
-
'';
|
|
129
|
-
const upToDateTxt = showUpdates && upToDate ?
|
|
130
|
-
` [Up to date]`.green :
|
|
131
|
-
'';
|
|
132
|
-
const unsafeUpdateTxt = showUpdates && unsafeUpdateVersion ?
|
|
133
|
-
` [${unsafeUpdateVersion} available (potentially unsafe)]`.cyan :
|
|
134
|
-
'';
|
|
135
164
|
|
|
136
165
|
console.log(`- ${name.yellow}${installTxt}${updateTxt}${upToDateTxt}${unsafeUpdateTxt}`);
|
|
137
166
|
}
|
|
138
167
|
|
|
139
|
-
return
|
|
168
|
+
return listData;
|
|
140
169
|
}
|
|
141
170
|
|
|
142
|
-
/**
|
|
143
|
-
* @typedef {Object} InstallArgs
|
|
144
|
-
* @property {string} ext - the name or spec of an extension to install
|
|
145
|
-
* @property {string} installType - how to install this extension. One of the INSTALL_TYPES
|
|
146
|
-
* @property {string} [packageName] - for git/github installs, the extension node package name
|
|
147
|
-
*/
|
|
148
|
-
|
|
149
171
|
/**
|
|
150
172
|
* Install an extension
|
|
151
173
|
*
|
|
152
174
|
* @param {InstallArgs} args
|
|
153
|
-
* @return {
|
|
175
|
+
* @return {Promise<ExtRecord<ExtType>>} map of all installed extension names to extension data
|
|
154
176
|
*/
|
|
155
|
-
async
|
|
156
|
-
log(this.isJsonOutput, `Attempting to find and install ${this.type} '${ext}'`);
|
|
157
|
-
|
|
177
|
+
async _install ({ext, installType, packageName}) {
|
|
158
178
|
let extData;
|
|
159
179
|
let installSpec = ext;
|
|
160
180
|
|
|
@@ -166,66 +186,63 @@ export default class ExtensionCommand {
|
|
|
166
186
|
throw new Error(`When using --source=${installType}, must also use --package`);
|
|
167
187
|
}
|
|
168
188
|
|
|
169
|
-
if (installType ===
|
|
170
|
-
const msg = `Linking ${this.type} from local path`;
|
|
171
|
-
const pkgJsonData = await spinWith(this.isJsonOutput, msg, async () => (
|
|
172
|
-
await this.npm.linkPackage(installSpec))
|
|
173
|
-
);
|
|
174
|
-
extData = this.getExtensionFields(pkgJsonData);
|
|
175
|
-
extData.installPath = extData.pkgName;
|
|
176
|
-
} else if (installType === INSTALL_TYPE_GITHUB) {
|
|
189
|
+
if (installType === INSTALL_TYPE_GITHUB) {
|
|
177
190
|
if (installSpec.split('/').length !== 2) {
|
|
178
191
|
throw new Error(`Github ${this.type} spec ${installSpec} appeared to be invalid; ` +
|
|
179
192
|
'it should be of the form <org>/<repo>');
|
|
180
193
|
}
|
|
181
|
-
extData = await this.installViaNpm({ext: installSpec, pkgName: packageName});
|
|
194
|
+
extData = await this.installViaNpm({ext: installSpec, pkgName: /** @type {string} */(packageName)});
|
|
182
195
|
} else if (installType === INSTALL_TYPE_GIT) {
|
|
183
196
|
// git urls can have '.git' at the end, but this is not necessary and would complicate the
|
|
184
197
|
// way we download and name directories, so we can just remove it
|
|
185
198
|
installSpec = installSpec.replace(/\.git$/, '');
|
|
186
|
-
extData = await this.installViaNpm({ext: installSpec, pkgName: packageName});
|
|
199
|
+
extData = await this.installViaNpm({ext: installSpec, pkgName: /** @type {string} */(packageName)});
|
|
187
200
|
} else {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// sign, so check for that. We also need to be careful that package names themselves can
|
|
192
|
-
// contain the '@' symbol, as in `npm install @appium/fake-driver@1.2.0`
|
|
193
|
-
let name, pkgVer;
|
|
194
|
-
const splits = installSpec.split('@');
|
|
195
|
-
if (installSpec[0] === '@') {
|
|
196
|
-
// this is the case where we have an npm org included in the package name
|
|
197
|
-
[name, pkgVer] = [`@${splits[1]}`, splits[2]];
|
|
201
|
+
let pkgName, pkgVer;
|
|
202
|
+
if (installType === INSTALL_TYPE_LOCAL) {
|
|
203
|
+
pkgName = path.isAbsolute(installSpec) ? installSpec : path.resolve(installSpec);
|
|
198
204
|
} else {
|
|
199
|
-
// this
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
// at this point we have either an npm package or an appium verified extension
|
|
206
|
+
// name or a local path. both of which will be installed via npm.
|
|
207
|
+
// extensions installed via npm can include versions or tags after the '@'
|
|
208
|
+
// sign, so check for that. We also need to be careful that package names themselves can
|
|
209
|
+
// contain the '@' symbol, as in `npm install @appium/fake-driver@1.2.0`
|
|
210
|
+
let name;
|
|
211
|
+
const splits = installSpec.split('@');
|
|
212
|
+
if (installSpec[0] === '@') {
|
|
213
|
+
// this is the case where we have an npm org included in the package name
|
|
214
|
+
[name, pkgVer] = [`@${splits[1]}`, splits[2]];
|
|
215
|
+
} else {
|
|
216
|
+
// this is the case without an npm org
|
|
217
|
+
[name, pkgVer] = splits;
|
|
218
|
+
}
|
|
203
219
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
220
|
+
if (installType === INSTALL_TYPE_NPM) {
|
|
221
|
+
// if we're installing a named package from npm, we don't need to check
|
|
222
|
+
// against the appium extension list; just use the installSpec as is
|
|
223
|
+
pkgName = name;
|
|
224
|
+
} else {
|
|
225
|
+
// if we're installing a named appium driver (like 'xcuitest') we need to
|
|
226
|
+
// dereference the actual npm package ('appiupm-xcuitest-driver'), so
|
|
227
|
+
// check it exists and get the correct package
|
|
228
|
+
const knownNames = Object.keys(this.knownExtensions);
|
|
229
|
+
if (!_.includes(knownNames, name)) {
|
|
230
|
+
const msg = `Could not resolve ${this.type}; are you sure it's in the list ` +
|
|
231
|
+
`of supported ${this.type}s? ${JSON.stringify(knownNames)}`;
|
|
232
|
+
throw new Error(msg);
|
|
233
|
+
}
|
|
234
|
+
pkgName = this.knownExtensions[name];
|
|
235
|
+
// given that we'll use the install type in the driver json, store it as
|
|
236
|
+
// 'npm' now
|
|
237
|
+
installType = INSTALL_TYPE_NPM;
|
|
217
238
|
}
|
|
218
|
-
pkgName = this.knownExtensions[name];
|
|
219
|
-
// given that we'll use the install type in the driver json, store it as
|
|
220
|
-
// 'npm' now
|
|
221
|
-
installType = INSTALL_TYPE_NPM;
|
|
222
239
|
}
|
|
223
240
|
|
|
224
241
|
extData = await this.installViaNpm({ext, pkgName, pkgVer});
|
|
225
242
|
}
|
|
226
243
|
|
|
227
|
-
const extName = extData[`${this.type}Name`];
|
|
228
|
-
delete extData[`${this.type}Name`];
|
|
244
|
+
const extName = extData[/** @type {string} */(`${this.type}Name`)];
|
|
245
|
+
delete extData[/** @type {string} */(`${this.type}Name`)];
|
|
229
246
|
|
|
230
247
|
if (this.config.isInstalled(extName)) {
|
|
231
248
|
throw new Error(`A ${this.type} named '${extName}' is already installed. ` +
|
|
@@ -233,9 +250,13 @@ export default class ExtensionCommand {
|
|
|
233
250
|
`installed ${this.type}s with 'appium ${this.type} list --installed'.`);
|
|
234
251
|
}
|
|
235
252
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
253
|
+
const extManifest = {...extData, installType, installSpec};
|
|
254
|
+
await this.config.addExtension(extName, extManifest);
|
|
255
|
+
|
|
256
|
+
// update the if we've changed the local `package.json`
|
|
257
|
+
if (await env.hasAppiumDependency(this.config.appiumHome)) {
|
|
258
|
+
await packageDidChange(this.config.appiumHome);
|
|
259
|
+
}
|
|
239
260
|
|
|
240
261
|
// log info for the user
|
|
241
262
|
log(this.isJsonOutput, this.getPostInstallText({extName, extData}));
|
|
@@ -243,13 +264,6 @@ export default class ExtensionCommand {
|
|
|
243
264
|
return this.config.installedExtensions;
|
|
244
265
|
}
|
|
245
266
|
|
|
246
|
-
/**
|
|
247
|
-
* @typedef {Object} InstallViaNpmArgs
|
|
248
|
-
* @property {string} ext - the name or spec of an extension to install
|
|
249
|
-
* @property {string} pkgName - the NPM package name of the extension
|
|
250
|
-
* @property {string} [pkgVer] - the specific version of the NPM package
|
|
251
|
-
*/
|
|
252
|
-
|
|
253
267
|
/**
|
|
254
268
|
* Install an extension via NPM
|
|
255
269
|
*
|
|
@@ -261,33 +275,25 @@ export default class ExtensionCommand {
|
|
|
261
275
|
const msg = `Installing '${ext}'${specMsg}`;
|
|
262
276
|
try {
|
|
263
277
|
const pkgJsonData = await spinWith(this.isJsonOutput, msg, async () => (
|
|
264
|
-
await
|
|
265
|
-
pkgDir: path.resolve(this.config.appiumHome, pkgName),
|
|
266
|
-
pkgName,
|
|
278
|
+
await npm.installPackage(this.config.appiumHome, pkgName, {
|
|
267
279
|
pkgVer
|
|
268
280
|
})
|
|
269
281
|
));
|
|
270
|
-
|
|
271
|
-
extData.installPath = pkgName;
|
|
272
|
-
return extData;
|
|
282
|
+
return this.getExtensionFields(pkgJsonData);
|
|
273
283
|
} catch (err) {
|
|
274
284
|
throw new Error(`Encountered an error when installing package: ${err.message}`);
|
|
275
285
|
}
|
|
276
286
|
}
|
|
277
287
|
|
|
278
|
-
/**
|
|
279
|
-
* @typedef {Object} ExtensionArgs
|
|
280
|
-
* @property {string} extName - the name of an extension
|
|
281
|
-
* @property {object} extData - the data for an installed extension
|
|
282
|
-
*/
|
|
283
|
-
|
|
284
288
|
/**
|
|
285
289
|
* Get the text which should be displayed to the user after an extension has been installed. This
|
|
286
290
|
* is designed to be overridden by drivers/plugins with their own particular text.
|
|
287
291
|
*
|
|
288
292
|
* @param {ExtensionArgs} args
|
|
293
|
+
* @returns {string}
|
|
289
294
|
*/
|
|
290
|
-
|
|
295
|
+
// eslint-disable-next-line no-unused-vars
|
|
296
|
+
getPostInstallText (args) {
|
|
291
297
|
throw new Error('Must be implemented in final class');
|
|
292
298
|
}
|
|
293
299
|
|
|
@@ -297,8 +303,9 @@ export default class ExtensionCommand {
|
|
|
297
303
|
* load as the main driver class, or to be able to detect incompatibilities between driver and
|
|
298
304
|
* appium versions.
|
|
299
305
|
*
|
|
300
|
-
* @param {
|
|
306
|
+
* @param {ExtPackageJson<ExtType>} pkgJsonData - the package.json data for a driver module, as if it had been
|
|
301
307
|
* straightforwardly 'require'd
|
|
308
|
+
* @returns {ExtensionFields<ExtType>}
|
|
302
309
|
*/
|
|
303
310
|
getExtensionFields (pkgJsonData) {
|
|
304
311
|
if (!pkgJsonData.appium) {
|
|
@@ -307,8 +314,9 @@ export default class ExtensionCommand {
|
|
|
307
314
|
}
|
|
308
315
|
const {appium, name, version} = pkgJsonData;
|
|
309
316
|
this.validateExtensionFields(appium);
|
|
310
|
-
|
|
311
|
-
|
|
317
|
+
/** @type {unknown} */
|
|
318
|
+
const result = {...appium, pkgName: name, version};
|
|
319
|
+
return /** @type {ExtensionFields<ExtType>} */(result);
|
|
312
320
|
}
|
|
313
321
|
|
|
314
322
|
/**
|
|
@@ -316,30 +324,26 @@ export default class ExtensionCommand {
|
|
|
316
324
|
* presence and form of those fields on the package.json data, throwing an error if anything is
|
|
317
325
|
* amiss.
|
|
318
326
|
*
|
|
319
|
-
* @param {
|
|
320
|
-
* extension
|
|
327
|
+
* @param {ExtMetadata<ExtType>} appiumPkgData - the data in the "appium" field of package.json for an extension
|
|
321
328
|
*/
|
|
322
|
-
|
|
329
|
+
// eslint-disable-next-line no-unused-vars
|
|
330
|
+
validateExtensionFields (appiumPkgData) {
|
|
323
331
|
throw new Error('Must be implemented in final class');
|
|
324
332
|
}
|
|
325
333
|
|
|
326
|
-
/**
|
|
327
|
-
* @typedef {Object} UninstallArgs
|
|
328
|
-
* @property {string} ext - the name or spec of an extension to uninstall
|
|
329
|
-
*/
|
|
330
|
-
|
|
331
334
|
/**
|
|
332
335
|
* Uninstall an extension
|
|
333
336
|
*
|
|
334
|
-
* @param {
|
|
335
|
-
* @return {
|
|
337
|
+
* @param {UninstallOpts} opts
|
|
338
|
+
* @return {Promise<ExtRecord<ExtType>>} map of all installed extension names to extension data
|
|
336
339
|
*/
|
|
337
|
-
async
|
|
340
|
+
async _uninstall ({ext}) {
|
|
338
341
|
if (!this.config.isInstalled(ext)) {
|
|
339
342
|
throw new Error(`Can't uninstall ${this.type} '${ext}'; it is not installed`);
|
|
340
343
|
}
|
|
344
|
+
const installPath = this.config.getInstallPath(ext);
|
|
341
345
|
try {
|
|
342
|
-
await fs.rimraf(
|
|
346
|
+
await fs.rimraf(installPath);
|
|
343
347
|
} finally {
|
|
344
348
|
await this.config.removeExtension(ext);
|
|
345
349
|
}
|
|
@@ -347,32 +351,13 @@ export default class ExtensionCommand {
|
|
|
347
351
|
return this.config.installedExtensions;
|
|
348
352
|
}
|
|
349
353
|
|
|
350
|
-
/**
|
|
351
|
-
* @typedef {Object} ExtensionUpdateOpts
|
|
352
|
-
* @property {string} ext - the name of the extension to update
|
|
353
|
-
* @property {boolean} unsafe - if true, will perform unsafe updates past major revision
|
|
354
|
-
* boundaries
|
|
355
|
-
*/
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* @typedef {Object} UpdateReport
|
|
359
|
-
* @property {string} from - version updated from
|
|
360
|
-
* @property {string} to - version updated to
|
|
361
|
-
*/
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* @typedef {Object} ExtensionUpdateResult
|
|
365
|
-
* @property {Object} errors - map of ext names to error objects
|
|
366
|
-
* @property {Object} updates - map of ext names to {@link UpdateReport}s
|
|
367
|
-
*/
|
|
368
|
-
|
|
369
354
|
/**
|
|
370
355
|
* Attempt to update one or more drivers using NPM
|
|
371
356
|
*
|
|
372
357
|
* @param {ExtensionUpdateOpts} updateSpec
|
|
373
|
-
* @return {ExtensionUpdateResult}
|
|
358
|
+
* @return {Promise<ExtensionUpdateResult>}
|
|
374
359
|
*/
|
|
375
|
-
async
|
|
360
|
+
async _update ({ext, unsafe}) {
|
|
376
361
|
const shouldUpdateAll = ext === UPDATE_ALL;
|
|
377
362
|
// if we're specifically requesting an update for an extension, make sure it's installed
|
|
378
363
|
if (!shouldUpdateAll && !this.config.isInstalled(ext)) {
|
|
@@ -381,10 +366,12 @@ export default class ExtensionCommand {
|
|
|
381
366
|
const extsToUpdate = shouldUpdateAll ? Object.keys(this.config.installedExtensions) : [ext];
|
|
382
367
|
|
|
383
368
|
// 'errors' will have ext names as keys and error objects as values
|
|
369
|
+
/** @type {Record<string,Error>} */
|
|
384
370
|
const errors = {};
|
|
385
371
|
|
|
386
372
|
// 'updates' will have ext names as keys and update objects as values, where an update
|
|
387
373
|
// object is of the form {from: versionString, to: versionString}
|
|
374
|
+
/** @type {Record<string,UpdateReport>} */
|
|
388
375
|
const updates = {};
|
|
389
376
|
|
|
390
377
|
for (const e of extsToUpdate) {
|
|
@@ -437,27 +424,20 @@ export default class ExtensionCommand {
|
|
|
437
424
|
return {updates, errors};
|
|
438
425
|
}
|
|
439
426
|
|
|
440
|
-
/**
|
|
441
|
-
* @typedef PossibleUpdates
|
|
442
|
-
* @property {string} current - current version
|
|
443
|
-
* @property {string|null} safeUpdate - version we can safely update to if it exists, or null
|
|
444
|
-
* @property {string|null} unsafeUpdate - version we can unsafely update to if it exists, or null
|
|
445
|
-
*/
|
|
446
|
-
|
|
447
427
|
/**
|
|
448
428
|
* Given an extension name, figure out what its highest possible version upgrade is, and also the
|
|
449
429
|
* highest possible safe upgrade.
|
|
450
430
|
*
|
|
451
431
|
* @param {string} ext - name of extension
|
|
452
|
-
* @return {PossibleUpdates}
|
|
432
|
+
* @return {Promise<PossibleUpdates>}
|
|
453
433
|
*/
|
|
454
434
|
async checkForExtensionUpdate (ext) {
|
|
455
435
|
// TODO decide how we want to handle beta versions?
|
|
456
436
|
// this is a helper method, 'ext' is assumed to already be installed here, and of the npm
|
|
457
437
|
// install type
|
|
458
438
|
const {version, pkgName} = this.config.installedExtensions[ext];
|
|
459
|
-
let unsafeUpdate = await
|
|
460
|
-
let safeUpdate = await
|
|
439
|
+
let unsafeUpdate = await npm.getLatestVersion(this.config.appiumHome, pkgName);
|
|
440
|
+
let safeUpdate = await npm.getLatestSafeUpgradeVersion(this.config.appiumHome, pkgName, version);
|
|
461
441
|
if (!util.compareVersions(unsafeUpdate, '>', version)) {
|
|
462
442
|
// the latest version is not greater than the current version, so there's no possible update
|
|
463
443
|
unsafeUpdate = null;
|
|
@@ -480,12 +460,13 @@ export default class ExtensionCommand {
|
|
|
480
460
|
*
|
|
481
461
|
* @param {string} ext - name of extension to update
|
|
482
462
|
* @param {string} version - version string identifier to update extension to
|
|
463
|
+
* @returns {Promise<void>}
|
|
483
464
|
*/
|
|
484
465
|
async updateExtension (ext, version) {
|
|
485
466
|
const {pkgName} = this.config.installedExtensions[ext];
|
|
486
467
|
await fs.rimraf(this.config.getInstallPath(ext));
|
|
487
468
|
const extData = await this.installViaNpm({ext, pkgName, pkgVer: version});
|
|
488
|
-
delete extData[`${this.type}Name`];
|
|
469
|
+
delete extData[/** @type {string} */(`${this.type}Name`)];
|
|
489
470
|
await this.config.updateExtension(ext, extData);
|
|
490
471
|
}
|
|
491
472
|
|
|
@@ -497,18 +478,18 @@ export default class ExtensionCommand {
|
|
|
497
478
|
* "scripts" field is not a plain object, or if the scriptName is
|
|
498
479
|
* not found within "scripts" object.
|
|
499
480
|
*
|
|
500
|
-
* @param {
|
|
501
|
-
* @
|
|
502
|
-
* @return {RunOutput}
|
|
481
|
+
* @param {RunOptions} opts
|
|
482
|
+
* @return {Promise<RunOutput>}
|
|
503
483
|
*/
|
|
504
|
-
async
|
|
484
|
+
async _run ({ext, scriptName}) {
|
|
505
485
|
if (!_.has(this.config.installedExtensions, ext)) {
|
|
506
486
|
throw new Error(`please install the ${this.type} first`);
|
|
507
487
|
}
|
|
508
488
|
|
|
509
489
|
const extConfig = this.config.installedExtensions[ext];
|
|
510
490
|
|
|
511
|
-
|
|
491
|
+
// note: TS cannot understand that _.has() is a type guard
|
|
492
|
+
if (!extConfig.scripts) {
|
|
512
493
|
throw new Error(`The ${this.type} named '${ext}' does not contain the ` +
|
|
513
494
|
`"scripts" field underneath the "appium" field in its package.json`);
|
|
514
495
|
}
|
|
@@ -523,8 +504,10 @@ export default class ExtensionCommand {
|
|
|
523
504
|
throw new Error(`The ${this.type} named '${ext}' does not support the script: '${scriptName}'`);
|
|
524
505
|
}
|
|
525
506
|
|
|
526
|
-
const runner = new SubProcess(process.execPath, [
|
|
527
|
-
|
|
507
|
+
const runner = new SubProcess(process.execPath, [
|
|
508
|
+
extScripts[scriptName]
|
|
509
|
+
], {
|
|
510
|
+
cwd: this.config.getInstallPath(ext)
|
|
528
511
|
});
|
|
529
512
|
|
|
530
513
|
const output = new RingBuffer(50);
|
|
@@ -547,8 +530,155 @@ export default class ExtensionCommand {
|
|
|
547
530
|
}
|
|
548
531
|
}
|
|
549
532
|
|
|
533
|
+
export default ExtensionCommand;
|
|
534
|
+
export {ExtensionCommand};
|
|
535
|
+
|
|
550
536
|
/**
|
|
551
|
-
* @
|
|
552
|
-
* @
|
|
537
|
+
* Options for the {@linkcode ExtensionCommand} constructor
|
|
538
|
+
* @template {ExtensionType} ExtType
|
|
539
|
+
* @typedef ExtensionCommandOptions
|
|
540
|
+
* @property {ExtensionConfig<ExtType>} config - the `DriverConfig` or `PluginConfig` instance used for this command
|
|
541
|
+
* @property {boolean} json - whether the output of this command should be JSON or text
|
|
542
|
+
*/
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Extra stuff about extensions; used indirectly by {@linkcode ExtensionCommand.list}.
|
|
546
|
+
*
|
|
547
|
+
* @typedef ExtensionMetadata
|
|
548
|
+
* @property {boolean} installed - If `true`, the extension is installed
|
|
549
|
+
* @property {string?} updateVersion - If the extension is installed, the version it can be updated to
|
|
550
|
+
* @property {string?} unsafeUpdateVersion - Same as above, but a major version bump
|
|
551
|
+
* @property {boolean} upToDate - If the extension is installed and the latest
|
|
552
|
+
*/
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* @typedef {import('../../types').ExtensionType} ExtensionType
|
|
556
|
+
* @typedef {import('../../types').DriverType} DriverType
|
|
557
|
+
* @typedef {import('../../types').PluginType} PluginType
|
|
558
|
+
*/
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* @template {ExtensionType} ExtType
|
|
562
|
+
* @typedef {import('../../types/appium-manifest').ExtRecord<ExtType>} ExtRecord
|
|
563
|
+
*/
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* @template {ExtensionType} ExtType
|
|
567
|
+
* @typedef {import('../extension/extension-config').ExtensionConfig<ExtType>} ExtensionConfig
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @template {ExtensionType} ExtType
|
|
572
|
+
* @typedef {import('../../types/external-manifest').ExtMetadata<ExtType>} ExtMetadata
|
|
573
|
+
*/
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* @template {ExtensionType} ExtType
|
|
577
|
+
* @typedef {import('../../types/appium-manifest').ExtManifest<ExtType>} ExtManifest
|
|
578
|
+
*/
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* @template {ExtensionType} ExtType
|
|
582
|
+
* @typedef {import('../../types/external-manifest').ExtPackageJson<ExtType>} ExtPackageJson
|
|
583
|
+
*/
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Possible return value for {@linkcode ExtensionCommand.list}
|
|
587
|
+
* @typedef UninstalledExtensionListData
|
|
588
|
+
* @property {string} pkgName
|
|
589
|
+
* @property {false} installed
|
|
590
|
+
*/
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Possible return value for {@linkcode ExtensionCommand.list}
|
|
594
|
+
* @typedef {import('../../types/appium-manifest').InternalMetadata & ExtensionMetadata} InstalledExtensionListData
|
|
595
|
+
*/
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Return value of {@linkcode ExtensionCommand.list}.
|
|
599
|
+
* @typedef {Record<string,InstalledExtensionListData|UninstalledExtensionListData>} ExtensionListData
|
|
600
|
+
*/
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Options for {@linkcode ExtensionCommand._run}.
|
|
604
|
+
* @typedef RunOptions
|
|
605
|
+
* @property {string} ext - name of the extension to run a script from
|
|
606
|
+
* @property {string} scriptName - name of the script to run
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Return value of {@linkcode ExtensionCommand._run}
|
|
611
|
+
*
|
|
612
|
+
* @typedef RunOutput
|
|
613
|
+
* @property {string} [error] - error message if script ran unsuccessfully, otherwise undefined
|
|
553
614
|
* @property {string[]} output - script output
|
|
554
615
|
*/
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Options for {@linkcode ExtensionCommand._update}.
|
|
619
|
+
* @typedef ExtensionUpdateOpts
|
|
620
|
+
* @property {string} ext - the name of the extension to update
|
|
621
|
+
* @property {boolean} unsafe - if true, will perform unsafe updates past major revision boundaries
|
|
622
|
+
*/
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Return value of {@linkcode ExtensionCommand._update}.
|
|
626
|
+
* @typedef ExtensionUpdateResult
|
|
627
|
+
* @property {Record<string,Error>} errors - map of ext names to error objects
|
|
628
|
+
* @property {Record<string,UpdateReport>} updates - map of ext names to {@linkcode UpdateReport}s
|
|
629
|
+
*/
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Part of result of {@linkcode ExtensionCommand._update}.
|
|
633
|
+
* @typedef UpdateReport
|
|
634
|
+
* @property {string} from - version the extension was updated from
|
|
635
|
+
* @property {string} to - version the extension was updated to
|
|
636
|
+
*/
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Options for {@linkcode ExtensionCommand._uninstall}.
|
|
640
|
+
* @typedef UninstallOpts
|
|
641
|
+
* @property {string} ext - the name or spec of an extension to uninstall
|
|
642
|
+
*/
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Used by {@linkcode ExtensionCommand.getPostInstallText}
|
|
646
|
+
* @typedef ExtensionArgs
|
|
647
|
+
* @property {string} extName - the name of an extension
|
|
648
|
+
* @property {object} extData - the data for an installed extension
|
|
649
|
+
*/
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Options for {@linkcode ExtensionCommand.installViaNpm}
|
|
653
|
+
* @typedef InstallViaNpmArgs
|
|
654
|
+
* @property {string} ext - the name or spec of an extension to install
|
|
655
|
+
* @property {string} pkgName - the NPM package name of the extension
|
|
656
|
+
* @property {string} [pkgVer] - the specific version of the NPM package
|
|
657
|
+
*/
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Object returned by {@linkcode ExtensionCommand.checkForExtensionUpdate}
|
|
661
|
+
* @typedef PossibleUpdates
|
|
662
|
+
* @property {string} current - current version
|
|
663
|
+
* @property {string?} safeUpdate - version we can safely update to if it exists, or null
|
|
664
|
+
* @property {string?} unsafeUpdate - version we can unsafely update to if it exists, or null
|
|
665
|
+
*/
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Options for {@linkcode ExtensionCommand._install}
|
|
669
|
+
* @typedef InstallArgs
|
|
670
|
+
* @property {string} ext - the name or spec of an extension to install
|
|
671
|
+
* @property {import('../../types/appium-manifest').InstallType} installType - how to install this extension. One of the INSTALL_TYPES
|
|
672
|
+
* @property {string} [packageName] - for git/github installs, the extension node package name
|
|
673
|
+
*/
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Returned by {@linkcode ExtensionCommand.getExtensionFields}
|
|
677
|
+
* @template {ExtensionType} ExtType
|
|
678
|
+
* @typedef {ExtMetadata<ExtType> & { pkgName: string, version: string } & import('../../types/external-manifest').CommonMetadata} ExtensionFields
|
|
679
|
+
*/
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* @template {ExtensionType} ExtType
|
|
683
|
+
* @typedef {ExtType extends DriverType ? typeof import('../constants').KNOWN_DRIVERS : ExtType extends PluginType ? typeof import('../constants').KNOWN_PLUGINS : never} KnownExtensions
|
|
684
|
+
*/
|