web-ext 6.7.0 → 7.1.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 +199 -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 +121 -178
  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 +663 -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 +50 -52
  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
@@ -0,0 +1,362 @@
1
+ import nodeFs from 'fs';
2
+ import path from 'path';
3
+ import { promisify } from 'util';
4
+ import { default as defaultFxRunner } from 'fx-runner';
5
+ import FirefoxProfile from 'firefox-profile';
6
+ import { fs } from 'mz';
7
+ import fromEvent from 'promise-toolbox/fromEvent';
8
+ import isDirectory from '../util/is-directory.js';
9
+ import { isErrorWithCode, UsageError, WebExtError } from '../errors.js';
10
+ import { getPrefs as defaultPrefGetter } from './preferences.js';
11
+ import { getManifestId } from '../util/manifest.js';
12
+ import { findFreeTcpPort as defaultRemotePortFinder } from './remote.js';
13
+ import { createLogger } from '../util/logger.js'; // Import flow types
14
+
15
+ const log = createLogger(import.meta.url);
16
+ const defaultAsyncFsStat = fs.stat.bind(fs);
17
+ const defaultUserProfileCopier = FirefoxProfile.copyFromUserProfile;
18
+ export const defaultFirefoxEnv = {
19
+ XPCOM_DEBUG_BREAK: 'stack',
20
+ NS_TRACE_MALLOC_DISABLE_STACKS: '1'
21
+ }; // defaultRemotePortFinder types and implementation.
22
+
23
+ /*
24
+ * Runs Firefox with the given profile object and resolves a promise on exit.
25
+ */
26
+ export async function run(profile, {
27
+ fxRunner = defaultFxRunner,
28
+ findRemotePort = defaultRemotePortFinder,
29
+ firefoxBinary,
30
+ binaryArgs
31
+ } = {}) {
32
+ log.debug(`Running Firefox with profile at ${profile.path()}`);
33
+ const remotePort = await findRemotePort();
34
+ const results = await fxRunner({
35
+ // if this is falsey, fxRunner tries to find the default one.
36
+ 'binary': firefoxBinary,
37
+ 'binary-args': binaryArgs,
38
+ // This ensures a new instance of Firefox is created. It has nothing
39
+ // to do with the devtools remote debugger.
40
+ 'no-remote': true,
41
+ 'listen': remotePort,
42
+ 'foreground': true,
43
+ 'profile': profile.path(),
44
+ 'env': { ...process.env,
45
+ ...defaultFirefoxEnv
46
+ },
47
+ 'verbose': true
48
+ });
49
+ const firefox = results.process;
50
+ log.debug(`Executing Firefox binary: ${results.binary}`);
51
+ log.debug(`Firefox args: ${results.args.join(' ')}`);
52
+ firefox.on('error', error => {
53
+ // TODO: show a nice error when it can't find Firefox.
54
+ // if (/No such file/.test(err) || err.code === 'ENOENT') {
55
+ log.error(`Firefox error: ${error}`);
56
+ throw error;
57
+ });
58
+ log.info('Use --verbose or open Tools > Web Developer > Browser Console ' + 'to see logging');
59
+ firefox.stderr.on('data', data => {
60
+ log.debug(`Firefox stderr: ${data.toString().trim()}`);
61
+ });
62
+ firefox.stdout.on('data', data => {
63
+ log.debug(`Firefox stdout: ${data.toString().trim()}`);
64
+ });
65
+ firefox.on('close', () => {
66
+ log.debug('Firefox closed');
67
+ });
68
+ return {
69
+ firefox,
70
+ debuggerPort: remotePort
71
+ };
72
+ } // isDefaultProfile types and implementation.
73
+
74
+ const DEFAULT_PROFILES_NAMES = ['default', 'dev-edition-default'];
75
+
76
+ /*
77
+ * Tests if a profile is a default Firefox profile (both as a profile name or
78
+ * profile path).
79
+ *
80
+ * Returns a promise that resolves to true if the profile is one of default Firefox profile.
81
+ */
82
+ export async function isDefaultProfile(profilePathOrName, ProfileFinder = FirefoxProfile.Finder, fsStat = fs.stat) {
83
+ if (DEFAULT_PROFILES_NAMES.includes(profilePathOrName)) {
84
+ return true;
85
+ }
86
+
87
+ const baseProfileDir = ProfileFinder.locateUserDirectory();
88
+ const profilesIniPath = path.join(baseProfileDir, 'profiles.ini');
89
+
90
+ try {
91
+ await fsStat(profilesIniPath);
92
+ } catch (error) {
93
+ if (isErrorWithCode('ENOENT', error)) {
94
+ log.debug(`profiles.ini not found: ${error}`); // No profiles exist yet, default to false (the default profile name contains a
95
+ // random generated component).
96
+
97
+ return false;
98
+ } // Re-throw any unexpected exception.
99
+
100
+
101
+ throw error;
102
+ } // Check for profile dir path.
103
+
104
+
105
+ const finder = new ProfileFinder(baseProfileDir);
106
+ const readProfiles = promisify((...args) => finder.readProfiles(...args));
107
+ await readProfiles();
108
+ const normalizedProfileDirPath = path.normalize(path.join(path.resolve(profilePathOrName), path.sep));
109
+
110
+ for (const profile of finder.profiles) {
111
+ // Check if the profile dir path or name is one of the default profiles
112
+ // defined in the profiles.ini file.
113
+ if (DEFAULT_PROFILES_NAMES.includes(profile.Name) || profile.Default === '1') {
114
+ let profileFullPath; // Check for profile name.
115
+
116
+ if (profile.Name === profilePathOrName) {
117
+ return true;
118
+ } // Check for profile path.
119
+
120
+
121
+ if (profile.IsRelative === '1') {
122
+ profileFullPath = path.join(baseProfileDir, profile.Path, path.sep);
123
+ } else {
124
+ profileFullPath = path.join(profile.Path, path.sep);
125
+ }
126
+
127
+ if (path.normalize(profileFullPath) === normalizedProfileDirPath) {
128
+ return true;
129
+ }
130
+ }
131
+ } // Profile directory not found.
132
+
133
+
134
+ return false;
135
+ } // configureProfile types and implementation.
136
+
137
+ /*
138
+ * Configures a profile with common preferences that are required to
139
+ * activate extension development.
140
+ *
141
+ * Returns a promise that resolves with the original profile object.
142
+ */
143
+ export function configureProfile(profile, {
144
+ app = 'firefox',
145
+ getPrefs = defaultPrefGetter,
146
+ customPrefs = {}
147
+ } = {}) {
148
+ // Set default preferences. Some of these are required for the add-on to
149
+ // operate, such as disabling signatures.
150
+ const prefs = getPrefs(app);
151
+ Object.keys(prefs).forEach(pref => {
152
+ profile.setPreference(pref, prefs[pref]);
153
+ });
154
+
155
+ if (Object.keys(customPrefs).length > 0) {
156
+ const customPrefsStr = JSON.stringify(customPrefs, null, 2);
157
+ log.info(`Setting custom Firefox preferences: ${customPrefsStr}`);
158
+ Object.keys(customPrefs).forEach(custom => {
159
+ profile.setPreference(custom, customPrefs[custom]);
160
+ });
161
+ }
162
+
163
+ profile.updatePreferences();
164
+ return Promise.resolve(profile);
165
+ }
166
+ export function defaultCreateProfileFinder({
167
+ userDirectoryPath,
168
+ FxProfile = FirefoxProfile
169
+ } = {}) {
170
+ const finder = new FxProfile.Finder(userDirectoryPath);
171
+ const readProfiles = promisify((...args) => finder.readProfiles(...args));
172
+ const getPath = promisify((...args) => finder.getPath(...args));
173
+ return async profileName => {
174
+ try {
175
+ await readProfiles();
176
+ const hasProfileName = finder.profiles.filter(profileDef => profileDef.Name === profileName).length !== 0;
177
+
178
+ if (hasProfileName) {
179
+ return await getPath(profileName);
180
+ }
181
+ } catch (error) {
182
+ if (!isErrorWithCode('ENOENT', error)) {
183
+ throw error;
184
+ }
185
+
186
+ log.warn('Unable to find Firefox profiles.ini');
187
+ }
188
+ };
189
+ } // useProfile types and implementation.
190
+
191
+ // Use the target path as a Firefox profile without cloning it
192
+ export async function useProfile(profilePath, {
193
+ app,
194
+ configureThisProfile = configureProfile,
195
+ isFirefoxDefaultProfile = isDefaultProfile,
196
+ customPrefs = {},
197
+ createProfileFinder = defaultCreateProfileFinder
198
+ } = {}) {
199
+ const isForbiddenProfile = await isFirefoxDefaultProfile(profilePath);
200
+
201
+ if (isForbiddenProfile) {
202
+ throw new UsageError('Cannot use --keep-profile-changes on a default profile' + ` ("${profilePath}")` + ' because web-ext will make it insecure and unsuitable for daily use.' + '\nSee https://github.com/mozilla/web-ext/issues/1005');
203
+ }
204
+
205
+ let destinationDirectory;
206
+ const getProfilePath = createProfileFinder();
207
+ const profileIsDirPath = await isDirectory(profilePath);
208
+
209
+ if (profileIsDirPath) {
210
+ log.debug(`Using profile directory "${profilePath}"`);
211
+ destinationDirectory = profilePath;
212
+ } else {
213
+ log.debug(`Assuming ${profilePath} is a named profile`);
214
+ destinationDirectory = await getProfilePath(profilePath);
215
+
216
+ if (!destinationDirectory) {
217
+ throw new UsageError(`The request "${profilePath}" profile name ` + 'cannot be resolved to a profile path');
218
+ }
219
+ }
220
+
221
+ const profile = new FirefoxProfile({
222
+ destinationDirectory
223
+ });
224
+ return await configureThisProfile(profile, {
225
+ app,
226
+ customPrefs
227
+ });
228
+ } // createProfile types and implementation.
229
+
230
+ /*
231
+ * Creates a new temporary profile and resolves with the profile object.
232
+ *
233
+ * The profile will be deleted when the system process exits.
234
+ */
235
+ export async function createProfile({
236
+ app,
237
+ configureThisProfile = configureProfile,
238
+ customPrefs = {}
239
+ } = {}) {
240
+ const profile = new FirefoxProfile();
241
+ return await configureThisProfile(profile, {
242
+ app,
243
+ customPrefs
244
+ });
245
+ } // copyProfile types and implementation.
246
+
247
+ /*
248
+ * Copies an existing Firefox profile and creates a new temporary profile.
249
+ * The new profile will be configured with some preferences required to
250
+ * activate extension development.
251
+ *
252
+ * It resolves with the new profile object.
253
+ *
254
+ * The temporary profile will be deleted when the system process exits.
255
+ *
256
+ * The existing profile can be specified as a directory path or a name of
257
+ * one that exists in the current user's Firefox directory.
258
+ */
259
+ export async function copyProfile(profileDirectory, {
260
+ app,
261
+ configureThisProfile = configureProfile,
262
+ copyFromUserProfile = defaultUserProfileCopier,
263
+ customPrefs = {}
264
+ } = {}) {
265
+ const copy = promisify(FirefoxProfile.copy);
266
+ const copyByName = promisify(copyFromUserProfile);
267
+
268
+ try {
269
+ const dirExists = await isDirectory(profileDirectory);
270
+ let profile;
271
+
272
+ if (dirExists) {
273
+ log.debug(`Copying profile directory from "${profileDirectory}"`);
274
+ profile = await copy({
275
+ profileDirectory
276
+ });
277
+ } else {
278
+ log.debug(`Assuming ${profileDirectory} is a named profile`);
279
+ profile = await copyByName({
280
+ name: profileDirectory
281
+ });
282
+ }
283
+
284
+ return configureThisProfile(profile, {
285
+ app,
286
+ customPrefs
287
+ });
288
+ } catch (error) {
289
+ throw new WebExtError(`Could not copy Firefox profile from ${profileDirectory}: ${error}`);
290
+ }
291
+ } // installExtension types and implementation.
292
+
293
+ /*
294
+ * Installs an extension into the given Firefox profile object.
295
+ * Resolves when complete.
296
+ *
297
+ * The extension is copied into a special location and you need to turn
298
+ * on some preferences to allow this. See extensions.autoDisableScopes in
299
+ * ./preferences.js.
300
+ *
301
+ * When asProxy is true, a special proxy file will be installed. This is a
302
+ * text file that contains the path to the extension source.
303
+ */
304
+ export async function installExtension({
305
+ asProxy = false,
306
+ manifestData,
307
+ profile,
308
+ extensionPath,
309
+ asyncFsStat = defaultAsyncFsStat
310
+ }) {
311
+ // This more or less follows
312
+ // https://github.com/saadtazi/firefox-profile-js/blob/master/lib/firefox_profile.js#L531
313
+ // (which is broken for web extensions).
314
+ // TODO: maybe uplift a patch that supports web extensions instead?
315
+ if (!profile.extensionsDir) {
316
+ throw new WebExtError('profile.extensionsDir was unexpectedly empty');
317
+ }
318
+
319
+ try {
320
+ await asyncFsStat(profile.extensionsDir);
321
+ } catch (error) {
322
+ if (isErrorWithCode('ENOENT', error)) {
323
+ log.debug(`Creating extensions directory: ${profile.extensionsDir}`);
324
+ await fs.mkdir(profile.extensionsDir);
325
+ } else {
326
+ throw error;
327
+ }
328
+ }
329
+
330
+ const id = getManifestId(manifestData);
331
+
332
+ if (!id) {
333
+ throw new UsageError('An explicit extension ID is required when installing to ' + 'a profile (applications.gecko.id not found in manifest.json)');
334
+ }
335
+
336
+ if (asProxy) {
337
+ log.debug(`Installing as an extension proxy; source: ${extensionPath}`);
338
+ const isDir = await isDirectory(extensionPath);
339
+
340
+ if (!isDir) {
341
+ throw new WebExtError('proxy install: extensionPath must be the extension source ' + `directory; got: ${extensionPath}`);
342
+ } // Write a special extension proxy file containing the source
343
+ // directory. See:
344
+ // https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment#Firefox_extension_proxy_file
345
+
346
+
347
+ const destPath = path.join(profile.extensionsDir, `${id}`);
348
+ const writeStream = nodeFs.createWriteStream(destPath);
349
+ writeStream.write(extensionPath);
350
+ writeStream.end();
351
+ return await fromEvent(writeStream, 'close');
352
+ } else {
353
+ // Write the XPI file to the profile.
354
+ const readStream = nodeFs.createReadStream(extensionPath);
355
+ const destPath = path.join(profile.extensionsDir, `${id}.xpi`);
356
+ const writeStream = nodeFs.createWriteStream(destPath);
357
+ log.debug(`Installing extension from ${extensionPath} to ${destPath}`);
358
+ readStream.pipe(writeStream);
359
+ return await Promise.all([fromEvent(readStream, 'close'), fromEvent(writeStream, 'close')]);
360
+ }
361
+ }
362
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["nodeFs","path","promisify","default","defaultFxRunner","FirefoxProfile","fs","fromEvent","isDirectory","isErrorWithCode","UsageError","WebExtError","getPrefs","defaultPrefGetter","getManifestId","findFreeTcpPort","defaultRemotePortFinder","createLogger","log","import","meta","url","defaultAsyncFsStat","stat","bind","defaultUserProfileCopier","copyFromUserProfile","defaultFirefoxEnv","XPCOM_DEBUG_BREAK","NS_TRACE_MALLOC_DISABLE_STACKS","run","profile","fxRunner","findRemotePort","firefoxBinary","binaryArgs","debug","remotePort","results","process","env","firefox","binary","args","join","on","error","info","stderr","data","toString","trim","stdout","debuggerPort","DEFAULT_PROFILES_NAMES","isDefaultProfile","profilePathOrName","ProfileFinder","Finder","fsStat","includes","baseProfileDir","locateUserDirectory","profilesIniPath","finder","readProfiles","normalizedProfileDirPath","normalize","resolve","sep","profiles","Name","Default","profileFullPath","IsRelative","Path","configureProfile","app","customPrefs","prefs","Object","keys","forEach","pref","setPreference","length","customPrefsStr","JSON","stringify","custom","updatePreferences","Promise","defaultCreateProfileFinder","userDirectoryPath","FxProfile","getPath","profileName","hasProfileName","filter","profileDef","warn","useProfile","profilePath","configureThisProfile","isFirefoxDefaultProfile","createProfileFinder","isForbiddenProfile","destinationDirectory","getProfilePath","profileIsDirPath","createProfile","copyProfile","profileDirectory","copy","copyByName","dirExists","name","installExtension","asProxy","manifestData","extensionPath","asyncFsStat","extensionsDir","mkdir","id","isDir","destPath","writeStream","createWriteStream","write","end","readStream","createReadStream","pipe","all"],"sources":["../../src/firefox/index.js"],"sourcesContent":["/* @flow */\nimport nodeFs from 'fs';\nimport path from 'path';\nimport {promisify} from 'util';\n\nimport {default as defaultFxRunner} from 'fx-runner';\nimport FirefoxProfile from 'firefox-profile';\nimport {fs} from 'mz';\nimport fromEvent from 'promise-toolbox/fromEvent';\n\nimport isDirectory from '../util/is-directory.js';\nimport {isErrorWithCode, UsageError, WebExtError} from '../errors.js';\nimport {getPrefs as defaultPrefGetter} from './preferences.js';\nimport {getManifestId} from '../util/manifest.js';\nimport {findFreeTcpPort as defaultRemotePortFinder} from './remote.js';\nimport {createLogger} from '../util/logger.js';\n// Import flow types\nimport type {\n PreferencesAppName,\n PreferencesGetterFn,\n FirefoxPreferences,\n} from './preferences';\nimport type {ExtensionManifest} from '../util/manifest.js';\n\n\nconst log = createLogger(import.meta.url);\n\nconst defaultAsyncFsStat: typeof fs.stat = fs.stat.bind(fs);\n\nconst defaultUserProfileCopier = FirefoxProfile.copyFromUserProfile;\n\nexport const defaultFirefoxEnv = {\n XPCOM_DEBUG_BREAK: 'stack',\n NS_TRACE_MALLOC_DISABLE_STACKS: '1',\n};\n\n// defaultRemotePortFinder types and implementation.\n\n\nexport type RemotePortFinderFn =\n () => Promise<number>;\n\n// Declare the needed 'fx-runner' module flow types.\n\nexport type FirefoxRunnerParams = {|\n binary: ?string,\n profile?: string,\n 'new-instance'?: boolean,\n 'no-remote'?: boolean,\n 'foreground'?: boolean,\n 'listen': number,\n 'binary-args'?: Array<string> | string,\n 'env'?: {\n // This match the flowtype signature for process.env (and prevent flow\n // from complaining about differences between their type signature)\n [key: string]: string | void\n },\n 'verbose'?: boolean,\n|};\n\nexport interface FirefoxProcess extends events$EventEmitter {\n stderr: events$EventEmitter;\n stdout: events$EventEmitter;\n kill: Function;\n}\n\nexport type FirefoxRunnerResults = {|\n process: FirefoxProcess,\n binary: string,\n args: Array<string>,\n|}\n\nexport type FirefoxRunnerFn =\n (params: FirefoxRunnerParams) => Promise<FirefoxRunnerResults>;\n\n\nexport type FirefoxInfo = {|\n firefox: FirefoxProcess,\n debuggerPort: number,\n|}\n\n// Run command types and implementaion.\n\nexport type FirefoxRunOptions = {\n fxRunner?: FirefoxRunnerFn,\n findRemotePort?: RemotePortFinderFn,\n firefoxBinary?: string,\n binaryArgs?: Array<string>,\n args?: Array<any>,\n};\n\n/*\n * Runs Firefox with the given profile object and resolves a promise on exit.\n */\nexport async function run(\n profile: FirefoxProfile,\n {\n fxRunner = defaultFxRunner,\n findRemotePort = defaultRemotePortFinder,\n firefoxBinary, binaryArgs,\n }: FirefoxRunOptions = {}\n): Promise<FirefoxInfo> {\n\n log.debug(`Running Firefox with profile at ${profile.path()}`);\n\n const remotePort = await findRemotePort();\n\n const results = await fxRunner({\n // if this is falsey, fxRunner tries to find the default one.\n 'binary': firefoxBinary,\n 'binary-args': binaryArgs,\n // This ensures a new instance of Firefox is created. It has nothing\n // to do with the devtools remote debugger.\n 'no-remote': true,\n 'listen': remotePort,\n 'foreground': true,\n 'profile': profile.path(),\n 'env': {\n ...process.env,\n ...defaultFirefoxEnv,\n },\n 'verbose': true,\n });\n\n const firefox = results.process;\n\n log.debug(`Executing Firefox binary: ${results.binary}`);\n log.debug(`Firefox args: ${results.args.join(' ')}`);\n\n firefox.on('error', (error) => {\n // TODO: show a nice error when it can't find Firefox.\n // if (/No such file/.test(err) || err.code === 'ENOENT') {\n log.error(`Firefox error: ${error}`);\n throw error;\n });\n\n log.info(\n 'Use --verbose or open Tools > Web Developer > Browser Console ' +\n 'to see logging');\n\n firefox.stderr.on('data', (data) => {\n log.debug(`Firefox stderr: ${data.toString().trim()}`);\n });\n\n firefox.stdout.on('data', (data) => {\n log.debug(`Firefox stdout: ${data.toString().trim()}`);\n });\n\n firefox.on('close', () => {\n log.debug('Firefox closed');\n });\n\n return { firefox, debuggerPort: remotePort };\n}\n\n\n// isDefaultProfile types and implementation.\n\nconst DEFAULT_PROFILES_NAMES = [\n 'default',\n 'dev-edition-default',\n];\n\nexport type IsDefaultProfileFn = (\n profilePathOrName: string,\n ProfileFinder?: typeof FirefoxProfile.Finder,\n fsStat?: typeof fs.stat,\n) => Promise<boolean>;\n\n/*\n * Tests if a profile is a default Firefox profile (both as a profile name or\n * profile path).\n *\n * Returns a promise that resolves to true if the profile is one of default Firefox profile.\n */\nexport async function isDefaultProfile(\n profilePathOrName: string,\n ProfileFinder?: typeof FirefoxProfile.Finder = FirefoxProfile.Finder,\n fsStat?: typeof fs.stat = fs.stat,\n): Promise<boolean> {\n if (DEFAULT_PROFILES_NAMES.includes(profilePathOrName)) {\n return true;\n }\n\n const baseProfileDir = ProfileFinder.locateUserDirectory();\n const profilesIniPath = path.join(baseProfileDir, 'profiles.ini');\n try {\n await fsStat(profilesIniPath);\n } catch (error) {\n if (isErrorWithCode('ENOENT', error)) {\n log.debug(`profiles.ini not found: ${error}`);\n\n // No profiles exist yet, default to false (the default profile name contains a\n // random generated component).\n return false;\n }\n\n // Re-throw any unexpected exception.\n throw error;\n }\n\n // Check for profile dir path.\n const finder = new ProfileFinder(baseProfileDir);\n const readProfiles = promisify((...args) => finder.readProfiles(...args));\n\n await readProfiles();\n\n const normalizedProfileDirPath = path.normalize(\n path.join(path.resolve(profilePathOrName), path.sep)\n );\n\n for (const profile of finder.profiles) {\n // Check if the profile dir path or name is one of the default profiles\n // defined in the profiles.ini file.\n if (DEFAULT_PROFILES_NAMES.includes(profile.Name) ||\n profile.Default === '1') {\n let profileFullPath;\n\n // Check for profile name.\n if (profile.Name === profilePathOrName) {\n return true;\n }\n\n // Check for profile path.\n if (profile.IsRelative === '1') {\n profileFullPath = path.join(baseProfileDir, profile.Path, path.sep);\n } else {\n profileFullPath = path.join(profile.Path, path.sep);\n }\n\n if (path.normalize(profileFullPath) === normalizedProfileDirPath) {\n return true;\n }\n }\n }\n\n // Profile directory not found.\n return false;\n}\n\n// configureProfile types and implementation.\n\nexport type ConfigureProfileOptions = {\n app?: PreferencesAppName,\n getPrefs?: PreferencesGetterFn,\n customPrefs?: FirefoxPreferences,\n};\n\nexport type ConfigureProfileFn = (\n profile: FirefoxProfile,\n options?: ConfigureProfileOptions\n) => Promise<FirefoxProfile>;\n\n/*\n * Configures a profile with common preferences that are required to\n * activate extension development.\n *\n * Returns a promise that resolves with the original profile object.\n */\nexport function configureProfile(\n profile: FirefoxProfile,\n {\n app = 'firefox',\n getPrefs = defaultPrefGetter,\n customPrefs = {},\n }: ConfigureProfileOptions = {},\n): Promise<FirefoxProfile> {\n // Set default preferences. Some of these are required for the add-on to\n // operate, such as disabling signatures.\n const prefs = getPrefs(app);\n Object.keys(prefs).forEach((pref) => {\n profile.setPreference(pref, prefs[pref]);\n });\n if (Object.keys(customPrefs).length > 0) {\n const customPrefsStr = JSON.stringify(customPrefs, null, 2);\n log.info(`Setting custom Firefox preferences: ${customPrefsStr}`);\n Object.keys(customPrefs).forEach((custom) => {\n profile.setPreference(custom, customPrefs[custom]);\n });\n }\n profile.updatePreferences();\n return Promise.resolve(profile);\n}\n\nexport type getProfileFn = (profileName: string) => Promise<string | void>;\n\nexport type CreateProfileFinderParams = {\n userDirectoryPath?: string,\n FxProfile?: typeof FirefoxProfile\n}\n\nexport function defaultCreateProfileFinder(\n {\n userDirectoryPath,\n FxProfile = FirefoxProfile,\n }: CreateProfileFinderParams = {}\n): getProfileFn {\n const finder = new FxProfile.Finder(userDirectoryPath);\n const readProfiles = promisify((...args) => finder.readProfiles(...args));\n const getPath = promisify((...args) => finder.getPath(...args));\n return async (profileName: string): Promise<string | void> => {\n try {\n await readProfiles();\n const hasProfileName = finder.profiles.filter(\n (profileDef) => profileDef.Name === profileName).length !== 0;\n if (hasProfileName) {\n return await getPath(profileName);\n }\n } catch (error) {\n if (!isErrorWithCode('ENOENT', error)) {\n throw error;\n }\n log.warn('Unable to find Firefox profiles.ini');\n }\n };\n}\n\n// useProfile types and implementation.\n\nexport type UseProfileParams = {\n app?: PreferencesAppName,\n configureThisProfile?: ConfigureProfileFn,\n isFirefoxDefaultProfile?: IsDefaultProfileFn,\n customPrefs?: FirefoxPreferences,\n createProfileFinder?: typeof defaultCreateProfileFinder,\n};\n\n// Use the target path as a Firefox profile without cloning it\n\nexport async function useProfile(\n profilePath: string,\n {\n app,\n configureThisProfile = configureProfile,\n isFirefoxDefaultProfile = isDefaultProfile,\n customPrefs = {},\n createProfileFinder = defaultCreateProfileFinder,\n }: UseProfileParams = {},\n): Promise<FirefoxProfile> {\n const isForbiddenProfile = await isFirefoxDefaultProfile(profilePath);\n if (isForbiddenProfile) {\n throw new UsageError(\n 'Cannot use --keep-profile-changes on a default profile' +\n ` (\"${profilePath}\")` +\n ' because web-ext will make it insecure and unsuitable for daily use.' +\n '\\nSee https://github.com/mozilla/web-ext/issues/1005'\n );\n }\n\n let destinationDirectory;\n const getProfilePath = createProfileFinder();\n\n const profileIsDirPath = await isDirectory(profilePath);\n if (profileIsDirPath) {\n log.debug(`Using profile directory \"${profilePath}\"`);\n destinationDirectory = profilePath;\n } else {\n log.debug(`Assuming ${profilePath} is a named profile`);\n destinationDirectory = await getProfilePath(profilePath);\n if (!destinationDirectory) {\n throw new UsageError(\n `The request \"${profilePath}\" profile name ` +\n 'cannot be resolved to a profile path'\n );\n }\n }\n\n const profile = new FirefoxProfile({destinationDirectory});\n return await configureThisProfile(profile, {app, customPrefs});\n}\n\n\n// createProfile types and implementation.\n\nexport type CreateProfileParams = {\n app?: PreferencesAppName,\n configureThisProfile?: ConfigureProfileFn,\n customPrefs?: FirefoxPreferences,\n};\n\n/*\n * Creates a new temporary profile and resolves with the profile object.\n *\n * The profile will be deleted when the system process exits.\n */\nexport async function createProfile(\n {\n app,\n configureThisProfile = configureProfile,\n customPrefs = {},\n }: CreateProfileParams = {},\n): Promise<FirefoxProfile> {\n const profile = new FirefoxProfile();\n return await configureThisProfile(profile, {app, customPrefs});\n}\n\n\n// copyProfile types and implementation.\n\nexport type CopyProfileOptions = {\n app?: PreferencesAppName,\n configureThisProfile?: ConfigureProfileFn,\n copyFromUserProfile?: Function,\n customPrefs?: FirefoxPreferences,\n};\n\n/*\n * Copies an existing Firefox profile and creates a new temporary profile.\n * The new profile will be configured with some preferences required to\n * activate extension development.\n *\n * It resolves with the new profile object.\n *\n * The temporary profile will be deleted when the system process exits.\n *\n * The existing profile can be specified as a directory path or a name of\n * one that exists in the current user's Firefox directory.\n */\nexport async function copyProfile(\n profileDirectory: string,\n {\n app,\n configureThisProfile = configureProfile,\n copyFromUserProfile = defaultUserProfileCopier,\n customPrefs = {},\n }: CopyProfileOptions = {},\n): Promise<FirefoxProfile> {\n\n const copy = promisify(FirefoxProfile.copy);\n const copyByName = promisify(copyFromUserProfile);\n\n try {\n const dirExists = await isDirectory(profileDirectory);\n\n let profile;\n\n if (dirExists) {\n log.debug(`Copying profile directory from \"${profileDirectory}\"`);\n profile = await copy({profileDirectory});\n } else {\n log.debug(`Assuming ${profileDirectory} is a named profile`);\n profile = await copyByName({name: profileDirectory});\n }\n\n return configureThisProfile(profile, {app, customPrefs});\n } catch (error) {\n throw new WebExtError(\n `Could not copy Firefox profile from ${profileDirectory}: ${error}`);\n }\n}\n\n\n// installExtension types and implementation.\n\nexport type InstallExtensionParams = {|\n asProxy?: boolean,\n manifestData: ExtensionManifest,\n profile: FirefoxProfile,\n extensionPath: string,\n asyncFsStat?: typeof defaultAsyncFsStat,\n|};\n\n/*\n * Installs an extension into the given Firefox profile object.\n * Resolves when complete.\n *\n * The extension is copied into a special location and you need to turn\n * on some preferences to allow this. See extensions.autoDisableScopes in\n * ./preferences.js.\n *\n * When asProxy is true, a special proxy file will be installed. This is a\n * text file that contains the path to the extension source.\n */\nexport async function installExtension(\n {\n asProxy = false,\n manifestData,\n profile,\n extensionPath,\n asyncFsStat = defaultAsyncFsStat,\n }: InstallExtensionParams): Promise<any> {\n // This more or less follows\n // https://github.com/saadtazi/firefox-profile-js/blob/master/lib/firefox_profile.js#L531\n // (which is broken for web extensions).\n // TODO: maybe uplift a patch that supports web extensions instead?\n\n if (!profile.extensionsDir) {\n throw new WebExtError('profile.extensionsDir was unexpectedly empty');\n }\n\n try {\n await asyncFsStat(profile.extensionsDir);\n } catch (error) {\n if (isErrorWithCode('ENOENT', error)) {\n log.debug(`Creating extensions directory: ${profile.extensionsDir}`);\n await fs.mkdir(profile.extensionsDir);\n } else {\n throw error;\n }\n }\n\n const id = getManifestId(manifestData);\n if (!id) {\n throw new UsageError(\n 'An explicit extension ID is required when installing to ' +\n 'a profile (applications.gecko.id not found in manifest.json)');\n }\n\n if (asProxy) {\n log.debug(`Installing as an extension proxy; source: ${extensionPath}`);\n\n const isDir = await isDirectory(extensionPath);\n if (!isDir) {\n throw new WebExtError(\n 'proxy install: extensionPath must be the extension source ' +\n `directory; got: ${extensionPath}`);\n }\n\n // Write a special extension proxy file containing the source\n // directory. See:\n // https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment#Firefox_extension_proxy_file\n const destPath = path.join(profile.extensionsDir, `${id}`);\n const writeStream = nodeFs.createWriteStream(destPath);\n writeStream.write(extensionPath);\n writeStream.end();\n return await fromEvent(writeStream, 'close');\n } else {\n // Write the XPI file to the profile.\n const readStream = nodeFs.createReadStream(extensionPath);\n const destPath = path.join(profile.extensionsDir, `${id}.xpi`);\n const writeStream = nodeFs.createWriteStream(destPath);\n\n log.debug(`Installing extension from ${extensionPath} to ${destPath}`);\n readStream.pipe(writeStream);\n\n return await Promise.all([\n fromEvent(readStream, 'close'),\n fromEvent(writeStream, 'close'),\n ]);\n }\n}\n"],"mappings":"AACA,OAAOA,MAAP,MAAmB,IAAnB;AACA,OAAOC,IAAP,MAAiB,MAAjB;AACA,SAAQC,SAAR,QAAwB,MAAxB;AAEA,SAAQC,OAAO,IAAIC,eAAnB,QAAyC,WAAzC;AACA,OAAOC,cAAP,MAA2B,iBAA3B;AACA,SAAQC,EAAR,QAAiB,IAAjB;AACA,OAAOC,SAAP,MAAsB,2BAAtB;AAEA,OAAOC,WAAP,MAAwB,yBAAxB;AACA,SAAQC,eAAR,EAAyBC,UAAzB,EAAqCC,WAArC,QAAuD,cAAvD;AACA,SAAQC,QAAQ,IAAIC,iBAApB,QAA4C,kBAA5C;AACA,SAAQC,aAAR,QAA4B,qBAA5B;AACA,SAAQC,eAAe,IAAIC,uBAA3B,QAAyD,aAAzD;AACA,SAAQC,YAAR,QAA2B,mBAA3B,C,CACA;;AASA,MAAMC,GAAG,GAAGD,YAAY,CAACE,MAAM,CAACC,IAAP,CAAYC,GAAb,CAAxB;AAEA,MAAMC,kBAAkC,GAAGhB,EAAE,CAACiB,IAAH,CAAQC,IAAR,CAAalB,EAAb,CAA3C;AAEA,MAAMmB,wBAAwB,GAAGpB,cAAc,CAACqB,mBAAhD;AAEA,OAAO,MAAMC,iBAAiB,GAAG;EAC/BC,iBAAiB,EAAE,OADY;EAE/BC,8BAA8B,EAAE;AAFD,CAA1B,C,CAKP;;AAuDA;AACA;AACA;AACA,OAAO,eAAeC,GAAf,CACLC,OADK,EAEL;EACEC,QAAQ,GAAG5B,eADb;EAEE6B,cAAc,GAAGjB,uBAFnB;EAGEkB,aAHF;EAGiBC;AAHjB,IAIuB,EANlB,EAOiB;EAEtBjB,GAAG,CAACkB,KAAJ,CAAW,mCAAkCL,OAAO,CAAC9B,IAAR,EAAe,EAA5D;EAEA,MAAMoC,UAAU,GAAG,MAAMJ,cAAc,EAAvC;EAEA,MAAMK,OAAO,GAAG,MAAMN,QAAQ,CAAC;IAC7B;IACA,UAAUE,aAFmB;IAG7B,eAAeC,UAHc;IAI7B;IACA;IACA,aAAa,IANgB;IAO7B,UAAUE,UAPmB;IAQ7B,cAAc,IARe;IAS7B,WAAWN,OAAO,CAAC9B,IAAR,EATkB;IAU7B,OAAO,EACL,GAAGsC,OAAO,CAACC,GADN;MAEL,GAAGb;IAFE,CAVsB;IAc7B,WAAW;EAdkB,CAAD,CAA9B;EAiBA,MAAMc,OAAO,GAAGH,OAAO,CAACC,OAAxB;EAEArB,GAAG,CAACkB,KAAJ,CAAW,6BAA4BE,OAAO,CAACI,MAAO,EAAtD;EACAxB,GAAG,CAACkB,KAAJ,CAAW,iBAAgBE,OAAO,CAACK,IAAR,CAAaC,IAAb,CAAkB,GAAlB,CAAuB,EAAlD;EAEAH,OAAO,CAACI,EAAR,CAAW,OAAX,EAAqBC,KAAD,IAAW;IAC7B;IACA;IACA5B,GAAG,CAAC4B,KAAJ,CAAW,kBAAiBA,KAAM,EAAlC;IACA,MAAMA,KAAN;EACD,CALD;EAOA5B,GAAG,CAAC6B,IAAJ,CACE,mEACA,gBAFF;EAIAN,OAAO,CAACO,MAAR,CAAeH,EAAf,CAAkB,MAAlB,EAA2BI,IAAD,IAAU;IAClC/B,GAAG,CAACkB,KAAJ,CAAW,mBAAkBa,IAAI,CAACC,QAAL,GAAgBC,IAAhB,EAAuB,EAApD;EACD,CAFD;EAIAV,OAAO,CAACW,MAAR,CAAeP,EAAf,CAAkB,MAAlB,EAA2BI,IAAD,IAAU;IAClC/B,GAAG,CAACkB,KAAJ,CAAW,mBAAkBa,IAAI,CAACC,QAAL,GAAgBC,IAAhB,EAAuB,EAApD;EACD,CAFD;EAIAV,OAAO,CAACI,EAAR,CAAW,OAAX,EAAoB,MAAM;IACxB3B,GAAG,CAACkB,KAAJ,CAAU,gBAAV;EACD,CAFD;EAIA,OAAO;IAAEK,OAAF;IAAWY,YAAY,EAAEhB;EAAzB,CAAP;AACD,C,CAGD;;AAEA,MAAMiB,sBAAsB,GAAG,CAC7B,SAD6B,EAE7B,qBAF6B,CAA/B;;AAWA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeC,gBAAf,CACLC,iBADK,EAELC,aAA4C,GAAGpD,cAAc,CAACqD,MAFzD,EAGLC,MAAuB,GAAGrD,EAAE,CAACiB,IAHxB,EAIa;EAClB,IAAI+B,sBAAsB,CAACM,QAAvB,CAAgCJ,iBAAhC,CAAJ,EAAwD;IACtD,OAAO,IAAP;EACD;;EAED,MAAMK,cAAc,GAAGJ,aAAa,CAACK,mBAAd,EAAvB;EACA,MAAMC,eAAe,GAAG9D,IAAI,CAAC2C,IAAL,CAAUiB,cAAV,EAA0B,cAA1B,CAAxB;;EACA,IAAI;IACF,MAAMF,MAAM,CAACI,eAAD,CAAZ;EACD,CAFD,CAEE,OAAOjB,KAAP,EAAc;IACd,IAAIrC,eAAe,CAAC,QAAD,EAAWqC,KAAX,CAAnB,EAAsC;MACpC5B,GAAG,CAACkB,KAAJ,CAAW,2BAA0BU,KAAM,EAA3C,EADoC,CAGpC;MACA;;MACA,OAAO,KAAP;IACD,CAPa,CASd;;;IACA,MAAMA,KAAN;EACD,CApBiB,CAsBlB;;;EACA,MAAMkB,MAAM,GAAG,IAAIP,aAAJ,CAAkBI,cAAlB,CAAf;EACA,MAAMI,YAAY,GAAG/D,SAAS,CAAC,CAAC,GAAGyC,IAAJ,KAAaqB,MAAM,CAACC,YAAP,CAAoB,GAAGtB,IAAvB,CAAd,CAA9B;EAEA,MAAMsB,YAAY,EAAlB;EAEA,MAAMC,wBAAwB,GAAGjE,IAAI,CAACkE,SAAL,CAC/BlE,IAAI,CAAC2C,IAAL,CAAU3C,IAAI,CAACmE,OAAL,CAAaZ,iBAAb,CAAV,EAA2CvD,IAAI,CAACoE,GAAhD,CAD+B,CAAjC;;EAIA,KAAK,MAAMtC,OAAX,IAAsBiC,MAAM,CAACM,QAA7B,EAAuC;IACrC;IACA;IACA,IAAIhB,sBAAsB,CAACM,QAAvB,CAAgC7B,OAAO,CAACwC,IAAxC,KACAxC,OAAO,CAACyC,OAAR,KAAoB,GADxB,EAC6B;MAC3B,IAAIC,eAAJ,CAD2B,CAG3B;;MACA,IAAI1C,OAAO,CAACwC,IAAR,KAAiBf,iBAArB,EAAwC;QACtC,OAAO,IAAP;MACD,CAN0B,CAQ3B;;;MACA,IAAIzB,OAAO,CAAC2C,UAAR,KAAuB,GAA3B,EAAgC;QAC9BD,eAAe,GAAGxE,IAAI,CAAC2C,IAAL,CAAUiB,cAAV,EAA0B9B,OAAO,CAAC4C,IAAlC,EAAwC1E,IAAI,CAACoE,GAA7C,CAAlB;MACD,CAFD,MAEO;QACLI,eAAe,GAAGxE,IAAI,CAAC2C,IAAL,CAAUb,OAAO,CAAC4C,IAAlB,EAAwB1E,IAAI,CAACoE,GAA7B,CAAlB;MACD;;MAED,IAAIpE,IAAI,CAACkE,SAAL,CAAeM,eAAf,MAAoCP,wBAAxC,EAAkE;QAChE,OAAO,IAAP;MACD;IACF;EACF,CAvDiB,CAyDlB;;;EACA,OAAO,KAAP;AACD,C,CAED;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASU,gBAAT,CACL7C,OADK,EAEL;EACE8C,GAAG,GAAG,SADR;EAEEjE,QAAQ,GAAGC,iBAFb;EAGEiE,WAAW,GAAG;AAHhB,IAI6B,EANxB,EAOoB;EACzB;EACA;EACA,MAAMC,KAAK,GAAGnE,QAAQ,CAACiE,GAAD,CAAtB;EACAG,MAAM,CAACC,IAAP,CAAYF,KAAZ,EAAmBG,OAAnB,CAA4BC,IAAD,IAAU;IACnCpD,OAAO,CAACqD,aAAR,CAAsBD,IAAtB,EAA4BJ,KAAK,CAACI,IAAD,CAAjC;EACD,CAFD;;EAGA,IAAIH,MAAM,CAACC,IAAP,CAAYH,WAAZ,EAAyBO,MAAzB,GAAkC,CAAtC,EAAyC;IACvC,MAAMC,cAAc,GAAGC,IAAI,CAACC,SAAL,CAAeV,WAAf,EAA4B,IAA5B,EAAkC,CAAlC,CAAvB;IACA5D,GAAG,CAAC6B,IAAJ,CAAU,uCAAsCuC,cAAe,EAA/D;IACAN,MAAM,CAACC,IAAP,CAAYH,WAAZ,EAAyBI,OAAzB,CAAkCO,MAAD,IAAY;MAC3C1D,OAAO,CAACqD,aAAR,CAAsBK,MAAtB,EAA8BX,WAAW,CAACW,MAAD,CAAzC;IACD,CAFD;EAGD;;EACD1D,OAAO,CAAC2D,iBAAR;EACA,OAAOC,OAAO,CAACvB,OAAR,CAAgBrC,OAAhB,CAAP;AACD;AASD,OAAO,SAAS6D,0BAAT,CACL;EACEC,iBADF;EAEEC,SAAS,GAAGzF;AAFd,IAG+B,EAJ1B,EAKS;EACd,MAAM2D,MAAM,GAAG,IAAI8B,SAAS,CAACpC,MAAd,CAAqBmC,iBAArB,CAAf;EACA,MAAM5B,YAAY,GAAG/D,SAAS,CAAC,CAAC,GAAGyC,IAAJ,KAAaqB,MAAM,CAACC,YAAP,CAAoB,GAAGtB,IAAvB,CAAd,CAA9B;EACA,MAAMoD,OAAO,GAAG7F,SAAS,CAAC,CAAC,GAAGyC,IAAJ,KAAaqB,MAAM,CAAC+B,OAAP,CAAe,GAAGpD,IAAlB,CAAd,CAAzB;EACA,OAAO,MAAOqD,WAAP,IAAuD;IAC5D,IAAI;MACF,MAAM/B,YAAY,EAAlB;MACA,MAAMgC,cAAc,GAAGjC,MAAM,CAACM,QAAP,CAAgB4B,MAAhB,CACpBC,UAAD,IAAgBA,UAAU,CAAC5B,IAAX,KAAoByB,WADf,EAC4BX,MAD5B,KACuC,CAD9D;;MAEA,IAAIY,cAAJ,EAAoB;QAClB,OAAO,MAAMF,OAAO,CAACC,WAAD,CAApB;MACD;IACF,CAPD,CAOE,OAAOlD,KAAP,EAAc;MACd,IAAI,CAACrC,eAAe,CAAC,QAAD,EAAWqC,KAAX,CAApB,EAAuC;QACrC,MAAMA,KAAN;MACD;;MACD5B,GAAG,CAACkF,IAAJ,CAAS,qCAAT;IACD;EACF,CAdD;AAeD,C,CAED;;AAUA;AAEA,OAAO,eAAeC,UAAf,CACLC,WADK,EAEL;EACEzB,GADF;EAEE0B,oBAAoB,GAAG3B,gBAFzB;EAGE4B,uBAAuB,GAAGjD,gBAH5B;EAIEuB,WAAW,GAAG,EAJhB;EAKE2B,mBAAmB,GAAGb;AALxB,IAMsB,EARjB,EASoB;EACzB,MAAMc,kBAAkB,GAAG,MAAMF,uBAAuB,CAACF,WAAD,CAAxD;;EACA,IAAII,kBAAJ,EAAwB;IACtB,MAAM,IAAIhG,UAAJ,CACJ,2DACC,MAAK4F,WAAY,IADlB,GAEA,sEAFA,GAGA,sDAJI,CAAN;EAMD;;EAED,IAAIK,oBAAJ;EACA,MAAMC,cAAc,GAAGH,mBAAmB,EAA1C;EAEA,MAAMI,gBAAgB,GAAG,MAAMrG,WAAW,CAAC8F,WAAD,CAA1C;;EACA,IAAIO,gBAAJ,EAAsB;IACpB3F,GAAG,CAACkB,KAAJ,CAAW,4BAA2BkE,WAAY,GAAlD;IACAK,oBAAoB,GAAGL,WAAvB;EACD,CAHD,MAGO;IACLpF,GAAG,CAACkB,KAAJ,CAAW,YAAWkE,WAAY,qBAAlC;IACAK,oBAAoB,GAAG,MAAMC,cAAc,CAACN,WAAD,CAA3C;;IACA,IAAI,CAACK,oBAAL,EAA2B;MACzB,MAAM,IAAIjG,UAAJ,CACH,gBAAe4F,WAAY,iBAA5B,GACA,sCAFI,CAAN;IAID;EACF;;EAED,MAAMvE,OAAO,GAAG,IAAI1B,cAAJ,CAAmB;IAACsG;EAAD,CAAnB,CAAhB;EACA,OAAO,MAAMJ,oBAAoB,CAACxE,OAAD,EAAU;IAAC8C,GAAD;IAAMC;EAAN,CAAV,CAAjC;AACD,C,CAGD;;AAQA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAegC,aAAf,CACL;EACEjC,GADF;EAEE0B,oBAAoB,GAAG3B,gBAFzB;EAGEE,WAAW,GAAG;AAHhB,IAIyB,EALpB,EAMoB;EACzB,MAAM/C,OAAO,GAAG,IAAI1B,cAAJ,EAAhB;EACA,OAAO,MAAMkG,oBAAoB,CAACxE,OAAD,EAAU;IAAC8C,GAAD;IAAMC;EAAN,CAAV,CAAjC;AACD,C,CAGD;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeiC,WAAf,CACLC,gBADK,EAEL;EACEnC,GADF;EAEE0B,oBAAoB,GAAG3B,gBAFzB;EAGElD,mBAAmB,GAAGD,wBAHxB;EAIEqD,WAAW,GAAG;AAJhB,IAKwB,EAPnB,EAQoB;EAEzB,MAAMmC,IAAI,GAAG/G,SAAS,CAACG,cAAc,CAAC4G,IAAhB,CAAtB;EACA,MAAMC,UAAU,GAAGhH,SAAS,CAACwB,mBAAD,CAA5B;;EAEA,IAAI;IACF,MAAMyF,SAAS,GAAG,MAAM3G,WAAW,CAACwG,gBAAD,CAAnC;IAEA,IAAIjF,OAAJ;;IAEA,IAAIoF,SAAJ,EAAe;MACbjG,GAAG,CAACkB,KAAJ,CAAW,mCAAkC4E,gBAAiB,GAA9D;MACAjF,OAAO,GAAG,MAAMkF,IAAI,CAAC;QAACD;MAAD,CAAD,CAApB;IACD,CAHD,MAGO;MACL9F,GAAG,CAACkB,KAAJ,CAAW,YAAW4E,gBAAiB,qBAAvC;MACAjF,OAAO,GAAG,MAAMmF,UAAU,CAAC;QAACE,IAAI,EAAEJ;MAAP,CAAD,CAA1B;IACD;;IAED,OAAOT,oBAAoB,CAACxE,OAAD,EAAU;MAAC8C,GAAD;MAAMC;IAAN,CAAV,CAA3B;EACD,CAdD,CAcE,OAAOhC,KAAP,EAAc;IACd,MAAM,IAAInC,WAAJ,CACH,uCAAsCqG,gBAAiB,KAAIlE,KAAM,EAD9D,CAAN;EAED;AACF,C,CAGD;;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeuE,gBAAf,CACL;EACEC,OAAO,GAAG,KADZ;EAEEC,YAFF;EAGExF,OAHF;EAIEyF,aAJF;EAKEC,WAAW,GAAGnG;AALhB,CADK,EAOoC;EACzC;EACA;EACA;EACA;EAEA,IAAI,CAACS,OAAO,CAAC2F,aAAb,EAA4B;IAC1B,MAAM,IAAI/G,WAAJ,CAAgB,8CAAhB,CAAN;EACD;;EAED,IAAI;IACF,MAAM8G,WAAW,CAAC1F,OAAO,CAAC2F,aAAT,CAAjB;EACD,CAFD,CAEE,OAAO5E,KAAP,EAAc;IACd,IAAIrC,eAAe,CAAC,QAAD,EAAWqC,KAAX,CAAnB,EAAsC;MACpC5B,GAAG,CAACkB,KAAJ,CAAW,kCAAiCL,OAAO,CAAC2F,aAAc,EAAlE;MACA,MAAMpH,EAAE,CAACqH,KAAH,CAAS5F,OAAO,CAAC2F,aAAjB,CAAN;IACD,CAHD,MAGO;MACL,MAAM5E,KAAN;IACD;EACF;;EAED,MAAM8E,EAAE,GAAG9G,aAAa,CAACyG,YAAD,CAAxB;;EACA,IAAI,CAACK,EAAL,EAAS;IACP,MAAM,IAAIlH,UAAJ,CACJ,6DACA,8DAFI,CAAN;EAGD;;EAED,IAAI4G,OAAJ,EAAa;IACXpG,GAAG,CAACkB,KAAJ,CAAW,6CAA4CoF,aAAc,EAArE;IAEA,MAAMK,KAAK,GAAG,MAAMrH,WAAW,CAACgH,aAAD,CAA/B;;IACA,IAAI,CAACK,KAAL,EAAY;MACV,MAAM,IAAIlH,WAAJ,CACJ,+DACC,mBAAkB6G,aAAc,EAF7B,CAAN;IAGD,CARU,CAUX;IACA;IACA;;;IACA,MAAMM,QAAQ,GAAG7H,IAAI,CAAC2C,IAAL,CAAUb,OAAO,CAAC2F,aAAlB,EAAkC,GAAEE,EAAG,EAAvC,CAAjB;IACA,MAAMG,WAAW,GAAG/H,MAAM,CAACgI,iBAAP,CAAyBF,QAAzB,CAApB;IACAC,WAAW,CAACE,KAAZ,CAAkBT,aAAlB;IACAO,WAAW,CAACG,GAAZ;IACA,OAAO,MAAM3H,SAAS,CAACwH,WAAD,EAAc,OAAd,CAAtB;EACD,CAlBD,MAkBO;IACL;IACA,MAAMI,UAAU,GAAGnI,MAAM,CAACoI,gBAAP,CAAwBZ,aAAxB,CAAnB;IACA,MAAMM,QAAQ,GAAG7H,IAAI,CAAC2C,IAAL,CAAUb,OAAO,CAAC2F,aAAlB,EAAkC,GAAEE,EAAG,MAAvC,CAAjB;IACA,MAAMG,WAAW,GAAG/H,MAAM,CAACgI,iBAAP,CAAyBF,QAAzB,CAApB;IAEA5G,GAAG,CAACkB,KAAJ,CAAW,6BAA4BoF,aAAc,OAAMM,QAAS,EAApE;IACAK,UAAU,CAACE,IAAX,CAAgBN,WAAhB;IAEA,OAAO,MAAMpC,OAAO,CAAC2C,GAAR,CAAY,CACvB/H,SAAS,CAAC4H,UAAD,EAAa,OAAb,CADc,EAEvB5H,SAAS,CAACwH,WAAD,EAAc,OAAd,CAFc,CAAZ,CAAb;EAID;AACF"}
@@ -0,0 +1,5 @@
1
+ export default ['org.mozilla.fennec', 'org.mozilla.fenix', 'org.mozilla.geckoview_example', 'org.mozilla.geckoview', 'org.mozilla.firefox', 'org.mozilla.reference.browser'];
2
+ export const defaultApkComponents = {
3
+ 'org.mozilla.reference.browser': '.BrowserActivity'
4
+ };
5
+ //# sourceMappingURL=package-identifiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-identifiers.js","names":["defaultApkComponents"],"sources":["../../src/firefox/package-identifiers.js"],"sourcesContent":["/* @flow */\n\nexport default [\n 'org.mozilla.fennec',\n 'org.mozilla.fenix',\n 'org.mozilla.geckoview_example',\n 'org.mozilla.geckoview',\n 'org.mozilla.firefox',\n 'org.mozilla.reference.browser',\n];\n\nexport const defaultApkComponents = {\n 'org.mozilla.reference.browser': '.BrowserActivity',\n};\n"],"mappings":"AAEA,eAAe,CACb,oBADa,EAEb,mBAFa,EAGb,+BAHa,EAIb,uBAJa,EAKb,qBALa,EAMb,+BANa,CAAf;AASA,OAAO,MAAMA,oBAAoB,GAAG;EAClC,iCAAiC;AADC,CAA7B"}
@@ -1,48 +1,28 @@
1
- /* @flow */
2
- import {WebExtError, UsageError} from '../errors';
3
- import {createLogger} from '../util/logger';
4
-
5
- const log = createLogger(__filename);
6
- export const nonOverridablePreferences = [
7
- 'devtools.debugger.remote-enabled', 'devtools.debugger.prompt-connection',
8
- 'xpinstall.signatures.required',
9
- ];
10
-
11
- // Flow Types
12
-
13
- export type FirefoxPreferences = {
14
- [key: string]: boolean | string | number,
15
- };
16
-
17
- export type PreferencesAppName = 'firefox' | 'fennec';
18
-
1
+ import { WebExtError, UsageError } from '../errors.js';
2
+ import { createLogger } from '../util/logger.js';
3
+ const log = createLogger(import.meta.url);
4
+ export const nonOverridablePreferences = ['devtools.debugger.remote-enabled', 'devtools.debugger.prompt-connection', 'xpinstall.signatures.required']; // Flow Types
19
5
 
20
6
  // Preferences Maps
21
-
22
- const prefsCommon: FirefoxPreferences = {
7
+ const prefsCommon = {
23
8
  // Allow debug output via dump to be printed to the system console
24
9
  'browser.dom.window.dump.enabled': true,
25
-
26
10
  // From:
27
11
  // https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/internals/preferences.html#data-choices-notification
28
12
  // This is the data submission master kill switch. If disabled, no policy is shown or upload takes place, ever.
29
13
  'datareporting.policy.dataSubmissionEnabled': false,
30
-
31
14
  // Allow remote connections to the debugger.
32
15
  'devtools.debugger.remote-enabled': true,
33
16
  // Disable the prompt for allowing connections.
34
17
  'devtools.debugger.prompt-connection': false,
35
18
  // Allow extensions to log messages on browser's console.
36
19
  'devtools.browserconsole.contentMessages': true,
37
-
38
20
  // Turn off platform logging because it is a lot of info.
39
21
  'extensions.logging.enabled': false,
40
-
41
22
  // Disable extension updates and notifications.
42
23
  'extensions.checkCompatibility.nightly': false,
43
24
  'extensions.update.enabled': false,
44
25
  'extensions.update.notifyUser': false,
45
-
46
26
  // From:
47
27
  // http://hg.mozilla.org/mozilla-central/file/1dd81c324ac7/build/automation.py.in//l372
48
28
  // Only load extensions from the application and user profile.
@@ -54,95 +34,70 @@ const prefsCommon: FirefoxPreferences = {
54
34
  'extensions.installDistroAddons': false,
55
35
  // Allow installing extensions dropped into the profile folder.
56
36
  'extensions.autoDisableScopes': 10,
57
-
58
37
  // Disable app update.
59
38
  'app.update.enabled': false,
60
-
61
39
  // Allow unsigned add-ons.
62
40
  'xpinstall.signatures.required': false,
63
-
64
41
  // browser.link.open_newwindow is changed from 3 to 2 in:
65
42
  // https://github.com/saadtazi/firefox-profile-js/blob/cafc793d940a779d280103ae17d02a92de862efc/lib/firefox_profile.js#L32
66
43
  // Restore original value to avoid https://github.com/mozilla/web-ext/issues/1592
67
- 'browser.link.open_newwindow': 3,
68
- };
44
+ 'browser.link.open_newwindow': 3
45
+ }; // Prefs specific to Firefox for Android.
69
46
 
70
- // Prefs specific to Firefox for Android.
71
- const prefsFennec: FirefoxPreferences = {
47
+ const prefsFennec = {
72
48
  'browser.console.showInPanel': true,
73
49
  'browser.firstrun.show.uidiscovery': false,
74
- 'devtools.remote.usb.enabled': true,
75
- };
50
+ 'devtools.remote.usb.enabled': true
51
+ }; // Prefs specific to Firefox for desktop.
76
52
 
77
- // Prefs specific to Firefox for desktop.
78
- const prefsFirefox: FirefoxPreferences = {
53
+ const prefsFirefox = {
79
54
  'browser.startup.homepage': 'about:blank',
80
55
  'startup.homepage_welcome_url': 'about:blank',
81
56
  'startup.homepage_welcome_url.additional': '',
82
57
  'devtools.errorconsole.enabled': true,
83
58
  'devtools.chrome.enabled': true,
84
-
85
59
  // From:
86
60
  // http://hg.mozilla.org/mozilla-central/file/1dd81c324ac7/build/automation.py.in//l388
87
61
  // Make url-classifier updates so rare that they won't affect tests.
88
62
  'urlclassifier.updateinterval': 172800,
89
63
  // Point the url-classifier to a nonexistent local URL for fast failures.
90
- 'browser.safebrowsing.provider.0.gethashURL':
91
- 'http://localhost/safebrowsing-dummy/gethash',
92
- 'browser.safebrowsing.provider.0.keyURL':
93
- 'http://localhost/safebrowsing-dummy/newkey',
94
- 'browser.safebrowsing.provider.0.updateURL':
95
- 'http://localhost/safebrowsing-dummy/update',
96
-
64
+ 'browser.safebrowsing.provider.0.gethashURL': 'http://localhost/safebrowsing-dummy/gethash',
65
+ 'browser.safebrowsing.provider.0.keyURL': 'http://localhost/safebrowsing-dummy/newkey',
66
+ 'browser.safebrowsing.provider.0.updateURL': 'http://localhost/safebrowsing-dummy/update',
97
67
  // Disable self repair/SHIELD
98
68
  'browser.selfsupport.url': 'https://localhost/selfrepair',
99
69
  // Disable Reader Mode UI tour
100
70
  'browser.reader.detectedFirstArticle': true,
101
-
102
71
  // Set the policy firstURL to an empty string to prevent
103
72
  // the privacy info page to be opened on every "web-ext run".
104
73
  // (See #1114 for rationale)
105
- 'datareporting.policy.firstRunURL': '',
74
+ 'datareporting.policy.firstRunURL': ''
106
75
  };
107
-
108
76
  const prefs = {
109
77
  common: prefsCommon,
110
78
  fennec: prefsFennec,
111
- firefox: prefsFirefox,
112
- };
79
+ firefox: prefsFirefox
80
+ }; // Module exports
113
81
 
114
-
115
- // Module exports
116
-
117
- export type PreferencesGetterFn =
118
- (appName: PreferencesAppName) => FirefoxPreferences;
119
-
120
- export function getPrefs(
121
- app: PreferencesAppName = 'firefox'
122
- ): FirefoxPreferences {
82
+ export function getPrefs(app = 'firefox') {
123
83
  const appPrefs = prefs[app];
84
+
124
85
  if (!appPrefs) {
125
86
  throw new WebExtError(`Unsupported application: ${app}`);
126
87
  }
127
- return {
128
- ...prefsCommon,
129
- ...appPrefs,
88
+
89
+ return { ...prefsCommon,
90
+ ...appPrefs
130
91
  };
131
92
  }
132
-
133
- export function coerceCLICustomPreference(
134
- cliPrefs: Array<string>
135
- ): FirefoxPreferences {
93
+ export function coerceCLICustomPreference(cliPrefs) {
136
94
  const customPrefs = {};
137
95
 
138
96
  for (const pref of cliPrefs) {
139
97
  const prefsAry = pref.split('=');
140
98
 
141
99
  if (prefsAry.length < 2) {
142
- throw new UsageError(
143
- `Incomplete custom preference: "${pref}". ` +
144
- 'Syntax expected: "prefname=prefvalue".'
145
- );
100
+ throw new UsageError(`Incomplete custom preference: "${pref}". ` + 'Syntax expected: "prefname=prefvalue".');
146
101
  }
147
102
 
148
103
  const key = prefsAry[0];
@@ -155,15 +110,17 @@ export function coerceCLICustomPreference(
155
110
  if (value === `${parseInt(value)}`) {
156
111
  value = parseInt(value, 10);
157
112
  } else if (value === 'true' || value === 'false') {
158
- value = (value === 'true');
113
+ value = value === 'true';
159
114
  }
160
115
 
161
116
  if (nonOverridablePreferences.includes(key)) {
162
117
  log.warn(`'${key}' preference cannot be customized.`);
163
118
  continue;
164
119
  }
120
+
165
121
  customPrefs[`${key}`] = value;
166
122
  }
167
123
 
168
124
  return customPrefs;
169
125
  }
126
+ //# sourceMappingURL=preferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preferences.js","names":["WebExtError","UsageError","createLogger","log","import","meta","url","nonOverridablePreferences","prefsCommon","prefsFennec","prefsFirefox","prefs","common","fennec","firefox","getPrefs","app","appPrefs","coerceCLICustomPreference","cliPrefs","customPrefs","pref","prefsAry","split","length","key","value","slice","join","test","parseInt","includes","warn"],"sources":["../../src/firefox/preferences.js"],"sourcesContent":["/* @flow */\nimport {WebExtError, UsageError} from '../errors.js';\nimport {createLogger} from '../util/logger.js';\n\nconst log = createLogger(import.meta.url);\n\nexport const nonOverridablePreferences = [\n 'devtools.debugger.remote-enabled', 'devtools.debugger.prompt-connection',\n 'xpinstall.signatures.required',\n];\n\n// Flow Types\n\nexport type FirefoxPreferences = {\n [key: string]: boolean | string | number,\n};\n\nexport type PreferencesAppName = 'firefox' | 'fennec';\n\n\n// Preferences Maps\n\nconst prefsCommon: FirefoxPreferences = {\n // Allow debug output via dump to be printed to the system console\n 'browser.dom.window.dump.enabled': true,\n\n // From:\n // https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/internals/preferences.html#data-choices-notification\n // This is the data submission master kill switch. If disabled, no policy is shown or upload takes place, ever.\n 'datareporting.policy.dataSubmissionEnabled': false,\n\n // Allow remote connections to the debugger.\n 'devtools.debugger.remote-enabled': true,\n // Disable the prompt for allowing connections.\n 'devtools.debugger.prompt-connection': false,\n // Allow extensions to log messages on browser's console.\n 'devtools.browserconsole.contentMessages': true,\n\n // Turn off platform logging because it is a lot of info.\n 'extensions.logging.enabled': false,\n\n // Disable extension updates and notifications.\n 'extensions.checkCompatibility.nightly': false,\n 'extensions.update.enabled': false,\n 'extensions.update.notifyUser': false,\n\n // From:\n // http://hg.mozilla.org/mozilla-central/file/1dd81c324ac7/build/automation.py.in//l372\n // Only load extensions from the application and user profile.\n // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION\n 'extensions.enabledScopes': 5,\n // Disable metadata caching for installed add-ons by default.\n 'extensions.getAddons.cache.enabled': false,\n // Disable intalling any distribution add-ons.\n 'extensions.installDistroAddons': false,\n // Allow installing extensions dropped into the profile folder.\n 'extensions.autoDisableScopes': 10,\n\n // Disable app update.\n 'app.update.enabled': false,\n\n // Allow unsigned add-ons.\n 'xpinstall.signatures.required': false,\n\n // browser.link.open_newwindow is changed from 3 to 2 in:\n // https://github.com/saadtazi/firefox-profile-js/blob/cafc793d940a779d280103ae17d02a92de862efc/lib/firefox_profile.js#L32\n // Restore original value to avoid https://github.com/mozilla/web-ext/issues/1592\n 'browser.link.open_newwindow': 3,\n};\n\n// Prefs specific to Firefox for Android.\nconst prefsFennec: FirefoxPreferences = {\n 'browser.console.showInPanel': true,\n 'browser.firstrun.show.uidiscovery': false,\n 'devtools.remote.usb.enabled': true,\n};\n\n// Prefs specific to Firefox for desktop.\nconst prefsFirefox: FirefoxPreferences = {\n 'browser.startup.homepage': 'about:blank',\n 'startup.homepage_welcome_url': 'about:blank',\n 'startup.homepage_welcome_url.additional': '',\n 'devtools.errorconsole.enabled': true,\n 'devtools.chrome.enabled': true,\n\n // From:\n // http://hg.mozilla.org/mozilla-central/file/1dd81c324ac7/build/automation.py.in//l388\n // Make url-classifier updates so rare that they won't affect tests.\n 'urlclassifier.updateinterval': 172800,\n // Point the url-classifier to a nonexistent local URL for fast failures.\n 'browser.safebrowsing.provider.0.gethashURL':\n 'http://localhost/safebrowsing-dummy/gethash',\n 'browser.safebrowsing.provider.0.keyURL':\n 'http://localhost/safebrowsing-dummy/newkey',\n 'browser.safebrowsing.provider.0.updateURL':\n 'http://localhost/safebrowsing-dummy/update',\n\n // Disable self repair/SHIELD\n 'browser.selfsupport.url': 'https://localhost/selfrepair',\n // Disable Reader Mode UI tour\n 'browser.reader.detectedFirstArticle': true,\n\n // Set the policy firstURL to an empty string to prevent\n // the privacy info page to be opened on every \"web-ext run\".\n // (See #1114 for rationale)\n 'datareporting.policy.firstRunURL': '',\n};\n\nconst prefs = {\n common: prefsCommon,\n fennec: prefsFennec,\n firefox: prefsFirefox,\n};\n\n\n// Module exports\n\nexport type PreferencesGetterFn =\n (appName: PreferencesAppName) => FirefoxPreferences;\n\nexport function getPrefs(\n app: PreferencesAppName = 'firefox'\n): FirefoxPreferences {\n const appPrefs = prefs[app];\n if (!appPrefs) {\n throw new WebExtError(`Unsupported application: ${app}`);\n }\n return {\n ...prefsCommon,\n ...appPrefs,\n };\n}\n\nexport function coerceCLICustomPreference(\n cliPrefs: Array<string>\n): FirefoxPreferences {\n const customPrefs = {};\n\n for (const pref of cliPrefs) {\n const prefsAry = pref.split('=');\n\n if (prefsAry.length < 2) {\n throw new UsageError(\n `Incomplete custom preference: \"${pref}\". ` +\n 'Syntax expected: \"prefname=prefvalue\".'\n );\n }\n\n const key = prefsAry[0];\n let value = prefsAry.slice(1).join('=');\n\n if (/[^\\w{@}.-]/.test(key)) {\n throw new UsageError(`Invalid custom preference name: ${key}`);\n }\n\n if (value === `${parseInt(value)}`) {\n value = parseInt(value, 10);\n } else if (value === 'true' || value === 'false') {\n value = (value === 'true');\n }\n\n if (nonOverridablePreferences.includes(key)) {\n log.warn(`'${key}' preference cannot be customized.`);\n continue;\n }\n customPrefs[`${key}`] = value;\n }\n\n return customPrefs;\n}\n"],"mappings":"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"}