web-ext 7.2.0 → 7.3.1

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 (70) hide show
  1. package/README.md +2 -2
  2. package/lib/cmd/build.js +18 -36
  3. package/lib/cmd/build.js.map +1 -1
  4. package/lib/cmd/docs.js +1 -0
  5. package/lib/cmd/docs.js.map +1 -1
  6. package/lib/cmd/index.js +3 -5
  7. package/lib/cmd/index.js.map +1 -1
  8. package/lib/cmd/lint.js +28 -17
  9. package/lib/cmd/lint.js.map +1 -1
  10. package/lib/cmd/run.js +19 -23
  11. package/lib/cmd/run.js.map +1 -1
  12. package/lib/cmd/sign.js +80 -47
  13. package/lib/cmd/sign.js.map +1 -1
  14. package/lib/config.js +18 -29
  15. package/lib/config.js.map +1 -1
  16. package/lib/errors.js +8 -18
  17. package/lib/errors.js.map +1 -1
  18. package/lib/extension-runners/base.js +2 -0
  19. package/lib/extension-runners/base.js.map +1 -1
  20. package/lib/extension-runners/chromium.js +36 -62
  21. package/lib/extension-runners/chromium.js.map +1 -1
  22. package/lib/extension-runners/firefox-android.js +65 -102
  23. package/lib/extension-runners/firefox-android.js.map +1 -1
  24. package/lib/extension-runners/firefox-desktop.js +29 -42
  25. package/lib/extension-runners/firefox-desktop.js.map +1 -1
  26. package/lib/extension-runners/index.js +33 -46
  27. package/lib/extension-runners/index.js.map +1 -1
  28. package/lib/firefox/index.js +59 -52
  29. package/lib/firefox/index.js.map +1 -1
  30. package/lib/firefox/package-identifiers.js +2 -0
  31. package/lib/firefox/package-identifiers.js.map +1 -1
  32. package/lib/firefox/preferences.js +14 -15
  33. package/lib/firefox/preferences.js.map +1 -1
  34. package/lib/firefox/rdp-client.js +16 -64
  35. package/lib/firefox/rdp-client.js.map +1 -1
  36. package/lib/firefox/remote.js +15 -30
  37. package/lib/firefox/remote.js.map +1 -1
  38. package/lib/main.js +4 -2
  39. package/lib/main.js.map +1 -1
  40. package/lib/program.js +74 -76
  41. package/lib/program.js.map +1 -1
  42. package/lib/util/adb.js +33 -63
  43. package/lib/util/adb.js.map +1 -1
  44. package/lib/util/artifacts.js +3 -5
  45. package/lib/util/artifacts.js.map +1 -1
  46. package/lib/util/desktop-notifier.js +1 -0
  47. package/lib/util/desktop-notifier.js.map +1 -1
  48. package/lib/util/file-exists.js +1 -2
  49. package/lib/util/file-exists.js.map +1 -1
  50. package/lib/util/file-filter.js +17 -19
  51. package/lib/util/file-filter.js.map +1 -1
  52. package/lib/util/is-directory.js +2 -1
  53. package/lib/util/is-directory.js.map +1 -1
  54. package/lib/util/logger.js +7 -12
  55. package/lib/util/logger.js.map +1 -1
  56. package/lib/util/manifest.js +6 -13
  57. package/lib/util/manifest.js.map +1 -1
  58. package/lib/util/promisify.js +7 -3
  59. package/lib/util/promisify.js.map +1 -1
  60. package/lib/util/stdin.js +2 -0
  61. package/lib/util/stdin.js.map +1 -1
  62. package/lib/util/submit-addon.js +288 -0
  63. package/lib/util/submit-addon.js.map +1 -0
  64. package/lib/util/temp-dir.js +8 -18
  65. package/lib/util/temp-dir.js.map +1 -1
  66. package/lib/util/updates.js +1 -1
  67. package/lib/util/updates.js.map +1 -1
  68. package/lib/watcher.js +14 -9
  69. package/lib/watcher.js.map +1 -1
  70. package/package.json +16 -14
package/lib/program.js CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  import os from 'os';
2
3
  import path from 'path';
3
4
  import { readFileSync } from 'fs';
@@ -12,11 +13,10 @@ import { coerceCLICustomPreference } from './firefox/preferences.js';
12
13
  import { checkForUpdates as defaultUpdateChecker } from './util/updates.js';
13
14
  import { discoverConfigFiles as defaultConfigDiscovery, loadJSConfigFile as defaultLoadJSConfigFile, applyConfigToArgv as defaultApplyConfigToArgv } from './config.js';
14
15
  const log = createLogger(import.meta.url);
15
- const envPrefix = 'WEB_EXT'; // Default to "development" (the value actually assigned will be interpolated
16
+ const envPrefix = 'WEB_EXT';
17
+ // Default to "development" (the value actually assigned will be interpolated
16
18
  // by babel-plugin-transform-inline-environment-variables).
17
-
18
19
  const defaultGlobalEnv = "production" || 'development';
19
-
20
20
  /*
21
21
  * The command line program.
22
22
  */
@@ -29,14 +29,15 @@ export class Program {
29
29
  // NOTE: process.argv.slice(2) removes the path to node and web-ext
30
30
  // executables from the process.argv array.
31
31
  argv = argv || process.argv.slice(2);
32
- this.programArgv = argv; // NOTE: always initialize yargs explicitly with the package dir
32
+ this.programArgv = argv;
33
+
34
+ // NOTE: always initialize yargs explicitly with the package dir
33
35
  // to avoid side-effects due to yargs looking for its configuration
34
36
  // section from a package.json file stored in an arbitrary directory
35
37
  // (e.g. in tests yargs would end up loading yargs config from the
36
38
  // mocha package.json). web-ext package.json doesn't contain any yargs
37
39
  // section as it is deprecated and we configure yargs using
38
40
  // yargs.parserConfiguration. See web-ext#469 for rationale.
39
-
40
41
  const yargsInstance = yargs(argv, absolutePackageDir);
41
42
  this.absolutePackageDir = absolutePackageDir;
42
43
  this.verboseEnabled = false;
@@ -50,35 +51,34 @@ export class Program {
50
51
  this.commands = {};
51
52
  this.options = {};
52
53
  }
53
-
54
54
  command(name, description, executor, commandOptions = {}) {
55
55
  this.options[camelCase(name)] = commandOptions;
56
56
  this.yargs.command(name, description, yargsForCmd => {
57
57
  if (!commandOptions) {
58
58
  return;
59
59
  }
60
-
61
- return yargsForCmd // Make sure the user does not add any extra commands. For example,
60
+ return yargsForCmd
61
+ // Make sure the user does not add any extra commands. For example,
62
62
  // this would be a mistake because lint does not accept arguments:
63
63
  // web-ext lint ./src/path/to/file.js
64
- .demandCommand(0, 0, undefined, 'This command does not take any arguments').strict().exitProcess(this.shouldExitProgram) // Calling env() will be unnecessary after
64
+ .demandCommand(0, 0, undefined, 'This command does not take any arguments').strict().exitProcess(this.shouldExitProgram)
65
+ // Calling env() will be unnecessary after
65
66
  // https://github.com/yargs/yargs/issues/486 is fixed
66
67
  .env(envPrefix).options(commandOptions);
67
68
  });
68
69
  this.commands[name] = executor;
69
70
  return this;
70
71
  }
71
-
72
72
  setGlobalOptions(options) {
73
73
  // This is a convenience for setting global options.
74
74
  // An option is only global (i.e. available to all sub commands)
75
75
  // with the `global` flag so this makes sure every option has it.
76
- this.options = { ...this.options,
76
+ this.options = {
77
+ ...this.options,
77
78
  ...options
78
79
  };
79
80
  Object.keys(options).forEach(key => {
80
81
  options[key].global = true;
81
-
82
82
  if (options[key].demandOption === undefined) {
83
83
  // By default, all options should be "demanded" otherwise
84
84
  // yargs.strict() will think they are missing when declared.
@@ -88,19 +88,17 @@ export class Program {
88
88
  this.yargs.options(options);
89
89
  return this;
90
90
  }
91
-
92
91
  enableVerboseMode(logStream, version) {
93
92
  if (this.verboseEnabled) {
94
93
  return;
95
94
  }
96
-
97
95
  logStream.makeVerbose();
98
96
  log.info('Version:', version);
99
97
  this.verboseEnabled = true;
100
- } // Retrieve the yargs argv object and apply any further fix needed
101
- // on the output of the yargs options parsing.
102
-
98
+ }
103
99
 
100
+ // Retrieve the yargs argv object and apply any further fix needed
101
+ // on the output of the yargs options parsing.
104
102
  getArguments() {
105
103
  // To support looking up required parameters via config files, we need to
106
104
  // temporarily disable the requiredArguments validation. Otherwise yargs
@@ -114,93 +112,81 @@ export class Program {
114
112
  const validationInstance = this.yargs.getInternalMethods().getValidationInstance();
115
113
  const {
116
114
  requiredArguments
117
- } = validationInstance; // Initialize demandedOptions (which is going to be set to an object with one
115
+ } = validationInstance;
116
+ // Initialize demandedOptions (which is going to be set to an object with one
118
117
  // property for each mandatory global options, then the arrow function below
119
118
  // will receive as its demandedOptions parameter a new one that also includes
120
119
  // all mandatory options for the sub command selected).
121
-
122
120
  this.demandedOptions = this.yargs.getDemandedOptions();
123
-
124
121
  validationInstance.requiredArguments = (args, demandedOptions) => {
125
122
  this.demandedOptions = demandedOptions;
126
123
  };
127
-
128
124
  let argv;
129
-
130
125
  try {
131
126
  argv = this.yargs.argv;
132
127
  } catch (err) {
133
128
  if (err.name === 'YError' && err.message.startsWith('Unknown argument: ')) {
134
129
  throw new UsageError(err.message);
135
130
  }
136
-
137
131
  throw err;
138
132
  }
133
+ validationInstance.requiredArguments = requiredArguments;
139
134
 
140
- validationInstance.requiredArguments = requiredArguments; // Yargs boolean options doesn't define the no* counterpart
135
+ // Yargs boolean options doesn't define the no* counterpart
141
136
  // with negate-boolean on Yargs 15. Define as expected by the
142
137
  // web-ext execute method.
143
-
144
138
  if (argv.configDiscovery != null) {
145
139
  argv.noConfigDiscovery = !argv.configDiscovery;
146
140
  }
147
-
148
141
  if (argv.reload != null) {
149
142
  argv.noReload = !argv.reload;
150
- } // Yargs doesn't accept --no-input as a valid option if there isn't a
143
+ }
144
+
145
+ // Yargs doesn't accept --no-input as a valid option if there isn't a
151
146
  // --input option defined to be negated, to fix that the --input is
152
147
  // defined and hidden from the yargs help output and we define here
153
148
  // the negated argument name that we expect to be set in the parsed
154
149
  // arguments (and fix https://github.com/mozilla/web-ext/issues/1860).
155
-
156
-
157
150
  if (argv.input != null) {
158
151
  argv.noInput = !argv.input;
159
- } // Replacement for the "requiresArg: true" parameter until the following bug
160
- // is fixed: https://github.com/yargs/yargs/issues/1098
161
-
152
+ }
162
153
 
154
+ // Replacement for the "requiresArg: true" parameter until the following bug
155
+ // is fixed: https://github.com/yargs/yargs/issues/1098
163
156
  if (argv.ignoreFiles && !argv.ignoreFiles.length) {
164
157
  throw new UsageError('Not enough arguments following: ignore-files');
165
158
  }
166
-
167
159
  if (argv.startUrl && !argv.startUrl.length) {
168
160
  throw new UsageError('Not enough arguments following: start-url');
169
161
  }
170
-
171
162
  if (Array.isArray(argv.firefoxPreview) && !argv.firefoxPreview.length) {
172
163
  argv.firefoxPreview = ['mv3'];
173
164
  }
174
-
175
165
  return argv;
176
- } // getArguments() disables validation of required parameters, to allow us to
166
+ }
167
+
168
+ // getArguments() disables validation of required parameters, to allow us to
177
169
  // read parameters from config files first. Before the program continues, it
178
170
  // must call checkRequiredArguments() to ensure that required parameters are
179
171
  // defined (in the CLI or in a config file).
180
-
181
-
182
172
  checkRequiredArguments(adjustedArgv) {
183
173
  const validationInstance = this.yargs.getInternalMethods().getValidationInstance();
184
174
  validationInstance.requiredArguments(adjustedArgv, this.demandedOptions);
185
- } // Remove WEB_EXT_* environment vars that are not a global cli options
186
- // or an option supported by the current command (See #793).
187
-
175
+ }
188
176
 
177
+ // Remove WEB_EXT_* environment vars that are not a global cli options
178
+ // or an option supported by the current command (See #793).
189
179
  cleanupProcessEnvConfigs(systemProcess) {
190
180
  const cmd = yargsParser(this.programArgv)._[0];
191
-
192
181
  const env = systemProcess.env || {};
193
-
194
182
  const toOptionKey = k => decamelize(camelCase(k.replace(envPrefix, '')), {
195
183
  separator: '-'
196
184
  });
197
-
198
185
  if (cmd) {
199
186
  Object.keys(env).filter(k => k.startsWith(envPrefix)).forEach(k => {
200
187
  const optKey = toOptionKey(k);
201
188
  const globalOpt = this.options[optKey];
202
189
  const cmdOpt = this.options[cmd] && this.options[cmd][optKey];
203
-
204
190
  if (!globalOpt && !cmdOpt) {
205
191
  log.debug(`Environment ${k} not supported by web-ext ${cmd}`);
206
192
  delete env[k];
@@ -208,7 +194,6 @@ export class Program {
208
194
  });
209
195
  }
210
196
  }
211
-
212
197
  async execute({
213
198
  checkForUpdates = defaultUpdateChecker,
214
199
  systemProcess = process,
@@ -227,31 +212,25 @@ export class Program {
227
212
  const cmd = argv._[0];
228
213
  const version = await getVersion(this.absolutePackageDir);
229
214
  const runCommand = this.commands[cmd];
230
-
231
215
  if (argv.verbose) {
232
216
  this.enableVerboseMode(logStream, version);
233
217
  }
234
-
235
- let adjustedArgv = { ...argv
218
+ let adjustedArgv = {
219
+ ...argv
236
220
  };
237
-
238
221
  try {
239
222
  if (cmd === undefined) {
240
223
  throw new UsageError('No sub-command was specified in the args');
241
224
  }
242
-
243
225
  if (!runCommand) {
244
226
  throw new UsageError(`Unknown command: ${cmd}`);
245
227
  }
246
-
247
228
  if (globalEnv === 'production') {
248
229
  checkForUpdates({
249
230
  version
250
231
  });
251
232
  }
252
-
253
233
  const configFiles = [];
254
-
255
234
  if (argv.configDiscovery) {
256
235
  log.debug('Discovering config files. ' + 'Set --no-config-discovery to disable');
257
236
  const discoveredConfigs = await discoverConfigFiles();
@@ -259,16 +238,13 @@ export class Program {
259
238
  } else {
260
239
  log.debug('Not discovering config files');
261
240
  }
262
-
263
241
  if (argv.config) {
264
242
  configFiles.push(path.resolve(argv.config));
265
243
  }
266
-
267
244
  if (configFiles.length) {
268
245
  const niceFileList = configFiles.map(f => f.replace(process.cwd(), '.')).map(f => f.replace(os.homedir(), '~')).join(', ');
269
246
  log.info('Applying config file' + `${configFiles.length !== 1 ? 's' : ''}: ` + `${niceFileList}`);
270
247
  }
271
-
272
248
  configFiles.forEach(configFileName => {
273
249
  const configObject = loadJSConfigFile(configFileName);
274
250
  adjustedArgv = applyConfigToArgv({
@@ -279,12 +255,10 @@ export class Program {
279
255
  options: this.options
280
256
  });
281
257
  });
282
-
283
258
  if (adjustedArgv.verbose) {
284
259
  // Ensure that the verbose is enabled when specified in a config file.
285
260
  this.enableVerboseMode(logStream, version);
286
261
  }
287
-
288
262
  this.checkRequiredArguments(adjustedArgv);
289
263
  await runCommand(adjustedArgv, {
290
264
  shouldExitProgram
@@ -295,13 +269,10 @@ export class Program {
295
269
  } else {
296
270
  log.error(`\n${String(error)}\n`);
297
271
  }
298
-
299
272
  if (error.code) {
300
273
  log.error(`Error code: ${error.code}\n`);
301
274
  }
302
-
303
275
  log.debug(`Command executed: ${cmd}`);
304
-
305
276
  if (this.shouldExitProgram) {
306
277
  systemProcess.exit(1);
307
278
  } else {
@@ -309,8 +280,9 @@ export class Program {
309
280
  }
310
281
  }
311
282
  }
283
+ }
312
284
 
313
- } //A defintion of type of argument for defaultVersionGetter
285
+ //A defintion of type of argument for defaultVersionGetter
314
286
 
315
287
  export async function defaultVersionGetter(absolutePackageDir, {
316
288
  globalEnv = defaultGlobalEnv
@@ -320,22 +292,23 @@ export async function defaultVersionGetter(absolutePackageDir, {
320
292
  const packageData = readFileSync(path.join(absolutePackageDir, 'package.json'));
321
293
  return JSON.parse(packageData).version;
322
294
  } else {
323
- log.debug('Getting version from the git revision'); // This branch is only reached during development.
295
+ log.debug('Getting version from the git revision');
296
+ // This branch is only reached during development.
324
297
  // git-rev-sync is in devDependencies, and lazily imported using require.
325
298
  // This also avoids logspam from https://github.com/mozilla/web-ext/issues/1916
326
299
  // eslint-disable-next-line import/no-extraneous-dependencies
327
-
328
300
  const git = await import('git-rev-sync');
329
301
  return `${git.branch(absolutePackageDir)}-${git.long(absolutePackageDir)}`;
330
302
  }
331
- } // TODO: add pipes to Flow type after https://github.com/facebook/flow/issues/2405 is fixed
303
+ }
304
+
305
+ // TODO: add pipes to Flow type after https://github.com/facebook/flow/issues/2405 is fixed
332
306
 
333
307
  export function throwUsageErrorIfArray(errorMessage) {
334
308
  return value => {
335
309
  if (Array.isArray(value)) {
336
310
  throw new UsageError(errorMessage);
337
311
  }
338
-
339
312
  return value;
340
313
  };
341
314
  }
@@ -348,10 +321,19 @@ export async function main(absolutePackageDir, {
348
321
  const program = new Program(argv, {
349
322
  absolutePackageDir
350
323
  });
351
- const version = await getVersion(absolutePackageDir); // yargs uses magic camel case expansion to expose options on the
324
+ const version = await getVersion(absolutePackageDir);
325
+
326
+ // This is an option shared by some commands but not all of them, hence why
327
+ // it isn't a global option.
328
+ const firefoxPreviewOption = {
329
+ describe: 'Turn on developer preview features in Firefox' + ' (defaults to "mv3")',
330
+ demandOption: false,
331
+ type: 'array'
332
+ };
333
+
334
+ // yargs uses magic camel case expansion to expose options on the
352
335
  // final argv object. For example, the 'artifacts-dir' option is alternatively
353
336
  // available as argv.artifactsDir.
354
-
355
337
  program.yargs.usage(`Usage: $0 [options] command
356
338
 
357
339
  Option values can also be set by declaring an environment variable prefixed
@@ -442,6 +424,12 @@ Example: $0 --help run.
442
424
  type: 'boolean'
443
425
  }
444
426
  }).command('sign', 'Sign the extension so it can be installed in Firefox', commands.sign, {
427
+ 'amo-base-url': {
428
+ describe: 'Signing API URL prefix - only used with `use-submission-api`',
429
+ default: 'https://addons.mozilla.org/api/v5',
430
+ demandOption: true,
431
+ type: 'string'
432
+ },
445
433
  'api-key': {
446
434
  describe: 'API key (JWT issuer) from addons.mozilla.org',
447
435
  demandOption: true,
@@ -463,6 +451,11 @@ Example: $0 --help run.
463
451
  demandOption: false,
464
452
  type: 'string'
465
453
  },
454
+ 'use-submission-api': {
455
+ describe: 'Sign using the addon submission API',
456
+ demandOption: false,
457
+ type: 'boolean'
458
+ },
466
459
  'id': {
467
460
  describe: 'A custom ID for the extension. This has no effect if the ' + 'extension already declares an explicit ID in its manifest.',
468
461
  demandOption: false,
@@ -473,7 +466,10 @@ Example: $0 --help run.
473
466
  type: 'number'
474
467
  },
475
468
  'channel': {
476
- describe: 'The channel for which to sign the addon. Either ' + '\'listed\' or \'unlisted\'',
469
+ describe: 'The channel for which to sign the addon. Either ' + '\'listed\' or \'unlisted\''
470
+ },
471
+ 'amo-metadata': {
472
+ describe: 'Path to a JSON file containing an object with metadata ' + 'to be passed to the API. ' + 'See https://addons-server.readthedocs.io' + '/en/latest/topics/api/addons.html for details. ' + 'Only used with `use-submission-api`',
477
473
  type: 'string'
478
474
  }
479
475
  }).command('run', 'Run the extension', commands.run, {
@@ -552,6 +548,11 @@ Example: $0 --help run.
552
548
  demandOption: false,
553
549
  type: 'array'
554
550
  },
551
+ 'devtools': {
552
+ describe: 'Open the DevTools for the installed add-on ' + '(Firefox 106 and later)',
553
+ demandOption: false,
554
+ type: 'boolean'
555
+ },
555
556
  'browser-console': {
556
557
  alias: ['bc'],
557
558
  describe: 'Open the DevTools Browser Console.',
@@ -564,11 +565,7 @@ Example: $0 --help run.
564
565
  demandOption: false,
565
566
  type: 'array'
566
567
  },
567
- 'firefox-preview': {
568
- describe: 'Turn on developer preview features in Firefox' + ' (defaults to "mv3")',
569
- demandOption: false,
570
- type: 'array'
571
- },
568
+ 'firefox-preview': firefoxPreviewOption,
572
569
  // Firefox for Android CLI options.
573
570
  'adb-bin': {
574
571
  describe: 'Specify a custom path to the adb binary',
@@ -656,7 +653,8 @@ Example: $0 --help run.
656
653
  describe: 'Disables colorful shell output',
657
654
  type: 'boolean',
658
655
  default: false
659
- }
656
+ },
657
+ 'firefox-preview': firefoxPreviewOption
660
658
  }).command('docs', 'Open the web-ext documentation in a browser', commands.docs, {});
661
659
  return program.execute({
662
660
  getVersion,