web-ext 6.6.0 → 7.0.0

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 (94) hide show
  1. package/README.md +17 -8
  2. package/bin/web-ext.js +13 -0
  3. package/index.js +12 -0
  4. package/lib/cmd/build.js +226 -0
  5. package/lib/cmd/build.js.map +1 -0
  6. package/lib/cmd/docs.js +16 -0
  7. package/lib/cmd/docs.js.map +1 -0
  8. package/lib/cmd/index.js +47 -0
  9. package/lib/cmd/index.js.map +1 -0
  10. package/lib/cmd/lint.js +50 -0
  11. package/lib/cmd/lint.js.map +1 -0
  12. package/lib/cmd/run.js +191 -0
  13. package/lib/cmd/run.js.map +1 -0
  14. package/lib/cmd/sign.js +140 -0
  15. package/lib/cmd/sign.js.map +1 -0
  16. package/lib/config.js +144 -0
  17. package/lib/config.js.map +1 -0
  18. package/{src → lib}/errors.js +26 -35
  19. package/lib/errors.js.map +1 -0
  20. package/lib/extension-runners/base.js +2 -0
  21. package/lib/extension-runners/base.js.map +1 -0
  22. package/{src → lib}/extension-runners/chromium.js +123 -179
  23. package/lib/extension-runners/chromium.js.map +1 -0
  24. package/{src → lib}/extension-runners/firefox-android.js +168 -326
  25. package/lib/extension-runners/firefox-android.js.map +1 -0
  26. package/{src → lib}/extension-runners/firefox-desktop.js +73 -114
  27. package/lib/extension-runners/firefox-desktop.js.map +1 -0
  28. package/lib/extension-runners/index.js +311 -0
  29. package/lib/extension-runners/index.js.map +1 -0
  30. package/lib/firefox/index.js +362 -0
  31. package/lib/firefox/index.js.map +1 -0
  32. package/lib/firefox/package-identifiers.js +5 -0
  33. package/lib/firefox/package-identifiers.js.map +1 -0
  34. package/{src → lib}/firefox/preferences.js +27 -70
  35. package/lib/firefox/preferences.js.map +1 -0
  36. package/{src → lib}/firefox/rdp-client.js +98 -105
  37. package/lib/firefox/rdp-client.js.map +1 -0
  38. package/{src → lib}/firefox/remote.js +55 -129
  39. package/lib/firefox/remote.js.map +1 -0
  40. package/lib/main.js +9 -0
  41. package/lib/main.js.map +1 -0
  42. package/lib/program.js +657 -0
  43. package/lib/program.js.map +1 -0
  44. package/lib/util/adb.js +322 -0
  45. package/lib/util/adb.js.map +1 -0
  46. package/lib/util/artifacts.js +52 -0
  47. package/lib/util/artifacts.js.map +1 -0
  48. package/lib/util/desktop-notifier.js +27 -0
  49. package/lib/util/desktop-notifier.js.map +1 -0
  50. package/{src → lib}/util/file-exists.js +7 -14
  51. package/lib/util/file-exists.js.map +1 -0
  52. package/{src → lib}/util/file-filter.js +31 -59
  53. package/lib/util/file-filter.js.map +1 -0
  54. package/lib/util/is-directory.js +20 -0
  55. package/lib/util/is-directory.js.map +1 -0
  56. package/lib/util/logger.js +79 -0
  57. package/lib/util/logger.js.map +1 -0
  58. package/{src → lib}/util/manifest.js +18 -50
  59. package/lib/util/manifest.js.map +1 -0
  60. package/{src → lib}/util/promisify.js +6 -9
  61. package/lib/util/promisify.js.map +1 -0
  62. package/{src → lib}/util/stdin.js +3 -7
  63. package/lib/util/stdin.js.map +1 -0
  64. package/{src → lib}/util/temp-dir.js +47 -52
  65. package/lib/util/temp-dir.js.map +1 -0
  66. package/lib/util/updates.js +16 -0
  67. package/lib/util/updates.js.map +1 -0
  68. package/lib/watcher.js +78 -0
  69. package/lib/watcher.js.map +1 -0
  70. package/package.json +52 -54
  71. package/CODE_OF_CONDUCT.md +0 -10
  72. package/bin/web-ext +0 -7
  73. package/dist/web-ext.js +0 -2
  74. package/index.mjs +0 -13
  75. package/src/cmd/build.js +0 -319
  76. package/src/cmd/docs.js +0 -33
  77. package/src/cmd/index.js +0 -57
  78. package/src/cmd/lint.js +0 -102
  79. package/src/cmd/run.js +0 -266
  80. package/src/cmd/sign.js +0 -198
  81. package/src/config.js +0 -187
  82. package/src/extension-runners/base.js +0 -40
  83. package/src/extension-runners/index.js +0 -381
  84. package/src/firefox/index.js +0 -541
  85. package/src/firefox/package-identifiers.js +0 -14
  86. package/src/main.js +0 -19
  87. package/src/program.js +0 -765
  88. package/src/util/adb.js +0 -433
  89. package/src/util/artifacts.js +0 -69
  90. package/src/util/desktop-notifier.js +0 -41
  91. package/src/util/is-directory.js +0 -23
  92. package/src/util/logger.js +0 -131
  93. package/src/util/updates.js +0 -21
  94. package/src/watcher.js +0 -114
@@ -1,64 +1,64 @@
1
- /* @flow */
2
1
  import ExtendableError from 'es6-error';
3
-
4
-
5
2
  /*
6
3
  * Base error for all custom web-ext errors.
7
4
  */
5
+
8
6
  export class WebExtError extends ExtendableError {
9
- constructor(message: string) {
7
+ constructor(message) {
10
8
  super(message);
11
9
  }
12
- }
13
-
14
10
 
11
+ }
15
12
  /*
16
13
  * The class for errors that can be fixed by the developer.
17
14
  */
15
+
18
16
  export class UsageError extends WebExtError {
19
- constructor(message: string) {
17
+ constructor(message) {
20
18
  super(message);
21
19
  }
22
- }
23
-
24
20
 
21
+ }
25
22
  /*
26
23
  * The manifest for the extension is invalid (or missing).
27
24
  */
25
+
28
26
  export class InvalidManifest extends UsageError {
29
- constructor(message: string) {
27
+ constructor(message) {
30
28
  super(message);
31
29
  }
32
- }
33
-
34
30
 
31
+ }
35
32
  /*
36
33
  * The remote Firefox does not support temporary add-on installation.
37
34
  */
35
+
38
36
  export class RemoteTempInstallNotSupported extends WebExtError {
39
- constructor(message: string) {
37
+ constructor(message) {
40
38
  super(message);
41
39
  }
42
- }
43
40
 
41
+ }
44
42
  /*
45
43
  * The errors collected when reloading all extensions at once
46
44
  * (initialized from a map of errors by extensionSourceDir string).
47
45
  */
46
+
48
47
  export class MultiExtensionsReloadError extends WebExtError {
49
- constructor(errorsMap: Map<string, Error>) {
48
+ constructor(errorsMap) {
50
49
  let errors = '';
50
+
51
51
  for (const [sourceDir, error] of errorsMap) {
52
52
  const msg = String(error);
53
53
  errors += `\nError on extension loaded from ${sourceDir}: ${msg}\n`;
54
54
  }
55
- const message = `Reload errors: ${errors}`;
56
55
 
56
+ const message = `Reload errors: ${errors}`;
57
57
  super(message);
58
58
  this.errorsBySourceDir = errorsMap;
59
59
  }
60
- }
61
60
 
61
+ }
62
62
  /*
63
63
  * Sugar-y way to catch only instances of a certain error.
64
64
  *
@@ -72,10 +72,9 @@ export class MultiExtensionsReloadError extends WebExtError {
72
72
  * All other errors will be re-thrown.
73
73
  *
74
74
  */
75
- export function onlyInstancesOf(
76
- predicate: Function, errorHandler: Function
77
- ): Function {
78
- return (error) => {
75
+
76
+ export function onlyInstancesOf(predicate, errorHandler) {
77
+ return error => {
79
78
  if (error instanceof predicate) {
80
79
  return errorHandler(error);
81
80
  } else {
@@ -83,8 +82,6 @@ export function onlyInstancesOf(
83
82
  }
84
83
  };
85
84
  }
86
-
87
-
88
85
  /*
89
86
  * Sugar-y way to catch only errors having certain code(s).
90
87
  *
@@ -105,16 +102,13 @@ export function onlyInstancesOf(
105
102
  * All other errors will be re-thrown.
106
103
  *
107
104
  */
108
- export function onlyErrorsWithCode(
109
- codeWanted: (string | number) | Array<string | number>,
110
- errorHandler: Function
111
- ): Function {
112
- return (error) => {
105
+
106
+ export function onlyErrorsWithCode(codeWanted, errorHandler) {
107
+ return error => {
113
108
  let throwError = true;
114
109
 
115
110
  if (Array.isArray(codeWanted)) {
116
- if (codeWanted.indexOf(error.code) !== -1 ||
117
- codeWanted.indexOf(error.errno) !== -1) {
111
+ if (codeWanted.indexOf(error.code) !== -1 || codeWanted.indexOf(error.errno) !== -1) {
118
112
  throwError = false;
119
113
  }
120
114
  } else if (error.code === codeWanted || error.errno === codeWanted) {
@@ -128,11 +122,7 @@ export function onlyErrorsWithCode(
128
122
  return errorHandler(error);
129
123
  };
130
124
  }
131
-
132
- export function isErrorWithCode(
133
- codeWanted: string | Array<string>,
134
- error: Object,
135
- ): boolean {
125
+ export function isErrorWithCode(codeWanted, error) {
136
126
  if (Array.isArray(codeWanted) && codeWanted.indexOf(error.code) !== -1) {
137
127
  return true;
138
128
  } else if (error.code === codeWanted) {
@@ -141,3 +131,4 @@ export function isErrorWithCode(
141
131
 
142
132
  return false;
143
133
  }
134
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","names":["ExtendableError","WebExtError","constructor","message","UsageError","InvalidManifest","RemoteTempInstallNotSupported","MultiExtensionsReloadError","errorsMap","errors","sourceDir","error","msg","String","errorsBySourceDir","onlyInstancesOf","predicate","errorHandler","onlyErrorsWithCode","codeWanted","throwError","Array","isArray","indexOf","code","errno","isErrorWithCode"],"sources":["../src/errors.js"],"sourcesContent":["/* @flow */\nimport ExtendableError from 'es6-error';\n\n\n/*\n * Base error for all custom web-ext errors.\n */\nexport class WebExtError extends ExtendableError {\n constructor(message: string) {\n super(message);\n }\n}\n\n\n/*\n * The class for errors that can be fixed by the developer.\n */\nexport class UsageError extends WebExtError {\n constructor(message: string) {\n super(message);\n }\n}\n\n\n/*\n * The manifest for the extension is invalid (or missing).\n */\nexport class InvalidManifest extends UsageError {\n constructor(message: string) {\n super(message);\n }\n}\n\n\n/*\n * The remote Firefox does not support temporary add-on installation.\n */\nexport class RemoteTempInstallNotSupported extends WebExtError {\n constructor(message: string) {\n super(message);\n }\n}\n\n/*\n * The errors collected when reloading all extensions at once\n * (initialized from a map of errors by extensionSourceDir string).\n */\nexport class MultiExtensionsReloadError extends WebExtError {\n constructor(errorsMap: Map<string, Error>) {\n let errors = '';\n for (const [sourceDir, error] of errorsMap) {\n const msg = String(error);\n errors += `\\nError on extension loaded from ${sourceDir}: ${msg}\\n`;\n }\n const message = `Reload errors: ${errors}`;\n\n super(message);\n this.errorsBySourceDir = errorsMap;\n }\n}\n\n/*\n * Sugar-y way to catch only instances of a certain error.\n *\n * Usage:\n *\n * Promise.reject(SyntaxError)\n * .catch(onlyInstancesOf(SyntaxError, (error) => {\n * // error is guaranteed to be an instance of SyntaxError\n * }))\n *\n * All other errors will be re-thrown.\n *\n */\nexport function onlyInstancesOf(\n predicate: Function, errorHandler: Function\n): Function {\n return (error) => {\n if (error instanceof predicate) {\n return errorHandler(error);\n } else {\n throw error;\n }\n };\n}\n\n\n/*\n * Sugar-y way to catch only errors having certain code(s).\n *\n * Usage:\n *\n * Promise.resolve()\n * .catch(onlyErrorsWithCode('ENOENT', (error) => {\n * // error.code is guaranteed to be ENOENT\n * }))\n *\n * or:\n *\n * Promise.resolve()\n * .catch(onlyErrorsWithCode(['ENOENT', 'ENOTDIR'], (error) => {\n * // ...\n * }))\n *\n * All other errors will be re-thrown.\n *\n */\nexport function onlyErrorsWithCode(\n codeWanted: (string | number) | Array<string | number>,\n errorHandler: Function\n): Function {\n return (error) => {\n let throwError = true;\n\n if (Array.isArray(codeWanted)) {\n if (codeWanted.indexOf(error.code) !== -1 ||\n codeWanted.indexOf(error.errno) !== -1) {\n throwError = false;\n }\n } else if (error.code === codeWanted || error.errno === codeWanted) {\n throwError = false;\n }\n\n if (throwError) {\n throw error;\n }\n\n return errorHandler(error);\n };\n}\n\nexport function isErrorWithCode(\n codeWanted: string | Array<string>,\n error: Object,\n): boolean {\n if (Array.isArray(codeWanted) && codeWanted.indexOf(error.code) !== -1) {\n return true;\n } else if (error.code === codeWanted) {\n return true;\n }\n\n return false;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier';
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","names":["showDesktopNotification","defaultDesktopNotifications"],"sources":["../../src/extension-runners/base.js"],"sourcesContent":["/* @flow */\n\nimport {\n showDesktopNotification as defaultDesktopNotifications,\n} from '../util/desktop-notifier';\nimport type {ExtensionManifest} from '../util/manifest';\n\nexport type Extension = {|\n sourceDir: string,\n manifestData: ExtensionManifest,\n|};\n\nexport type ExtensionRunnerParams = {|\n // Common cli params.\n extensions: Array<Extension>,\n profilePath?: string,\n keepProfileChanges: boolean,\n startUrl: ?string | ?Array<string>,\n args?: Array<string>,\n\n // Common injected dependencies.\n desktopNotifications: typeof defaultDesktopNotifications,\n|};\n\nexport type ExtensionRunnerReloadResult = {|\n runnerName: string,\n reloadError?: Error,\n sourceDir?: string,\n|};\n\nexport interface IExtensionRunner {\n getName(): string,\n run(): Promise<void>,\n reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>>,\n reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>>,\n registerCleanup(fn: Function): void,\n exit(): Promise<void>,\n}\n"],"mappings":"AAEA,SACEA,uBAAuB,IAAIC,2BAD7B,QAEO,0BAFP"}
@@ -1,167 +1,121 @@
1
- /* @flow */
2
-
3
1
  /**
4
2
  * This module provide an ExtensionRunner subclass that manage an extension executed
5
3
  * in a Chromium-based browser instance.
6
4
  */
7
-
8
5
  import path from 'path';
9
-
10
6
  import fs from 'fs-extra';
11
7
  import asyncMkdirp from 'mkdirp';
12
- import {
13
- Launcher as ChromeLauncher,
14
- launch as defaultChromiumLaunch,
15
- } from 'chrome-launcher';
16
- import WebSocket from 'ws';
17
-
18
- import {createLogger} from '../util/logger';
19
- import {TempDir} from '../util/temp-dir';
20
- import type {
21
- ExtensionRunnerParams,
22
- ExtensionRunnerReloadResult,
23
- } from './base';
24
- import isDirectory from '../util/is-directory';
25
- import fileExists from '../util/file-exists';
26
-
27
- type ChromiumSpecificRunnerParams = {|
28
- chromiumBinary?: string,
29
- chromiumProfile?: string,
30
- chromiumLaunch?: typeof defaultChromiumLaunch,
31
- |};
32
-
33
- export type ChromiumExtensionRunnerParams = {|
34
- ...ExtensionRunnerParams,
35
- // Chromium desktop CLI params.
36
- ...ChromiumSpecificRunnerParams,
37
- |};
38
-
39
- const log = createLogger(__filename);
40
-
41
- const EXCLUDED_CHROME_FLAGS = [
42
- '--disable-extensions',
43
- '--mute-audio',
44
- ];
45
-
46
- export const DEFAULT_CHROME_FLAGS: Array<string> = ChromeLauncher.defaultFlags()
47
- .filter((flag) => !EXCLUDED_CHROME_FLAGS.includes(flag));
48
-
8
+ import { Launcher as ChromeLauncher, launch as defaultChromiumLaunch } from 'chrome-launcher';
9
+ import WebSocket, { WebSocketServer } from 'ws';
10
+ import { createLogger } from '../util/logger.js';
11
+ import { TempDir } from '../util/temp-dir.js';
12
+ import isDirectory from '../util/is-directory.js';
13
+ import fileExists from '../util/file-exists.js';
14
+ const log = createLogger(import.meta.url);
15
+ const EXCLUDED_CHROME_FLAGS = ['--disable-extensions', '--mute-audio'];
16
+ export const DEFAULT_CHROME_FLAGS = ChromeLauncher.defaultFlags().filter(flag => !EXCLUDED_CHROME_FLAGS.includes(flag));
49
17
  /**
50
18
  * Implements an IExtensionRunner which manages a Chromium instance.
51
19
  */
20
+
52
21
  export class ChromiumExtensionRunner {
53
- cleanupCallbacks: Set<Function>;
54
- params: ChromiumExtensionRunnerParams;
55
- chromiumInstance: ?ChromeLauncher;
56
- chromiumLaunch: typeof defaultChromiumLaunch;
57
- reloadManagerExtension: string;
58
- wss: ?WebSocket.Server;
59
- exiting: boolean;
60
- _promiseSetupDone: ?Promise<void>;
61
-
62
- constructor(params: ChromiumExtensionRunnerParams) {
22
+ constructor(params) {
63
23
  const {
64
- chromiumLaunch = defaultChromiumLaunch,
24
+ chromiumLaunch = defaultChromiumLaunch
65
25
  } = params;
66
26
  this.params = params;
67
27
  this.chromiumLaunch = chromiumLaunch;
68
28
  this.cleanupCallbacks = new Set();
69
- }
70
-
71
- // Method exported from the IExtensionRunner interface.
29
+ } // Method exported from the IExtensionRunner interface.
72
30
 
73
31
  /**
74
32
  * Returns the runner name.
75
33
  */
76
- getName(): string {
34
+
35
+
36
+ getName() {
77
37
  return 'Chromium';
78
38
  }
79
39
 
80
- async run(): Promise<void> {
40
+ async run() {
81
41
  // Run should never be called more than once.
82
42
  this._promiseSetupDone = this.setupInstance();
83
43
  await this._promiseSetupDone;
84
44
  }
85
45
 
86
- static async isUserDataDir(dirPath: string): Promise<boolean> {
46
+ static async isUserDataDir(dirPath) {
87
47
  const localStatePath = path.join(dirPath, 'Local State');
88
- const defaultPath = path.join(dirPath, 'Default');
89
- // Local State and Default are typical for the user-data-dir
90
- return await fileExists(localStatePath)
91
- && await isDirectory(defaultPath);
48
+ const defaultPath = path.join(dirPath, 'Default'); // Local State and Default are typical for the user-data-dir
49
+
50
+ return (await fileExists(localStatePath)) && (await isDirectory(defaultPath));
92
51
  }
93
52
 
94
- static async isProfileDir(dirPath: string): Promise<boolean> {
95
- const securePreferencesPath = path.join(
96
- dirPath, 'Secure Preferences');
97
- //Secure Preferences is typical for a profile dir inside a user data dir
53
+ static async isProfileDir(dirPath) {
54
+ const securePreferencesPath = path.join(dirPath, 'Secure Preferences'); //Secure Preferences is typical for a profile dir inside a user data dir
55
+
98
56
  return await fileExists(securePreferencesPath);
99
57
  }
100
58
 
101
- static async getProfilePaths(chromiumProfile: ?string): Promise<{
102
- userDataDir: ?string,
103
- profileDirName: ?string
104
- }> {
59
+ static async getProfilePaths(chromiumProfile) {
105
60
  if (!chromiumProfile) {
106
61
  return {
107
62
  userDataDir: null,
108
- profileDirName: null,
63
+ profileDirName: null
109
64
  };
110
65
  }
111
66
 
112
- const isProfileDirAndNotUserData =
113
- await ChromiumExtensionRunner.isProfileDir(chromiumProfile)
114
- && !await ChromiumExtensionRunner.isUserDataDir(chromiumProfile);
67
+ const isProfileDirAndNotUserData = (await ChromiumExtensionRunner.isProfileDir(chromiumProfile)) && !(await ChromiumExtensionRunner.isUserDataDir(chromiumProfile));
115
68
 
116
69
  if (isProfileDirAndNotUserData) {
117
- const {dir: userDataDir, base: profileDirName} =
118
- path.parse(chromiumProfile);
70
+ const {
71
+ dir: userDataDir,
72
+ base: profileDirName
73
+ } = path.parse(chromiumProfile);
119
74
  return {
120
75
  userDataDir,
121
- profileDirName,
76
+ profileDirName
122
77
  };
123
78
  }
124
79
 
125
80
  return {
126
81
  userDataDir: chromiumProfile,
127
- profileDirName: null,
82
+ profileDirName: null
128
83
  };
129
-
130
84
  }
131
-
132
85
  /**
133
86
  * Setup the Chromium Profile and run a Chromium instance.
134
87
  */
135
- async setupInstance(): Promise<void> {
136
- // Start a websocket server on a free localhost TCP port.
137
- this.wss = await new Promise((resolve) => {
138
- const server = new WebSocket.Server(
139
- // Use a ipv4 host so we don't need to escape ipv6 address
140
- // https://github.com/mozilla/web-ext/issues/2331
141
- {port: 0, host: '127.0.0.1'},
142
- // Wait the server to be listening (so that the extension
143
- // runner can successfully retrieve server address and port).
144
- () => resolve(server));
145
- });
146
88
 
147
- // Prevent unhandled socket error (e.g. when chrome
89
+
90
+ async setupInstance() {
91
+ // Start a websocket server on a free localhost TCP port.
92
+ this.wss = await new Promise(resolve => {
93
+ const server = new WebSocketServer( // Use a ipv4 host so we don't need to escape ipv6 address
94
+ // https://github.com/mozilla/web-ext/issues/2331
95
+ {
96
+ port: 0,
97
+ host: '127.0.0.1',
98
+ clientTracking: true
99
+ }, // Wait the server to be listening (so that the extension
100
+ // runner can successfully retrieve server address and port).
101
+ () => resolve(server));
102
+ }); // Prevent unhandled socket error (e.g. when chrome
148
103
  // is exiting, See https://github.com/websockets/ws/issues/1256).
149
- this.wss.on('connection', function(socket) {
150
- socket.on('error', (err) => {
104
+
105
+ this.wss.on('connection', function (socket) {
106
+ socket.on('error', err => {
151
107
  log.debug(`websocket connection error: ${err}`);
152
108
  });
153
- });
109
+ }); // Create the extension that will manage the addon reloads
154
110
 
155
- // Create the extension that will manage the addon reloads
156
- this.reloadManagerExtension = await this.createReloadManagerExtension();
157
-
158
- // Start chrome pointing it to a given profile dir
159
- const extensions = [this.reloadManagerExtension].concat(
160
- this.params.extensions.map(({sourceDir}) => sourceDir)
161
- ).join(',');
162
-
163
- const {chromiumBinary} = this.params;
111
+ this.reloadManagerExtension = await this.createReloadManagerExtension(); // Start chrome pointing it to a given profile dir
164
112
 
113
+ const extensions = [this.reloadManagerExtension].concat(this.params.extensions.map(({
114
+ sourceDir
115
+ }) => sourceDir)).join(',');
116
+ const {
117
+ chromiumBinary
118
+ } = this.params;
165
119
  log.debug('Starting Chromium instance...');
166
120
 
167
121
  if (chromiumBinary) {
@@ -169,25 +123,21 @@ export class ChromiumExtensionRunner {
169
123
  }
170
124
 
171
125
  const chromeFlags = [...DEFAULT_CHROME_FLAGS];
172
-
173
126
  chromeFlags.push(`--load-extension=${extensions}`);
174
127
 
175
128
  if (this.params.args) {
176
129
  chromeFlags.push(...this.params.args);
177
- }
130
+ } // eslint-disable-next-line prefer-const
178
131
 
179
- // eslint-disable-next-line prefer-const
180
- let {userDataDir, profileDirName} =
181
- await ChromiumExtensionRunner.getProfilePaths(
182
- this.params.chromiumProfile);
132
+
133
+ let {
134
+ userDataDir,
135
+ profileDirName
136
+ } = await ChromiumExtensionRunner.getProfilePaths(this.params.chromiumProfile);
183
137
 
184
138
  if (userDataDir && this.params.keepProfileChanges) {
185
- if (profileDirName
186
- && !await ChromiumExtensionRunner.isUserDataDir(userDataDir)) {
187
- throw new Error('The profile you provided is not in a ' +
188
- 'user-data-dir. The changes cannot be kept. Please either ' +
189
- 'remove --keep-profile-changes or use a profile in a ' +
190
- 'user-data-dir directory');
139
+ if (profileDirName && !(await ChromiumExtensionRunner.isUserDataDir(userDataDir))) {
140
+ throw new Error('The profile you provided is not in a ' + 'user-data-dir. The changes cannot be kept. Please either ' + 'remove --keep-profile-changes or use a profile in a ' + 'user-data-dir directory');
191
141
  }
192
142
  } else if (!this.params.keepProfileChanges) {
193
143
  // the user provided an existing profile directory but doesn't want
@@ -199,15 +149,11 @@ export class ChromiumExtensionRunner {
199
149
 
200
150
  if (userDataDir && profileDirName) {
201
151
  // copy profile dir to this temp user data dir.
202
- await fs.copy(path.join(
203
- userDataDir,
204
- profileDirName), path.join(
205
- tmpDirPath,
206
- profileDirName),
207
- );
152
+ await fs.copy(path.join(userDataDir, profileDirName), path.join(tmpDirPath, profileDirName));
208
153
  } else if (userDataDir) {
209
154
  await fs.copy(userDataDir, tmpDirPath);
210
155
  }
156
+
211
157
  userDataDir = tmpDirPath;
212
158
  }
213
159
 
@@ -216,9 +162,9 @@ export class ChromiumExtensionRunner {
216
162
  }
217
163
 
218
164
  let startingUrl;
165
+
219
166
  if (this.params.startUrl) {
220
- const startingUrls = Array.isArray(this.params.startUrl) ?
221
- this.params.startUrl : [this.params.startUrl];
167
+ const startingUrls = Array.isArray(this.params.startUrl) ? this.params.startUrl : [this.params.startUrl];
222
168
  startingUrl = startingUrls.shift();
223
169
  chromeFlags.push(...startingUrls);
224
170
  }
@@ -230,9 +176,8 @@ export class ChromiumExtensionRunner {
230
176
  startingUrl,
231
177
  userDataDir,
232
178
  // Ignore default flags to keep the extension enabled.
233
- ignoreDefaultFlags: true,
179
+ ignoreDefaultFlags: true
234
180
  });
235
-
236
181
  this.chromiumInstance.process.once('close', () => {
237
182
  this.chromiumInstance = null;
238
183
 
@@ -243,8 +188,8 @@ export class ChromiumExtensionRunner {
243
188
  });
244
189
  }
245
190
 
246
- async wssBroadcast(data: Object): Promise<void> {
247
- return new Promise((resolve) => {
191
+ async wssBroadcast(data) {
192
+ return new Promise(resolve => {
248
193
  const clients = this.wss ? new Set(this.wss.clients) : new Set();
249
194
 
250
195
  function cleanWebExtReloadComplete() {
@@ -254,13 +199,14 @@ export class ChromiumExtensionRunner {
254
199
  clients.delete(client);
255
200
  }
256
201
 
257
- const webExtReloadComplete = async (message) => {
202
+ const webExtReloadComplete = async message => {
258
203
  const msg = JSON.parse(message.data);
259
204
 
260
205
  if (msg.type === 'webExtReloadExtensionComplete') {
261
206
  for (const client of clients) {
262
207
  cleanWebExtReloadComplete.call(client);
263
208
  }
209
+
264
210
  resolve();
265
211
  }
266
212
  };
@@ -269,7 +215,6 @@ export class ChromiumExtensionRunner {
269
215
  if (client.readyState === WebSocket.OPEN) {
270
216
  client.addEventListener('message', webExtReloadComplete);
271
217
  client.addEventListener('close', cleanWebExtReloadComplete);
272
-
273
218
  client.send(JSON.stringify(data));
274
219
  } else {
275
220
  clients.delete(client);
@@ -282,43 +227,32 @@ export class ChromiumExtensionRunner {
282
227
  });
283
228
  }
284
229
 
285
- async createReloadManagerExtension(): Promise<string> {
230
+ async createReloadManagerExtension() {
286
231
  const tmpDir = new TempDir();
287
232
  await tmpDir.create();
288
233
  this.registerCleanup(() => tmpDir.remove());
289
-
290
- const extPath = path.join(
291
- tmpDir.path(),
292
- `reload-manager-extension-${Date.now()}`
293
- );
294
-
234
+ const extPath = path.join(tmpDir.path(), `reload-manager-extension-${Date.now()}`);
295
235
  log.debug(`Creating reload-manager-extension in ${extPath}`);
296
-
297
236
  await asyncMkdirp(extPath);
237
+ await fs.writeFile(path.join(extPath, 'manifest.json'), JSON.stringify({
238
+ manifest_version: 2,
239
+ name: 'web-ext Reload Manager Extension',
240
+ version: '1.0',
241
+ permissions: ['management', 'tabs'],
242
+ background: {
243
+ scripts: ['bg.js']
244
+ }
245
+ })); // $FlowIgnore: this method is only called right after creating the server and so wss should be defined.
298
246
 
299
- await fs.writeFile(
300
- path.join(extPath, 'manifest.json'),
301
- JSON.stringify({
302
- manifest_version: 2,
303
- name: 'web-ext Reload Manager Extension',
304
- version: '1.0',
305
- permissions: ['management', 'tabs'],
306
- background: {
307
- scripts: ['bg.js'],
308
- },
309
- })
310
- );
311
-
312
- // $FlowIgnore: this method is only called right after creating the server and so wss should be defined.
313
247
  const wssInfo = this.wss.address();
314
-
315
248
  const bgPage = `(function bgPage() {
316
249
  async function getAllDevExtensions() {
317
250
  const allExtensions = await new Promise(
318
251
  r => chrome.management.getAll(r));
319
252
 
320
253
  return allExtensions.filter((extension) => {
321
- return extension.installType === "development" &&
254
+ return extension.enabled &&
255
+ extension.installType === "development" &&
322
256
  extension.id !== chrome.runtime.id;
323
257
  });
324
258
  }
@@ -345,62 +279,60 @@ export class ChromiumExtensionRunner {
345
279
  }
346
280
  };
347
281
  })()`;
348
-
349
282
  await fs.writeFile(path.join(extPath, 'bg.js'), bgPage);
350
283
  return extPath;
351
284
  }
352
-
353
285
  /**
354
286
  * Reloads all the extensions, collect any reload error and resolves to
355
287
  * an array composed by a single ExtensionRunnerReloadResult object.
356
288
  */
357
- async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {
358
- const runnerName = this.getName();
359
289
 
290
+
291
+ async reloadAllExtensions() {
292
+ const runnerName = this.getName();
360
293
  await this.wssBroadcast({
361
- type: 'webExtReloadAllExtensions',
294
+ type: 'webExtReloadAllExtensions'
362
295
  });
363
-
364
- process.stdout.write(
365
- `\rLast extension reload: ${(new Date()).toTimeString()}`);
296
+ process.stdout.write(`\rLast extension reload: ${new Date().toTimeString()}`);
366
297
  log.debug('\n');
367
-
368
- return [{runnerName}];
298
+ return [{
299
+ runnerName
300
+ }];
369
301
  }
370
-
371
302
  /**
372
303
  * Reloads a single extension, collect any reload error and resolves to
373
304
  * an array composed by a single ExtensionRunnerReloadResult object.
374
305
  */
375
- async reloadExtensionBySourceDir(
376
- extensionSourceDir: string // eslint-disable-line no-unused-vars
377
- ): Promise<Array<ExtensionRunnerReloadResult>> {
306
+
307
+
308
+ async reloadExtensionBySourceDir(extensionSourceDir) {
378
309
  // TODO(rpl): detect the extension ids assigned to the
379
310
  // target extensions and map it to the extensions source dir
380
311
  // (https://github.com/mozilla/web-ext/issues/1687).
381
312
  return this.reloadAllExtensions();
382
313
  }
383
-
384
314
  /**
385
315
  * Register a callback to be called when the runner has been exited
386
316
  * (e.g. the Chromium instance exits or the user has requested web-ext
387
317
  * to exit).
388
318
  */
389
- registerCleanup(fn: Function): void {
319
+
320
+
321
+ registerCleanup(fn) {
390
322
  this.cleanupCallbacks.add(fn);
391
323
  }
392
-
393
324
  /**
394
325
  * Exits the runner, by closing the managed Chromium instance.
395
326
  */
396
- async exit(): Promise<void> {
397
- this.exiting = true;
398
327
 
399
- // Wait for the setup to complete if the extension runner is already
328
+
329
+ async exit() {
330
+ this.exiting = true; // Wait for the setup to complete if the extension runner is already
400
331
  // being started.
332
+
401
333
  if (this._promiseSetupDone) {
402
334
  // Ignore initialization errors if any.
403
- await this._promiseSetupDone.catch((err) => {
335
+ await this._promiseSetupDone.catch(err => {
404
336
  log.debug(`ignored setup error on chromium runner shutdown: ${err}`);
405
337
  });
406
338
  }
@@ -411,12 +343,22 @@ export class ChromiumExtensionRunner {
411
343
  }
412
344
 
413
345
  if (this.wss) {
414
- await new Promise((resolve) =>
415
- this.wss ? this.wss.close(resolve) : resolve());
346
+ // Close all websocket clients, closing the WebSocketServer
347
+ // does not terminate the existing connection and it wouldn't
348
+ // resolve until all of the existing connections are closed.
349
+ for (const wssClient of ((_this$wss = this.wss) === null || _this$wss === void 0 ? void 0 : _this$wss.clients) || []) {
350
+ var _this$wss;
351
+
352
+ if (wssClient.readyState === WebSocket.OPEN) {
353
+ wssClient.terminate();
354
+ }
355
+ }
356
+
357
+ await new Promise(resolve => this.wss ? this.wss.close(resolve) : resolve());
416
358
  this.wss = null;
417
- }
359
+ } // Call all the registered cleanup callbacks.
360
+
418
361
 
419
- // Call all the registered cleanup callbacks.
420
362
  for (const fn of this.cleanupCallbacks) {
421
363
  try {
422
364
  fn();
@@ -425,4 +367,6 @@ export class ChromiumExtensionRunner {
425
367
  }
426
368
  }
427
369
  }
370
+
428
371
  }
372
+ //# sourceMappingURL=chromium.js.map