web-ext 7.2.0 → 7.3.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 (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
@@ -1,22 +1,21 @@
1
+
1
2
  import net from 'net';
2
3
  import EventEmitter from 'events';
3
4
  import domain from 'domain';
4
5
  export const DEFAULT_PORT = 6000;
5
6
  export const DEFAULT_HOST = '127.0.0.1';
6
- const UNSOLICITED_EVENTS = new Set(['tabNavigated', 'styleApplied', 'propertyChange', 'networkEventUpdate', 'networkEvent', 'propertyChange', 'newMutations', 'frameUpdate', 'tabListChanged']); // Parse RDP packets: BYTE_LENGTH + ':' + DATA.
7
+ const UNSOLICITED_EVENTS = new Set(['tabNavigated', 'styleApplied', 'propertyChange', 'networkEventUpdate', 'networkEvent', 'propertyChange', 'newMutations', 'frameUpdate', 'tabListChanged']);
7
8
 
9
+ // Parse RDP packets: BYTE_LENGTH + ':' + DATA.
8
10
  export function parseRDPMessage(data) {
9
11
  const str = data.toString();
10
12
  const sepIdx = str.indexOf(':');
11
-
12
13
  if (sepIdx < 1) {
13
14
  return {
14
15
  data
15
16
  };
16
17
  }
17
-
18
18
  const byteLen = parseInt(str.slice(0, sepIdx));
19
-
20
19
  if (isNaN(byteLen)) {
21
20
  const error = new Error('Error parsing RDP message length');
22
21
  return {
@@ -25,18 +24,15 @@ export function parseRDPMessage(data) {
25
24
  fatal: true
26
25
  };
27
26
  }
28
-
29
27
  if (data.length - (sepIdx + 1) < byteLen) {
30
28
  // Can't parse yet, will retry once more data has been received.
31
29
  return {
32
30
  data
33
31
  };
34
32
  }
35
-
36
33
  data = data.slice(sepIdx + 1);
37
34
  const msg = data.slice(0, byteLen);
38
35
  data = data.slice(byteLen);
39
-
40
36
  try {
41
37
  return {
42
38
  data,
@@ -60,16 +56,11 @@ export default class FirefoxRDPClient extends EventEmitter {
60
56
  this._incoming = Buffer.alloc(0);
61
57
  this._pending = [];
62
58
  this._active = new Map();
63
-
64
59
  this._onData = (...args) => this.onData(...args);
65
-
66
60
  this._onError = (...args) => this.onError(...args);
67
-
68
61
  this._onEnd = (...args) => this.onEnd(...args);
69
-
70
62
  this._onTimeout = (...args) => this.onTimeout(...args);
71
63
  }
72
-
73
64
  connect(port) {
74
65
  return new Promise((resolve, reject) => {
75
66
  // Create a domain to wrap the errors that may be triggered
@@ -87,9 +78,10 @@ export default class FirefoxRDPClient extends EventEmitter {
87
78
  conn.on('data', this._onData);
88
79
  conn.on('error', this._onError);
89
80
  conn.on('end', this._onEnd);
90
- conn.on('timeout', this._onTimeout); // Resolve once the expected initial root message
91
- // has been received.
81
+ conn.on('timeout', this._onTimeout);
92
82
 
83
+ // Resolve once the expected initial root message
84
+ // has been received.
93
85
  this._expectReply('root', {
94
86
  resolve,
95
87
  reject
@@ -97,41 +89,32 @@ export default class FirefoxRDPClient extends EventEmitter {
97
89
  });
98
90
  });
99
91
  }
100
-
101
92
  disconnect() {
102
93
  if (!this._rdpConnection) {
103
94
  return;
104
95
  }
105
-
106
96
  const conn = this._rdpConnection;
107
97
  conn.off('data', this._onData);
108
98
  conn.off('error', this._onError);
109
99
  conn.off('end', this._onEnd);
110
100
  conn.off('timeout', this._onTimeout);
111
101
  conn.end();
112
-
113
102
  this._rejectAllRequests(new Error('RDP connection closed'));
114
103
  }
115
-
116
104
  _rejectAllRequests(error) {
117
105
  for (const activeDeferred of this._active.values()) {
118
106
  activeDeferred.reject(error);
119
107
  }
120
-
121
108
  this._active.clear();
122
-
123
109
  for (const {
124
110
  deferred
125
111
  } of this._pending) {
126
112
  deferred.reject(error);
127
113
  }
128
-
129
114
  this._pending = [];
130
115
  }
131
-
132
116
  async request(requestProps) {
133
117
  let request;
134
-
135
118
  if (typeof requestProps === 'string') {
136
119
  request = {
137
120
  to: 'root',
@@ -140,26 +123,21 @@ export default class FirefoxRDPClient extends EventEmitter {
140
123
  } else {
141
124
  request = requestProps;
142
125
  }
143
-
144
126
  if (request.to == null) {
145
127
  throw new Error(`Unexpected RDP request without target actor: ${request.type}`);
146
128
  }
147
-
148
129
  return new Promise((resolve, reject) => {
149
130
  const deferred = {
150
131
  resolve,
151
132
  reject
152
133
  };
153
-
154
134
  this._pending.push({
155
135
  request,
156
136
  deferred
157
137
  });
158
-
159
138
  this._flushPendingRequests();
160
139
  });
161
140
  }
162
-
163
141
  _flushPendingRequests() {
164
142
  this._pending = this._pending.filter(({
165
143
  request,
@@ -170,71 +148,55 @@ export default class FirefoxRDPClient extends EventEmitter {
170
148
  // active on the target RDP actor.
171
149
  return true;
172
150
  }
173
-
174
151
  const conn = this._rdpConnection;
175
-
176
152
  if (!conn) {
177
153
  throw new Error('RDP connection closed');
178
154
  }
179
-
180
155
  try {
181
156
  let str = JSON.stringify(request);
182
157
  str = `${Buffer.from(str).length}:${str}`;
183
158
  conn.write(str);
184
-
185
159
  this._expectReply(request.to, deferred);
186
160
  } catch (err) {
187
161
  deferred.reject(err);
188
- } // Remove the pending request from the queue.
189
-
162
+ }
190
163
 
164
+ // Remove the pending request from the queue.
191
165
  return false;
192
166
  });
193
167
  }
194
-
195
168
  _expectReply(targetActor, deferred) {
196
169
  if (this._active.has(targetActor)) {
197
170
  throw new Error(`${targetActor} does already have an active request`);
198
171
  }
199
-
200
172
  this._active.set(targetActor, deferred);
201
173
  }
202
-
203
174
  _handleMessage(rdpData) {
204
175
  if (rdpData.from == null) {
205
176
  if (rdpData.error) {
206
177
  this.emit('rdp-error', rdpData);
207
178
  return;
208
179
  }
209
-
210
180
  this.emit('error', new Error(`Received an RDP message without a sender actor: ${JSON.stringify(rdpData)}`));
211
181
  return;
212
182
  }
213
-
214
183
  if (UNSOLICITED_EVENTS.has(rdpData.type)) {
215
184
  this.emit('unsolicited-event', rdpData);
216
185
  return;
217
186
  }
218
-
219
187
  if (this._active.has(rdpData.from)) {
220
188
  const deferred = this._active.get(rdpData.from);
221
-
222
189
  this._active.delete(rdpData.from);
223
-
224
190
  if (rdpData.error) {
225
191
  deferred === null || deferred === void 0 ? void 0 : deferred.reject(rdpData);
226
192
  } else {
227
193
  deferred === null || deferred === void 0 ? void 0 : deferred.resolve(rdpData);
228
194
  }
229
-
230
195
  this._flushPendingRequests();
231
-
232
196
  return;
233
197
  }
234
-
235
198
  this.emit('error', new Error(`Unexpected RDP message received: ${JSON.stringify(rdpData)}`));
236
199
  }
237
-
238
200
  _readMessage() {
239
201
  const {
240
202
  data,
@@ -243,50 +205,40 @@ export default class FirefoxRDPClient extends EventEmitter {
243
205
  fatal
244
206
  } = parseRDPMessage(this._incoming);
245
207
  this._incoming = data;
246
-
247
208
  if (error) {
248
- this.emit('error', new Error(`Error parsing RDP packet: ${String(error)}`)); // Disconnect automatically on a fatal error.
249
-
209
+ this.emit('error', new Error(`Error parsing RDP packet: ${String(error)}`));
210
+ // Disconnect automatically on a fatal error.
250
211
  if (fatal) {
251
212
  this.disconnect();
252
- } // Caller can parse the next message if the error wasn't fatal
213
+ }
214
+ // Caller can parse the next message if the error wasn't fatal
253
215
  // (e.g. the RDP packet that couldn't be parsed has been already
254
216
  // removed from the incoming data buffer).
255
-
256
-
257
217
  return !fatal;
258
218
  }
259
-
260
219
  if (!rdpMessage) {
261
220
  // Caller will need to wait more data to parse the next message.
262
221
  return false;
263
222
  }
264
-
265
- this._handleMessage(rdpMessage); // Caller can try to parse the next message from the remining data.
266
-
267
-
223
+ this._handleMessage(rdpMessage);
224
+ // Caller can try to parse the next message from the remining data.
268
225
  return true;
269
226
  }
270
-
271
227
  onData(data) {
272
228
  this._incoming = Buffer.concat([this._incoming, data]);
273
-
274
- while (this._readMessage()) {// Keep parsing and handling messages until readMessage
229
+ while (this._readMessage()) {
230
+ // Keep parsing and handling messages until readMessage
275
231
  // returns false.
276
232
  }
277
233
  }
278
-
279
234
  onError(error) {
280
235
  this.emit('error', error);
281
236
  }
282
-
283
237
  onEnd() {
284
238
  this.emit('end');
285
239
  }
286
-
287
240
  onTimeout() {
288
241
  this.emit('timeout');
289
242
  }
290
-
291
243
  }
292
244
  //# sourceMappingURL=rdp-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rdp-client.js","names":["net","EventEmitter","domain","DEFAULT_PORT","DEFAULT_HOST","UNSOLICITED_EVENTS","Set","parseRDPMessage","data","str","toString","sepIdx","indexOf","byteLen","parseInt","slice","isNaN","error","Error","fatal","length","msg","rdpMessage","JSON","parse","connectToFirefox","port","client","FirefoxRDPClient","connect","then","constructor","_incoming","Buffer","alloc","_pending","_active","Map","_onData","args","onData","_onError","onError","_onEnd","onEnd","_onTimeout","onTimeout","Promise","resolve","reject","d","create","once","run","conn","createConnection","host","_rdpConnection","on","_expectReply","disconnect","off","end","_rejectAllRequests","activeDeferred","values","clear","deferred","request","requestProps","to","type","push","_flushPendingRequests","filter","has","stringify","from","write","err","targetActor","set","_handleMessage","rdpData","emit","get","delete","_readMessage","String","concat"],"sources":["../../src/firefox/rdp-client.js"],"sourcesContent":["/* @flow */\nimport net from 'net';\nimport EventEmitter from 'events';\nimport domain from 'domain';\n\nexport type RDPRequest = {\n to: string,\n type: string,\n}\n\nexport type RDPResult = {\n from: string,\n type: string,\n}\n\nexport type Deferred = {|\n resolve: Function,\n reject: Function,\n|}\n\ntype ParseResult = {|\n data: Buffer,\n rdpMessage?: Object,\n error?: Error,\n fatal?: boolean,\n|}\n\nexport const DEFAULT_PORT = 6000;\nexport const DEFAULT_HOST = '127.0.0.1';\n\nconst UNSOLICITED_EVENTS = new Set([\n 'tabNavigated',\n 'styleApplied',\n 'propertyChange',\n 'networkEventUpdate',\n 'networkEvent',\n 'propertyChange',\n 'newMutations',\n 'frameUpdate',\n 'tabListChanged',\n]);\n\n// Parse RDP packets: BYTE_LENGTH + ':' + DATA.\nexport function parseRDPMessage(data: Buffer): ParseResult {\n const str = data.toString();\n const sepIdx = str.indexOf(':');\n if (sepIdx < 1) {\n return {data};\n }\n\n const byteLen = parseInt(str.slice(0, sepIdx));\n if (isNaN(byteLen)) {\n const error = new Error('Error parsing RDP message length');\n return {data, error, fatal: true};\n }\n\n if (data.length - (sepIdx + 1) < byteLen) {\n // Can't parse yet, will retry once more data has been received.\n return {data};\n }\n\n data = data.slice(sepIdx + 1);\n const msg = data.slice(0, byteLen);\n data = data.slice(byteLen);\n\n try {\n return {data, rdpMessage: JSON.parse(msg.toString())};\n } catch (error) {\n return {data, error, fatal: false};\n }\n}\n\nexport function connectToFirefox(port: number): Promise<FirefoxRDPClient> {\n const client = new FirefoxRDPClient();\n return client.connect(port).then(() => client);\n}\n\nexport default class FirefoxRDPClient extends EventEmitter {\n _incoming: Buffer;\n _pending: Array<{| request: RDPRequest, deferred: Deferred |}>;\n _active: Map<string, Deferred>;\n _rdpConnection: net.Socket;\n _onData: Function;\n _onError: Function;\n _onEnd: Function;\n _onTimeout: Function;\n\n constructor() {\n super();\n this._incoming = Buffer.alloc(0);\n this._pending = [];\n this._active = new Map();\n\n this._onData = (...args) => this.onData(...args);\n this._onError = (...args) => this.onError(...args);\n this._onEnd = (...args) => this.onEnd(...args);\n this._onTimeout = (...args) => this.onTimeout(...args);\n }\n\n connect(port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n // Create a domain to wrap the errors that may be triggered\n // by creating the client connection (e.g. ECONNREFUSED)\n // so that we can reject the promise returned instead of\n // exiting the entire process.\n const d = domain.create();\n d.once('error', reject);\n d.run(() => {\n const conn = net.createConnection({\n port,\n host: DEFAULT_HOST,\n });\n\n this._rdpConnection = conn;\n conn.on('data', this._onData);\n conn.on('error', this._onError);\n conn.on('end', this._onEnd);\n conn.on('timeout', this._onTimeout);\n\n // Resolve once the expected initial root message\n // has been received.\n this._expectReply('root', {resolve, reject});\n });\n });\n }\n\n disconnect(): void {\n if (!this._rdpConnection) {\n return;\n }\n\n const conn = this._rdpConnection;\n conn.off('data', this._onData);\n conn.off('error', this._onError);\n conn.off('end', this._onEnd);\n conn.off('timeout', this._onTimeout);\n conn.end();\n\n this._rejectAllRequests(new Error('RDP connection closed'));\n }\n\n _rejectAllRequests(error: Error) {\n for (const activeDeferred of this._active.values()) {\n activeDeferred.reject(error);\n }\n this._active.clear();\n\n for (const {deferred} of this._pending) {\n deferred.reject(error);\n }\n this._pending = [];\n }\n\n async request(requestProps: string | RDPRequest): Promise<RDPResult> {\n let request: RDPRequest;\n\n if (typeof requestProps === 'string') {\n request = {to: 'root', type: requestProps};\n } else {\n request = requestProps;\n }\n\n if (request.to == null) {\n throw new Error(\n `Unexpected RDP request without target actor: ${request.type}`\n );\n }\n\n return new Promise((resolve, reject) => {\n const deferred = {resolve, reject};\n this._pending.push({request, deferred});\n this._flushPendingRequests();\n });\n }\n\n _flushPendingRequests(): void {\n this._pending = this._pending.filter(({request, deferred}) => {\n if (this._active.has(request.to)) {\n // Keep in the pending requests until there are no requests\n // active on the target RDP actor.\n return true;\n }\n\n const conn = this._rdpConnection;\n if (!conn) {\n throw new Error('RDP connection closed');\n }\n\n try {\n let str = JSON.stringify(request);\n str = `${Buffer.from(str).length}:${str}`;\n conn.write(str);\n this._expectReply(request.to, deferred);\n } catch (err) {\n deferred.reject(err);\n }\n\n // Remove the pending request from the queue.\n return false;\n });\n }\n\n _expectReply(targetActor: string, deferred: Deferred): void {\n if (this._active.has(targetActor)) {\n throw new Error(`${targetActor} does already have an active request`);\n }\n\n this._active.set(targetActor, deferred);\n }\n\n _handleMessage(rdpData: Object): void {\n if (rdpData.from == null) {\n if (rdpData.error) {\n this.emit('rdp-error', rdpData);\n return;\n }\n\n this.emit('error', new Error(\n `Received an RDP message without a sender actor: ${\n JSON.stringify(rdpData)\n }`\n ));\n return;\n }\n\n if (UNSOLICITED_EVENTS.has(rdpData.type)) {\n this.emit('unsolicited-event', rdpData);\n return;\n }\n\n if (this._active.has(rdpData.from)) {\n const deferred = this._active.get(rdpData.from);\n this._active.delete(rdpData.from);\n if (rdpData.error) {\n deferred?.reject(rdpData);\n } else {\n deferred?.resolve(rdpData);\n }\n this._flushPendingRequests();\n return;\n }\n\n this.emit('error', new Error(\n `Unexpected RDP message received: ${JSON.stringify(rdpData)}`\n ));\n }\n\n _readMessage(): boolean {\n const {\n data, rdpMessage, error, fatal,\n } = parseRDPMessage(this._incoming);\n\n this._incoming = data;\n\n if (error) {\n this.emit(\n 'error',\n new Error(`Error parsing RDP packet: ${String(error)}`)\n );\n // Disconnect automatically on a fatal error.\n if (fatal) {\n this.disconnect();\n }\n // Caller can parse the next message if the error wasn't fatal\n // (e.g. the RDP packet that couldn't be parsed has been already\n // removed from the incoming data buffer).\n return !fatal;\n }\n\n if (!rdpMessage) {\n // Caller will need to wait more data to parse the next message.\n return false;\n }\n\n this._handleMessage(rdpMessage);\n // Caller can try to parse the next message from the remining data.\n return true;\n }\n\n onData(data: Buffer) {\n this._incoming = Buffer.concat([this._incoming, data]);\n while (this._readMessage()) {\n // Keep parsing and handling messages until readMessage\n // returns false.\n }\n }\n\n onError(error: Error) {\n this.emit('error', error);\n }\n\n onEnd() {\n this.emit('end');\n }\n\n onTimeout() {\n this.emit('timeout');\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rdp-client.js","names":["net","EventEmitter","domain","DEFAULT_PORT","DEFAULT_HOST","UNSOLICITED_EVENTS","Set","parseRDPMessage","data","str","toString","sepIdx","indexOf","byteLen","parseInt","slice","isNaN","error","Error","fatal","length","msg","rdpMessage","JSON","parse","connectToFirefox","port","client","FirefoxRDPClient","connect","then","constructor","_incoming","Buffer","alloc","_pending","_active","Map","_onData","args","onData","_onError","onError","_onEnd","onEnd","_onTimeout","onTimeout","Promise","resolve","reject","d","create","once","run","conn","createConnection","host","_rdpConnection","on","_expectReply","disconnect","off","end","_rejectAllRequests","activeDeferred","values","clear","deferred","request","requestProps","to","type","push","_flushPendingRequests","filter","has","stringify","from","write","err","targetActor","set","_handleMessage","rdpData","emit","get","delete","_readMessage","String","concat"],"sources":["../../src/firefox/rdp-client.js"],"sourcesContent":["/* @flow */\nimport net from 'net';\nimport EventEmitter from 'events';\nimport domain from 'domain';\n\nexport type RDPRequest = {\n to: string,\n type: string,\n}\n\nexport type RDPResult = {\n from: string,\n type: string,\n}\n\nexport type Deferred = {|\n resolve: Function,\n reject: Function,\n|}\n\ntype ParseResult = {|\n data: Buffer,\n rdpMessage?: Object,\n error?: Error,\n fatal?: boolean,\n|}\n\nexport const DEFAULT_PORT = 6000;\nexport const DEFAULT_HOST = '127.0.0.1';\n\nconst UNSOLICITED_EVENTS = new Set([\n 'tabNavigated',\n 'styleApplied',\n 'propertyChange',\n 'networkEventUpdate',\n 'networkEvent',\n 'propertyChange',\n 'newMutations',\n 'frameUpdate',\n 'tabListChanged',\n]);\n\n// Parse RDP packets: BYTE_LENGTH + ':' + DATA.\nexport function parseRDPMessage(data: Buffer): ParseResult {\n const str = data.toString();\n const sepIdx = str.indexOf(':');\n if (sepIdx < 1) {\n return {data};\n }\n\n const byteLen = parseInt(str.slice(0, sepIdx));\n if (isNaN(byteLen)) {\n const error = new Error('Error parsing RDP message length');\n return {data, error, fatal: true};\n }\n\n if (data.length - (sepIdx + 1) < byteLen) {\n // Can't parse yet, will retry once more data has been received.\n return {data};\n }\n\n data = data.slice(sepIdx + 1);\n const msg = data.slice(0, byteLen);\n data = data.slice(byteLen);\n\n try {\n return {data, rdpMessage: JSON.parse(msg.toString())};\n } catch (error) {\n return {data, error, fatal: false};\n }\n}\n\nexport function connectToFirefox(port: number): Promise<FirefoxRDPClient> {\n const client = new FirefoxRDPClient();\n return client.connect(port).then(() => client);\n}\n\nexport default class FirefoxRDPClient extends EventEmitter {\n _incoming: Buffer;\n _pending: Array<{| request: RDPRequest, deferred: Deferred |}>;\n _active: Map<string, Deferred>;\n _rdpConnection: net.Socket;\n _onData: Function;\n _onError: Function;\n _onEnd: Function;\n _onTimeout: Function;\n\n constructor() {\n super();\n this._incoming = Buffer.alloc(0);\n this._pending = [];\n this._active = new Map();\n\n this._onData = (...args) => this.onData(...args);\n this._onError = (...args) => this.onError(...args);\n this._onEnd = (...args) => this.onEnd(...args);\n this._onTimeout = (...args) => this.onTimeout(...args);\n }\n\n connect(port: number): Promise<void> {\n return new Promise((resolve, reject) => {\n // Create a domain to wrap the errors that may be triggered\n // by creating the client connection (e.g. ECONNREFUSED)\n // so that we can reject the promise returned instead of\n // exiting the entire process.\n const d = domain.create();\n d.once('error', reject);\n d.run(() => {\n const conn = net.createConnection({\n port,\n host: DEFAULT_HOST,\n });\n\n this._rdpConnection = conn;\n conn.on('data', this._onData);\n conn.on('error', this._onError);\n conn.on('end', this._onEnd);\n conn.on('timeout', this._onTimeout);\n\n // Resolve once the expected initial root message\n // has been received.\n this._expectReply('root', {resolve, reject});\n });\n });\n }\n\n disconnect(): void {\n if (!this._rdpConnection) {\n return;\n }\n\n const conn = this._rdpConnection;\n conn.off('data', this._onData);\n conn.off('error', this._onError);\n conn.off('end', this._onEnd);\n conn.off('timeout', this._onTimeout);\n conn.end();\n\n this._rejectAllRequests(new Error('RDP connection closed'));\n }\n\n _rejectAllRequests(error: Error) {\n for (const activeDeferred of this._active.values()) {\n activeDeferred.reject(error);\n }\n this._active.clear();\n\n for (const {deferred} of this._pending) {\n deferred.reject(error);\n }\n this._pending = [];\n }\n\n async request(requestProps: string | RDPRequest): Promise<RDPResult> {\n let request: RDPRequest;\n\n if (typeof requestProps === 'string') {\n request = {to: 'root', type: requestProps};\n } else {\n request = requestProps;\n }\n\n if (request.to == null) {\n throw new Error(\n `Unexpected RDP request without target actor: ${request.type}`\n );\n }\n\n return new Promise((resolve, reject) => {\n const deferred = {resolve, reject};\n this._pending.push({request, deferred});\n this._flushPendingRequests();\n });\n }\n\n _flushPendingRequests(): void {\n this._pending = this._pending.filter(({request, deferred}) => {\n if (this._active.has(request.to)) {\n // Keep in the pending requests until there are no requests\n // active on the target RDP actor.\n return true;\n }\n\n const conn = this._rdpConnection;\n if (!conn) {\n throw new Error('RDP connection closed');\n }\n\n try {\n let str = JSON.stringify(request);\n str = `${Buffer.from(str).length}:${str}`;\n conn.write(str);\n this._expectReply(request.to, deferred);\n } catch (err) {\n deferred.reject(err);\n }\n\n // Remove the pending request from the queue.\n return false;\n });\n }\n\n _expectReply(targetActor: string, deferred: Deferred): void {\n if (this._active.has(targetActor)) {\n throw new Error(`${targetActor} does already have an active request`);\n }\n\n this._active.set(targetActor, deferred);\n }\n\n _handleMessage(rdpData: Object): void {\n if (rdpData.from == null) {\n if (rdpData.error) {\n this.emit('rdp-error', rdpData);\n return;\n }\n\n this.emit('error', new Error(\n `Received an RDP message without a sender actor: ${\n JSON.stringify(rdpData)\n }`\n ));\n return;\n }\n\n if (UNSOLICITED_EVENTS.has(rdpData.type)) {\n this.emit('unsolicited-event', rdpData);\n return;\n }\n\n if (this._active.has(rdpData.from)) {\n const deferred = this._active.get(rdpData.from);\n this._active.delete(rdpData.from);\n if (rdpData.error) {\n deferred?.reject(rdpData);\n } else {\n deferred?.resolve(rdpData);\n }\n this._flushPendingRequests();\n return;\n }\n\n this.emit('error', new Error(\n `Unexpected RDP message received: ${JSON.stringify(rdpData)}`\n ));\n }\n\n _readMessage(): boolean {\n const {\n data, rdpMessage, error, fatal,\n } = parseRDPMessage(this._incoming);\n\n this._incoming = data;\n\n if (error) {\n this.emit(\n 'error',\n new Error(`Error parsing RDP packet: ${String(error)}`)\n );\n // Disconnect automatically on a fatal error.\n if (fatal) {\n this.disconnect();\n }\n // Caller can parse the next message if the error wasn't fatal\n // (e.g. the RDP packet that couldn't be parsed has been already\n // removed from the incoming data buffer).\n return !fatal;\n }\n\n if (!rdpMessage) {\n // Caller will need to wait more data to parse the next message.\n return false;\n }\n\n this._handleMessage(rdpMessage);\n // Caller can try to parse the next message from the remining data.\n return true;\n }\n\n onData(data: Buffer) {\n this._incoming = Buffer.concat([this._incoming, data]);\n while (this._readMessage()) {\n // Keep parsing and handling messages until readMessage\n // returns false.\n }\n }\n\n onError(error: Error) {\n this.emit('error', error);\n }\n\n onEnd() {\n this.emit('end');\n }\n\n onTimeout() {\n this.emit('timeout');\n }\n}\n"],"mappings":"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"}
@@ -1,18 +1,16 @@
1
+
1
2
  import net from 'net';
2
3
  import FirefoxRDPClient, { connectToFirefox as defaultFirefoxConnector } from './rdp-client.js';
3
4
  import { createLogger } from '../util/logger.js';
4
5
  import { isErrorWithCode, RemoteTempInstallNotSupported, UsageError, WebExtError } from '../errors.js';
5
6
  const log = createLogger(import.meta.url);
6
-
7
7
  // Convert a request rejection to a message string.
8
8
  function requestErrorToMessage(err) {
9
9
  if (err instanceof Error) {
10
10
  return String(err);
11
11
  }
12
-
13
12
  return `${err.error}: ${err.message}`;
14
13
  }
15
-
16
14
  export class RemoteFirefox {
17
15
  constructor(client) {
18
16
  this.client = client;
@@ -33,11 +31,9 @@ export class RemoteFirefox {
33
31
  log.debug(`Received error from client: ${String(error)}`);
34
32
  });
35
33
  }
36
-
37
34
  disconnect() {
38
35
  this.client.disconnect();
39
36
  }
40
-
41
37
  async addonRequest(addon, request) {
42
38
  try {
43
39
  const response = await this.client.request({
@@ -51,30 +47,25 @@ export class RemoteFirefox {
51
47
  throw new WebExtError(`Remote Firefox: addonRequest() error: ${message}`);
52
48
  }
53
49
  }
54
-
55
50
  async getAddonsActor() {
56
51
  try {
57
52
  // getRoot should work since Firefox 55 (bug 1352157).
58
53
  const response = await this.client.request('getRoot');
59
-
60
54
  if (response.addonsActor == null) {
61
55
  return Promise.reject(new RemoteTempInstallNotSupported('This version of Firefox does not provide an add-ons actor for ' + 'remote installation.'));
62
56
  }
63
-
64
57
  return response.addonsActor;
65
58
  } catch (err) {
66
59
  // Fallback to listTabs otherwise, Firefox 49 - 77 (bug 1618691).
67
60
  log.debug('Falling back to listTabs because getRoot failed', err);
68
61
  }
69
-
70
62
  try {
71
- const response = await this.client.request('listTabs'); // addonsActor was added to listTabs in Firefox 49 (bug 1273183).
72
-
63
+ const response = await this.client.request('listTabs');
64
+ // addonsActor was added to listTabs in Firefox 49 (bug 1273183).
73
65
  if (response.addonsActor == null) {
74
66
  log.debug('listTabs returned a falsey addonsActor: ' + `${JSON.stringify(response)}`);
75
67
  return Promise.reject(new RemoteTempInstallNotSupported('This is an older version of Firefox that does not provide an ' + 'add-ons actor for remote installation. Try Firefox 49 or ' + 'higher.'));
76
68
  }
77
-
78
69
  return response.addonsActor;
79
70
  } catch (err) {
80
71
  log.debug('listTabs error', err);
@@ -82,15 +73,14 @@ export class RemoteFirefox {
82
73
  throw new WebExtError(`Remote Firefox: listTabs() error: ${message}`);
83
74
  }
84
75
  }
85
-
86
- async installTemporaryAddon(addonPath) {
76
+ async installTemporaryAddon(addonPath, openDevTools) {
87
77
  const addonsActor = await this.getAddonsActor();
88
-
89
78
  try {
90
79
  const response = await this.client.request({
91
80
  to: addonsActor,
92
81
  type: 'installTemporaryAddon',
93
- addonPath
82
+ addonPath,
83
+ openDevTools
94
84
  });
95
85
  log.debug(`installTemporaryAddon: ${JSON.stringify(response)}`);
96
86
  log.info(`Installed ${addonPath} as a temporary add-on`);
@@ -100,17 +90,14 @@ export class RemoteFirefox {
100
90
  throw new WebExtError(`installTemporaryAddon: Error: ${message}`);
101
91
  }
102
92
  }
103
-
104
93
  async getInstalledAddon(addonId) {
105
94
  try {
106
95
  const response = await this.client.request('listAddons');
107
-
108
96
  for (const addon of response.addons) {
109
97
  if (addon.id === addonId) {
110
98
  return addon;
111
99
  }
112
100
  }
113
-
114
101
  log.debug(`Remote Firefox has these addons: ${response.addons.map(a => a.id)}`);
115
102
  return Promise.reject(new WebExtError('The remote Firefox does not have your extension installed'));
116
103
  } catch (err) {
@@ -118,14 +105,12 @@ export class RemoteFirefox {
118
105
  throw new WebExtError(`Remote Firefox: listAddons() error: ${message}`);
119
106
  }
120
107
  }
121
-
122
108
  async checkForAddonReloading(addon) {
123
109
  if (this.checkedForAddonReloading) {
124
110
  // We only need to check once if reload() is supported.
125
111
  return addon;
126
112
  } else {
127
113
  const response = await this.addonRequest(addon, 'requestTypes');
128
-
129
114
  if (response.requestTypes.indexOf('reload') === -1) {
130
115
  const supportedRequestTypes = JSON.stringify(response.requestTypes);
131
116
  log.debug(`Remote Firefox only supports: ${supportedRequestTypes}`);
@@ -136,7 +121,6 @@ export class RemoteFirefox {
136
121
  }
137
122
  }
138
123
  }
139
-
140
124
  async reloadAddon(addonId) {
141
125
  const addon = await this.getInstalledAddon(addonId);
142
126
  await this.checkForAddonReloading(addon);
@@ -144,8 +128,9 @@ export class RemoteFirefox {
144
128
  process.stdout.write(`\rLast extension reload: ${new Date().toTimeString()}`);
145
129
  log.debug('\n');
146
130
  }
131
+ }
147
132
 
148
- } // Connect types and implementation
133
+ // Connect types and implementation
149
134
 
150
135
  export async function connect(port, {
151
136
  connectToFirefox = defaultFirefoxConnector
@@ -154,9 +139,12 @@ export async function connect(port, {
154
139
  const client = await connectToFirefox(port);
155
140
  log.debug(`Connected to the remote Firefox debugger on port ${port}`);
156
141
  return new RemoteFirefox(client);
157
- } // ConnectWithMaxRetries types and implementation
142
+ }
143
+
144
+ // ConnectWithMaxRetries types and implementation
158
145
 
159
- export async function connectWithMaxRetries( // A max of 250 will try connecting for 30 seconds.
146
+ export async function connectWithMaxRetries(
147
+ // A max of 250 will try connecting for 30 seconds.
160
148
  {
161
149
  maxRetries = 250,
162
150
  retryInterval = 120,
@@ -166,7 +154,6 @@ export async function connectWithMaxRetries( // A max of 250 will try connecting
166
154
  } = {}) {
167
155
  async function establishConnection() {
168
156
  var lastError;
169
-
170
157
  for (let retries = 0; retries <= maxRetries; retries++) {
171
158
  try {
172
159
  return await connectToFirefox(port);
@@ -184,18 +171,16 @@ export async function connectWithMaxRetries( // A max of 250 will try connecting
184
171
  }
185
172
  }
186
173
  }
187
-
188
174
  log.debug('Connect to Firefox debugger: too many retries');
189
175
  throw lastError;
190
176
  }
191
-
192
177
  log.debug('Connecting to the remote Firefox debugger');
193
178
  return establishConnection();
194
179
  }
195
180
  export function findFreeTcpPort() {
196
181
  return new Promise(resolve => {
197
- const srv = net.createServer(); // $FlowFixMe: signature for listen() is missing - see https://github.com/facebook/flow/pull/8290
198
-
182
+ const srv = net.createServer();
183
+ // $FlowFixMe: signature for listen() is missing - see https://github.com/facebook/flow/pull/8290
199
184
  srv.listen(0, '127.0.0.1', () => {
200
185
  const freeTcpPort = srv.address().port;
201
186
  srv.close(() => resolve(freeTcpPort));
@@ -1 +1 @@
1
- {"version":3,"file":"remote.js","names":["net","FirefoxRDPClient","connectToFirefox","defaultFirefoxConnector","createLogger","isErrorWithCode","RemoteTempInstallNotSupported","UsageError","WebExtError","log","import","meta","url","requestErrorToMessage","err","Error","String","error","message","RemoteFirefox","constructor","client","checkedForAddonReloading","on","debug","info","JSON","stringify","rdpError","disconnect","addonRequest","addon","request","response","to","actor","type","getAddonsActor","addonsActor","Promise","reject","installTemporaryAddon","addonPath","getInstalledAddon","addonId","addons","id","map","a","checkForAddonReloading","requestTypes","indexOf","supportedRequestTypes","reloadAddon","process","stdout","write","Date","toTimeString","connect","port","connectWithMaxRetries","maxRetries","retryInterval","establishConnection","lastError","retries","resolve","setTimeout","stack","findFreeTcpPort","srv","createServer","listen","freeTcpPort","address","close"],"sources":["../../src/firefox/remote.js"],"sourcesContent":["/* @flow */\nimport net from 'net';\n\nimport FirefoxRDPClient, {\n connectToFirefox as defaultFirefoxConnector,\n} from './rdp-client.js';\nimport {createLogger} from '../util/logger.js';\nimport {\n isErrorWithCode,\n RemoteTempInstallNotSupported,\n UsageError,\n WebExtError,\n} from '../errors.js';\n\nconst log = createLogger(import.meta.url);\n\nexport type FirefoxConnectorFn =\n (port: number) => Promise<FirefoxRDPClient>;\n\nexport type FirefoxRDPAddonActor = {|\n id: string,\n actor: string,\n|};\n\nexport type FirefoxRDPResponseError = {|\n error: string,\n message: string,\n|};\n\nexport type FirefoxRDPResponseAddon = {|\n addon: FirefoxRDPAddonActor,\n|};\n\nexport type FirefoxRDPResponseRequestTypes = {|\n requestTypes: Array<string>,\n|};\n\n// NOTE: this type aliases Object to catch any other possible response.\nexport type FirefoxRDPResponseAny = Object;\n\nexport type FirefoxRDPResponseMaybe =\n FirefoxRDPResponseRequestTypes | FirefoxRDPResponseAny;\n\n// Convert a request rejection to a message string.\nfunction requestErrorToMessage(err: Error | FirefoxRDPResponseError) {\n if (err instanceof Error) {\n return String(err);\n }\n return `${err.error}: ${err.message}`;\n}\n\nexport class RemoteFirefox {\n client: Object;\n checkedForAddonReloading: boolean;\n\n constructor(client: FirefoxRDPClient) {\n this.client = client;\n this.checkedForAddonReloading = false;\n\n client.on('disconnect', () => {\n log.debug('Received \"disconnect\" from Firefox client');\n });\n client.on('end', () => {\n log.debug('Received \"end\" from Firefox client');\n });\n client.on('unsolicited-event', (info) => {\n log.debug(`Received message from client: ${JSON.stringify(info)}`);\n });\n client.on('rdp-error', (rdpError) => {\n log.debug(`Received error from client: ${JSON.stringify(rdpError)}`);\n });\n client.on('error', (error) => {\n log.debug(`Received error from client: ${String(error)}`);\n });\n }\n\n disconnect() {\n this.client.disconnect();\n }\n\n async addonRequest(\n addon: FirefoxRDPAddonActor,\n request: string\n ): Promise<FirefoxRDPResponseMaybe> {\n try {\n const response = await this.client.request({\n to: addon.actor, type: request,\n });\n return response;\n } catch (err) {\n log.debug(\n `Client responded to '${request}' request with error:`, err);\n const message = requestErrorToMessage(err);\n throw new WebExtError(`Remote Firefox: addonRequest() error: ${message}`);\n }\n }\n\n async getAddonsActor(): Promise<string> {\n try {\n // getRoot should work since Firefox 55 (bug 1352157).\n const response = await this.client.request('getRoot');\n if (response.addonsActor == null) {\n return Promise.reject(new RemoteTempInstallNotSupported(\n 'This version of Firefox does not provide an add-ons actor for ' +\n 'remote installation.'));\n }\n return response.addonsActor;\n } catch (err) {\n // Fallback to listTabs otherwise, Firefox 49 - 77 (bug 1618691).\n log.debug('Falling back to listTabs because getRoot failed', err);\n }\n\n try {\n const response = await this.client.request('listTabs');\n // addonsActor was added to listTabs in Firefox 49 (bug 1273183).\n if (response.addonsActor == null) {\n log.debug(\n 'listTabs returned a falsey addonsActor: ' +\n `${JSON.stringify(response)}`);\n return Promise.reject(new RemoteTempInstallNotSupported(\n 'This is an older version of Firefox that does not provide an ' +\n 'add-ons actor for remote installation. Try Firefox 49 or ' +\n 'higher.'));\n }\n return response.addonsActor;\n } catch (err) {\n log.debug('listTabs error', err);\n const message = requestErrorToMessage(err);\n throw new WebExtError(`Remote Firefox: listTabs() error: ${message}`);\n }\n }\n\n async installTemporaryAddon(\n addonPath: string\n ): Promise<FirefoxRDPResponseAddon> {\n const addonsActor = await this.getAddonsActor();\n\n try {\n const response = await this.client.request({\n to: addonsActor,\n type: 'installTemporaryAddon',\n addonPath,\n });\n log.debug(`installTemporaryAddon: ${JSON.stringify(response)}`);\n log.info(`Installed ${addonPath} as a temporary add-on`);\n return response;\n } catch (err) {\n const message = requestErrorToMessage(err);\n throw new WebExtError(`installTemporaryAddon: Error: ${message}`);\n }\n }\n\n async getInstalledAddon(addonId: string): Promise<FirefoxRDPAddonActor> {\n try {\n const response = await this.client.request('listAddons');\n for (const addon of response.addons) {\n if (addon.id === addonId) {\n return addon;\n }\n }\n log.debug(\n `Remote Firefox has these addons: ${response.addons.map((a) => a.id)}`);\n return Promise.reject(new WebExtError(\n 'The remote Firefox does not have your extension installed'));\n } catch (err) {\n const message = requestErrorToMessage(err);\n throw new WebExtError(`Remote Firefox: listAddons() error: ${message}`);\n }\n }\n\n async checkForAddonReloading(\n addon: FirefoxRDPAddonActor\n ): Promise<FirefoxRDPAddonActor> {\n if (this.checkedForAddonReloading) {\n // We only need to check once if reload() is supported.\n return addon;\n } else {\n const response = await this.addonRequest(addon, 'requestTypes');\n\n if (response.requestTypes.indexOf('reload') === -1) {\n const supportedRequestTypes = JSON.stringify(response.requestTypes);\n log.debug(\n `Remote Firefox only supports: ${supportedRequestTypes}`);\n throw new UsageError(\n 'This Firefox version does not support add-on reloading. ' +\n 'Re-run with --no-reload');\n } else {\n this.checkedForAddonReloading = true;\n return addon;\n }\n }\n }\n\n async reloadAddon(addonId: string): Promise<void> {\n const addon = await this.getInstalledAddon(addonId);\n await this.checkForAddonReloading(addon);\n await this.addonRequest(addon, 'reload');\n process.stdout.write(\n `\\rLast extension reload: ${(new Date()).toTimeString()}`);\n log.debug('\\n');\n }\n}\n\n\n// Connect types and implementation\n\nexport type ConnectOptions = {\n connectToFirefox: FirefoxConnectorFn,\n};\n\nexport async function connect(\n port: number,\n {connectToFirefox = defaultFirefoxConnector}: ConnectOptions = {}\n): Promise<RemoteFirefox> {\n log.debug(`Connecting to Firefox on port ${port}`);\n const client = await connectToFirefox(port);\n log.debug(`Connected to the remote Firefox debugger on port ${port}`);\n return new RemoteFirefox(client);\n}\n\n\n// ConnectWithMaxRetries types and implementation\n\nexport type ConnectWithMaxRetriesParams = {|\n maxRetries?: number,\n retryInterval?: number,\n port: number,\n|};\n\nexport type ConnectWithMaxRetriesDeps = {\n connectToFirefox: typeof connect,\n};\n\nexport async function connectWithMaxRetries(\n // A max of 250 will try connecting for 30 seconds.\n {maxRetries = 250, retryInterval = 120, port}: ConnectWithMaxRetriesParams,\n {connectToFirefox = connect}: ConnectWithMaxRetriesDeps = {}\n): Promise<RemoteFirefox> {\n async function establishConnection() {\n var lastError;\n\n for (let retries = 0; retries <= maxRetries; retries++) {\n try {\n return await connectToFirefox(port);\n } catch (error) {\n if (isErrorWithCode('ECONNREFUSED', error)) {\n // Wait for `retryInterval` ms.\n await new Promise((resolve) => {\n setTimeout(resolve, retryInterval);\n });\n\n lastError = error;\n log.debug(\n `Retrying Firefox (${retries}); connection error: ${error}`);\n } else {\n log.error(error.stack);\n throw error;\n }\n }\n }\n\n log.debug('Connect to Firefox debugger: too many retries');\n throw lastError;\n }\n\n log.debug('Connecting to the remote Firefox debugger');\n return establishConnection();\n}\n\nexport function findFreeTcpPort(): Promise<number> {\n return new Promise((resolve) => {\n const srv = net.createServer();\n // $FlowFixMe: signature for listen() is missing - see https://github.com/facebook/flow/pull/8290\n srv.listen(0, '127.0.0.1', () => {\n const freeTcpPort = srv.address().port;\n srv.close(() => resolve(freeTcpPort));\n });\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"remote.js","names":["net","FirefoxRDPClient","connectToFirefox","defaultFirefoxConnector","createLogger","isErrorWithCode","RemoteTempInstallNotSupported","UsageError","WebExtError","log","import","meta","url","requestErrorToMessage","err","Error","String","error","message","RemoteFirefox","constructor","client","checkedForAddonReloading","on","debug","info","JSON","stringify","rdpError","disconnect","addonRequest","addon","request","response","to","actor","type","getAddonsActor","addonsActor","Promise","reject","installTemporaryAddon","addonPath","openDevTools","getInstalledAddon","addonId","addons","id","map","a","checkForAddonReloading","requestTypes","indexOf","supportedRequestTypes","reloadAddon","process","stdout","write","Date","toTimeString","connect","port","connectWithMaxRetries","maxRetries","retryInterval","establishConnection","lastError","retries","resolve","setTimeout","stack","findFreeTcpPort","srv","createServer","listen","freeTcpPort","address","close"],"sources":["../../src/firefox/remote.js"],"sourcesContent":["/* @flow */\nimport net from 'net';\n\nimport FirefoxRDPClient, {\n connectToFirefox as defaultFirefoxConnector,\n} from './rdp-client.js';\nimport {createLogger} from '../util/logger.js';\nimport {\n isErrorWithCode,\n RemoteTempInstallNotSupported,\n UsageError,\n WebExtError,\n} from '../errors.js';\n\nconst log = createLogger(import.meta.url);\n\nexport type FirefoxConnectorFn =\n (port: number) => Promise<FirefoxRDPClient>;\n\nexport type FirefoxRDPAddonActor = {|\n id: string,\n actor: string,\n|};\n\nexport type FirefoxRDPResponseError = {|\n error: string,\n message: string,\n|};\n\nexport type FirefoxRDPResponseAddon = {|\n addon: FirefoxRDPAddonActor,\n|};\n\nexport type FirefoxRDPResponseRequestTypes = {|\n requestTypes: Array<string>,\n|};\n\n// NOTE: this type aliases Object to catch any other possible response.\nexport type FirefoxRDPResponseAny = Object;\n\nexport type FirefoxRDPResponseMaybe =\n FirefoxRDPResponseRequestTypes | FirefoxRDPResponseAny;\n\n// Convert a request rejection to a message string.\nfunction requestErrorToMessage(err: Error | FirefoxRDPResponseError) {\n if (err instanceof Error) {\n return String(err);\n }\n return `${err.error}: ${err.message}`;\n}\n\nexport class RemoteFirefox {\n client: Object;\n checkedForAddonReloading: boolean;\n\n constructor(client: FirefoxRDPClient) {\n this.client = client;\n this.checkedForAddonReloading = false;\n\n client.on('disconnect', () => {\n log.debug('Received \"disconnect\" from Firefox client');\n });\n client.on('end', () => {\n log.debug('Received \"end\" from Firefox client');\n });\n client.on('unsolicited-event', (info) => {\n log.debug(`Received message from client: ${JSON.stringify(info)}`);\n });\n client.on('rdp-error', (rdpError) => {\n log.debug(`Received error from client: ${JSON.stringify(rdpError)}`);\n });\n client.on('error', (error) => {\n log.debug(`Received error from client: ${String(error)}`);\n });\n }\n\n disconnect() {\n this.client.disconnect();\n }\n\n async addonRequest(\n addon: FirefoxRDPAddonActor,\n request: string\n ): Promise<FirefoxRDPResponseMaybe> {\n try {\n const response = await this.client.request({\n to: addon.actor, type: request,\n });\n return response;\n } catch (err) {\n log.debug(\n `Client responded to '${request}' request with error:`, err);\n const message = requestErrorToMessage(err);\n throw new WebExtError(`Remote Firefox: addonRequest() error: ${message}`);\n }\n }\n\n async getAddonsActor(): Promise<string> {\n try {\n // getRoot should work since Firefox 55 (bug 1352157).\n const response = await this.client.request('getRoot');\n if (response.addonsActor == null) {\n return Promise.reject(new RemoteTempInstallNotSupported(\n 'This version of Firefox does not provide an add-ons actor for ' +\n 'remote installation.'));\n }\n return response.addonsActor;\n } catch (err) {\n // Fallback to listTabs otherwise, Firefox 49 - 77 (bug 1618691).\n log.debug('Falling back to listTabs because getRoot failed', err);\n }\n\n try {\n const response = await this.client.request('listTabs');\n // addonsActor was added to listTabs in Firefox 49 (bug 1273183).\n if (response.addonsActor == null) {\n log.debug(\n 'listTabs returned a falsey addonsActor: ' +\n `${JSON.stringify(response)}`);\n return Promise.reject(new RemoteTempInstallNotSupported(\n 'This is an older version of Firefox that does not provide an ' +\n 'add-ons actor for remote installation. Try Firefox 49 or ' +\n 'higher.'));\n }\n return response.addonsActor;\n } catch (err) {\n log.debug('listTabs error', err);\n const message = requestErrorToMessage(err);\n throw new WebExtError(`Remote Firefox: listTabs() error: ${message}`);\n }\n }\n\n async installTemporaryAddon(\n addonPath: string,\n openDevTools?: boolean\n ): Promise<FirefoxRDPResponseAddon> {\n const addonsActor = await this.getAddonsActor();\n\n try {\n const response = await this.client.request({\n to: addonsActor,\n type: 'installTemporaryAddon',\n addonPath,\n openDevTools,\n });\n log.debug(`installTemporaryAddon: ${JSON.stringify(response)}`);\n log.info(`Installed ${addonPath} as a temporary add-on`);\n return response;\n } catch (err) {\n const message = requestErrorToMessage(err);\n throw new WebExtError(`installTemporaryAddon: Error: ${message}`);\n }\n }\n\n async getInstalledAddon(addonId: string): Promise<FirefoxRDPAddonActor> {\n try {\n const response = await this.client.request('listAddons');\n for (const addon of response.addons) {\n if (addon.id === addonId) {\n return addon;\n }\n }\n log.debug(\n `Remote Firefox has these addons: ${response.addons.map((a) => a.id)}`);\n return Promise.reject(new WebExtError(\n 'The remote Firefox does not have your extension installed'));\n } catch (err) {\n const message = requestErrorToMessage(err);\n throw new WebExtError(`Remote Firefox: listAddons() error: ${message}`);\n }\n }\n\n async checkForAddonReloading(\n addon: FirefoxRDPAddonActor\n ): Promise<FirefoxRDPAddonActor> {\n if (this.checkedForAddonReloading) {\n // We only need to check once if reload() is supported.\n return addon;\n } else {\n const response = await this.addonRequest(addon, 'requestTypes');\n\n if (response.requestTypes.indexOf('reload') === -1) {\n const supportedRequestTypes = JSON.stringify(response.requestTypes);\n log.debug(\n `Remote Firefox only supports: ${supportedRequestTypes}`);\n throw new UsageError(\n 'This Firefox version does not support add-on reloading. ' +\n 'Re-run with --no-reload');\n } else {\n this.checkedForAddonReloading = true;\n return addon;\n }\n }\n }\n\n async reloadAddon(addonId: string): Promise<void> {\n const addon = await this.getInstalledAddon(addonId);\n await this.checkForAddonReloading(addon);\n await this.addonRequest(addon, 'reload');\n process.stdout.write(\n `\\rLast extension reload: ${(new Date()).toTimeString()}`);\n log.debug('\\n');\n }\n}\n\n\n// Connect types and implementation\n\nexport type ConnectOptions = {\n connectToFirefox: FirefoxConnectorFn,\n};\n\nexport async function connect(\n port: number,\n {connectToFirefox = defaultFirefoxConnector}: ConnectOptions = {}\n): Promise<RemoteFirefox> {\n log.debug(`Connecting to Firefox on port ${port}`);\n const client = await connectToFirefox(port);\n log.debug(`Connected to the remote Firefox debugger on port ${port}`);\n return new RemoteFirefox(client);\n}\n\n\n// ConnectWithMaxRetries types and implementation\n\nexport type ConnectWithMaxRetriesParams = {|\n maxRetries?: number,\n retryInterval?: number,\n port: number,\n|};\n\nexport type ConnectWithMaxRetriesDeps = {\n connectToFirefox: typeof connect,\n};\n\nexport async function connectWithMaxRetries(\n // A max of 250 will try connecting for 30 seconds.\n {maxRetries = 250, retryInterval = 120, port}: ConnectWithMaxRetriesParams,\n {connectToFirefox = connect}: ConnectWithMaxRetriesDeps = {}\n): Promise<RemoteFirefox> {\n async function establishConnection() {\n var lastError;\n\n for (let retries = 0; retries <= maxRetries; retries++) {\n try {\n return await connectToFirefox(port);\n } catch (error) {\n if (isErrorWithCode('ECONNREFUSED', error)) {\n // Wait for `retryInterval` ms.\n await new Promise((resolve) => {\n setTimeout(resolve, retryInterval);\n });\n\n lastError = error;\n log.debug(\n `Retrying Firefox (${retries}); connection error: ${error}`);\n } else {\n log.error(error.stack);\n throw error;\n }\n }\n }\n\n log.debug('Connect to Firefox debugger: too many retries');\n throw lastError;\n }\n\n log.debug('Connecting to the remote Firefox debugger');\n return establishConnection();\n}\n\nexport function findFreeTcpPort(): Promise<number> {\n return new Promise((resolve) => {\n const srv = net.createServer();\n // $FlowFixMe: signature for listen() is missing - see https://github.com/facebook/flow/pull/8290\n srv.listen(0, '127.0.0.1', () => {\n const freeTcpPort = srv.address().port;\n srv.close(() => resolve(freeTcpPort));\n });\n });\n}\n"],"mappings":"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"}
package/lib/main.js CHANGED
@@ -1,7 +1,9 @@
1
+
1
2
  import { main } from './program.js';
2
- import cmd from './cmd/index.js'; // This only exposes main and cmd, while util/logger and util/adb are defined as
3
- // separate additional exports in the package.json.
3
+ import cmd from './cmd/index.js';
4
4
 
5
+ // This only exposes main and cmd, while util/logger and util/adb are defined as
6
+ // separate additional exports in the package.json.
5
7
  export default {
6
8
  main,
7
9
  cmd
package/lib/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","names":["main","cmd"],"sources":["../src/main.js"],"sourcesContent":["/* @flow */\nimport {main} from './program.js';\nimport cmd from './cmd/index.js';\n\n// This only exposes main and cmd, while util/logger and util/adb are defined as\n// separate additional exports in the package.json.\nexport default {main, cmd};\n"],"mappings":"AACA,SAAQA,IAAR,QAAmB,cAAnB;AACA,OAAOC,GAAP,MAAgB,gBAAhB,C,CAEA;AACA;;AACA,eAAe;EAACD,IAAD;EAAOC;AAAP,CAAf"}
1
+ {"version":3,"file":"main.js","names":["main","cmd"],"sources":["../src/main.js"],"sourcesContent":["/* @flow */\nimport {main} from './program.js';\nimport cmd from './cmd/index.js';\n\n// This only exposes main and cmd, while util/logger and util/adb are defined as\n// separate additional exports in the package.json.\nexport default {main, cmd};\n"],"mappings":";AACA,SAAQA,IAAI,QAAO,cAAc;AACjC,OAAOC,GAAG,MAAM,gBAAgB;;AAEhC;AACA;AACA,eAAe;EAACD,IAAI;EAAEC;AAAG,CAAC"}