appium 2.0.0-beta.56 → 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.
Files changed (85) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +6 -8
  3. package/build/lib/appium.d.ts +43 -35
  4. package/build/lib/appium.d.ts.map +1 -1
  5. package/build/lib/appium.js +38 -30
  6. package/build/lib/appium.js.map +1 -1
  7. package/build/lib/cli/args.d.ts.map +1 -1
  8. package/build/lib/cli/args.js +10 -0
  9. package/build/lib/cli/args.js.map +1 -1
  10. package/build/lib/cli/driver-command.d.ts +7 -7
  11. package/build/lib/cli/driver-command.d.ts.map +1 -1
  12. package/build/lib/cli/driver-command.js +13 -8
  13. package/build/lib/cli/driver-command.js.map +1 -1
  14. package/build/lib/cli/extension-command.d.ts +60 -43
  15. package/build/lib/cli/extension-command.d.ts.map +1 -1
  16. package/build/lib/cli/extension-command.js +133 -65
  17. package/build/lib/cli/extension-command.js.map +1 -1
  18. package/build/lib/cli/extension.d.ts +5 -5
  19. package/build/lib/cli/extension.d.ts.map +1 -1
  20. package/build/lib/cli/extension.js +1 -1
  21. package/build/lib/cli/extension.js.map +1 -1
  22. package/build/lib/cli/plugin-command.d.ts +7 -7
  23. package/build/lib/cli/plugin-command.d.ts.map +1 -1
  24. package/build/lib/cli/plugin-command.js +13 -8
  25. package/build/lib/cli/plugin-command.js.map +1 -1
  26. package/build/lib/config.d.ts +1 -1
  27. package/build/lib/config.d.ts.map +1 -1
  28. package/build/lib/config.js +3 -2
  29. package/build/lib/config.js.map +1 -1
  30. package/build/lib/constants.d.ts +8 -1
  31. package/build/lib/constants.d.ts.map +1 -1
  32. package/build/lib/constants.js +9 -2
  33. package/build/lib/constants.js.map +1 -1
  34. package/build/lib/extension/driver-config.d.ts +6 -6
  35. package/build/lib/extension/driver-config.d.ts.map +1 -1
  36. package/build/lib/extension/driver-config.js +5 -7
  37. package/build/lib/extension/driver-config.js.map +1 -1
  38. package/build/lib/extension/extension-config.d.ts +31 -10
  39. package/build/lib/extension/extension-config.d.ts.map +1 -1
  40. package/build/lib/extension/extension-config.js +44 -24
  41. package/build/lib/extension/extension-config.js.map +1 -1
  42. package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
  43. package/build/lib/extension/manifest-migrations.js +29 -13
  44. package/build/lib/extension/manifest-migrations.js.map +1 -1
  45. package/build/lib/extension/manifest.d.ts +5 -5
  46. package/build/lib/extension/manifest.d.ts.map +1 -1
  47. package/build/lib/extension/manifest.js +19 -12
  48. package/build/lib/extension/manifest.js.map +1 -1
  49. package/build/lib/main.d.ts.map +1 -1
  50. package/build/lib/main.js +3 -3
  51. package/build/lib/main.js.map +1 -1
  52. package/build/lib/schema/cli-args.d.ts +1 -1
  53. package/build/lib/schema/cli-args.d.ts.map +1 -1
  54. package/build/lib/schema/cli-args.js +1 -1
  55. package/build/lib/utils.d.ts +118 -12
  56. package/build/lib/utils.d.ts.map +1 -1
  57. package/build/lib/utils.js +8 -10
  58. package/build/lib/utils.js.map +1 -1
  59. package/build/types/manifest/index.d.ts +4 -2
  60. package/build/types/manifest/index.d.ts.map +1 -1
  61. package/build/types/manifest/index.js +4 -2
  62. package/build/types/manifest/index.js.map +1 -1
  63. package/build/types/manifest/v4.d.ts +139 -0
  64. package/build/types/manifest/v4.d.ts.map +1 -0
  65. package/build/types/manifest/v4.js +3 -0
  66. package/build/types/manifest/v4.js.map +1 -0
  67. package/lib/appium.js +43 -32
  68. package/lib/cli/args.js +10 -0
  69. package/lib/cli/driver-command.js +13 -8
  70. package/lib/cli/extension-command.js +146 -75
  71. package/lib/cli/extension.js +5 -5
  72. package/lib/cli/plugin-command.js +13 -8
  73. package/lib/config.js +3 -2
  74. package/lib/constants.js +9 -1
  75. package/lib/extension/driver-config.js +5 -8
  76. package/lib/extension/extension-config.js +42 -15
  77. package/lib/extension/manifest-migrations.js +31 -15
  78. package/lib/extension/manifest.js +26 -19
  79. package/lib/main.js +7 -4
  80. package/lib/schema/cli-args.js +1 -1
  81. package/lib/utils.js +8 -10
  82. package/package.json +11 -11
  83. package/scripts/autoinstall-extensions.js +23 -0
  84. package/types/manifest/index.ts +4 -3
  85. package/types/manifest/v4.ts +161 -0
@@ -1,15 +1,15 @@
1
1
  import _ from 'lodash';
2
- import ExtensionCommand from './extension-command';
2
+ import ExtensionCliCommand from './extension-command';
3
3
  import {KNOWN_DRIVERS} from '../constants';
4
4
  import '@colors/colors';
5
5
 
6
6
  const REQ_DRIVER_FIELDS = ['driverName', 'automationName', 'platformNames', 'mainClass'];
7
7
 
8
8
  /**
9
- * @extends {ExtensionCommand<DriverType>}
9
+ * @extends {ExtensionCliCommand<DriverType>}
10
10
  */
11
11
 
12
- export default class DriverCommand extends ExtensionCommand {
12
+ export default class DriverCliCommand extends ExtensionCliCommand {
13
13
  /**
14
14
  * @param {import('./extension-command').ExtensionCommandOptions<DriverType>} opts
15
15
  */
@@ -58,7 +58,12 @@ export default class DriverCommand extends ExtensionCommand {
58
58
  * @return {Promise<import('./extension-command').RunOutput>}
59
59
  */
60
60
  async run({driver, scriptName, extraArgs}) {
61
- return await super._run({installSpec: driver, scriptName, extraArgs});
61
+ return await super._run({
62
+ installSpec: driver,
63
+ scriptName,
64
+ extraArgs,
65
+ bufferOutput: this.isJsonOutput,
66
+ });
62
67
  }
63
68
 
64
69
  /**
@@ -115,7 +120,7 @@ export default class DriverCommand extends ExtensionCommand {
115
120
  */
116
121
 
117
122
  /**
118
- * Options for {@linkcode DriverCommand.install}
123
+ * Options for {@linkcode DriverCliCommand.install}
119
124
  * @typedef DriverInstallOpts
120
125
  * @property {string} driver - the name or spec of a driver to install
121
126
  * @property {InstallType} installType - how to install this driver. One of the INSTALL_TYPES
@@ -127,20 +132,20 @@ export default class DriverCommand extends ExtensionCommand {
127
132
  */
128
133
 
129
134
  /**
130
- * Options for {@linkcode DriverCommand.uninstall}
135
+ * Options for {@linkcode DriverCliCommand.uninstall}
131
136
  * @typedef DriverUninstallOpts
132
137
  * @property {string} driver - the name or spec of a driver to uninstall
133
138
  */
134
139
 
135
140
  /**
136
- * Options for {@linkcode DriverCommand.update}
141
+ * Options for {@linkcode DriverCliCommand.update}
137
142
  * @typedef DriverUpdateOpts
138
143
  * @property {string} driver - the name of the driver to update
139
144
  * @property {boolean} unsafe - if true, will perform unsafe updates past major revision boundaries
140
145
  */
141
146
 
142
147
  /**
143
- * Options for {@linkcode DriverCommand.run}.
148
+ * Options for {@linkcode DriverCliCommand.run}.
144
149
  * @typedef DriverRunOptions
145
150
  * @property {string} driver - name of the driver to run a script from
146
151
  * @property {string} scriptName - name of the script to run
@@ -4,14 +4,17 @@ import _ from 'lodash';
4
4
  import path from 'path';
5
5
  import {npm, util, env, console} from '@appium/support';
6
6
  import {spinWith, RingBuffer} from './utils';
7
- import {SubProcess} from 'teen_process';
8
7
  import {
9
8
  INSTALL_TYPE_NPM,
10
9
  INSTALL_TYPE_GIT,
11
10
  INSTALL_TYPE_GITHUB,
12
11
  INSTALL_TYPE_LOCAL,
12
+ INSTALL_TYPE_DEV,
13
13
  } from '../extension/extension-config';
14
+ import {SubProcess} from 'teen_process';
14
15
  import {packageDidChange} from '../extension/package-changed';
16
+ import {spawn} from 'child_process';
17
+ import {inspect} from 'node:util';
15
18
 
16
19
  const UPDATE_ALL = 'installed';
17
20
 
@@ -31,7 +34,7 @@ function receiptToManifest(receipt) {
31
34
  /**
32
35
  * @template {ExtensionType} ExtType
33
36
  */
34
- class ExtensionCommand {
37
+ class ExtensionCliCommand {
35
38
  /**
36
39
  * This is the `DriverConfig` or `PluginConfig`, depending on `ExtType`.
37
40
  * @type {ExtensionConfig<ExtType>}
@@ -98,41 +101,40 @@ class ExtensionCommand {
98
101
 
99
102
  /**
100
103
  * List extensions
101
- *
104
+ * @template {ExtensionType} ExtType
102
105
  * @param {ListOptions} opts
103
- * @return {Promise<ExtensionListData>} map of extension names to extension data
106
+ * @return {Promise<ExtensionList<ExtType>>} map of extension names to extension data
104
107
  */
105
- async list({showInstalled, showUpdates}) {
106
- const lsMsg = `Listing ${showInstalled ? 'installed' : 'available'} ${this.type}s`;
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
+ }
107
113
  const installedNames = Object.keys(this.config.installedExtensions);
108
114
  const knownNames = Object.keys(this.knownExtensions);
109
- const exts = [...installedNames, ...knownNames].reduce(
110
- (acc, name) => {
111
- if (!acc[name]) {
112
- if (installedNames.includes(name)) {
113
- acc[name] = {
114
- ...this.config.installedExtensions[name],
115
- installed: true,
116
- };
117
- } else if (!showInstalled) {
118
- acc[name] = {pkgName: this.knownExtensions[name], installed: false};
119
- }
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
+ });
120
127
  }
121
- return acc;
122
- },
123
- /**
124
- * This accumulator contains either {@linkcode UninstalledExtensionLIstData} _or_
125
- * {@linkcode InstalledExtensionListData} without upgrade information (which is added by the below code block)
126
- * @type {Record<string,Partial<InstalledExtensionListData>|UninstalledExtensionListData>}
127
- */ ({})
128
- );
128
+ }
129
+ return acc;
130
+ }, /** @type {ExtensionList<ExtType>} */ ({}));
129
131
 
130
132
  // if we want to show whether updates are available, put that behind a spinner
131
133
  await spinWith(this.isJsonOutput, lsMsg, async () => {
132
134
  if (!showUpdates) {
133
135
  return;
134
136
  }
135
- for (const [ext, data] of _.toPairs(exts)) {
137
+ for (const [ext, data] of _.toPairs(listData)) {
136
138
  if (!data.installed || data.installType !== INSTALL_TYPE_NPM) {
137
139
  // don't need to check for updates on exts that aren't installed
138
140
  // also don't need to check for updates on non-npm exts
@@ -149,7 +151,12 @@ class ExtensionCommand {
149
151
  }
150
152
  });
151
153
 
152
- const listData = /** @type {ExtensionListData} */ (exts);
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);
153
160
 
154
161
  // if we're just getting the data, short circuit return here since we don't need to do any
155
162
  // formatting logic
@@ -157,12 +164,16 @@ class ExtensionCommand {
157
164
  return listData;
158
165
  }
159
166
 
167
+ if (verbose) {
168
+ this.log.log(inspect(listData, {colors: true, depth: null}));
169
+ return listData;
170
+ }
160
171
  for (const [name, data] of _.toPairs(listData)) {
161
172
  let installTxt = ' [not installed]'.grey;
162
173
  let updateTxt = '';
163
174
  let upToDateTxt = '';
164
175
  let unsafeUpdateTxt = '';
165
- if (data.installed) {
176
+ if (extIsInstalled(data)) {
166
177
  const {
167
178
  installType,
168
179
  installSpec,
@@ -181,8 +192,11 @@ class ExtensionCommand {
181
192
  case INSTALL_TYPE_LOCAL:
182
193
  typeTxt = `(linked from ${installSpec})`.magenta;
183
194
  break;
195
+ case INSTALL_TYPE_DEV:
196
+ typeTxt = '(dev mode)';
197
+ break;
184
198
  default:
185
- typeTxt = '(NPM)';
199
+ typeTxt = '(npm)';
186
200
  }
187
201
  installTxt = `@${version.yellow} ${('[installed ' + typeTxt + ']').green}`;
188
202
 
@@ -512,7 +526,12 @@ class ExtensionCommand {
512
526
  `Can't uninstall ${this.type} '${installSpec}'; it is not installed`
513
527
  );
514
528
  }
515
- const pkgName = this.config.installedExtensions[installSpec].pkgName;
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;
516
535
  await npm.uninstallPackage(this.config.appiumHome, pkgName);
517
536
  await this.config.removeExtension(installSpec);
518
537
  this.log.ok(`Successfully uninstalled ${this.type} '${installSpec}'`.green);
@@ -660,17 +679,34 @@ class ExtensionCommand {
660
679
  }
661
680
 
662
681
  /**
663
- * Runs a script cached inside the "scripts" field under "appium"
664
- * inside of the driver/plugins "package.json" file. Will throw
665
- * an error if the driver/plugin does not contain a "scripts" field
666
- * underneath the "appium" field in its package.json, if the
667
- * "scripts" field is not a plain object, or if the scriptName is
668
- * not found within "scripts" object.
682
+ * Just wraps {@linkcode child_process.spawn} with some default options
683
+ *
684
+ * @param {string} cwd - CWD
685
+ * @param {string} script - Path to script
686
+ * @param {string[]} args - Extra args for script
687
+ * @param {import('child_process').SpawnOptions} opts - Options
688
+ * @returns {import('node:child_process').ChildProcess}
689
+ */
690
+ _runUnbuffered(cwd, script, args = [], opts = {}) {
691
+ return spawn(process.execPath, [script, ...args], {
692
+ cwd,
693
+ stdio: 'inherit',
694
+ ...opts,
695
+ });
696
+ }
697
+
698
+ /**
699
+ * Runs a script cached inside the `scripts` field under `appium`
700
+ * inside of the extension's `package.json` file. Will throw
701
+ * an error if the driver/plugin does not contain a `scripts` field
702
+ * underneath the `appium` field in its `package.json`, if the
703
+ * `scripts` field is not a plain object, or if the `scriptName` is
704
+ * not found within `scripts` object.
669
705
  *
670
706
  * @param {RunOptions} opts
671
707
  * @return {Promise<RunOutput>}
672
708
  */
673
- async _run({installSpec, scriptName, extraArgs = []}) {
709
+ async _run({installSpec, scriptName, extraArgs = [], bufferOutput = false}) {
674
710
  if (!this.config.isInstalled(installSpec)) {
675
711
  throw this._createFatalError(`The ${this.type} "${installSpec}" is not installed`);
676
712
  }
@@ -699,35 +735,65 @@ class ExtensionCommand {
699
735
  );
700
736
  }
701
737
 
702
- const runner = new SubProcess(process.execPath, [extScripts[scriptName], ...extraArgs], {
703
- cwd: this.config.getInstallPath(installSpec),
704
- });
738
+ if (bufferOutput) {
739
+ const runner = new SubProcess(process.execPath, [extScripts[scriptName], ...extraArgs], {
740
+ cwd: this.config.getInstallPath(installSpec),
741
+ });
705
742
 
706
- const output = new RingBuffer(50);
743
+ const output = new RingBuffer(50);
707
744
 
708
- runner.on('stream-line', (line) => {
709
- output.enqueue(line);
710
- this.log.log(line);
711
- });
745
+ runner.on('stream-line', (line) => {
746
+ output.enqueue(line);
747
+ this.log.log(line);
748
+ });
712
749
 
713
- await runner.start(0);
750
+ await runner.start(0);
751
+
752
+ try {
753
+ await runner.join();
754
+ this.log.ok(`${scriptName} successfully ran`.green);
755
+ return {output: output.getBuff()};
756
+ } catch (err) {
757
+ this.log.error(`Encountered an error when running '${scriptName}': ${err.message}`.red);
758
+ return {error: err.message, output: output.getBuff()};
759
+ }
760
+ }
714
761
 
715
762
  try {
716
- await runner.join();
763
+ await new B((resolve, reject) => {
764
+ this._runUnbuffered(
765
+ this.config.getInstallPath(installSpec),
766
+ extScripts[scriptName],
767
+ extraArgs
768
+ )
769
+ .on('error', (err) => {
770
+ // generally this is of the "I can't find the script" variety.
771
+ // this is a developer bug: the extension is pointing to a script that is not where the
772
+ // developer said it would be (in `appium.scripts` of the extension's `package.json`)
773
+ reject(err);
774
+ })
775
+ .on('close', (code) => {
776
+ if (code === 0) {
777
+ resolve();
778
+ } else {
779
+ reject(new Error(`Script "${scriptName}" exited with code ${code}`));
780
+ }
781
+ });
782
+ });
717
783
  this.log.ok(`${scriptName} successfully ran`.green);
718
- return {output: output.getBuff()};
784
+ return {};
719
785
  } catch (err) {
720
786
  this.log.error(`Encountered an error when running '${scriptName}': ${err.message}`.red);
721
- return {error: err.message, output: output.getBuff()};
787
+ return {error: err.message};
722
788
  }
723
789
  }
724
790
  }
725
791
 
726
- export default ExtensionCommand;
727
- export {ExtensionCommand};
792
+ export default ExtensionCliCommand;
793
+ export {ExtensionCliCommand as ExtensionCommand};
728
794
 
729
795
  /**
730
- * Options for the {@linkcode ExtensionCommand} constructor
796
+ * Options for the {@linkcode ExtensionCliCommand} constructor
731
797
  * @template {ExtensionType} ExtType
732
798
  * @typedef ExtensionCommandOptions
733
799
  * @property {ExtensionConfig<ExtType>} config - the `DriverConfig` or `PluginConfig` instance used for this command
@@ -735,14 +801,15 @@ export {ExtensionCommand};
735
801
  */
736
802
 
737
803
  /**
738
- * Extra stuff about extensions; used indirectly by {@linkcode ExtensionCommand.list}.
804
+ * Extra stuff about extensions; used indirectly by {@linkcode ExtensionCliCommand.list}.
739
805
  *
740
- * @typedef ExtensionMetadata
806
+ * @typedef ExtensionListMetadata
741
807
  * @property {boolean} installed - If `true`, the extension is installed
742
- * @property {string?} updateVersion - If the extension is installed, the version it can be updated to
743
- * @property {string?} unsafeUpdateVersion - Same as above, but a major version bump
744
808
  * @property {boolean} upToDate - If the extension is installed and the latest
745
- * @property {string?} updateError - Update check error message (if present)
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
746
813
  */
747
814
 
748
815
  /**
@@ -782,72 +849,75 @@ export {ExtensionCommand};
782
849
  */
783
850
 
784
851
  /**
785
- * Possible return value for {@linkcode ExtensionCommand.list}
786
- * @typedef {Partial<InstalledExtensionListData> & {pkgName: string, installed: false}} UninstalledExtensionListData
852
+ * Possible return value for {@linkcode ExtensionCliCommand.list}
853
+ * @template {ExtensionType} ExtType
854
+ * @typedef {Partial<ExtManifest<ExtType>> & Partial<ExtensionListMetadata>} ExtensionListData
787
855
  */
788
856
 
789
857
  /**
790
- * Possible return value for {@linkcode ExtensionCommand.list}
791
- * @typedef {import('appium/types').InternalMetadata & ExtensionMetadata} InstalledExtensionListData
858
+ * @template {ExtensionType} ExtType
859
+ * @typedef {ExtManifest<ExtType> & ExtensionListMetadata} InstalledExtensionListData
792
860
  */
793
861
 
794
862
  /**
795
- * Return value of {@linkcode ExtensionCommand.list}.
796
- * @typedef {Record<string,InstalledExtensionListData|UninstalledExtensionListData>} ExtensionListData
863
+ * Return value of {@linkcode ExtensionCliCommand.list}.
864
+ * @template {ExtensionType} ExtType
865
+ * @typedef {Record<string,ExtensionListData<ExtType>>} ExtensionList
797
866
  */
798
867
 
799
868
  /**
800
- * Options for {@linkcode ExtensionCommand._run}.
869
+ * Options for {@linkcode ExtensionCliCommand._run}.
801
870
  * @typedef RunOptions
802
871
  * @property {string} installSpec - name of the extension to run a script from
803
872
  * @property {string} scriptName - name of the script to run
804
873
  * @property {string[]} [extraArgs] - arguments to pass to the script
874
+ * @property {boolean} [bufferOutput] - if true, will buffer the output of the script and return it
805
875
  */
806
876
 
807
877
  /**
808
- * Return value of {@linkcode ExtensionCommand._run}
878
+ * Return value of {@linkcode ExtensionCliCommand._run}
809
879
  *
810
880
  * @typedef RunOutput
811
881
  * @property {string} [error] - error message if script ran unsuccessfully, otherwise undefined
812
- * @property {string[]} output - script output
882
+ * @property {string[]} [output] - script output if `bufferOutput` was `true` in {@linkcode RunOptions}
813
883
  */
814
884
 
815
885
  /**
816
- * Options for {@linkcode ExtensionCommand._update}.
886
+ * Options for {@linkcode ExtensionCliCommand._update}.
817
887
  * @typedef ExtensionUpdateOpts
818
888
  * @property {string} installSpec - the name of the extension to update
819
889
  * @property {boolean} unsafe - if true, will perform unsafe updates past major revision boundaries
820
890
  */
821
891
 
822
892
  /**
823
- * Return value of {@linkcode ExtensionCommand._update}.
893
+ * Return value of {@linkcode ExtensionCliCommand._update}.
824
894
  * @typedef ExtensionUpdateResult
825
895
  * @property {Record<string,Error>} errors - map of ext names to error objects
826
896
  * @property {Record<string,UpdateReport>} updates - map of ext names to {@linkcode UpdateReport}s
827
897
  */
828
898
 
829
899
  /**
830
- * Part of result of {@linkcode ExtensionCommand._update}.
900
+ * Part of result of {@linkcode ExtensionCliCommand._update}.
831
901
  * @typedef UpdateReport
832
902
  * @property {string} from - version the extension was updated from
833
903
  * @property {string} to - version the extension was updated to
834
904
  */
835
905
 
836
906
  /**
837
- * Options for {@linkcode ExtensionCommand._uninstall}.
907
+ * Options for {@linkcode ExtensionCliCommand._uninstall}.
838
908
  * @typedef UninstallOpts
839
909
  * @property {string} installSpec - the name or spec of an extension to uninstall
840
910
  */
841
911
 
842
912
  /**
843
- * Used by {@linkcode ExtensionCommand.getPostInstallText}
913
+ * Used by {@linkcode ExtensionCliCommand.getPostInstallText}
844
914
  * @typedef ExtensionArgs
845
915
  * @property {string} extName - the name of an extension
846
916
  * @property {object} extData - the data for an installed extension
847
917
  */
848
918
 
849
919
  /**
850
- * Options for {@linkcode ExtensionCommand.installViaNpm}
920
+ * Options for {@linkcode ExtensionCliCommand.installViaNpm}
851
921
  * @typedef InstallViaNpmArgs
852
922
  * @property {string} installSpec - the name or spec of an extension to install
853
923
  * @property {string} pkgName - the NPM package name of the extension
@@ -856,7 +926,7 @@ export {ExtensionCommand};
856
926
  */
857
927
 
858
928
  /**
859
- * Object returned by {@linkcode ExtensionCommand.checkForExtensionUpdate}
929
+ * Object returned by {@linkcode ExtensionCliCommand.checkForExtensionUpdate}
860
930
  * @typedef PossibleUpdates
861
931
  * @property {string} current - current version
862
932
  * @property {string?} safeUpdate - version we can safely update to if it exists, or null
@@ -864,7 +934,7 @@ export {ExtensionCommand};
864
934
  */
865
935
 
866
936
  /**
867
- * Options for {@linkcode ExtensionCommand._install}
937
+ * Options for {@linkcode ExtensionCliCommand._install}
868
938
  * @typedef InstallOpts
869
939
  * @property {string} installSpec - the name or spec of an extension to install
870
940
  * @property {InstallType} installType - how to install this extension. One of the INSTALL_TYPES
@@ -880,10 +950,11 @@ export {ExtensionCommand};
880
950
  * @typedef ListOptions
881
951
  * @property {boolean} showInstalled - whether should show only installed extensions
882
952
  * @property {boolean} showUpdates - whether should show available updates
953
+ * @property {boolean} [verbose] - whether to show additional data from the extension
883
954
  */
884
955
 
885
956
  /**
886
- * Opts for {@linkcode ExtensionCommand.getInstallationReceipt}
957
+ * Opts for {@linkcode ExtensionCliCommand.getInstallationReceipt}
887
958
  * @template {ExtensionType} ExtType
888
959
  * @typedef GetInstallationReceiptOpts
889
960
  * @property {string} installPath
@@ -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 DriverCommand from './driver-command';
5
- import PluginCommand from './plugin-command';
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]: DriverCommand,
11
- [PLUGIN_TYPE]: PluginCommand,
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<DriverCommand> : ExtType extends PluginType ? Class<PluginCommand> : never} ExtCommand
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 ExtensionCommand from './extension-command';
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 {ExtensionCommand<PluginType>}
8
+ * @extends {ExtensionCliCommand<PluginType>}
9
9
  */
10
- export default class PluginCommand extends ExtensionCommand {
10
+ export default class PluginCliCommand extends ExtensionCliCommand {
11
11
  /**
12
12
  *
13
13
  * @param {import('./extension-command').ExtensionCommandOptions<PluginType>} opts
@@ -57,7 +57,12 @@ export default class PluginCommand extends ExtensionCommand {
57
57
  * @returns {Promise<import('./extension-command').RunOutput>}
58
58
  */
59
59
  async run({plugin, scriptName, extraArgs}) {
60
- return await super._run({installSpec: plugin, scriptName, extraArgs});
60
+ return await super._run({
61
+ installSpec: plugin,
62
+ scriptName,
63
+ extraArgs,
64
+ bufferOutput: this.isJsonOutput,
65
+ });
61
66
  }
62
67
 
63
68
  /**
@@ -105,7 +110,7 @@ export default class PluginCommand extends ExtensionCommand {
105
110
  */
106
111
 
107
112
  /**
108
- * Options for {@linkcode PluginCommand.install}
113
+ * Options for {@linkcode PluginCliCommand.install}
109
114
  * @typedef PluginInstallOpts
110
115
  * @property {string} plugin - the name or spec of a plugin to install
111
116
  * @property {InstallType} installType - how to install this plugin. One of the INSTALL_TYPES
@@ -117,20 +122,20 @@ export default class PluginCommand extends ExtensionCommand {
117
122
  */
118
123
 
119
124
  /**
120
- * Options for {@linkcode PluginCommand.uninstall}
125
+ * Options for {@linkcode PluginCliCommand.uninstall}
121
126
  * @typedef PluginUninstallOpts
122
127
  * @property {string} plugin - the name or spec of a plugin to uninstall
123
128
  */
124
129
 
125
130
  /**
126
- * Options for {@linkcode PluginCommand.update}
131
+ * Options for {@linkcode PluginCliCommand.update}
127
132
  * @typedef PluginUpdateOpts
128
133
  * @property {string} plugin - the name of the plugin to update
129
134
  * @property {boolean} unsafe - if true, will perform unsafe updates past major revision boundaries
130
135
  */
131
136
 
132
137
  /**
133
- * Options for {@linkcode PluginCommand.run}.
138
+ * Options for {@linkcode PluginCliCommand.run}.
134
139
  * @typedef PluginRunOptions
135
140
  * @property {string} plugin - name of the plugin to run a script from
136
141
  * @property {string} scriptName - name of the script to run
package/lib/config.js CHANGED
@@ -10,8 +10,9 @@ import {getDefaultsForSchema, getAllArgSpecs} from './schema/schema';
10
10
  const npmPackage = fs.readPackageJsonFrom(__dirname);
11
11
 
12
12
  const APPIUM_VER = npmPackage.version;
13
- const MIN_NODE_VERSION = npmPackage.engines.node;
14
- const MIN_NPM_VERSION = npmPackage.engines.npm;
13
+ const ENGINES = /** @type {Record<string,string>} */ (npmPackage.engines);
14
+ const MIN_NODE_VERSION = ENGINES.node;
15
+ const MIN_NPM_VERSION = ENGINES.npm;
15
16
 
16
17
  const GIT_META_ROOT = '.git';
17
18
  const GIT_BINARY = `git${system.isWindows() ? '.exe' : ''}`;
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 = 3;
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
- */