appium 2.0.0-beta.57 → 2.0.0-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/build/lib/appium.d.ts +43 -35
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +37 -29
- package/build/lib/appium.js.map +1 -1
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +10 -0
- package/build/lib/cli/args.js.map +1 -1
- package/build/lib/cli/driver-command.d.ts +7 -7
- package/build/lib/cli/driver-command.js +7 -7
- package/build/lib/cli/driver-command.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +37 -34
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +67 -44
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts +5 -5
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +1 -1
- package/build/lib/cli/extension.js.map +1 -1
- package/build/lib/cli/plugin-command.d.ts +7 -7
- package/build/lib/cli/plugin-command.js +7 -7
- package/build/lib/cli/plugin-command.js.map +1 -1
- package/build/lib/constants.d.ts +8 -1
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +9 -2
- package/build/lib/constants.js.map +1 -1
- package/build/lib/extension/driver-config.d.ts +6 -6
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +5 -7
- package/build/lib/extension/driver-config.js.map +1 -1
- package/build/lib/extension/extension-config.d.ts +31 -10
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +44 -24
- package/build/lib/extension/extension-config.js.map +1 -1
- package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
- package/build/lib/extension/manifest-migrations.js +29 -13
- package/build/lib/extension/manifest-migrations.js.map +1 -1
- package/build/lib/extension/manifest.d.ts +5 -5
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +19 -12
- package/build/lib/extension/manifest.js.map +1 -1
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +3 -3
- package/build/lib/main.js.map +1 -1
- package/build/lib/schema/cli-args.d.ts +1 -1
- package/build/lib/schema/cli-args.d.ts.map +1 -1
- package/build/lib/schema/cli-args.js +1 -1
- package/build/lib/utils.d.ts +118 -12
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +8 -10
- package/build/lib/utils.js.map +1 -1
- package/build/types/manifest/index.d.ts +4 -2
- package/build/types/manifest/index.d.ts.map +1 -1
- package/build/types/manifest/index.js +4 -2
- package/build/types/manifest/index.js.map +1 -1
- package/build/types/manifest/v4.d.ts +139 -0
- package/build/types/manifest/v4.d.ts.map +1 -0
- package/build/types/manifest/v4.js +3 -0
- package/build/types/manifest/v4.js.map +1 -0
- package/lib/appium.js +42 -31
- package/lib/cli/args.js +10 -0
- package/lib/cli/driver-command.js +7 -7
- package/lib/cli/extension-command.js +76 -54
- package/lib/cli/extension.js +5 -5
- package/lib/cli/plugin-command.js +7 -7
- package/lib/constants.js +9 -1
- package/lib/extension/driver-config.js +5 -8
- package/lib/extension/extension-config.js +42 -15
- package/lib/extension/manifest-migrations.js +31 -15
- package/lib/extension/manifest.js +26 -19
- package/lib/main.js +7 -4
- package/lib/schema/cli-args.js +1 -1
- package/lib/utils.js +8 -10
- package/package.json +9 -9
- package/types/manifest/index.ts +4 -3
- package/types/manifest/v4.ts +161 -0
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
INSTALL_TYPE_GIT,
|
|
10
10
|
INSTALL_TYPE_GITHUB,
|
|
11
11
|
INSTALL_TYPE_LOCAL,
|
|
12
|
+
INSTALL_TYPE_DEV,
|
|
12
13
|
} from '../extension/extension-config';
|
|
13
14
|
import {SubProcess} from 'teen_process';
|
|
14
15
|
import {packageDidChange} from '../extension/package-changed';
|
|
15
16
|
import {spawn} from 'child_process';
|
|
17
|
+
import {inspect} from 'node:util';
|
|
16
18
|
|
|
17
19
|
const UPDATE_ALL = 'installed';
|
|
18
20
|
|
|
@@ -32,7 +34,7 @@ function receiptToManifest(receipt) {
|
|
|
32
34
|
/**
|
|
33
35
|
* @template {ExtensionType} ExtType
|
|
34
36
|
*/
|
|
35
|
-
class
|
|
37
|
+
class ExtensionCliCommand {
|
|
36
38
|
/**
|
|
37
39
|
* This is the `DriverConfig` or `PluginConfig`, depending on `ExtType`.
|
|
38
40
|
* @type {ExtensionConfig<ExtType>}
|
|
@@ -99,41 +101,40 @@ class ExtensionCommand {
|
|
|
99
101
|
|
|
100
102
|
/**
|
|
101
103
|
* List extensions
|
|
102
|
-
*
|
|
104
|
+
* @template {ExtensionType} ExtType
|
|
103
105
|
* @param {ListOptions} opts
|
|
104
|
-
* @return {Promise<
|
|
106
|
+
* @return {Promise<ExtensionList<ExtType>>} map of extension names to extension data
|
|
105
107
|
*/
|
|
106
|
-
async list({showInstalled, showUpdates}) {
|
|
107
|
-
|
|
108
|
+
async list({showInstalled, showUpdates, verbose = false}) {
|
|
109
|
+
let lsMsg = `Listing ${showInstalled ? 'installed' : 'available'} ${this.type}s`;
|
|
110
|
+
if (verbose) {
|
|
111
|
+
lsMsg += ' (verbose mode)';
|
|
112
|
+
}
|
|
108
113
|
const installedNames = Object.keys(this.config.installedExtensions);
|
|
109
114
|
const knownNames = Object.keys(this.knownExtensions);
|
|
110
|
-
const
|
|
111
|
-
(acc
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
const listData = [...installedNames, ...knownNames].reduce((acc, name) => {
|
|
116
|
+
if (!acc[name]) {
|
|
117
|
+
if (installedNames.includes(name)) {
|
|
118
|
+
acc[name] = {
|
|
119
|
+
.../** @type {Partial<ExtManifest<ExtType>>} */ (this.config.installedExtensions[name]),
|
|
120
|
+
installed: true,
|
|
121
|
+
};
|
|
122
|
+
} else if (!showInstalled) {
|
|
123
|
+
acc[name] = /** @type {ExtensionListData<ExtType>} */ ({
|
|
124
|
+
pkgName: this.knownExtensions[name],
|
|
125
|
+
installed: false,
|
|
126
|
+
});
|
|
121
127
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
* This accumulator contains either {@linkcode UninstalledExtensionLIstData} _or_
|
|
126
|
-
* {@linkcode InstalledExtensionListData} without upgrade information (which is added by the below code block)
|
|
127
|
-
* @type {Record<string,Partial<InstalledExtensionListData>|UninstalledExtensionListData>}
|
|
128
|
-
*/ ({})
|
|
129
|
-
);
|
|
128
|
+
}
|
|
129
|
+
return acc;
|
|
130
|
+
}, /** @type {ExtensionList<ExtType>} */ ({}));
|
|
130
131
|
|
|
131
132
|
// if we want to show whether updates are available, put that behind a spinner
|
|
132
133
|
await spinWith(this.isJsonOutput, lsMsg, async () => {
|
|
133
134
|
if (!showUpdates) {
|
|
134
135
|
return;
|
|
135
136
|
}
|
|
136
|
-
for (const [ext, data] of _.toPairs(
|
|
137
|
+
for (const [ext, data] of _.toPairs(listData)) {
|
|
137
138
|
if (!data.installed || data.installType !== INSTALL_TYPE_NPM) {
|
|
138
139
|
// don't need to check for updates on exts that aren't installed
|
|
139
140
|
// also don't need to check for updates on non-npm exts
|
|
@@ -150,7 +151,12 @@ class ExtensionCommand {
|
|
|
150
151
|
}
|
|
151
152
|
});
|
|
152
153
|
|
|
153
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Type guard to narrow "installed" extensions, which have more data
|
|
156
|
+
* @param {any} data
|
|
157
|
+
* @returns {data is InstalledExtensionListData<ExtType>}
|
|
158
|
+
*/
|
|
159
|
+
const extIsInstalled = (data) => Boolean(data.installed);
|
|
154
160
|
|
|
155
161
|
// if we're just getting the data, short circuit return here since we don't need to do any
|
|
156
162
|
// formatting logic
|
|
@@ -158,12 +164,16 @@ class ExtensionCommand {
|
|
|
158
164
|
return listData;
|
|
159
165
|
}
|
|
160
166
|
|
|
167
|
+
if (verbose) {
|
|
168
|
+
this.log.log(inspect(listData, {colors: true, depth: null}));
|
|
169
|
+
return listData;
|
|
170
|
+
}
|
|
161
171
|
for (const [name, data] of _.toPairs(listData)) {
|
|
162
172
|
let installTxt = ' [not installed]'.grey;
|
|
163
173
|
let updateTxt = '';
|
|
164
174
|
let upToDateTxt = '';
|
|
165
175
|
let unsafeUpdateTxt = '';
|
|
166
|
-
if (data
|
|
176
|
+
if (extIsInstalled(data)) {
|
|
167
177
|
const {
|
|
168
178
|
installType,
|
|
169
179
|
installSpec,
|
|
@@ -182,8 +192,11 @@ class ExtensionCommand {
|
|
|
182
192
|
case INSTALL_TYPE_LOCAL:
|
|
183
193
|
typeTxt = `(linked from ${installSpec})`.magenta;
|
|
184
194
|
break;
|
|
195
|
+
case INSTALL_TYPE_DEV:
|
|
196
|
+
typeTxt = '(dev mode)';
|
|
197
|
+
break;
|
|
185
198
|
default:
|
|
186
|
-
typeTxt = '(
|
|
199
|
+
typeTxt = '(npm)';
|
|
187
200
|
}
|
|
188
201
|
installTxt = `@${version.yellow} ${('[installed ' + typeTxt + ']').green}`;
|
|
189
202
|
|
|
@@ -513,7 +526,12 @@ class ExtensionCommand {
|
|
|
513
526
|
`Can't uninstall ${this.type} '${installSpec}'; it is not installed`
|
|
514
527
|
);
|
|
515
528
|
}
|
|
516
|
-
const
|
|
529
|
+
const extRecord = this.config.installedExtensions[installSpec];
|
|
530
|
+
if (extRecord.installType === INSTALL_TYPE_DEV) {
|
|
531
|
+
this.log.warn(`Cannot uninstall ${this.type} "${installSpec}" because it is in development!`);
|
|
532
|
+
return this.config.installedExtensions;
|
|
533
|
+
}
|
|
534
|
+
const pkgName = extRecord.pkgName;
|
|
517
535
|
await npm.uninstallPackage(this.config.appiumHome, pkgName);
|
|
518
536
|
await this.config.removeExtension(installSpec);
|
|
519
537
|
this.log.ok(`Successfully uninstalled ${this.type} '${installSpec}'`.green);
|
|
@@ -771,11 +789,11 @@ class ExtensionCommand {
|
|
|
771
789
|
}
|
|
772
790
|
}
|
|
773
791
|
|
|
774
|
-
export default
|
|
775
|
-
export {ExtensionCommand};
|
|
792
|
+
export default ExtensionCliCommand;
|
|
793
|
+
export {ExtensionCliCommand as ExtensionCommand};
|
|
776
794
|
|
|
777
795
|
/**
|
|
778
|
-
* Options for the {@linkcode
|
|
796
|
+
* Options for the {@linkcode ExtensionCliCommand} constructor
|
|
779
797
|
* @template {ExtensionType} ExtType
|
|
780
798
|
* @typedef ExtensionCommandOptions
|
|
781
799
|
* @property {ExtensionConfig<ExtType>} config - the `DriverConfig` or `PluginConfig` instance used for this command
|
|
@@ -783,14 +801,15 @@ export {ExtensionCommand};
|
|
|
783
801
|
*/
|
|
784
802
|
|
|
785
803
|
/**
|
|
786
|
-
* Extra stuff about extensions; used indirectly by {@linkcode
|
|
804
|
+
* Extra stuff about extensions; used indirectly by {@linkcode ExtensionCliCommand.list}.
|
|
787
805
|
*
|
|
788
|
-
* @typedef
|
|
806
|
+
* @typedef ExtensionListMetadata
|
|
789
807
|
* @property {boolean} installed - If `true`, the extension is installed
|
|
790
|
-
* @property {string?} updateVersion - If the extension is installed, the version it can be updated to
|
|
791
|
-
* @property {string?} unsafeUpdateVersion - Same as above, but a major version bump
|
|
792
808
|
* @property {boolean} upToDate - If the extension is installed and the latest
|
|
793
|
-
* @property {string
|
|
809
|
+
* @property {string|null} updateVersion - If the extension is installed, the version it can be updated to
|
|
810
|
+
* @property {string|null} unsafeUpdateVersion - Same as above, but a major version bump
|
|
811
|
+
* @property {string} [updateError] - Update check error message (if present)
|
|
812
|
+
* @property {boolean} [devMode] - If Appium is run from an extension's working copy
|
|
794
813
|
*/
|
|
795
814
|
|
|
796
815
|
/**
|
|
@@ -830,22 +849,24 @@ export {ExtensionCommand};
|
|
|
830
849
|
*/
|
|
831
850
|
|
|
832
851
|
/**
|
|
833
|
-
* Possible return value for {@linkcode
|
|
834
|
-
* @
|
|
852
|
+
* Possible return value for {@linkcode ExtensionCliCommand.list}
|
|
853
|
+
* @template {ExtensionType} ExtType
|
|
854
|
+
* @typedef {Partial<ExtManifest<ExtType>> & Partial<ExtensionListMetadata>} ExtensionListData
|
|
835
855
|
*/
|
|
836
856
|
|
|
837
857
|
/**
|
|
838
|
-
*
|
|
839
|
-
* @typedef {
|
|
858
|
+
* @template {ExtensionType} ExtType
|
|
859
|
+
* @typedef {ExtManifest<ExtType> & ExtensionListMetadata} InstalledExtensionListData
|
|
840
860
|
*/
|
|
841
861
|
|
|
842
862
|
/**
|
|
843
|
-
* Return value of {@linkcode
|
|
844
|
-
* @
|
|
863
|
+
* Return value of {@linkcode ExtensionCliCommand.list}.
|
|
864
|
+
* @template {ExtensionType} ExtType
|
|
865
|
+
* @typedef {Record<string,ExtensionListData<ExtType>>} ExtensionList
|
|
845
866
|
*/
|
|
846
867
|
|
|
847
868
|
/**
|
|
848
|
-
* Options for {@linkcode
|
|
869
|
+
* Options for {@linkcode ExtensionCliCommand._run}.
|
|
849
870
|
* @typedef RunOptions
|
|
850
871
|
* @property {string} installSpec - name of the extension to run a script from
|
|
851
872
|
* @property {string} scriptName - name of the script to run
|
|
@@ -854,7 +875,7 @@ export {ExtensionCommand};
|
|
|
854
875
|
*/
|
|
855
876
|
|
|
856
877
|
/**
|
|
857
|
-
* Return value of {@linkcode
|
|
878
|
+
* Return value of {@linkcode ExtensionCliCommand._run}
|
|
858
879
|
*
|
|
859
880
|
* @typedef RunOutput
|
|
860
881
|
* @property {string} [error] - error message if script ran unsuccessfully, otherwise undefined
|
|
@@ -862,41 +883,41 @@ export {ExtensionCommand};
|
|
|
862
883
|
*/
|
|
863
884
|
|
|
864
885
|
/**
|
|
865
|
-
* Options for {@linkcode
|
|
886
|
+
* Options for {@linkcode ExtensionCliCommand._update}.
|
|
866
887
|
* @typedef ExtensionUpdateOpts
|
|
867
888
|
* @property {string} installSpec - the name of the extension to update
|
|
868
889
|
* @property {boolean} unsafe - if true, will perform unsafe updates past major revision boundaries
|
|
869
890
|
*/
|
|
870
891
|
|
|
871
892
|
/**
|
|
872
|
-
* Return value of {@linkcode
|
|
893
|
+
* Return value of {@linkcode ExtensionCliCommand._update}.
|
|
873
894
|
* @typedef ExtensionUpdateResult
|
|
874
895
|
* @property {Record<string,Error>} errors - map of ext names to error objects
|
|
875
896
|
* @property {Record<string,UpdateReport>} updates - map of ext names to {@linkcode UpdateReport}s
|
|
876
897
|
*/
|
|
877
898
|
|
|
878
899
|
/**
|
|
879
|
-
* Part of result of {@linkcode
|
|
900
|
+
* Part of result of {@linkcode ExtensionCliCommand._update}.
|
|
880
901
|
* @typedef UpdateReport
|
|
881
902
|
* @property {string} from - version the extension was updated from
|
|
882
903
|
* @property {string} to - version the extension was updated to
|
|
883
904
|
*/
|
|
884
905
|
|
|
885
906
|
/**
|
|
886
|
-
* Options for {@linkcode
|
|
907
|
+
* Options for {@linkcode ExtensionCliCommand._uninstall}.
|
|
887
908
|
* @typedef UninstallOpts
|
|
888
909
|
* @property {string} installSpec - the name or spec of an extension to uninstall
|
|
889
910
|
*/
|
|
890
911
|
|
|
891
912
|
/**
|
|
892
|
-
* Used by {@linkcode
|
|
913
|
+
* Used by {@linkcode ExtensionCliCommand.getPostInstallText}
|
|
893
914
|
* @typedef ExtensionArgs
|
|
894
915
|
* @property {string} extName - the name of an extension
|
|
895
916
|
* @property {object} extData - the data for an installed extension
|
|
896
917
|
*/
|
|
897
918
|
|
|
898
919
|
/**
|
|
899
|
-
* Options for {@linkcode
|
|
920
|
+
* Options for {@linkcode ExtensionCliCommand.installViaNpm}
|
|
900
921
|
* @typedef InstallViaNpmArgs
|
|
901
922
|
* @property {string} installSpec - the name or spec of an extension to install
|
|
902
923
|
* @property {string} pkgName - the NPM package name of the extension
|
|
@@ -905,7 +926,7 @@ export {ExtensionCommand};
|
|
|
905
926
|
*/
|
|
906
927
|
|
|
907
928
|
/**
|
|
908
|
-
* Object returned by {@linkcode
|
|
929
|
+
* Object returned by {@linkcode ExtensionCliCommand.checkForExtensionUpdate}
|
|
909
930
|
* @typedef PossibleUpdates
|
|
910
931
|
* @property {string} current - current version
|
|
911
932
|
* @property {string?} safeUpdate - version we can safely update to if it exists, or null
|
|
@@ -913,7 +934,7 @@ export {ExtensionCommand};
|
|
|
913
934
|
*/
|
|
914
935
|
|
|
915
936
|
/**
|
|
916
|
-
* Options for {@linkcode
|
|
937
|
+
* Options for {@linkcode ExtensionCliCommand._install}
|
|
917
938
|
* @typedef InstallOpts
|
|
918
939
|
* @property {string} installSpec - the name or spec of an extension to install
|
|
919
940
|
* @property {InstallType} installType - how to install this extension. One of the INSTALL_TYPES
|
|
@@ -929,10 +950,11 @@ export {ExtensionCommand};
|
|
|
929
950
|
* @typedef ListOptions
|
|
930
951
|
* @property {boolean} showInstalled - whether should show only installed extensions
|
|
931
952
|
* @property {boolean} showUpdates - whether should show available updates
|
|
953
|
+
* @property {boolean} [verbose] - whether to show additional data from the extension
|
|
932
954
|
*/
|
|
933
955
|
|
|
934
956
|
/**
|
|
935
|
-
* Opts for {@linkcode
|
|
957
|
+
* Opts for {@linkcode ExtensionCliCommand.getInstallationReceipt}
|
|
936
958
|
* @template {ExtensionType} ExtType
|
|
937
959
|
* @typedef GetInstallationReceiptOpts
|
|
938
960
|
* @property {string} installPath
|
package/lib/cli/extension.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import {DRIVER_TYPE, PLUGIN_TYPE} from '../constants';
|
|
3
3
|
import {isExtensionCommandArgs} from '../utils';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import DriverCliCommand from './driver-command';
|
|
5
|
+
import PluginCliCommand from './plugin-command';
|
|
6
6
|
import {errAndQuit, JSON_SPACES} from './utils';
|
|
7
7
|
|
|
8
8
|
export const commandClasses = Object.freeze(
|
|
9
9
|
/** @type {const} */ ({
|
|
10
|
-
[DRIVER_TYPE]:
|
|
11
|
-
[PLUGIN_TYPE]:
|
|
10
|
+
[DRIVER_TYPE]: DriverCliCommand,
|
|
11
|
+
[PLUGIN_TYPE]: PluginCliCommand,
|
|
12
12
|
})
|
|
13
13
|
);
|
|
14
14
|
|
|
@@ -59,7 +59,7 @@ export {runExtensionCommand};
|
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
61
|
* @template {ExtensionType} ExtType
|
|
62
|
-
* @typedef {ExtType extends DriverType ? Class<
|
|
62
|
+
* @typedef {ExtType extends DriverType ? Class<DriverCliCommand> : ExtType extends PluginType ? Class<PluginCliCommand> : never} ExtCommand
|
|
63
63
|
*/
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import
|
|
2
|
+
import ExtensionCliCommand from './extension-command';
|
|
3
3
|
import {KNOWN_PLUGINS} from '../constants';
|
|
4
4
|
|
|
5
5
|
const REQ_PLUGIN_FIELDS = ['pluginName', 'mainClass'];
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @extends {
|
|
8
|
+
* @extends {ExtensionCliCommand<PluginType>}
|
|
9
9
|
*/
|
|
10
|
-
export default class
|
|
10
|
+
export default class PluginCliCommand extends ExtensionCliCommand {
|
|
11
11
|
/**
|
|
12
12
|
*
|
|
13
13
|
* @param {import('./extension-command').ExtensionCommandOptions<PluginType>} opts
|
|
@@ -110,7 +110,7 @@ export default class PluginCommand extends ExtensionCommand {
|
|
|
110
110
|
*/
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
|
-
* Options for {@linkcode
|
|
113
|
+
* Options for {@linkcode PluginCliCommand.install}
|
|
114
114
|
* @typedef PluginInstallOpts
|
|
115
115
|
* @property {string} plugin - the name or spec of a plugin to install
|
|
116
116
|
* @property {InstallType} installType - how to install this plugin. One of the INSTALL_TYPES
|
|
@@ -122,20 +122,20 @@ export default class PluginCommand extends ExtensionCommand {
|
|
|
122
122
|
*/
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
|
-
* Options for {@linkcode
|
|
125
|
+
* Options for {@linkcode PluginCliCommand.uninstall}
|
|
126
126
|
* @typedef PluginUninstallOpts
|
|
127
127
|
* @property {string} plugin - the name or spec of a plugin to uninstall
|
|
128
128
|
*/
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
* Options for {@linkcode
|
|
131
|
+
* Options for {@linkcode PluginCliCommand.update}
|
|
132
132
|
* @typedef PluginUpdateOpts
|
|
133
133
|
* @property {string} plugin - the name of the plugin to update
|
|
134
134
|
* @property {boolean} unsafe - if true, will perform unsafe updates past major revision boundaries
|
|
135
135
|
*/
|
|
136
136
|
|
|
137
137
|
/**
|
|
138
|
-
* Options for {@linkcode
|
|
138
|
+
* Options for {@linkcode PluginCliCommand.run}.
|
|
139
139
|
* @typedef PluginRunOptions
|
|
140
140
|
* @property {string} plugin - name of the plugin to run a script from
|
|
141
141
|
* @property {string} scriptName - name of the script to run
|
package/lib/constants.js
CHANGED
|
@@ -68,4 +68,12 @@ export const EXT_SUBCOMMAND_RUN = 'run';
|
|
|
68
68
|
/**
|
|
69
69
|
* Current revision of the manifest (`extensions.yaml`) schema
|
|
70
70
|
*/
|
|
71
|
-
export const CURRENT_SCHEMA_REV =
|
|
71
|
+
export const CURRENT_SCHEMA_REV = 4;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The default number of stack frames to show in a "long" stack trace, when enabled via `--long-stacktrace`
|
|
75
|
+
* @remarks This value may be increased in the future.
|
|
76
|
+
* @privateRemarks A value like `Infinity` may provide to have deleterious effects on
|
|
77
|
+
* memory usage, perf, and/or log output, and higher limits may be difficult to scan.
|
|
78
|
+
*/
|
|
79
|
+
export const LONG_STACKTRACE_LIMIT = 100;
|
|
@@ -212,28 +212,29 @@ export class DriverConfig extends ExtensionConfig {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
/**
|
|
215
|
-
* @template T
|
|
215
|
+
* @template {ExtensionType} T
|
|
216
216
|
* @typedef {import('appium/types').ExtMetadata<T>} ExtMetadata
|
|
217
217
|
*/
|
|
218
218
|
|
|
219
219
|
/**
|
|
220
|
-
* @template T
|
|
220
|
+
* @template {ExtensionType} T
|
|
221
221
|
* @typedef {import('appium/types').ExtManifest<T>} ExtManifest
|
|
222
222
|
*/
|
|
223
223
|
|
|
224
224
|
/**
|
|
225
|
+
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
225
226
|
* @typedef {import('appium/types').ManifestData} ManifestData
|
|
226
227
|
* @typedef {import('@appium/types').DriverType} DriverType
|
|
227
228
|
* @typedef {import('./manifest').Manifest} Manifest
|
|
228
229
|
*/
|
|
229
230
|
|
|
230
231
|
/**
|
|
231
|
-
* @template T
|
|
232
|
+
* @template {ExtensionType} T
|
|
232
233
|
* @typedef {import('appium/types').ExtRecord<T>} ExtRecord
|
|
233
234
|
*/
|
|
234
235
|
|
|
235
236
|
/**
|
|
236
|
-
* @template T
|
|
237
|
+
* @template {ExtensionType} T
|
|
237
238
|
* @typedef {import('appium/types').ExtName<T>} ExtName
|
|
238
239
|
*/
|
|
239
240
|
|
|
@@ -244,7 +245,3 @@ export class DriverConfig extends ExtensionConfig {
|
|
|
244
245
|
* @property {string} version
|
|
245
246
|
* @property {string} driverName
|
|
246
247
|
*/
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* @typedef {import('@appium/types').Capabilities} Capabilities
|
|
250
|
-
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {util} from '@appium/support';
|
|
2
2
|
import B from 'bluebird';
|
|
3
|
+
import _ from 'lodash';
|
|
3
4
|
import path from 'path';
|
|
4
5
|
import resolveFrom from 'resolve-from';
|
|
5
6
|
import {satisfies} from 'semver';
|
|
6
|
-
import {util} from '@appium/support';
|
|
7
7
|
import {commandClasses} from '../cli/extension';
|
|
8
8
|
import {APPIUM_VER} from '../config';
|
|
9
9
|
import log from '../logger';
|
|
@@ -13,17 +13,41 @@ import {
|
|
|
13
13
|
registerSchema,
|
|
14
14
|
} from '../schema/schema';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
/**
|
|
17
|
+
* "npm" install type
|
|
18
|
+
* Used when extension was installed by npm package name
|
|
19
|
+
* @remarks _All_ extensions are installed _by_ `npm`, but only this one means the package name was
|
|
20
|
+
* used to specify it
|
|
21
|
+
*/
|
|
22
|
+
export const INSTALL_TYPE_NPM = 'npm';
|
|
23
|
+
/**
|
|
24
|
+
* "local" install type
|
|
25
|
+
* Used when extension was installed from a local path
|
|
26
|
+
*/
|
|
27
|
+
export const INSTALL_TYPE_LOCAL = 'local';
|
|
28
|
+
/**
|
|
29
|
+
* "github" install type
|
|
30
|
+
* Used when extension was installed via GitHub URL
|
|
31
|
+
*/
|
|
32
|
+
export const INSTALL_TYPE_GITHUB = 'github';
|
|
33
|
+
/**
|
|
34
|
+
* "git" install type
|
|
35
|
+
* Used when extensions was installed via Git URL
|
|
36
|
+
*/
|
|
37
|
+
export const INSTALL_TYPE_GIT = 'git';
|
|
38
|
+
/**
|
|
39
|
+
* "dev" install type
|
|
40
|
+
* Used when automatically detected as a working copy
|
|
41
|
+
*/
|
|
42
|
+
export const INSTALL_TYPE_DEV = 'dev';
|
|
20
43
|
|
|
21
44
|
/** @type {Set<InstallType>} */
|
|
22
|
-
const INSTALL_TYPES = new Set([
|
|
45
|
+
export const INSTALL_TYPES = new Set([
|
|
23
46
|
INSTALL_TYPE_GIT,
|
|
24
47
|
INSTALL_TYPE_GITHUB,
|
|
25
48
|
INSTALL_TYPE_LOCAL,
|
|
26
49
|
INSTALL_TYPE_NPM,
|
|
50
|
+
INSTALL_TYPE_DEV,
|
|
27
51
|
]);
|
|
28
52
|
|
|
29
53
|
/**
|
|
@@ -54,7 +78,7 @@ export class ExtensionConfig {
|
|
|
54
78
|
manifest;
|
|
55
79
|
|
|
56
80
|
/**
|
|
57
|
-
* @type {
|
|
81
|
+
* @type {import('../cli/extension-command').ExtensionList<ExtType>|undefined}
|
|
58
82
|
*/
|
|
59
83
|
#listDataCache;
|
|
60
84
|
|
|
@@ -239,7 +263,7 @@ export class ExtensionConfig {
|
|
|
239
263
|
* This is an expensive operation, so the result is cached. Currently, there is no
|
|
240
264
|
* use case for invalidating the cache.
|
|
241
265
|
* @protected
|
|
242
|
-
* @returns {Promise<
|
|
266
|
+
* @returns {Promise<import('../cli/extension-command').ExtensionList<ExtType>>}
|
|
243
267
|
*/
|
|
244
268
|
async getListData() {
|
|
245
269
|
if (this.#listDataCache) {
|
|
@@ -300,7 +324,10 @@ export class ExtensionConfig {
|
|
|
300
324
|
|
|
301
325
|
if (_.isString(appiumVersion) && !satisfies(APPIUM_VER, appiumVersion)) {
|
|
302
326
|
const listData = await this.getListData();
|
|
303
|
-
const extListData =
|
|
327
|
+
const extListData =
|
|
328
|
+
/** @type {import('../cli/extension-command').ExtensionListData<ExtType>} */ (
|
|
329
|
+
listData[extName]
|
|
330
|
+
);
|
|
304
331
|
if (extListData?.installed) {
|
|
305
332
|
const {updateVersion, upToDate} = extListData;
|
|
306
333
|
if (!upToDate) {
|
|
@@ -319,7 +346,10 @@ export class ExtensionConfig {
|
|
|
319
346
|
}
|
|
320
347
|
} else if (!_.isString(appiumVersion)) {
|
|
321
348
|
const listData = await this.getListData();
|
|
322
|
-
const extListData =
|
|
349
|
+
const extListData =
|
|
350
|
+
/** @type {import('../cli/extension-command').InstalledExtensionListData<ExtType>} */ (
|
|
351
|
+
listData[extName]
|
|
352
|
+
);
|
|
323
353
|
if (!extListData?.upToDate && extListData?.updateVersion) {
|
|
324
354
|
warnings.push(
|
|
325
355
|
createPeerWarning(
|
|
@@ -544,6 +574,7 @@ export class ExtensionConfig {
|
|
|
544
574
|
delete require.cache[reqResolved];
|
|
545
575
|
}
|
|
546
576
|
log.debug(`Requiring ${this.extensionType} at ${reqPath}`);
|
|
577
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
547
578
|
const MainClass = require(reqPath)[mainClass];
|
|
548
579
|
if (!MainClass) {
|
|
549
580
|
throw new ReferenceError(
|
|
@@ -619,8 +650,6 @@ export class ExtensionConfig {
|
|
|
619
650
|
}
|
|
620
651
|
}
|
|
621
652
|
|
|
622
|
-
export {INSTALL_TYPE_NPM, INSTALL_TYPE_GIT, INSTALL_TYPE_LOCAL, INSTALL_TYPE_GITHUB, INSTALL_TYPES};
|
|
623
|
-
|
|
624
653
|
/**
|
|
625
654
|
* An issue with the {@linkcode ExtManifest} for a particular extension.
|
|
626
655
|
*
|
|
@@ -640,8 +669,6 @@ export {INSTALL_TYPE_NPM, INSTALL_TYPE_GIT, INSTALL_TYPE_LOCAL, INSTALL_TYPE_GIT
|
|
|
640
669
|
/**
|
|
641
670
|
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
642
671
|
* @typedef {import('./manifest').Manifest} Manifest
|
|
643
|
-
* @typedef {import('../cli/extension-command').ExtensionListData} ExtensionListData
|
|
644
|
-
* @typedef {import('../cli/extension-command').InstalledExtensionListData} InstalledExtensionListData
|
|
645
672
|
* @typedef {import('appium/types').InstallType} InstallType
|
|
646
673
|
*/
|
|
647
674
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {DRIVER_TYPE, PLUGIN_TYPE} from '../constants';
|
|
1
|
+
import {CURRENT_SCHEMA_REV, DRIVER_TYPE, PLUGIN_TYPE} from '../constants';
|
|
2
2
|
import log from '../logger';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -12,6 +12,11 @@ import log from '../logger';
|
|
|
12
12
|
*/
|
|
13
13
|
const SCHEMA_REV_3 = 3;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Constant for v4 of the schema rev.
|
|
17
|
+
*/
|
|
18
|
+
const SCHEMA_REV_4 = 4;
|
|
19
|
+
|
|
15
20
|
/**
|
|
16
21
|
* Collection of functions to migrate from one version to another.
|
|
17
22
|
*
|
|
@@ -20,7 +25,7 @@ const SCHEMA_REV_3 = 3;
|
|
|
20
25
|
* itself will happen within {@linkcode Manifest.syncWithInstalledExtensions}; the extensions
|
|
21
26
|
* will be checked and the manifest file updated per the state of the filesystem.
|
|
22
27
|
*
|
|
23
|
-
* @type {{[P in keyof ManifestDataVersions]?: Migration}}
|
|
28
|
+
* @type { {[P in keyof ManifestDataVersions]?: Migration} }
|
|
24
29
|
*/
|
|
25
30
|
const Migrations = {
|
|
26
31
|
/**
|
|
@@ -32,19 +37,32 @@ const Migrations = {
|
|
|
32
37
|
* @type {Migration}
|
|
33
38
|
*/
|
|
34
39
|
[SCHEMA_REV_3]: (manifest) => {
|
|
35
|
-
let shouldSync = false;
|
|
36
40
|
/** @type {Array<ExtManifest<PluginType>|ExtManifest<DriverType>>} */
|
|
37
41
|
const allExtData = [
|
|
38
42
|
...Object.values(manifest.getExtensionData(DRIVER_TYPE)),
|
|
39
43
|
...Object.values(manifest.getExtensionData(PLUGIN_TYPE)),
|
|
40
44
|
];
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
return allExtData.some((metadata) => !('installPath' in metadata));
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Updates installed extensions to use `InstallType` of `dev` if appropriate.
|
|
49
|
+
*
|
|
50
|
+
* Previously, these types of extensions (automatically discovered) would use the default `InstallType` of `npm`, so we need
|
|
51
|
+
* to refresh any with this install type.
|
|
52
|
+
*
|
|
53
|
+
* This should only happen once; we do not want to re-check everything with `npm` install type
|
|
54
|
+
* every time.
|
|
55
|
+
* @type {Migration}
|
|
56
|
+
*/
|
|
57
|
+
[SCHEMA_REV_4]: (manifest) => {
|
|
58
|
+
if (manifest.schemaRev < SCHEMA_REV_4) {
|
|
59
|
+
const allExtData = [
|
|
60
|
+
...Object.values(manifest.getExtensionData(DRIVER_TYPE)),
|
|
61
|
+
...Object.values(manifest.getExtensionData(PLUGIN_TYPE)),
|
|
62
|
+
];
|
|
63
|
+
return allExtData.some((metadata) => metadata.installType === 'npm');
|
|
46
64
|
}
|
|
47
|
-
return
|
|
65
|
+
return false;
|
|
48
66
|
},
|
|
49
67
|
};
|
|
50
68
|
|
|
@@ -61,7 +79,7 @@ const Migrations = {
|
|
|
61
79
|
* @returns {boolean} Whether the data was modified
|
|
62
80
|
*/
|
|
63
81
|
function setSchemaRev(manifest, version) {
|
|
64
|
-
if (manifest.schemaRev ?? 0 < version) {
|
|
82
|
+
if ((manifest.schemaRev ?? 0) < version) {
|
|
65
83
|
manifest.setSchemaRev(version);
|
|
66
84
|
return true;
|
|
67
85
|
}
|
|
@@ -78,15 +96,13 @@ function setSchemaRev(manifest, version) {
|
|
|
78
96
|
*/
|
|
79
97
|
export async function migrate(manifest) {
|
|
80
98
|
let didChange = false;
|
|
81
|
-
for await (const
|
|
82
|
-
const version = /** @type {keyof ManifestDataVersions} */ (Number(v));
|
|
99
|
+
for await (const migration of Object.values(Migrations)) {
|
|
83
100
|
didChange = (await migration(manifest)) || didChange;
|
|
84
|
-
didChange = setSchemaRev(manifest, version) || didChange;
|
|
85
101
|
}
|
|
86
|
-
|
|
102
|
+
didChange = setSchemaRev(manifest, CURRENT_SCHEMA_REV) || didChange;
|
|
87
103
|
if (didChange) {
|
|
88
104
|
// this is not _technically_ true, since we don't actually write the file here.
|
|
89
|
-
log.
|
|
105
|
+
log.debug(`Upgraded extension manifest to schema v${manifest.schemaRev}`);
|
|
90
106
|
}
|
|
91
107
|
|
|
92
108
|
return didChange;
|