web-ext 7.4.0 → 7.6.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.
- package/README.md +3 -2
- package/lib/cmd/build.js +0 -1
- package/lib/cmd/build.js.map +1 -1
- package/lib/cmd/docs.js +0 -1
- package/lib/cmd/docs.js.map +1 -1
- package/lib/cmd/index.js +0 -3
- package/lib/cmd/index.js.map +1 -1
- package/lib/cmd/lint.js +0 -1
- package/lib/cmd/lint.js.map +1 -1
- package/lib/cmd/run.js +0 -1
- package/lib/cmd/run.js.map +1 -1
- package/lib/cmd/sign.js +14 -4
- package/lib/cmd/sign.js.map +1 -1
- package/lib/config.js +0 -1
- package/lib/config.js.map +1 -1
- package/lib/errors.js +0 -1
- package/lib/errors.js.map +1 -1
- package/lib/extension-runners/base.js +0 -2
- package/lib/extension-runners/base.js.map +1 -1
- package/lib/extension-runners/chromium.js +0 -3
- package/lib/extension-runners/chromium.js.map +1 -1
- package/lib/extension-runners/firefox-android.js +0 -3
- package/lib/extension-runners/firefox-android.js.map +1 -1
- package/lib/extension-runners/firefox-desktop.js +0 -4
- package/lib/extension-runners/firefox-desktop.js.map +1 -1
- package/lib/extension-runners/index.js +0 -2
- package/lib/extension-runners/index.js.map +1 -1
- package/lib/firefox/index.js +0 -1
- package/lib/firefox/index.js.map +1 -1
- package/lib/firefox/package-identifiers.js +0 -2
- package/lib/firefox/package-identifiers.js.map +1 -1
- package/lib/firefox/preferences.js +0 -1
- package/lib/firefox/preferences.js.map +1 -1
- package/lib/firefox/rdp-client.js +0 -1
- package/lib/firefox/rdp-client.js.map +1 -1
- package/lib/firefox/remote.js +0 -1
- package/lib/firefox/remote.js.map +1 -1
- package/lib/main.js +0 -1
- package/lib/main.js.map +1 -1
- package/lib/program.js +13 -5
- package/lib/program.js.map +1 -1
- package/lib/util/adb.js +0 -1
- package/lib/util/adb.js.map +1 -1
- package/lib/util/artifacts.js +0 -1
- package/lib/util/artifacts.js.map +1 -1
- package/lib/util/desktop-notifier.js +0 -1
- package/lib/util/desktop-notifier.js.map +1 -1
- package/lib/util/file-exists.js +0 -1
- package/lib/util/file-exists.js.map +1 -1
- package/lib/util/file-filter.js +0 -1
- package/lib/util/file-filter.js.map +1 -1
- package/lib/util/is-directory.js +0 -1
- package/lib/util/is-directory.js.map +1 -1
- package/lib/util/logger.js +0 -1
- package/lib/util/logger.js.map +1 -1
- package/lib/util/manifest.js +0 -1
- package/lib/util/manifest.js.map +1 -1
- package/lib/util/promisify.js +0 -2
- package/lib/util/promisify.js.map +1 -1
- package/lib/util/stdin.js +0 -2
- package/lib/util/stdin.js.map +1 -1
- package/lib/util/submit-addon.js +12 -4
- package/lib/util/submit-addon.js.map +1 -1
- package/lib/util/temp-dir.js +0 -1
- package/lib/util/temp-dir.js.map +1 -1
- package/lib/util/updates.js +0 -1
- package/lib/util/updates.js.map +1 -1
- package/lib/watcher.js +0 -1
- package/lib/watcher.js.map +1 -1
- package/package.json +22 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chromium.js","names":["path","fs","asyncMkdirp","Launcher","ChromeLauncher","launch","defaultChromiumLaunch","WebSocket","WebSocketServer","createLogger","TempDir","isDirectory","fileExists","log","import","meta","url","EXCLUDED_CHROME_FLAGS","DEFAULT_CHROME_FLAGS","defaultFlags","filter","flag","includes","ChromiumExtensionRunner","constructor","params","chromiumLaunch","cleanupCallbacks","Set","getName","run","_promiseSetupDone","setupInstance","isUserDataDir","dirPath","localStatePath","join","defaultPath","isProfileDir","securePreferencesPath","getProfilePaths","chromiumProfile","userDataDir","profileDirName","isProfileDirAndNotUserData","dir","base","parse","wss","Promise","resolve","server","port","host","clientTracking","on","socket","err","debug","reloadManagerExtension","createReloadManagerExtension","extensions","concat","map","sourceDir","chromiumBinary","chromeFlags","push","args","keepProfileChanges","Error","tmpDir","create","tmpDirPath","copy","startingUrl","startUrl","startingUrls","Array","isArray","shift","chromiumInstance","enableExtensions","chromePath","ignoreDefaultFlags","process","once","exiting","info","exit","wssBroadcast","data","clients","cleanWebExtReloadComplete","client","removeEventListener","webExtReloadComplete","delete","message","msg","JSON","type","call","readyState","OPEN","addEventListener","send","stringify","size","registerCleanup","remove","extPath","Date","now","writeFile","manifest_version","name","version","permissions","background","scripts","wssInfo","address","bgPage","reloadAllExtensions","runnerName","stdout","write","toTimeString","reloadExtensionBySourceDir","extensionSourceDir","fn","add","catch","kill","wssClient","terminate","close","error"],"sources":["../../src/extension-runners/chromium.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Chromium-based browser instance.\n */\n\nimport path from 'path';\n\nimport fs from 'fs-extra';\nimport asyncMkdirp from 'mkdirp';\nimport {\n Launcher as ChromeLauncher,\n launch as defaultChromiumLaunch,\n} from 'chrome-launcher';\nimport WebSocket, { WebSocketServer } from 'ws';\n\nimport { createLogger } from '../util/logger.js';\nimport { TempDir } from '../util/temp-dir.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport isDirectory from '../util/is-directory.js';\nimport fileExists from '../util/file-exists.js';\n\ntype ChromiumSpecificRunnerParams = {|\n chromiumBinary?: string,\n chromiumProfile?: string,\n chromiumLaunch?: typeof defaultChromiumLaunch,\n|};\n\nexport type ChromiumExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n // Chromium desktop CLI params.\n ...ChromiumSpecificRunnerParams,\n|};\n\nconst log = createLogger(import.meta.url);\n\nconst EXCLUDED_CHROME_FLAGS = ['--disable-extensions', '--mute-audio'];\n\nexport const DEFAULT_CHROME_FLAGS: Array<string> =\n ChromeLauncher.defaultFlags().filter(\n (flag) => !EXCLUDED_CHROME_FLAGS.includes(flag)\n );\n\n/**\n * Implements an IExtensionRunner which manages a Chromium instance.\n */\nexport class ChromiumExtensionRunner {\n cleanupCallbacks: Set<Function>;\n params: ChromiumExtensionRunnerParams;\n chromiumInstance: ?ChromeLauncher;\n chromiumLaunch: typeof defaultChromiumLaunch;\n reloadManagerExtension: string;\n wss: ?WebSocketServer;\n exiting: boolean;\n _promiseSetupDone: ?Promise<void>;\n\n constructor(params: ChromiumExtensionRunnerParams) {\n const { chromiumLaunch = defaultChromiumLaunch } = params;\n this.params = params;\n this.chromiumLaunch = chromiumLaunch;\n this.cleanupCallbacks = new Set();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Chromium';\n }\n\n async run(): Promise<void> {\n // Run should never be called more than once.\n this._promiseSetupDone = this.setupInstance();\n await this._promiseSetupDone;\n }\n\n static async isUserDataDir(dirPath: string): Promise<boolean> {\n const localStatePath = path.join(dirPath, 'Local State');\n const defaultPath = path.join(dirPath, 'Default');\n // Local State and Default are typical for the user-data-dir\n return (\n (await fileExists(localStatePath)) && (await isDirectory(defaultPath))\n );\n }\n\n static async isProfileDir(dirPath: string): Promise<boolean> {\n const securePreferencesPath = path.join(dirPath, 'Secure Preferences');\n //Secure Preferences is typical for a profile dir inside a user data dir\n return await fileExists(securePreferencesPath);\n }\n\n static async getProfilePaths(chromiumProfile: ?string): Promise<{\n userDataDir: ?string,\n profileDirName: ?string,\n }> {\n if (!chromiumProfile) {\n return {\n userDataDir: null,\n profileDirName: null,\n };\n }\n\n const isProfileDirAndNotUserData =\n (await ChromiumExtensionRunner.isProfileDir(chromiumProfile)) &&\n !(await ChromiumExtensionRunner.isUserDataDir(chromiumProfile));\n\n if (isProfileDirAndNotUserData) {\n const { dir: userDataDir, base: profileDirName } =\n path.parse(chromiumProfile);\n return {\n userDataDir,\n profileDirName,\n };\n }\n\n return {\n userDataDir: chromiumProfile,\n profileDirName: null,\n };\n }\n\n /**\n * Setup the Chromium Profile and run a Chromium instance.\n */\n async setupInstance(): Promise<void> {\n // Start a websocket server on a free localhost TCP port.\n this.wss = await new Promise((resolve) => {\n const server = new WebSocketServer(\n // Use a ipv4 host so we don't need to escape ipv6 address\n // https://github.com/mozilla/web-ext/issues/2331\n { port: 0, host: '127.0.0.1', clientTracking: true },\n // Wait the server to be listening (so that the extension\n // runner can successfully retrieve server address and port).\n () => resolve(server)\n );\n });\n\n // Prevent unhandled socket error (e.g. when chrome\n // is exiting, See https://github.com/websockets/ws/issues/1256).\n this.wss.on('connection', function (socket) {\n socket.on('error', (err) => {\n log.debug(`websocket connection error: ${err}`);\n });\n });\n\n // Create the extension that will manage the addon reloads\n this.reloadManagerExtension = await this.createReloadManagerExtension();\n\n // Start chrome pointing it to a given profile dir\n const extensions = [this.reloadManagerExtension]\n .concat(this.params.extensions.map(({ sourceDir }) => sourceDir))\n .join(',');\n\n const { chromiumBinary } = this.params;\n\n log.debug('Starting Chromium instance...');\n\n if (chromiumBinary) {\n log.debug(`(chromiumBinary: ${chromiumBinary})`);\n }\n\n const chromeFlags = [...DEFAULT_CHROME_FLAGS];\n\n chromeFlags.push(`--load-extension=${extensions}`);\n\n if (this.params.args) {\n chromeFlags.push(...this.params.args);\n }\n\n // eslint-disable-next-line prefer-const\n let { userDataDir, profileDirName } =\n await ChromiumExtensionRunner.getProfilePaths(\n this.params.chromiumProfile\n );\n\n if (userDataDir && this.params.keepProfileChanges) {\n if (\n profileDirName &&\n !(await ChromiumExtensionRunner.isUserDataDir(userDataDir))\n ) {\n throw new Error(\n 'The profile you provided is not in a ' +\n 'user-data-dir. The changes cannot be kept. Please either ' +\n 'remove --keep-profile-changes or use a profile in a ' +\n 'user-data-dir directory'\n );\n }\n } else if (!this.params.keepProfileChanges) {\n // the user provided an existing profile directory but doesn't want\n // the changes to be kept. we copy this directory to a temporary\n // user data dir.\n const tmpDir = new TempDir();\n await tmpDir.create();\n const tmpDirPath = tmpDir.path();\n\n if (userDataDir && profileDirName) {\n // copy profile dir to this temp user data dir.\n await fs.copy(\n path.join(userDataDir, profileDirName),\n path.join(tmpDirPath, profileDirName)\n );\n } else if (userDataDir) {\n await fs.copy(userDataDir, tmpDirPath);\n }\n userDataDir = tmpDirPath;\n }\n\n if (profileDirName) {\n chromeFlags.push(`--profile-directory=${profileDirName}`);\n }\n\n let startingUrl;\n if (this.params.startUrl) {\n const startingUrls = Array.isArray(this.params.startUrl)\n ? this.params.startUrl\n : [this.params.startUrl];\n startingUrl = startingUrls.shift();\n chromeFlags.push(...startingUrls);\n }\n\n this.chromiumInstance = await this.chromiumLaunch({\n enableExtensions: true,\n chromePath: chromiumBinary,\n chromeFlags,\n startingUrl,\n userDataDir,\n // Ignore default flags to keep the extension enabled.\n ignoreDefaultFlags: true,\n });\n\n this.chromiumInstance.process.once('close', () => {\n this.chromiumInstance = null;\n\n if (!this.exiting) {\n log.info('Exiting on Chromium instance disconnected.');\n this.exit();\n }\n });\n }\n\n async wssBroadcast(data: Object): Promise<void> {\n return new Promise((resolve) => {\n const clients = this.wss ? new Set(this.wss.clients) : new Set();\n\n function cleanWebExtReloadComplete() {\n const client = this;\n client.removeEventListener('message', webExtReloadComplete);\n client.removeEventListener('close', cleanWebExtReloadComplete);\n clients.delete(client);\n }\n\n const webExtReloadComplete = async (message) => {\n const msg = JSON.parse(message.data);\n\n if (msg.type === 'webExtReloadExtensionComplete') {\n for (const client of clients) {\n cleanWebExtReloadComplete.call(client);\n }\n resolve();\n }\n };\n\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.addEventListener('message', webExtReloadComplete);\n client.addEventListener('close', cleanWebExtReloadComplete);\n\n client.send(JSON.stringify(data));\n } else {\n clients.delete(client);\n }\n }\n\n if (clients.size === 0) {\n resolve();\n }\n });\n }\n\n async createReloadManagerExtension(): Promise<string> {\n const tmpDir = new TempDir();\n await tmpDir.create();\n this.registerCleanup(() => tmpDir.remove());\n\n const extPath = path.join(\n tmpDir.path(),\n `reload-manager-extension-${Date.now()}`\n );\n\n log.debug(`Creating reload-manager-extension in ${extPath}`);\n\n await asyncMkdirp(extPath);\n\n await fs.writeFile(\n path.join(extPath, 'manifest.json'),\n JSON.stringify({\n manifest_version: 2,\n name: 'web-ext Reload Manager Extension',\n version: '1.0',\n permissions: ['management', 'tabs'],\n background: {\n scripts: ['bg.js'],\n },\n })\n );\n\n // $FlowIgnore: this method is only called right after creating the server and so wss should be defined.\n const wssInfo = this.wss.address();\n\n const bgPage = `(function bgPage() {\n async function getAllDevExtensions() {\n const allExtensions = await new Promise(\n r => chrome.management.getAll(r));\n\n return allExtensions.filter((extension) => {\n return extension.enabled &&\n extension.installType === \"development\" &&\n extension.id !== chrome.runtime.id;\n });\n }\n\n const setEnabled = (extensionId, value) =>\n chrome.runtime.id == extensionId ?\n new Promise.resolve() :\n new Promise(r => chrome.management.setEnabled(extensionId, value, r));\n\n async function reloadExtension(extensionId) {\n await setEnabled(extensionId, false);\n await setEnabled(extensionId, true);\n }\n\n const ws = new window.WebSocket(\n \"ws://${wssInfo.address}:${wssInfo.port}\");\n\n ws.onmessage = async (evt) => {\n const msg = JSON.parse(evt.data);\n if (msg.type === 'webExtReloadAllExtensions') {\n const devExtensions = await getAllDevExtensions();\n await Promise.all(devExtensions.map(ext => reloadExtension(ext.id)));\n ws.send(JSON.stringify({ type: 'webExtReloadExtensionComplete' }));\n }\n };\n })()`;\n\n await fs.writeFile(path.join(extPath, 'bg.js'), bgPage);\n return extPath;\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n\n await this.wssBroadcast({\n type: 'webExtReloadAllExtensions',\n });\n\n process.stdout.write(\n `\\rLast extension reload: ${new Date().toTimeString()}`\n );\n log.debug('\\n');\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string // eslint-disable-line no-unused-vars\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n // TODO(rpl): detect the extension ids assigned to the\n // target extensions and map it to the extensions source dir\n // (https://github.com/mozilla/web-ext/issues/1687).\n return this.reloadAllExtensions();\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Chromium instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Chromium instance.\n */\n async exit(): Promise<void> {\n this.exiting = true;\n\n // Wait for the setup to complete if the extension runner is already\n // being started.\n if (this._promiseSetupDone) {\n // Ignore initialization errors if any.\n await this._promiseSetupDone.catch((err) => {\n log.debug(`ignored setup error on chromium runner shutdown: ${err}`);\n });\n }\n\n if (this.chromiumInstance) {\n await this.chromiumInstance.kill();\n this.chromiumInstance = null;\n }\n\n if (this.wss) {\n // Close all websocket clients, closing the WebSocketServer\n // does not terminate the existing connection and it wouldn't\n // resolve until all of the existing connections are closed.\n for (const wssClient of this.wss?.clients || []) {\n if (wssClient.readyState === WebSocket.OPEN) {\n wssClient.terminate();\n }\n }\n await new Promise((resolve) =>\n this.wss ? this.wss.close(resolve) : resolve()\n );\n this.wss = null;\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n}\n"],"mappings":";;AAEA;AACA;AACA;AACA;;AAEA,OAAOA,IAAI,MAAM,MAAM;AAEvB,OAAOC,EAAE,MAAM,UAAU;AACzB,OAAOC,WAAW,MAAM,QAAQ;AAChC,SACEC,QAAQ,IAAIC,cAAc,EAC1BC,MAAM,IAAIC,qBAAqB,QAC1B,iBAAiB;AACxB,OAAOC,SAAS,IAAIC,eAAe,QAAQ,IAAI;AAE/C,SAASC,YAAY,QAAQ,mBAAmB;AAChD,SAASC,OAAO,QAAQ,qBAAqB;AAK7C,OAAOC,WAAW,MAAM,yBAAyB;AACjD,OAAOC,UAAU,MAAM,wBAAwB;AAc/C,MAAMC,GAAG,GAAGJ,YAAY,CAACK,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC;AAEzC,MAAMC,qBAAqB,GAAG,CAAC,sBAAsB,EAAE,cAAc,CAAC;AAEtE,OAAO,MAAMC,oBAAmC,GAC9Cd,cAAc,CAACe,YAAY,EAAE,CAACC,MAAM,CACjCC,IAAI,IAAK,CAACJ,qBAAqB,CAACK,QAAQ,CAACD,IAAI,CAAC,CAChD;;AAEH;AACA;AACA;AACA,OAAO,MAAME,uBAAuB,CAAC;EAUnCC,WAAW,CAACC,MAAqC,EAAE;IACjD,MAAM;MAAEC,cAAc,GAAGpB;IAAsB,CAAC,GAAGmB,MAAM;IACzD,IAAI,CAACA,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACC,cAAc,GAAGA,cAAc;IACpC,IAAI,CAACC,gBAAgB,GAAG,IAAIC,GAAG,EAAE;EACnC;;EAEA;;EAEA;AACF;AACA;EACEC,OAAO,GAAW;IAChB,OAAO,UAAU;EACnB;EAEA,MAAMC,GAAG,GAAkB;IACzB;IACA,IAAI,CAACC,iBAAiB,GAAG,IAAI,CAACC,aAAa,EAAE;IAC7C,MAAM,IAAI,CAACD,iBAAiB;EAC9B;EAEA,aAAaE,aAAa,CAACC,OAAe,EAAoB;IAC5D,MAAMC,cAAc,GAAGnC,IAAI,CAACoC,IAAI,CAACF,OAAO,EAAE,aAAa,CAAC;IACxD,MAAMG,WAAW,GAAGrC,IAAI,CAACoC,IAAI,CAACF,OAAO,EAAE,SAAS,CAAC;IACjD;IACA,OACE,CAAC,MAAMtB,UAAU,CAACuB,cAAc,CAAC,MAAM,MAAMxB,WAAW,CAAC0B,WAAW,CAAC,CAAC;EAE1E;EAEA,aAAaC,YAAY,CAACJ,OAAe,EAAoB;IAC3D,MAAMK,qBAAqB,GAAGvC,IAAI,CAACoC,IAAI,CAACF,OAAO,EAAE,oBAAoB,CAAC;IACtE;IACA,OAAO,MAAMtB,UAAU,CAAC2B,qBAAqB,CAAC;EAChD;EAEA,aAAaC,eAAe,CAACC,eAAwB,EAGlD;IACD,IAAI,CAACA,eAAe,EAAE;MACpB,OAAO;QACLC,WAAW,EAAE,IAAI;QACjBC,cAAc,EAAE;MAClB,CAAC;IACH;IAEA,MAAMC,0BAA0B,GAC9B,CAAC,MAAMrB,uBAAuB,CAACe,YAAY,CAACG,eAAe,CAAC,KAC5D,EAAE,MAAMlB,uBAAuB,CAACU,aAAa,CAACQ,eAAe,CAAC,CAAC;IAEjE,IAAIG,0BAA0B,EAAE;MAC9B,MAAM;QAAEC,GAAG,EAAEH,WAAW;QAAEI,IAAI,EAAEH;MAAe,CAAC,GAC9C3C,IAAI,CAAC+C,KAAK,CAACN,eAAe,CAAC;MAC7B,OAAO;QACLC,WAAW;QACXC;MACF,CAAC;IACH;IAEA,OAAO;MACLD,WAAW,EAAED,eAAe;MAC5BE,cAAc,EAAE;IAClB,CAAC;EACH;;EAEA;AACF;AACA;EACE,MAAMX,aAAa,GAAkB;IACnC;IACA,IAAI,CAACgB,GAAG,GAAG,MAAM,IAAIC,OAAO,CAAEC,OAAO,IAAK;MACxC,MAAMC,MAAM,GAAG,IAAI3C,eAAe;MAChC;MACA;MACA;QAAE4C,IAAI,EAAE,CAAC;QAAEC,IAAI,EAAE,WAAW;QAAEC,cAAc,EAAE;MAAK,CAAC;MACpD;MACA;MACA,MAAMJ,OAAO,CAACC,MAAM,CAAC,CACtB;IACH,CAAC,CAAC;;IAEF;IACA;IACA,IAAI,CAACH,GAAG,CAACO,EAAE,CAAC,YAAY,EAAE,UAAUC,MAAM,EAAE;MAC1CA,MAAM,CAACD,EAAE,CAAC,OAAO,EAAGE,GAAG,IAAK;QAC1B5C,GAAG,CAAC6C,KAAK,CAAE,+BAA8BD,GAAI,EAAC,CAAC;MACjD,CAAC,CAAC;IACJ,CAAC,CAAC;;IAEF;IACA,IAAI,CAACE,sBAAsB,GAAG,MAAM,IAAI,CAACC,4BAA4B,EAAE;;IAEvE;IACA,MAAMC,UAAU,GAAG,CAAC,IAAI,CAACF,sBAAsB,CAAC,CAC7CG,MAAM,CAAC,IAAI,CAACrC,MAAM,CAACoC,UAAU,CAACE,GAAG,CAAC,CAAC;MAAEC;IAAU,CAAC,KAAKA,SAAS,CAAC,CAAC,CAChE5B,IAAI,CAAC,GAAG,CAAC;IAEZ,MAAM;MAAE6B;IAAe,CAAC,GAAG,IAAI,CAACxC,MAAM;IAEtCZ,GAAG,CAAC6C,KAAK,CAAC,+BAA+B,CAAC;IAE1C,IAAIO,cAAc,EAAE;MAClBpD,GAAG,CAAC6C,KAAK,CAAE,oBAAmBO,cAAe,GAAE,CAAC;IAClD;IAEA,MAAMC,WAAW,GAAG,CAAC,GAAGhD,oBAAoB,CAAC;IAE7CgD,WAAW,CAACC,IAAI,CAAE,oBAAmBN,UAAW,EAAC,CAAC;IAElD,IAAI,IAAI,CAACpC,MAAM,CAAC2C,IAAI,EAAE;MACpBF,WAAW,CAACC,IAAI,CAAC,GAAG,IAAI,CAAC1C,MAAM,CAAC2C,IAAI,CAAC;IACvC;;IAEA;IACA,IAAI;MAAE1B,WAAW;MAAEC;IAAe,CAAC,GACjC,MAAMpB,uBAAuB,CAACiB,eAAe,CAC3C,IAAI,CAACf,MAAM,CAACgB,eAAe,CAC5B;IAEH,IAAIC,WAAW,IAAI,IAAI,CAACjB,MAAM,CAAC4C,kBAAkB,EAAE;MACjD,IACE1B,cAAc,IACd,EAAE,MAAMpB,uBAAuB,CAACU,aAAa,CAACS,WAAW,CAAC,CAAC,EAC3D;QACA,MAAM,IAAI4B,KAAK,CACb,uCAAuC,GACrC,2DAA2D,GAC3D,sDAAsD,GACtD,yBAAyB,CAC5B;MACH;IACF,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC7C,MAAM,CAAC4C,kBAAkB,EAAE;MAC1C;MACA;MACA;MACA,MAAME,MAAM,GAAG,IAAI7D,OAAO,EAAE;MAC5B,MAAM6D,MAAM,CAACC,MAAM,EAAE;MACrB,MAAMC,UAAU,GAAGF,MAAM,CAACvE,IAAI,EAAE;MAEhC,IAAI0C,WAAW,IAAIC,cAAc,EAAE;QACjC;QACA,MAAM1C,EAAE,CAACyE,IAAI,CACX1E,IAAI,CAACoC,IAAI,CAACM,WAAW,EAAEC,cAAc,CAAC,EACtC3C,IAAI,CAACoC,IAAI,CAACqC,UAAU,EAAE9B,cAAc,CAAC,CACtC;MACH,CAAC,MAAM,IAAID,WAAW,EAAE;QACtB,MAAMzC,EAAE,CAACyE,IAAI,CAAChC,WAAW,EAAE+B,UAAU,CAAC;MACxC;MACA/B,WAAW,GAAG+B,UAAU;IAC1B;IAEA,IAAI9B,cAAc,EAAE;MAClBuB,WAAW,CAACC,IAAI,CAAE,uBAAsBxB,cAAe,EAAC,CAAC;IAC3D;IAEA,IAAIgC,WAAW;IACf,IAAI,IAAI,CAAClD,MAAM,CAACmD,QAAQ,EAAE;MACxB,MAAMC,YAAY,GAAGC,KAAK,CAACC,OAAO,CAAC,IAAI,CAACtD,MAAM,CAACmD,QAAQ,CAAC,GACpD,IAAI,CAACnD,MAAM,CAACmD,QAAQ,GACpB,CAAC,IAAI,CAACnD,MAAM,CAACmD,QAAQ,CAAC;MAC1BD,WAAW,GAAGE,YAAY,CAACG,KAAK,EAAE;MAClCd,WAAW,CAACC,IAAI,CAAC,GAAGU,YAAY,CAAC;IACnC;IAEA,IAAI,CAACI,gBAAgB,GAAG,MAAM,IAAI,CAACvD,cAAc,CAAC;MAChDwD,gBAAgB,EAAE,IAAI;MACtBC,UAAU,EAAElB,cAAc;MAC1BC,WAAW;MACXS,WAAW;MACXjC,WAAW;MACX;MACA0C,kBAAkB,EAAE;IACtB,CAAC,CAAC;IAEF,IAAI,CAACH,gBAAgB,CAACI,OAAO,CAACC,IAAI,CAAC,OAAO,EAAE,MAAM;MAChD,IAAI,CAACL,gBAAgB,GAAG,IAAI;MAE5B,IAAI,CAAC,IAAI,CAACM,OAAO,EAAE;QACjB1E,GAAG,CAAC2E,IAAI,CAAC,4CAA4C,CAAC;QACtD,IAAI,CAACC,IAAI,EAAE;MACb;IACF,CAAC,CAAC;EACJ;EAEA,MAAMC,YAAY,CAACC,IAAY,EAAiB;IAC9C,OAAO,IAAI1C,OAAO,CAAEC,OAAO,IAAK;MAC9B,MAAM0C,OAAO,GAAG,IAAI,CAAC5C,GAAG,GAAG,IAAIpB,GAAG,CAAC,IAAI,CAACoB,GAAG,CAAC4C,OAAO,CAAC,GAAG,IAAIhE,GAAG,EAAE;MAEhE,SAASiE,yBAAyB,GAAG;QACnC,MAAMC,MAAM,GAAG,IAAI;QACnBA,MAAM,CAACC,mBAAmB,CAAC,SAAS,EAAEC,oBAAoB,CAAC;QAC3DF,MAAM,CAACC,mBAAmB,CAAC,OAAO,EAAEF,yBAAyB,CAAC;QAC9DD,OAAO,CAACK,MAAM,CAACH,MAAM,CAAC;MACxB;MAEA,MAAME,oBAAoB,GAAG,MAAOE,OAAO,IAAK;QAC9C,MAAMC,GAAG,GAAGC,IAAI,CAACrD,KAAK,CAACmD,OAAO,CAACP,IAAI,CAAC;QAEpC,IAAIQ,GAAG,CAACE,IAAI,KAAK,+BAA+B,EAAE;UAChD,KAAK,MAAMP,MAAM,IAAIF,OAAO,EAAE;YAC5BC,yBAAyB,CAACS,IAAI,CAACR,MAAM,CAAC;UACxC;UACA5C,OAAO,EAAE;QACX;MACF,CAAC;MAED,KAAK,MAAM4C,MAAM,IAAIF,OAAO,EAAE;QAC5B,IAAIE,MAAM,CAACS,UAAU,KAAKhG,SAAS,CAACiG,IAAI,EAAE;UACxCV,MAAM,CAACW,gBAAgB,CAAC,SAAS,EAAET,oBAAoB,CAAC;UACxDF,MAAM,CAACW,gBAAgB,CAAC,OAAO,EAAEZ,yBAAyB,CAAC;UAE3DC,MAAM,CAACY,IAAI,CAACN,IAAI,CAACO,SAAS,CAAChB,IAAI,CAAC,CAAC;QACnC,CAAC,MAAM;UACLC,OAAO,CAACK,MAAM,CAACH,MAAM,CAAC;QACxB;MACF;MAEA,IAAIF,OAAO,CAACgB,IAAI,KAAK,CAAC,EAAE;QACtB1D,OAAO,EAAE;MACX;IACF,CAAC,CAAC;EACJ;EAEA,MAAMU,4BAA4B,GAAoB;IACpD,MAAMW,MAAM,GAAG,IAAI7D,OAAO,EAAE;IAC5B,MAAM6D,MAAM,CAACC,MAAM,EAAE;IACrB,IAAI,CAACqC,eAAe,CAAC,MAAMtC,MAAM,CAACuC,MAAM,EAAE,CAAC;IAE3C,MAAMC,OAAO,GAAG/G,IAAI,CAACoC,IAAI,CACvBmC,MAAM,CAACvE,IAAI,EAAE,EACZ,4BAA2BgH,IAAI,CAACC,GAAG,EAAG,EAAC,CACzC;IAEDpG,GAAG,CAAC6C,KAAK,CAAE,wCAAuCqD,OAAQ,EAAC,CAAC;IAE5D,MAAM7G,WAAW,CAAC6G,OAAO,CAAC;IAE1B,MAAM9G,EAAE,CAACiH,SAAS,CAChBlH,IAAI,CAACoC,IAAI,CAAC2E,OAAO,EAAE,eAAe,CAAC,EACnCX,IAAI,CAACO,SAAS,CAAC;MACbQ,gBAAgB,EAAE,CAAC;MACnBC,IAAI,EAAE,kCAAkC;MACxCC,OAAO,EAAE,KAAK;MACdC,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC;MACnCC,UAAU,EAAE;QACVC,OAAO,EAAE,CAAC,OAAO;MACnB;IACF,CAAC,CAAC,CACH;;IAED;IACA,MAAMC,OAAO,GAAG,IAAI,CAACzE,GAAG,CAAC0E,OAAO,EAAE;IAElC,MAAMC,MAAM,GAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgBF,OAAO,CAACC,OAAQ,IAAGD,OAAO,CAACrE,IAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;IAEL,MAAMnD,EAAE,CAACiH,SAAS,CAAClH,IAAI,CAACoC,IAAI,CAAC2E,OAAO,EAAE,OAAO,CAAC,EAAEY,MAAM,CAAC;IACvD,OAAOZ,OAAO;EAChB;;EAEA;AACF;AACA;AACA;EACE,MAAMa,mBAAmB,GAAgD;IACvE,MAAMC,UAAU,GAAG,IAAI,CAAChG,OAAO,EAAE;IAEjC,MAAM,IAAI,CAAC6D,YAAY,CAAC;MACtBW,IAAI,EAAE;IACR,CAAC,CAAC;IAEFhB,OAAO,CAACyC,MAAM,CAACC,KAAK,CACjB,4BAA2B,IAAIf,IAAI,EAAE,CAACgB,YAAY,EAAG,EAAC,CACxD;IACDnH,GAAG,CAAC6C,KAAK,CAAC,IAAI,CAAC;IAEf,OAAO,CAAC;MAAEmE;IAAW,CAAC,CAAC;EACzB;;EAEA;AACF;AACA;AACA;EACE,MAAMI,0BAA0B,CAC9BC,kBAA0B,EACmB;IAC7C;IACA;IACA;IACA,OAAO,IAAI,CAACN,mBAAmB,EAAE;EACnC;;EAEA;AACF;AACA;AACA;AACA;EACEf,eAAe,CAACsB,EAAY,EAAQ;IAClC,IAAI,CAACxG,gBAAgB,CAACyG,GAAG,CAACD,EAAE,CAAC;EAC/B;;EAEA;AACF;AACA;EACE,MAAM1C,IAAI,GAAkB;IAC1B,IAAI,CAACF,OAAO,GAAG,IAAI;;IAEnB;IACA;IACA,IAAI,IAAI,CAACxD,iBAAiB,EAAE;MAC1B;MACA,MAAM,IAAI,CAACA,iBAAiB,CAACsG,KAAK,CAAE5E,GAAG,IAAK;QAC1C5C,GAAG,CAAC6C,KAAK,CAAE,oDAAmDD,GAAI,EAAC,CAAC;MACtE,CAAC,CAAC;IACJ;IAEA,IAAI,IAAI,CAACwB,gBAAgB,EAAE;MACzB,MAAM,IAAI,CAACA,gBAAgB,CAACqD,IAAI,EAAE;MAClC,IAAI,CAACrD,gBAAgB,GAAG,IAAI;IAC9B;IAEA,IAAI,IAAI,CAACjC,GAAG,EAAE;MACZ;MACA;MACA;MACA,KAAK,MAAMuF,SAAS,IAAI,kBAAI,CAACvF,GAAG,8CAAR,UAAU4C,OAAO,KAAI,EAAE,EAAE;QAAA;QAC/C,IAAI2C,SAAS,CAAChC,UAAU,KAAKhG,SAAS,CAACiG,IAAI,EAAE;UAC3C+B,SAAS,CAACC,SAAS,EAAE;QACvB;MACF;MACA,MAAM,IAAIvF,OAAO,CAAEC,OAAO,IACxB,IAAI,CAACF,GAAG,GAAG,IAAI,CAACA,GAAG,CAACyF,KAAK,CAACvF,OAAO,CAAC,GAAGA,OAAO,EAAE,CAC/C;MACD,IAAI,CAACF,GAAG,GAAG,IAAI;IACjB;;IAEA;IACA,KAAK,MAAMmF,EAAE,IAAI,IAAI,CAACxG,gBAAgB,EAAE;MACtC,IAAI;QACFwG,EAAE,EAAE;MACN,CAAC,CAAC,OAAOO,KAAK,EAAE;QACd7H,GAAG,CAAC6H,KAAK,CAACA,KAAK,CAAC;MAClB;IACF;EACF;AACF"}
|
|
1
|
+
{"version":3,"file":"chromium.js","names":["path","fs","asyncMkdirp","Launcher","ChromeLauncher","launch","defaultChromiumLaunch","WebSocket","WebSocketServer","createLogger","TempDir","isDirectory","fileExists","log","import","meta","url","EXCLUDED_CHROME_FLAGS","DEFAULT_CHROME_FLAGS","defaultFlags","filter","flag","includes","ChromiumExtensionRunner","constructor","params","chromiumLaunch","cleanupCallbacks","Set","getName","run","_promiseSetupDone","setupInstance","isUserDataDir","dirPath","localStatePath","join","defaultPath","isProfileDir","securePreferencesPath","getProfilePaths","chromiumProfile","userDataDir","profileDirName","isProfileDirAndNotUserData","dir","base","parse","wss","Promise","resolve","server","port","host","clientTracking","on","socket","err","debug","reloadManagerExtension","createReloadManagerExtension","extensions","concat","map","sourceDir","chromiumBinary","chromeFlags","push","args","keepProfileChanges","Error","tmpDir","create","tmpDirPath","copy","startingUrl","startUrl","startingUrls","Array","isArray","shift","chromiumInstance","enableExtensions","chromePath","ignoreDefaultFlags","process","once","exiting","info","exit","wssBroadcast","data","clients","cleanWebExtReloadComplete","client","removeEventListener","webExtReloadComplete","delete","message","msg","JSON","type","call","readyState","OPEN","addEventListener","send","stringify","size","registerCleanup","remove","extPath","Date","now","writeFile","manifest_version","name","version","permissions","background","scripts","wssInfo","address","bgPage","reloadAllExtensions","runnerName","stdout","write","toTimeString","reloadExtensionBySourceDir","extensionSourceDir","fn","add","catch","kill","wssClient","_this$wss","terminate","close","error"],"sources":["../../src/extension-runners/chromium.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Chromium-based browser instance.\n */\n\nimport path from 'path';\n\nimport fs from 'fs-extra';\nimport asyncMkdirp from 'mkdirp';\nimport {\n Launcher as ChromeLauncher,\n launch as defaultChromiumLaunch,\n} from 'chrome-launcher';\nimport WebSocket, { WebSocketServer } from 'ws';\n\nimport { createLogger } from '../util/logger.js';\nimport { TempDir } from '../util/temp-dir.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport isDirectory from '../util/is-directory.js';\nimport fileExists from '../util/file-exists.js';\n\ntype ChromiumSpecificRunnerParams = {|\n chromiumBinary?: string,\n chromiumProfile?: string,\n chromiumLaunch?: typeof defaultChromiumLaunch,\n|};\n\nexport type ChromiumExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n // Chromium desktop CLI params.\n ...ChromiumSpecificRunnerParams,\n|};\n\nconst log = createLogger(import.meta.url);\n\nconst EXCLUDED_CHROME_FLAGS = ['--disable-extensions', '--mute-audio'];\n\nexport const DEFAULT_CHROME_FLAGS: Array<string> =\n ChromeLauncher.defaultFlags().filter(\n (flag) => !EXCLUDED_CHROME_FLAGS.includes(flag)\n );\n\n/**\n * Implements an IExtensionRunner which manages a Chromium instance.\n */\nexport class ChromiumExtensionRunner {\n cleanupCallbacks: Set<Function>;\n params: ChromiumExtensionRunnerParams;\n chromiumInstance: ?ChromeLauncher;\n chromiumLaunch: typeof defaultChromiumLaunch;\n reloadManagerExtension: string;\n wss: ?WebSocketServer;\n exiting: boolean;\n _promiseSetupDone: ?Promise<void>;\n\n constructor(params: ChromiumExtensionRunnerParams) {\n const { chromiumLaunch = defaultChromiumLaunch } = params;\n this.params = params;\n this.chromiumLaunch = chromiumLaunch;\n this.cleanupCallbacks = new Set();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Chromium';\n }\n\n async run(): Promise<void> {\n // Run should never be called more than once.\n this._promiseSetupDone = this.setupInstance();\n await this._promiseSetupDone;\n }\n\n static async isUserDataDir(dirPath: string): Promise<boolean> {\n const localStatePath = path.join(dirPath, 'Local State');\n const defaultPath = path.join(dirPath, 'Default');\n // Local State and Default are typical for the user-data-dir\n return (\n (await fileExists(localStatePath)) && (await isDirectory(defaultPath))\n );\n }\n\n static async isProfileDir(dirPath: string): Promise<boolean> {\n const securePreferencesPath = path.join(dirPath, 'Secure Preferences');\n //Secure Preferences is typical for a profile dir inside a user data dir\n return await fileExists(securePreferencesPath);\n }\n\n static async getProfilePaths(chromiumProfile: ?string): Promise<{\n userDataDir: ?string,\n profileDirName: ?string,\n }> {\n if (!chromiumProfile) {\n return {\n userDataDir: null,\n profileDirName: null,\n };\n }\n\n const isProfileDirAndNotUserData =\n (await ChromiumExtensionRunner.isProfileDir(chromiumProfile)) &&\n !(await ChromiumExtensionRunner.isUserDataDir(chromiumProfile));\n\n if (isProfileDirAndNotUserData) {\n const { dir: userDataDir, base: profileDirName } =\n path.parse(chromiumProfile);\n return {\n userDataDir,\n profileDirName,\n };\n }\n\n return {\n userDataDir: chromiumProfile,\n profileDirName: null,\n };\n }\n\n /**\n * Setup the Chromium Profile and run a Chromium instance.\n */\n async setupInstance(): Promise<void> {\n // Start a websocket server on a free localhost TCP port.\n this.wss = await new Promise((resolve) => {\n const server = new WebSocketServer(\n // Use a ipv4 host so we don't need to escape ipv6 address\n // https://github.com/mozilla/web-ext/issues/2331\n { port: 0, host: '127.0.0.1', clientTracking: true },\n // Wait the server to be listening (so that the extension\n // runner can successfully retrieve server address and port).\n () => resolve(server)\n );\n });\n\n // Prevent unhandled socket error (e.g. when chrome\n // is exiting, See https://github.com/websockets/ws/issues/1256).\n this.wss.on('connection', function (socket) {\n socket.on('error', (err) => {\n log.debug(`websocket connection error: ${err}`);\n });\n });\n\n // Create the extension that will manage the addon reloads\n this.reloadManagerExtension = await this.createReloadManagerExtension();\n\n // Start chrome pointing it to a given profile dir\n const extensions = [this.reloadManagerExtension]\n .concat(this.params.extensions.map(({ sourceDir }) => sourceDir))\n .join(',');\n\n const { chromiumBinary } = this.params;\n\n log.debug('Starting Chromium instance...');\n\n if (chromiumBinary) {\n log.debug(`(chromiumBinary: ${chromiumBinary})`);\n }\n\n const chromeFlags = [...DEFAULT_CHROME_FLAGS];\n\n chromeFlags.push(`--load-extension=${extensions}`);\n\n if (this.params.args) {\n chromeFlags.push(...this.params.args);\n }\n\n // eslint-disable-next-line prefer-const\n let { userDataDir, profileDirName } =\n await ChromiumExtensionRunner.getProfilePaths(\n this.params.chromiumProfile\n );\n\n if (userDataDir && this.params.keepProfileChanges) {\n if (\n profileDirName &&\n !(await ChromiumExtensionRunner.isUserDataDir(userDataDir))\n ) {\n throw new Error(\n 'The profile you provided is not in a ' +\n 'user-data-dir. The changes cannot be kept. Please either ' +\n 'remove --keep-profile-changes or use a profile in a ' +\n 'user-data-dir directory'\n );\n }\n } else if (!this.params.keepProfileChanges) {\n // the user provided an existing profile directory but doesn't want\n // the changes to be kept. we copy this directory to a temporary\n // user data dir.\n const tmpDir = new TempDir();\n await tmpDir.create();\n const tmpDirPath = tmpDir.path();\n\n if (userDataDir && profileDirName) {\n // copy profile dir to this temp user data dir.\n await fs.copy(\n path.join(userDataDir, profileDirName),\n path.join(tmpDirPath, profileDirName)\n );\n } else if (userDataDir) {\n await fs.copy(userDataDir, tmpDirPath);\n }\n userDataDir = tmpDirPath;\n }\n\n if (profileDirName) {\n chromeFlags.push(`--profile-directory=${profileDirName}`);\n }\n\n let startingUrl;\n if (this.params.startUrl) {\n const startingUrls = Array.isArray(this.params.startUrl)\n ? this.params.startUrl\n : [this.params.startUrl];\n startingUrl = startingUrls.shift();\n chromeFlags.push(...startingUrls);\n }\n\n this.chromiumInstance = await this.chromiumLaunch({\n enableExtensions: true,\n chromePath: chromiumBinary,\n chromeFlags,\n startingUrl,\n userDataDir,\n // Ignore default flags to keep the extension enabled.\n ignoreDefaultFlags: true,\n });\n\n this.chromiumInstance.process.once('close', () => {\n this.chromiumInstance = null;\n\n if (!this.exiting) {\n log.info('Exiting on Chromium instance disconnected.');\n this.exit();\n }\n });\n }\n\n async wssBroadcast(data: Object): Promise<void> {\n return new Promise((resolve) => {\n const clients = this.wss ? new Set(this.wss.clients) : new Set();\n\n function cleanWebExtReloadComplete() {\n const client = this;\n client.removeEventListener('message', webExtReloadComplete);\n client.removeEventListener('close', cleanWebExtReloadComplete);\n clients.delete(client);\n }\n\n const webExtReloadComplete = async (message) => {\n const msg = JSON.parse(message.data);\n\n if (msg.type === 'webExtReloadExtensionComplete') {\n for (const client of clients) {\n cleanWebExtReloadComplete.call(client);\n }\n resolve();\n }\n };\n\n for (const client of clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.addEventListener('message', webExtReloadComplete);\n client.addEventListener('close', cleanWebExtReloadComplete);\n\n client.send(JSON.stringify(data));\n } else {\n clients.delete(client);\n }\n }\n\n if (clients.size === 0) {\n resolve();\n }\n });\n }\n\n async createReloadManagerExtension(): Promise<string> {\n const tmpDir = new TempDir();\n await tmpDir.create();\n this.registerCleanup(() => tmpDir.remove());\n\n const extPath = path.join(\n tmpDir.path(),\n `reload-manager-extension-${Date.now()}`\n );\n\n log.debug(`Creating reload-manager-extension in ${extPath}`);\n\n await asyncMkdirp(extPath);\n\n await fs.writeFile(\n path.join(extPath, 'manifest.json'),\n JSON.stringify({\n manifest_version: 2,\n name: 'web-ext Reload Manager Extension',\n version: '1.0',\n permissions: ['management', 'tabs'],\n background: {\n scripts: ['bg.js'],\n },\n })\n );\n\n // $FlowIgnore: this method is only called right after creating the server and so wss should be defined.\n const wssInfo = this.wss.address();\n\n const bgPage = `(function bgPage() {\n async function getAllDevExtensions() {\n const allExtensions = await new Promise(\n r => chrome.management.getAll(r));\n\n return allExtensions.filter((extension) => {\n return extension.enabled &&\n extension.installType === \"development\" &&\n extension.id !== chrome.runtime.id;\n });\n }\n\n const setEnabled = (extensionId, value) =>\n chrome.runtime.id == extensionId ?\n new Promise.resolve() :\n new Promise(r => chrome.management.setEnabled(extensionId, value, r));\n\n async function reloadExtension(extensionId) {\n await setEnabled(extensionId, false);\n await setEnabled(extensionId, true);\n }\n\n const ws = new window.WebSocket(\n \"ws://${wssInfo.address}:${wssInfo.port}\");\n\n ws.onmessage = async (evt) => {\n const msg = JSON.parse(evt.data);\n if (msg.type === 'webExtReloadAllExtensions') {\n const devExtensions = await getAllDevExtensions();\n await Promise.all(devExtensions.map(ext => reloadExtension(ext.id)));\n ws.send(JSON.stringify({ type: 'webExtReloadExtensionComplete' }));\n }\n };\n })()`;\n\n await fs.writeFile(path.join(extPath, 'bg.js'), bgPage);\n return extPath;\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n\n await this.wssBroadcast({\n type: 'webExtReloadAllExtensions',\n });\n\n process.stdout.write(\n `\\rLast extension reload: ${new Date().toTimeString()}`\n );\n log.debug('\\n');\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string // eslint-disable-line no-unused-vars\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n // TODO(rpl): detect the extension ids assigned to the\n // target extensions and map it to the extensions source dir\n // (https://github.com/mozilla/web-ext/issues/1687).\n return this.reloadAllExtensions();\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Chromium instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Chromium instance.\n */\n async exit(): Promise<void> {\n this.exiting = true;\n\n // Wait for the setup to complete if the extension runner is already\n // being started.\n if (this._promiseSetupDone) {\n // Ignore initialization errors if any.\n await this._promiseSetupDone.catch((err) => {\n log.debug(`ignored setup error on chromium runner shutdown: ${err}`);\n });\n }\n\n if (this.chromiumInstance) {\n await this.chromiumInstance.kill();\n this.chromiumInstance = null;\n }\n\n if (this.wss) {\n // Close all websocket clients, closing the WebSocketServer\n // does not terminate the existing connection and it wouldn't\n // resolve until all of the existing connections are closed.\n for (const wssClient of this.wss?.clients || []) {\n if (wssClient.readyState === WebSocket.OPEN) {\n wssClient.terminate();\n }\n }\n await new Promise((resolve) =>\n this.wss ? this.wss.close(resolve) : resolve()\n );\n this.wss = null;\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","showDesktopNotification","defaultDesktopNotifications","MultiExtensionsReloadError","UsageError","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","constructor","params","cleanupCallbacks","Set","adbExtensionsPathBySourceDir","Map","reloadableExtensions","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbCheckRuntimePermissions","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","selectedAdbDevice","selectedArtifactsDir","exiting","debug","clearArtifactsDir","getDeviceProfileDir","Object","keys","forEach","ignoredParam","warn","adbDevice","devices","discoverDevices","length","devicesMsg","map","dev","join","info","foundDevices","filter","device","JSON","stringify","firefoxApk","packages","discoverInstalledFirefoxAPKs","pkgsListMsg","pkgs","pkg","selectedFirefoxApk","filteredPackages","line","pkgsList","amForceStopAPK","androidVersion","getAndroidVersionNumber","Number","isNaN","requiredPermissions","ensureRequiredAPKRuntimePermissions","customPrefs","firefoxApp","adbRemoveOldArtifacts","profile","createProfile","app","foundOldArtifacts","detectOrRemoveOldArtifacts","getOrCreateArtifactsDir","deviceProfileDir","runShellCommand","pushFile","profileDir","firefoxApkComponent","startFirefoxAPK","buildSourceDir","tmpDir","extensionPath","extFileName","basename","adbExtensionPath","adbDiscoveryTimeout","stdin","process","handleCtrlC","str","key","ctrl","name","setUserAbortDiscovery","emitKeypressEvents","on","selectedRDPSocketFile","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","selectedTCPPort","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Android instance.\n */\n\nimport path from 'path';\nimport readline from 'readline';\n\nimport { withTempDir } from '../util/temp-dir.js';\nimport DefaultADBUtils from '../util/adb.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport {\n connectWithMaxRetries as defaultFirefoxConnector,\n findFreeTcpPort,\n} from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type { FirefoxPreferences } from '../firefox/preferences';\nimport type { FirefoxRDPResponseAddon, RemoteFirefox } from '../firefox/remote';\nimport type { ExtensionBuildResult } from '../cmd/build';\n\nconst log = createLogger(import.meta.url);\n\nconst ignoredParams = {\n profilePath: '--profile-path',\n keepProfileChanges: '--keep-profile-changes',\n browserConsole: '--browser-console',\n preInstall: '--pre-install',\n startUrl: '--start-url',\n args: '--args',\n};\n\n// Default adbHost to 127.0.0.1 to prevent issues with nodejs 17\n// (because if not specified adbkit may default to ipv6 while\n// adb may still only be listening on the ipv4 address),\n// see https://github.com/mozilla/web-ext/issues/2337.\nconst DEFAULT_ADB_HOST = '127.0.0.1';\n\nconst getIgnoredParamsWarningsMessage = (optionName) => {\n return `The Firefox for Android target does not support ${optionName}`;\n};\n\nexport type FirefoxAndroidExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n\n // Firefox specific.\n customPrefs?: FirefoxPreferences,\n\n // Not supported (currently ignored with logged warning).\n preInstall?: boolean,\n browserConsole?: boolean,\n\n // Firefox android injected dependencies.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n adbDiscoveryTimeout?: number,\n adbRemoveOldArtifacts?: boolean,\n firefoxApk?: string,\n firefoxApkComponent?: string,\n\n // Injected Dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n ADBUtils?: typeof DefaultADBUtils,\n buildSourceDir: (string, string) => Promise<ExtensionBuildResult>,\n desktopNotifications: typeof defaultDesktopNotifications,\n stdin?: stream$Readable,\n|};\n\n/**\n * Implements an IExtensionRunner which manages a Firefox for Android instance.\n */\nexport class FirefoxAndroidExtensionRunner {\n // Wait 3s before the next unix socket discovery loop.\n static unixSocketDiscoveryRetryInterval: number = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime: number = 3 * 60 * 1000;\n\n params: FirefoxAndroidExtensionRunnerParams;\n adbUtils: DefaultADBUtils;\n exiting: boolean;\n selectedAdbDevice: string;\n selectedFirefoxApk: string;\n selectedArtifactsDir: string;\n selectedRDPSocketFile: string;\n selectedTCPPort: number;\n cleanupCallbacks: Set<Function>;\n adbExtensionsPathBySourceDir: Map<string, string>;\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n\n constructor(params: FirefoxAndroidExtensionRunnerParams) {\n this.params = params;\n this.cleanupCallbacks = new Set();\n this.adbExtensionsPathBySourceDir = new Map();\n this.reloadableExtensions = new Map();\n\n // Print warning for not currently supported options (e.g. preInstall,\n // cloned profiles, browser console).\n this.printIgnoredParamsWarnings();\n }\n\n async run(): Promise<void> {\n const {\n adbBin,\n adbHost = DEFAULT_ADB_HOST,\n adbPort,\n ADBUtils = DefaultADBUtils,\n } = this.params;\n\n this.adbUtils = new ADBUtils({\n adbBin,\n adbHost,\n adbPort,\n });\n\n await this.adbDevicesDiscoveryAndSelect();\n await this.apkPackagesDiscoveryAndSelect();\n await this.adbCheckRuntimePermissions();\n await this.adbForceStopSelectedPackage();\n\n // Create profile prefs (with enabled remote RDP server), prepare the\n // artifacts and temporary directory on the selected device, and\n // push the profile preferences to the remote profile dir.\n await this.adbPrepareProfileDir();\n\n // NOTE: running Firefox for Android on the Android Emulator can be\n // pretty slow, we can run the following 3 steps in parallel to speed up\n // it a bit.\n await Promise.all([\n // Start Firefox for Android instance if not started yet.\n // (Fennec would run in an temporary profile and so it is explicitly\n // stopped, Fenix runs on its usual profile and so it may be already\n // running).\n this.adbStartSelectedPackage(),\n\n // Build and push to devices all the extension xpis\n // and keep track of the xpi built and uploaded by extension sourceDir.\n this.buildAndPushExtensions(),\n\n // Wait for RDP unix socket file created and\n // Create an ADB forward connection on a free tcp port\n this.adbDiscoveryAndForwardRDPUnixSocket(),\n ]);\n\n // Connect to RDP socket on the local tcp server, install all the pushed extension\n // and keep track of the built and installed extension by extension sourceDir.\n await this.rdpInstallExtensions();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Android';\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n\n for (const { sourceDir } of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [\n {\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n },\n ];\n }\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n },\n ];\n }\n\n try {\n await this.buildAndPushExtension(extensionSourceDir);\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n },\n ];\n }\n\n return [{ runnerName, sourceDir: extensionSourceDir }];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n const { adbUtils, selectedAdbDevice, selectedArtifactsDir } = this;\n\n this.exiting = true;\n\n // If a Firefox for Android instance has been started,\n // we should ensure that it has been stopped when we exit.\n await this.adbForceStopSelectedPackage();\n\n if (selectedArtifactsDir) {\n log.debug('Cleaning up artifacts directory on the Android device...');\n await adbUtils.clearArtifactsDir(selectedAdbDevice);\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n\n // Private helper methods.\n\n getDeviceProfileDir(): string {\n return `${this.selectedArtifactsDir}/profile`;\n }\n\n printIgnoredParamsWarnings() {\n Object.keys(ignoredParams).forEach((ignoredParam) => {\n if (this.params[ignoredParam]) {\n log.warn(getIgnoredParamsWarningsMessage(ignoredParams[ignoredParam]));\n }\n });\n }\n\n async adbDevicesDiscoveryAndSelect() {\n const { adbUtils } = this;\n const { adbDevice } = this.params;\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await adbUtils.discoverDevices();\n\n if (devices.length === 0) {\n throw new UsageError(\n 'No Android device found through ADB. ' +\n 'Make sure the device is connected and USB debugging is enabled.'\n );\n }\n\n if (!adbDevice) {\n const devicesMsg = devices.map((dev) => ` - ${dev}`).join('\\n');\n log.info(`\\nAndroid devices found:\\n${devicesMsg}`);\n throw new UsageError(\n 'Select an android device using --android-device=<name>'\n );\n }\n\n const foundDevices = devices.filter((device) => {\n return device === adbDevice;\n });\n\n if (foundDevices.length === 0) {\n const devicesMsg = JSON.stringify(devices);\n throw new UsageError(\n `Android device ${adbDevice} was not found in list: ${devicesMsg}`\n );\n }\n\n this.selectedAdbDevice = foundDevices[0];\n log.info(`Selected ADB device: ${this.selectedAdbDevice}`);\n }\n\n async apkPackagesDiscoveryAndSelect() {\n const {\n adbUtils,\n selectedAdbDevice,\n params: { firefoxApk },\n } = this;\n // Discovery and select a Firefox for Android version.\n const packages = await adbUtils.discoverInstalledFirefoxAPKs(\n selectedAdbDevice,\n firefoxApk\n );\n\n if (packages.length === 0) {\n throw new UsageError(\n 'No Firefox packages were found on the selected Android device'\n );\n }\n\n const pkgsListMsg = (pkgs) => {\n return pkgs.map((pkg) => ` - ${pkg}`).join('\\n');\n };\n\n if (!firefoxApk) {\n log.info(`\\nPackages found:\\n${pkgsListMsg(packages)}`);\n\n if (packages.length > 1) {\n throw new UsageError('Select one of the packages using --firefox-apk');\n }\n\n // If only one APK has been found, select it even if it has not been\n // specified explicitly on the comment line.\n this.selectedFirefoxApk = packages[0];\n log.info(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n return;\n }\n\n const filteredPackages = packages.filter((line) => line === firefoxApk);\n\n if (filteredPackages.length === 0) {\n const pkgsList = pkgsListMsg(filteredPackages);\n throw new UsageError(\n `Package ${firefoxApk} was not found in list: ${pkgsList}`\n );\n }\n\n this.selectedFirefoxApk = filteredPackages[0];\n log.debug(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n }\n\n async adbForceStopSelectedPackage() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.info(`Stopping existing instances of ${selectedFirefoxApk}...`);\n await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);\n }\n\n async adbCheckRuntimePermissions() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.debug(`Discovering Android version for ${selectedAdbDevice}...`);\n\n const androidVersion = await adbUtils.getAndroidVersionNumber(\n selectedAdbDevice\n );\n\n if (typeof androidVersion !== 'number' || Number.isNaN(androidVersion)) {\n throw new WebExtError(`Invalid Android version: ${androidVersion}`);\n }\n\n log.debug(`Detected Android version ${androidVersion}`);\n\n if (androidVersion < 23) {\n return;\n }\n\n log.debug(\n 'Checking read/write permissions needed for web-ext' +\n `on ${selectedFirefoxApk}...`\n );\n\n // Runtime permissions needed to Firefox to be able to access the\n // xpi file uploaded to the android device or emulator.\n const requiredPermissions = ['android.permission.READ_EXTERNAL_STORAGE'];\n\n await adbUtils.ensureRequiredAPKRuntimePermissions(\n selectedAdbDevice,\n selectedFirefoxApk,\n requiredPermissions\n );\n }\n\n async adbPrepareProfileDir() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { customPrefs, firefoxApp, adbRemoveOldArtifacts },\n } = this;\n // Create the preferences file and the Fennec temporary profile.\n log.debug(`Preparing a temporary profile for ${selectedFirefoxApk}...`);\n\n const profile = await firefoxApp.createProfile({\n app: 'fennec',\n customPrefs,\n });\n\n // Check if there are any artifacts dirs from previous runs and\n // automatically remove them if adbRemoteOldArtifacts is true.\n const foundOldArtifacts = await adbUtils.detectOrRemoveOldArtifacts(\n selectedAdbDevice,\n adbRemoveOldArtifacts\n );\n\n if (foundOldArtifacts) {\n if (adbRemoveOldArtifacts) {\n log.info(\n 'Old web-ext artifacts have been found and removed ' +\n `from ${selectedAdbDevice} device`\n );\n } else {\n log.warn(\n `Old artifacts directories have been found on ${selectedAdbDevice} ` +\n 'device. Use --adb-remove-old-artifacts to remove them automatically.'\n );\n }\n }\n\n // Choose a artifacts dir name for the assets pushed to the\n // Android device.\n this.selectedArtifactsDir = await adbUtils.getOrCreateArtifactsDir(\n selectedAdbDevice\n );\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n await adbUtils.runShellCommand(selectedAdbDevice, [\n 'mkdir',\n '-p',\n deviceProfileDir,\n ]);\n await adbUtils.pushFile(\n selectedAdbDevice,\n path.join(profile.profileDir, 'user.js'),\n `${deviceProfileDir}/user.js`\n );\n\n log.debug(`Created temporary profile at ${deviceProfileDir}.`);\n }\n\n async adbStartSelectedPackage() {\n const {\n adbUtils,\n selectedFirefoxApk,\n selectedAdbDevice,\n params: { firefoxApkComponent },\n } = this;\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n log.info(`Starting ${selectedFirefoxApk}...`);\n\n log.debug(`Using profile ${deviceProfileDir} (ignored by Fenix)`);\n\n await adbUtils.startFirefoxAPK(\n selectedAdbDevice,\n selectedFirefoxApk,\n firefoxApkComponent,\n deviceProfileDir\n );\n }\n\n async buildAndPushExtension(sourceDir: string) {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedArtifactsDir,\n params: { buildSourceDir },\n } = this;\n\n await withTempDir(async (tmpDir) => {\n const { extensionPath } = await buildSourceDir(sourceDir, tmpDir.path());\n\n const extFileName = path.basename(extensionPath, '.zip');\n\n let adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n adbExtensionPath = `${selectedArtifactsDir}/${extFileName}.xpi`;\n }\n\n log.debug(`Uploading ${extFileName} on the android device`);\n\n await adbUtils.pushFile(\n selectedAdbDevice,\n extensionPath,\n adbExtensionPath\n );\n\n log.debug(`Upload completed: ${adbExtensionPath}`);\n\n this.adbExtensionsPathBySourceDir.set(sourceDir, adbExtensionPath);\n });\n }\n\n async buildAndPushExtensions() {\n for (const { sourceDir } of this.params.extensions) {\n await this.buildAndPushExtension(sourceDir);\n }\n }\n\n async adbDiscoveryAndForwardRDPUnixSocket() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { adbDiscoveryTimeout },\n } = this;\n\n const stdin = this.params.stdin || process.stdin;\n\n const { unixSocketDiscoveryRetryInterval } = FirefoxAndroidExtensionRunner;\n\n let { unixSocketDiscoveryMaxTime } = FirefoxAndroidExtensionRunner;\n\n if (typeof adbDiscoveryTimeout === 'number') {\n unixSocketDiscoveryMaxTime = adbDiscoveryTimeout;\n }\n\n const handleCtrlC = (str, key) => {\n if (key.ctrl && key.name === 'c') {\n adbUtils.setUserAbortDiscovery(true);\n }\n };\n\n // TODO: use noInput property to decide if we should\n // disable direct keypress handling.\n if (isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n stdin.on('keypress', handleCtrlC);\n }\n\n try {\n // Got a debugger socket file to connect.\n this.selectedRDPSocketFile = await adbUtils.discoverRDPUnixSocket(\n selectedAdbDevice,\n selectedFirefoxApk,\n {\n maxDiscoveryTime: unixSocketDiscoveryMaxTime,\n retryInterval: unixSocketDiscoveryRetryInterval,\n }\n );\n } finally {\n if (isTTY(stdin)) {\n stdin.removeListener('keypress', handleCtrlC);\n }\n }\n\n log.debug(`RDP Socket File selected: ${this.selectedRDPSocketFile}`);\n\n const tcpPort = await findFreeTcpPort();\n\n // Log the choosen tcp port at info level (useful to the user to be able\n // to connect the Firefox DevTools to the Firefox for Android instance).\n log.info(`You can connect to this Android device on TCP port ${tcpPort}`);\n\n const forwardSocketSpec = this.selectedRDPSocketFile.startsWith('@')\n ? `localabstract:${this.selectedRDPSocketFile.substr(1)}`\n : `localfilesystem:${this.selectedRDPSocketFile}`;\n\n await adbUtils.setupForward(\n selectedAdbDevice,\n forwardSocketSpec,\n `tcp:${tcpPort}`\n );\n\n this.selectedTCPPort = tcpPort;\n }\n\n async rdpInstallExtensions() {\n const {\n selectedTCPPort,\n params: { extensions, firefoxClient },\n } = this;\n\n const remoteFirefox = (this.remoteFirefox = await firefoxClient({\n port: selectedTCPPort,\n }));\n\n // Exit and cleanup the extension runner if the connection to the\n // remote Firefox for Android instance has been closed.\n remoteFirefox.client.on('end', () => {\n if (!this.exiting) {\n log.info('Exiting the device because Firefox for Android disconnected');\n this.exit();\n }\n });\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n const { sourceDir } = extension;\n const adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n throw new WebExtError(\n `ADB extension path for \"${sourceDir}\" was unexpectedly empty`\n );\n }\n\n const addonId = await remoteFirefox\n .installTemporaryAddon(adbExtensionPath)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n });\n\n if (!addonId) {\n throw new WebExtError(\n 'Received an empty addonId from ' +\n `remoteFirefox.installTemporaryAddon(\"${adbExtensionPath}\")`\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","showDesktopNotification","defaultDesktopNotifications","MultiExtensionsReloadError","UsageError","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","constructor","params","cleanupCallbacks","Set","adbExtensionsPathBySourceDir","Map","reloadableExtensions","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbCheckRuntimePermissions","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","selectedAdbDevice","selectedArtifactsDir","exiting","debug","clearArtifactsDir","getDeviceProfileDir","Object","keys","forEach","ignoredParam","warn","adbDevice","devices","discoverDevices","length","devicesMsg","map","dev","join","info","foundDevices","filter","device","JSON","stringify","firefoxApk","packages","discoverInstalledFirefoxAPKs","pkgsListMsg","pkgs","pkg","selectedFirefoxApk","filteredPackages","line","pkgsList","amForceStopAPK","androidVersion","getAndroidVersionNumber","Number","isNaN","requiredPermissions","ensureRequiredAPKRuntimePermissions","customPrefs","firefoxApp","adbRemoveOldArtifacts","profile","createProfile","app","foundOldArtifacts","detectOrRemoveOldArtifacts","getOrCreateArtifactsDir","deviceProfileDir","runShellCommand","pushFile","profileDir","firefoxApkComponent","startFirefoxAPK","buildSourceDir","tmpDir","extensionPath","extFileName","basename","adbExtensionPath","adbDiscoveryTimeout","stdin","process","handleCtrlC","str","key","ctrl","name","setUserAbortDiscovery","emitKeypressEvents","on","selectedRDPSocketFile","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","selectedTCPPort","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Android instance.\n */\n\nimport path from 'path';\nimport readline from 'readline';\n\nimport { withTempDir } from '../util/temp-dir.js';\nimport DefaultADBUtils from '../util/adb.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport {\n connectWithMaxRetries as defaultFirefoxConnector,\n findFreeTcpPort,\n} from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type { FirefoxPreferences } from '../firefox/preferences';\nimport type { FirefoxRDPResponseAddon, RemoteFirefox } from '../firefox/remote';\nimport type { ExtensionBuildResult } from '../cmd/build';\n\nconst log = createLogger(import.meta.url);\n\nconst ignoredParams = {\n profilePath: '--profile-path',\n keepProfileChanges: '--keep-profile-changes',\n browserConsole: '--browser-console',\n preInstall: '--pre-install',\n startUrl: '--start-url',\n args: '--args',\n};\n\n// Default adbHost to 127.0.0.1 to prevent issues with nodejs 17\n// (because if not specified adbkit may default to ipv6 while\n// adb may still only be listening on the ipv4 address),\n// see https://github.com/mozilla/web-ext/issues/2337.\nconst DEFAULT_ADB_HOST = '127.0.0.1';\n\nconst getIgnoredParamsWarningsMessage = (optionName) => {\n return `The Firefox for Android target does not support ${optionName}`;\n};\n\nexport type FirefoxAndroidExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n\n // Firefox specific.\n customPrefs?: FirefoxPreferences,\n\n // Not supported (currently ignored with logged warning).\n preInstall?: boolean,\n browserConsole?: boolean,\n\n // Firefox android injected dependencies.\n adbBin?: string,\n adbHost?: string,\n adbPort?: string,\n adbDevice?: string,\n adbDiscoveryTimeout?: number,\n adbRemoveOldArtifacts?: boolean,\n firefoxApk?: string,\n firefoxApkComponent?: string,\n\n // Injected Dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n ADBUtils?: typeof DefaultADBUtils,\n buildSourceDir: (string, string) => Promise<ExtensionBuildResult>,\n desktopNotifications: typeof defaultDesktopNotifications,\n stdin?: stream$Readable,\n|};\n\n/**\n * Implements an IExtensionRunner which manages a Firefox for Android instance.\n */\nexport class FirefoxAndroidExtensionRunner {\n // Wait 3s before the next unix socket discovery loop.\n static unixSocketDiscoveryRetryInterval: number = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime: number = 3 * 60 * 1000;\n\n params: FirefoxAndroidExtensionRunnerParams;\n adbUtils: DefaultADBUtils;\n exiting: boolean;\n selectedAdbDevice: string;\n selectedFirefoxApk: string;\n selectedArtifactsDir: string;\n selectedRDPSocketFile: string;\n selectedTCPPort: number;\n cleanupCallbacks: Set<Function>;\n adbExtensionsPathBySourceDir: Map<string, string>;\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n\n constructor(params: FirefoxAndroidExtensionRunnerParams) {\n this.params = params;\n this.cleanupCallbacks = new Set();\n this.adbExtensionsPathBySourceDir = new Map();\n this.reloadableExtensions = new Map();\n\n // Print warning for not currently supported options (e.g. preInstall,\n // cloned profiles, browser console).\n this.printIgnoredParamsWarnings();\n }\n\n async run(): Promise<void> {\n const {\n adbBin,\n adbHost = DEFAULT_ADB_HOST,\n adbPort,\n ADBUtils = DefaultADBUtils,\n } = this.params;\n\n this.adbUtils = new ADBUtils({\n adbBin,\n adbHost,\n adbPort,\n });\n\n await this.adbDevicesDiscoveryAndSelect();\n await this.apkPackagesDiscoveryAndSelect();\n await this.adbCheckRuntimePermissions();\n await this.adbForceStopSelectedPackage();\n\n // Create profile prefs (with enabled remote RDP server), prepare the\n // artifacts and temporary directory on the selected device, and\n // push the profile preferences to the remote profile dir.\n await this.adbPrepareProfileDir();\n\n // NOTE: running Firefox for Android on the Android Emulator can be\n // pretty slow, we can run the following 3 steps in parallel to speed up\n // it a bit.\n await Promise.all([\n // Start Firefox for Android instance if not started yet.\n // (Fennec would run in an temporary profile and so it is explicitly\n // stopped, Fenix runs on its usual profile and so it may be already\n // running).\n this.adbStartSelectedPackage(),\n\n // Build and push to devices all the extension xpis\n // and keep track of the xpi built and uploaded by extension sourceDir.\n this.buildAndPushExtensions(),\n\n // Wait for RDP unix socket file created and\n // Create an ADB forward connection on a free tcp port\n this.adbDiscoveryAndForwardRDPUnixSocket(),\n ]);\n\n // Connect to RDP socket on the local tcp server, install all the pushed extension\n // and keep track of the built and installed extension by extension sourceDir.\n await this.rdpInstallExtensions();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Android';\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n\n for (const { sourceDir } of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [\n {\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n },\n ];\n }\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n },\n ];\n }\n\n try {\n await this.buildAndPushExtension(extensionSourceDir);\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n },\n ];\n }\n\n return [{ runnerName, sourceDir: extensionSourceDir }];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n const { adbUtils, selectedAdbDevice, selectedArtifactsDir } = this;\n\n this.exiting = true;\n\n // If a Firefox for Android instance has been started,\n // we should ensure that it has been stopped when we exit.\n await this.adbForceStopSelectedPackage();\n\n if (selectedArtifactsDir) {\n log.debug('Cleaning up artifacts directory on the Android device...');\n await adbUtils.clearArtifactsDir(selectedAdbDevice);\n }\n\n // Call all the registered cleanup callbacks.\n for (const fn of this.cleanupCallbacks) {\n try {\n fn();\n } catch (error) {\n log.error(error);\n }\n }\n }\n\n // Private helper methods.\n\n getDeviceProfileDir(): string {\n return `${this.selectedArtifactsDir}/profile`;\n }\n\n printIgnoredParamsWarnings() {\n Object.keys(ignoredParams).forEach((ignoredParam) => {\n if (this.params[ignoredParam]) {\n log.warn(getIgnoredParamsWarningsMessage(ignoredParams[ignoredParam]));\n }\n });\n }\n\n async adbDevicesDiscoveryAndSelect() {\n const { adbUtils } = this;\n const { adbDevice } = this.params;\n let devices = [];\n\n log.debug('Listing android devices');\n devices = await adbUtils.discoverDevices();\n\n if (devices.length === 0) {\n throw new UsageError(\n 'No Android device found through ADB. ' +\n 'Make sure the device is connected and USB debugging is enabled.'\n );\n }\n\n if (!adbDevice) {\n const devicesMsg = devices.map((dev) => ` - ${dev}`).join('\\n');\n log.info(`\\nAndroid devices found:\\n${devicesMsg}`);\n throw new UsageError(\n 'Select an android device using --android-device=<name>'\n );\n }\n\n const foundDevices = devices.filter((device) => {\n return device === adbDevice;\n });\n\n if (foundDevices.length === 0) {\n const devicesMsg = JSON.stringify(devices);\n throw new UsageError(\n `Android device ${adbDevice} was not found in list: ${devicesMsg}`\n );\n }\n\n this.selectedAdbDevice = foundDevices[0];\n log.info(`Selected ADB device: ${this.selectedAdbDevice}`);\n }\n\n async apkPackagesDiscoveryAndSelect() {\n const {\n adbUtils,\n selectedAdbDevice,\n params: { firefoxApk },\n } = this;\n // Discovery and select a Firefox for Android version.\n const packages = await adbUtils.discoverInstalledFirefoxAPKs(\n selectedAdbDevice,\n firefoxApk\n );\n\n if (packages.length === 0) {\n throw new UsageError(\n 'No Firefox packages were found on the selected Android device'\n );\n }\n\n const pkgsListMsg = (pkgs) => {\n return pkgs.map((pkg) => ` - ${pkg}`).join('\\n');\n };\n\n if (!firefoxApk) {\n log.info(`\\nPackages found:\\n${pkgsListMsg(packages)}`);\n\n if (packages.length > 1) {\n throw new UsageError('Select one of the packages using --firefox-apk');\n }\n\n // If only one APK has been found, select it even if it has not been\n // specified explicitly on the comment line.\n this.selectedFirefoxApk = packages[0];\n log.info(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n return;\n }\n\n const filteredPackages = packages.filter((line) => line === firefoxApk);\n\n if (filteredPackages.length === 0) {\n const pkgsList = pkgsListMsg(filteredPackages);\n throw new UsageError(\n `Package ${firefoxApk} was not found in list: ${pkgsList}`\n );\n }\n\n this.selectedFirefoxApk = filteredPackages[0];\n log.debug(`Selected Firefox for Android APK: ${this.selectedFirefoxApk}`);\n }\n\n async adbForceStopSelectedPackage() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.info(`Stopping existing instances of ${selectedFirefoxApk}...`);\n await adbUtils.amForceStopAPK(selectedAdbDevice, selectedFirefoxApk);\n }\n\n async adbCheckRuntimePermissions() {\n const { adbUtils, selectedAdbDevice, selectedFirefoxApk } = this;\n\n log.debug(`Discovering Android version for ${selectedAdbDevice}...`);\n\n const androidVersion = await adbUtils.getAndroidVersionNumber(\n selectedAdbDevice\n );\n\n if (typeof androidVersion !== 'number' || Number.isNaN(androidVersion)) {\n throw new WebExtError(`Invalid Android version: ${androidVersion}`);\n }\n\n log.debug(`Detected Android version ${androidVersion}`);\n\n if (androidVersion < 23) {\n return;\n }\n\n log.debug(\n 'Checking read/write permissions needed for web-ext' +\n `on ${selectedFirefoxApk}...`\n );\n\n // Runtime permissions needed to Firefox to be able to access the\n // xpi file uploaded to the android device or emulator.\n const requiredPermissions = ['android.permission.READ_EXTERNAL_STORAGE'];\n\n await adbUtils.ensureRequiredAPKRuntimePermissions(\n selectedAdbDevice,\n selectedFirefoxApk,\n requiredPermissions\n );\n }\n\n async adbPrepareProfileDir() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { customPrefs, firefoxApp, adbRemoveOldArtifacts },\n } = this;\n // Create the preferences file and the Fennec temporary profile.\n log.debug(`Preparing a temporary profile for ${selectedFirefoxApk}...`);\n\n const profile = await firefoxApp.createProfile({\n app: 'fennec',\n customPrefs,\n });\n\n // Check if there are any artifacts dirs from previous runs and\n // automatically remove them if adbRemoteOldArtifacts is true.\n const foundOldArtifacts = await adbUtils.detectOrRemoveOldArtifacts(\n selectedAdbDevice,\n adbRemoveOldArtifacts\n );\n\n if (foundOldArtifacts) {\n if (adbRemoveOldArtifacts) {\n log.info(\n 'Old web-ext artifacts have been found and removed ' +\n `from ${selectedAdbDevice} device`\n );\n } else {\n log.warn(\n `Old artifacts directories have been found on ${selectedAdbDevice} ` +\n 'device. Use --adb-remove-old-artifacts to remove them automatically.'\n );\n }\n }\n\n // Choose a artifacts dir name for the assets pushed to the\n // Android device.\n this.selectedArtifactsDir = await adbUtils.getOrCreateArtifactsDir(\n selectedAdbDevice\n );\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n await adbUtils.runShellCommand(selectedAdbDevice, [\n 'mkdir',\n '-p',\n deviceProfileDir,\n ]);\n await adbUtils.pushFile(\n selectedAdbDevice,\n path.join(profile.profileDir, 'user.js'),\n `${deviceProfileDir}/user.js`\n );\n\n log.debug(`Created temporary profile at ${deviceProfileDir}.`);\n }\n\n async adbStartSelectedPackage() {\n const {\n adbUtils,\n selectedFirefoxApk,\n selectedAdbDevice,\n params: { firefoxApkComponent },\n } = this;\n\n const deviceProfileDir = this.getDeviceProfileDir();\n\n log.info(`Starting ${selectedFirefoxApk}...`);\n\n log.debug(`Using profile ${deviceProfileDir} (ignored by Fenix)`);\n\n await adbUtils.startFirefoxAPK(\n selectedAdbDevice,\n selectedFirefoxApk,\n firefoxApkComponent,\n deviceProfileDir\n );\n }\n\n async buildAndPushExtension(sourceDir: string) {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedArtifactsDir,\n params: { buildSourceDir },\n } = this;\n\n await withTempDir(async (tmpDir) => {\n const { extensionPath } = await buildSourceDir(sourceDir, tmpDir.path());\n\n const extFileName = path.basename(extensionPath, '.zip');\n\n let adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n adbExtensionPath = `${selectedArtifactsDir}/${extFileName}.xpi`;\n }\n\n log.debug(`Uploading ${extFileName} on the android device`);\n\n await adbUtils.pushFile(\n selectedAdbDevice,\n extensionPath,\n adbExtensionPath\n );\n\n log.debug(`Upload completed: ${adbExtensionPath}`);\n\n this.adbExtensionsPathBySourceDir.set(sourceDir, adbExtensionPath);\n });\n }\n\n async buildAndPushExtensions() {\n for (const { sourceDir } of this.params.extensions) {\n await this.buildAndPushExtension(sourceDir);\n }\n }\n\n async adbDiscoveryAndForwardRDPUnixSocket() {\n const {\n adbUtils,\n selectedAdbDevice,\n selectedFirefoxApk,\n params: { adbDiscoveryTimeout },\n } = this;\n\n const stdin = this.params.stdin || process.stdin;\n\n const { unixSocketDiscoveryRetryInterval } = FirefoxAndroidExtensionRunner;\n\n let { unixSocketDiscoveryMaxTime } = FirefoxAndroidExtensionRunner;\n\n if (typeof adbDiscoveryTimeout === 'number') {\n unixSocketDiscoveryMaxTime = adbDiscoveryTimeout;\n }\n\n const handleCtrlC = (str, key) => {\n if (key.ctrl && key.name === 'c') {\n adbUtils.setUserAbortDiscovery(true);\n }\n };\n\n // TODO: use noInput property to decide if we should\n // disable direct keypress handling.\n if (isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n stdin.on('keypress', handleCtrlC);\n }\n\n try {\n // Got a debugger socket file to connect.\n this.selectedRDPSocketFile = await adbUtils.discoverRDPUnixSocket(\n selectedAdbDevice,\n selectedFirefoxApk,\n {\n maxDiscoveryTime: unixSocketDiscoveryMaxTime,\n retryInterval: unixSocketDiscoveryRetryInterval,\n }\n );\n } finally {\n if (isTTY(stdin)) {\n stdin.removeListener('keypress', handleCtrlC);\n }\n }\n\n log.debug(`RDP Socket File selected: ${this.selectedRDPSocketFile}`);\n\n const tcpPort = await findFreeTcpPort();\n\n // Log the choosen tcp port at info level (useful to the user to be able\n // to connect the Firefox DevTools to the Firefox for Android instance).\n log.info(`You can connect to this Android device on TCP port ${tcpPort}`);\n\n const forwardSocketSpec = this.selectedRDPSocketFile.startsWith('@')\n ? `localabstract:${this.selectedRDPSocketFile.substr(1)}`\n : `localfilesystem:${this.selectedRDPSocketFile}`;\n\n await adbUtils.setupForward(\n selectedAdbDevice,\n forwardSocketSpec,\n `tcp:${tcpPort}`\n );\n\n this.selectedTCPPort = tcpPort;\n }\n\n async rdpInstallExtensions() {\n const {\n selectedTCPPort,\n params: { extensions, firefoxClient },\n } = this;\n\n const remoteFirefox = (this.remoteFirefox = await firefoxClient({\n port: selectedTCPPort,\n }));\n\n // Exit and cleanup the extension runner if the connection to the\n // remote Firefox for Android instance has been closed.\n remoteFirefox.client.on('end', () => {\n if (!this.exiting) {\n log.info('Exiting the device because Firefox for Android disconnected');\n this.exit();\n }\n });\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n const { sourceDir } = extension;\n const adbExtensionPath = this.adbExtensionsPathBySourceDir.get(sourceDir);\n\n if (!adbExtensionPath) {\n throw new WebExtError(\n `ADB extension path for \"${sourceDir}\" was unexpectedly empty`\n );\n }\n\n const addonId = await remoteFirefox\n .installTemporaryAddon(adbExtensionPath)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n });\n\n if (!addonId) {\n throw new WebExtError(\n 'Received an empty addonId from ' +\n `remoteFirefox.installTemporaryAddon(\"${adbExtensionPath}\")`\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* This module provide an ExtensionRunner subclass that manage an extension executed
|
|
5
3
|
* in a Firefox for Desktop instance.
|
|
6
4
|
*/
|
|
7
|
-
|
|
8
5
|
// Import flow types from npm dependencies.
|
|
9
|
-
|
|
10
6
|
import { MultiExtensionsReloadError, RemoteTempInstallNotSupported, WebExtError } from '../errors.js';
|
|
11
7
|
import * as defaultFirefoxApp from '../firefox/index.js';
|
|
12
8
|
import { connectWithMaxRetries as defaultFirefoxConnector } from '../firefox/remote.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firefox-desktop.js","names":["MultiExtensionsReloadError","RemoteTempInstallNotSupported","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","createLogger","log","import","meta","url","FirefoxDesktopExtensionRunner","constructor","params","reloadableExtensions","Map","cleanupCallbacks","Set","getName","run","setupProfileDir","startFirefoxInstance","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","runningInfo","firefox","kill","customPrefs","keepProfileChanges","preInstall","profilePath","firefoxApp","debug","profile","useProfile","copyProfile","createProfile","extension","installExtension","asProxy","extensionPath","manifestData","browserConsole","devtools","firefoxBinary","startUrl","firefoxClient","args","binaryArgs","push","urls","Array","isArray","on","cleanupCb","port","debuggerPort","installTemporaryAddon","then","installResult","addon","id","String"],"sources":["../../src/extension-runners/firefox-desktop.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Desktop instance.\n */\n\n// Import flow types from npm dependencies.\nimport type FirefoxProfile from 'firefox-profile';\n\nimport {\n MultiExtensionsReloadError,\n RemoteTempInstallNotSupported,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport { connectWithMaxRetries as defaultFirefoxConnector } from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\n// Import flow types from project files.\nimport type { FirefoxRDPResponseAddon, RemoteFirefox } from '../firefox/remote';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type { FirefoxPreferences } from '../firefox/preferences';\nimport type { FirefoxInfo } from '../firefox/index'; // eslint-disable-line import/named\n\ntype FirefoxDesktopSpecificRunnerParams = {|\n customPrefs?: FirefoxPreferences,\n browserConsole: boolean,\n devtools: boolean,\n firefoxBinary: string,\n preInstall: boolean,\n\n // Firefox desktop injected dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n|};\n\nexport type FirefoxDesktopExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n // Firefox desktop CLI params.\n ...FirefoxDesktopSpecificRunnerParams,\n|};\n\nconst log = createLogger(import.meta.url);\n\n/**\n * Implements an IExtensionRunner which manages a Firefox Desktop instance.\n */\nexport class FirefoxDesktopExtensionRunner {\n cleanupCallbacks: Set<Function>;\n params: FirefoxDesktopExtensionRunnerParams;\n profile: FirefoxProfile;\n // Map extensions sourceDir to their related addon ids.\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n runningInfo: FirefoxInfo;\n\n constructor(params: FirefoxDesktopExtensionRunnerParams) {\n this.params = params;\n\n this.reloadableExtensions = new Map();\n this.cleanupCallbacks = new Set();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Desktop';\n }\n\n /**\n * Setup the Firefox Profile and run a Firefox Desktop instance.\n */\n async run(): Promise<void> {\n // Get a firefox profile with the custom Prefs set (a new or a cloned one).\n // Pre-install extensions as proxy if needed (and disable auto-reload if you do)\n await this.setupProfileDir();\n\n // (if reload is enabled):\n // - Connect to the firefox instance on RDP\n // - Install any extension if needed (if not installed as proxy)\n // - Keep track of the extension id assigned in a map with the sourceDir as a key\n await this.startFirefoxInstance();\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n for (const { sourceDir } of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [\n {\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n },\n ];\n }\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n },\n ];\n }\n\n try {\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n },\n ];\n }\n\n return [{ runnerName, sourceDir: extensionSourceDir }];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n if (!this.runningInfo || !this.runningInfo.firefox) {\n throw new WebExtError('No firefox instance is currently running');\n }\n\n this.runningInfo.firefox.kill();\n }\n\n // Private helper methods.\n\n async setupProfileDir() {\n const {\n customPrefs,\n extensions,\n keepProfileChanges,\n preInstall,\n profilePath,\n firefoxApp,\n } = this.params;\n\n if (profilePath) {\n if (keepProfileChanges) {\n log.debug(`Using Firefox profile from ${profilePath}`);\n this.profile = await firefoxApp.useProfile(profilePath, {\n customPrefs,\n });\n } else {\n log.debug(`Copying Firefox profile from ${profilePath}`);\n this.profile = await firefoxApp.copyProfile(profilePath, {\n customPrefs,\n });\n }\n } else {\n log.debug('Creating new Firefox profile');\n this.profile = await firefoxApp.createProfile({ customPrefs });\n }\n\n // preInstall the extensions if needed.\n if (preInstall) {\n for (const extension of extensions) {\n await firefoxApp.installExtension({\n asProxy: true,\n extensionPath: extension.sourceDir,\n manifestData: extension.manifestData,\n profile: this.profile,\n });\n }\n }\n }\n\n async startFirefoxInstance() {\n const {\n browserConsole,\n devtools,\n extensions,\n firefoxBinary,\n preInstall,\n startUrl,\n firefoxApp,\n firefoxClient,\n args,\n } = this.params;\n\n const binaryArgs = [];\n\n if (browserConsole) {\n binaryArgs.push('-jsconsole');\n }\n if (startUrl) {\n const urls = Array.isArray(startUrl) ? startUrl : [startUrl];\n for (const url of urls) {\n binaryArgs.push('--url', url);\n }\n }\n\n if (args) {\n binaryArgs.push(...args);\n }\n\n this.runningInfo = await firefoxApp.run(this.profile, {\n firefoxBinary,\n binaryArgs,\n extensions,\n devtools,\n });\n\n this.runningInfo.firefox.on('close', () => {\n for (const cleanupCb of this.cleanupCallbacks) {\n try {\n cleanupCb();\n } catch (error) {\n log.error(`Exception on executing cleanup callback: ${error}`);\n }\n }\n });\n\n if (!preInstall) {\n const remoteFirefox = (this.remoteFirefox = await firefoxClient({\n port: this.runningInfo.debuggerPort,\n }));\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n try {\n const addonId = await remoteFirefox\n .installTemporaryAddon(extension.sourceDir, devtools)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n });\n\n if (!addonId) {\n throw new WebExtError(\n 'Unexpected missing addonId in the installAsTemporaryAddon result'\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n } catch (error) {\n if (error instanceof RemoteTempInstallNotSupported) {\n log.debug(`Caught: ${String(error)}`);\n throw new WebExtError(\n 'Temporary add-on installation is not supported in this version' +\n ' of Firefox (you need Firefox 49 or higher). For older Firefox' +\n ' versions, use --pre-install'\n );\n } else {\n throw error;\n }\n }\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"firefox-desktop.js","names":["MultiExtensionsReloadError","RemoteTempInstallNotSupported","WebExtError","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxConnector","createLogger","log","import","meta","url","FirefoxDesktopExtensionRunner","constructor","params","reloadableExtensions","Map","cleanupCallbacks","Set","getName","run","setupProfileDir","startFirefoxInstance","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","remoteFirefox","reloadAddon","error","registerCleanup","fn","add","exit","runningInfo","firefox","kill","customPrefs","keepProfileChanges","preInstall","profilePath","firefoxApp","debug","profile","useProfile","copyProfile","createProfile","extension","installExtension","asProxy","extensionPath","manifestData","browserConsole","devtools","firefoxBinary","startUrl","firefoxClient","args","binaryArgs","push","urls","Array","isArray","on","cleanupCb","port","debuggerPort","installTemporaryAddon","then","installResult","addon","id","String"],"sources":["../../src/extension-runners/firefox-desktop.js"],"sourcesContent":["/* @flow */\n\n/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Firefox for Desktop instance.\n */\n\n// Import flow types from npm dependencies.\nimport type FirefoxProfile from 'firefox-profile';\n\nimport {\n MultiExtensionsReloadError,\n RemoteTempInstallNotSupported,\n WebExtError,\n} from '../errors.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport { connectWithMaxRetries as defaultFirefoxConnector } from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\n// Import flow types from project files.\nimport type { FirefoxRDPResponseAddon, RemoteFirefox } from '../firefox/remote';\nimport type {\n ExtensionRunnerParams,\n ExtensionRunnerReloadResult,\n} from './base';\nimport type { FirefoxPreferences } from '../firefox/preferences';\nimport type { FirefoxInfo } from '../firefox/index'; // eslint-disable-line import/named\n\ntype FirefoxDesktopSpecificRunnerParams = {|\n customPrefs?: FirefoxPreferences,\n browserConsole: boolean,\n devtools: boolean,\n firefoxBinary: string,\n preInstall: boolean,\n\n // Firefox desktop injected dependencies.\n firefoxApp: typeof defaultFirefoxApp,\n firefoxClient: typeof defaultFirefoxConnector,\n|};\n\nexport type FirefoxDesktopExtensionRunnerParams = {|\n ...ExtensionRunnerParams,\n // Firefox desktop CLI params.\n ...FirefoxDesktopSpecificRunnerParams,\n|};\n\nconst log = createLogger(import.meta.url);\n\n/**\n * Implements an IExtensionRunner which manages a Firefox Desktop instance.\n */\nexport class FirefoxDesktopExtensionRunner {\n cleanupCallbacks: Set<Function>;\n params: FirefoxDesktopExtensionRunnerParams;\n profile: FirefoxProfile;\n // Map extensions sourceDir to their related addon ids.\n reloadableExtensions: Map<string, string>;\n remoteFirefox: RemoteFirefox;\n runningInfo: FirefoxInfo;\n\n constructor(params: FirefoxDesktopExtensionRunnerParams) {\n this.params = params;\n\n this.reloadableExtensions = new Map();\n this.cleanupCallbacks = new Set();\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Firefox Desktop';\n }\n\n /**\n * Setup the Firefox Profile and run a Firefox Desktop instance.\n */\n async run(): Promise<void> {\n // Get a firefox profile with the custom Prefs set (a new or a cloned one).\n // Pre-install extensions as proxy if needed (and disable auto-reload if you do)\n await this.setupProfileDir();\n\n // (if reload is enabled):\n // - Connect to the firefox instance on RDP\n // - Install any extension if needed (if not installed as proxy)\n // - Keep track of the extension id assigned in a map with the sourceDir as a key\n await this.startFirefoxInstance();\n }\n\n /**\n * Reloads all the extensions, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const reloadErrors = new Map();\n for (const { sourceDir } of this.params.extensions) {\n const [res] = await this.reloadExtensionBySourceDir(sourceDir);\n if (res.reloadError instanceof Error) {\n reloadErrors.set(sourceDir, res.reloadError);\n }\n }\n\n if (reloadErrors.size > 0) {\n return [\n {\n runnerName,\n reloadError: new MultiExtensionsReloadError(reloadErrors),\n },\n ];\n }\n\n return [{ runnerName }];\n }\n\n /**\n * Reloads a single extension, collect any reload error and resolves to\n * an array composed by a single ExtensionRunnerReloadResult object.\n */\n async reloadExtensionBySourceDir(\n extensionSourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n const runnerName = this.getName();\n const addonId = this.reloadableExtensions.get(extensionSourceDir);\n\n if (!addonId) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: new WebExtError(\n 'Extension not reloadable: ' +\n `no addonId has been mapped to \"${extensionSourceDir}\"`\n ),\n runnerName,\n },\n ];\n }\n\n try {\n await this.remoteFirefox.reloadAddon(addonId);\n } catch (error) {\n return [\n {\n sourceDir: extensionSourceDir,\n reloadError: error,\n runnerName,\n },\n ];\n }\n\n return [{ runnerName, sourceDir: extensionSourceDir }];\n }\n\n /**\n * Register a callback to be called when the runner has been exited\n * (e.g. the Firefox instance exits or the user has requested web-ext\n * to exit).\n */\n registerCleanup(fn: Function): void {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit(): Promise<void> {\n if (!this.runningInfo || !this.runningInfo.firefox) {\n throw new WebExtError('No firefox instance is currently running');\n }\n\n this.runningInfo.firefox.kill();\n }\n\n // Private helper methods.\n\n async setupProfileDir() {\n const {\n customPrefs,\n extensions,\n keepProfileChanges,\n preInstall,\n profilePath,\n firefoxApp,\n } = this.params;\n\n if (profilePath) {\n if (keepProfileChanges) {\n log.debug(`Using Firefox profile from ${profilePath}`);\n this.profile = await firefoxApp.useProfile(profilePath, {\n customPrefs,\n });\n } else {\n log.debug(`Copying Firefox profile from ${profilePath}`);\n this.profile = await firefoxApp.copyProfile(profilePath, {\n customPrefs,\n });\n }\n } else {\n log.debug('Creating new Firefox profile');\n this.profile = await firefoxApp.createProfile({ customPrefs });\n }\n\n // preInstall the extensions if needed.\n if (preInstall) {\n for (const extension of extensions) {\n await firefoxApp.installExtension({\n asProxy: true,\n extensionPath: extension.sourceDir,\n manifestData: extension.manifestData,\n profile: this.profile,\n });\n }\n }\n }\n\n async startFirefoxInstance() {\n const {\n browserConsole,\n devtools,\n extensions,\n firefoxBinary,\n preInstall,\n startUrl,\n firefoxApp,\n firefoxClient,\n args,\n } = this.params;\n\n const binaryArgs = [];\n\n if (browserConsole) {\n binaryArgs.push('-jsconsole');\n }\n if (startUrl) {\n const urls = Array.isArray(startUrl) ? startUrl : [startUrl];\n for (const url of urls) {\n binaryArgs.push('--url', url);\n }\n }\n\n if (args) {\n binaryArgs.push(...args);\n }\n\n this.runningInfo = await firefoxApp.run(this.profile, {\n firefoxBinary,\n binaryArgs,\n extensions,\n devtools,\n });\n\n this.runningInfo.firefox.on('close', () => {\n for (const cleanupCb of this.cleanupCallbacks) {\n try {\n cleanupCb();\n } catch (error) {\n log.error(`Exception on executing cleanup callback: ${error}`);\n }\n }\n });\n\n if (!preInstall) {\n const remoteFirefox = (this.remoteFirefox = await firefoxClient({\n port: this.runningInfo.debuggerPort,\n }));\n\n // Install all the temporary addons.\n for (const extension of extensions) {\n try {\n const addonId = await remoteFirefox\n .installTemporaryAddon(extension.sourceDir, devtools)\n .then((installResult: FirefoxRDPResponseAddon) => {\n return installResult.addon.id;\n });\n\n if (!addonId) {\n throw new WebExtError(\n 'Unexpected missing addonId in the installAsTemporaryAddon result'\n );\n }\n\n this.reloadableExtensions.set(extension.sourceDir, addonId);\n } catch (error) {\n if (error instanceof RemoteTempInstallNotSupported) {\n log.debug(`Caught: ${String(error)}`);\n throw new WebExtError(\n 'Temporary add-on installation is not supported in this version' +\n ' of Firefox (you need Firefox 49 or higher). For older Firefox' +\n ' versions, use --pre-install'\n );\n } else {\n throw error;\n }\n }\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["readline","WebExtError","showDesktopNotification","defaultDesktopNotifications","createLogger","createFileFilter","defaultFileFilterCreator","isTTY","setRawMode","defaultSourceWatcher","log","import","meta","url","createExtensionRunner","config","target","FirefoxDesktopExtensionRunner","params","FirefoxAndroidExtensionRunner","ChromiumExtensionRunner","MultiExtensionRunner","constructor","extensionRunners","runners","desktopNotifications","getName","run","promises","runner","push","Promise","all","reloadAllExtensions","debug","reloadPromise","then","runnerName","error","reloadError","results","handleReloadResults","reloadExtensionBySourceDir","sourceDir","registerCleanup","cleanupCallback","resolve","exit","Error","message","stack","title","defaultWatcherCreator","reloadExtension","watchFile","watchIgnored","artifactsDir","ignoreFiles","onSourceChange","fileFilter","onChange","shouldWatchFile","file","wantFile","defaultReloadStrategy","extensionRunner","noInput","createWatcher","stdin","process","kill","allowInput","watcher","watchedSourceDir","close","pause","emitKeypressEvents","keypressUsageInfo","info","userExit","keyPressed","once","str","key","ctrl","name","pid","catch","err","warn"],"sources":["../../src/extension-runners/index.js"],"sourcesContent":["/* @flow */\n\nimport readline from 'readline';\n\nimport type Watchpack from 'watchpack';\n\nimport type {\n IExtensionRunner, // eslint-disable-line import/named\n ExtensionRunnerReloadResult,\n} from './base';\nimport { WebExtError } from '../errors.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport type { FirefoxAndroidExtensionRunnerParams } from './firefox-android.js';\nimport type { FirefoxDesktopExtensionRunnerParams } from './firefox-desktop.js';\nimport type { ChromiumExtensionRunnerParams } from './chromium.js';\nimport { createLogger } from '../util/logger.js';\nimport type { FileFilterCreatorFn } from '../util/file-filter.js';\nimport { createFileFilter as defaultFileFilterCreator } from '../util/file-filter.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\nimport defaultSourceWatcher from '../watcher.js';\nimport type { OnSourceChangeFn } from '../watcher';\n\nconst log = createLogger(import.meta.url);\n\nexport type ExtensionRunnerConfig =\n | {|\n target: 'firefox-desktop',\n params: FirefoxDesktopExtensionRunnerParams,\n |}\n | {|\n target: 'firefox-android',\n params: FirefoxAndroidExtensionRunnerParams,\n |}\n | {|\n target: 'chromium',\n params: ChromiumExtensionRunnerParams,\n |};\n\nexport type MultiExtensionRunnerParams = {|\n runners: Array<IExtensionRunner>,\n desktopNotifications: typeof defaultDesktopNotifications,\n|};\n\nexport async function createExtensionRunner(\n config: ExtensionRunnerConfig\n): Promise<IExtensionRunner> {\n switch (config.target) {\n case 'firefox-desktop': {\n const { FirefoxDesktopExtensionRunner } = await import(\n './firefox-desktop.js'\n );\n return new FirefoxDesktopExtensionRunner(config.params);\n }\n case 'firefox-android': {\n const { FirefoxAndroidExtensionRunner } = await import(\n './firefox-android.js'\n );\n return new FirefoxAndroidExtensionRunner(config.params);\n }\n case 'chromium': {\n const { ChromiumExtensionRunner } = await import('./chromium.js');\n return new ChromiumExtensionRunner(config.params);\n }\n default:\n throw new WebExtError(`Unknown target: \"${config.target}\"`);\n }\n}\n\n/**\n * Implements an IExtensionRunner which allow the caller to\n * manage multiple extension runners at the same time (e.g. by running\n * a Firefox Desktop instance alongside to a Firefox for Android instance).\n */\nexport class MultiExtensionRunner {\n extensionRunners: Array<IExtensionRunner>;\n desktopNotifications: typeof defaultDesktopNotifications;\n\n constructor(params: MultiExtensionRunnerParams) {\n this.extensionRunners = params.runners;\n this.desktopNotifications = params.desktopNotifications;\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Multi Extension Runner';\n }\n\n /**\n * Call the `run` method on all the managed extension runners,\n * and awaits that all the runners has been successfully started.\n */\n async run(): Promise<void> {\n const promises = [];\n for (const runner of this.extensionRunners) {\n promises.push(runner.run());\n }\n\n await Promise.all(promises);\n }\n\n /**\n * Reloads all the extensions on all the managed extension runners,\n * collect any reload error, and resolves to an array composed by\n * a ExtensionRunnerReloadResult object per managed runner.\n *\n * Any detected reload error is also logged on the terminal and shows as a\n * desktop notification.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n log.debug('Reloading all reloadable add-ons');\n\n const promises = [];\n for (const runner of this.extensionRunners) {\n const reloadPromise = runner.reloadAllExtensions().then(\n () => {\n return { runnerName: runner.getName() };\n },\n (error) => {\n return {\n runnerName: runner.getName(),\n reloadError: error,\n };\n }\n );\n\n promises.push(reloadPromise);\n }\n\n return await Promise.all(promises).then((results) => {\n this.handleReloadResults(results);\n return results;\n });\n }\n\n /**\n * Reloads a single extension on all the managed extension runners,\n * collect any reload error and resolves to an array composed by\n * a ExtensionRunnerReloadResult object per managed runner.\n *\n * Any detected reload error is also logged on the terminal and shows as a\n * desktop notification.\n */\n async reloadExtensionBySourceDir(\n sourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n log.debug(`Reloading add-on at ${sourceDir}`);\n\n const promises: Array<Promise<ExtensionRunnerReloadResult>> = [];\n for (const runner of this.extensionRunners) {\n const reloadPromise = runner.reloadExtensionBySourceDir(sourceDir).then(\n () => {\n return { runnerName: runner.getName(), sourceDir };\n },\n (error) => {\n return {\n runnerName: runner.getName(),\n reloadError: error,\n sourceDir,\n };\n }\n );\n\n promises.push(reloadPromise);\n }\n\n return await Promise.all(promises).then((results) => {\n this.handleReloadResults(results);\n return results;\n });\n }\n\n /**\n * Register a callback to be called when all the managed runners has been exited.\n */\n registerCleanup(cleanupCallback: Function): void {\n const promises = [];\n\n // Create a promise for every extension runner managed by this instance,\n // the promise will be resolved when the particular runner calls its\n // registered cleanup callbacks.\n for (const runner of this.extensionRunners) {\n promises.push(\n new Promise((resolve) => {\n runner.registerCleanup(resolve);\n })\n );\n }\n\n // Wait for all the created promises to be resolved or rejected\n // (once each one of the runners has cleaned up) and then call\n // the cleanup callback registered to this runner.\n Promise.all(promises).then(cleanupCallback, cleanupCallback);\n }\n\n /**\n * Exits all the managed runner has been exited.\n */\n async exit(): Promise<void> {\n const promises = [];\n for (const runner of this.extensionRunners) {\n promises.push(runner.exit());\n }\n\n await Promise.all(promises);\n }\n\n // Private helper methods.\n\n handleReloadResults(results: Array<ExtensionRunnerReloadResult>): void {\n for (const { runnerName, reloadError, sourceDir } of results) {\n if (reloadError instanceof Error) {\n let message = 'Error occurred while reloading';\n if (sourceDir) {\n message += ` \"${sourceDir}\" `;\n }\n\n message += `on \"${runnerName}\" - ${reloadError.message}`;\n\n log.error(`\\n${message}`);\n log.debug(reloadError.stack);\n\n this.desktopNotifications({\n title: 'web-ext run: extension reload error',\n message,\n });\n }\n }\n }\n}\n\n// defaultWatcherCreator types and implementation.\n\nexport type WatcherCreatorParams = {|\n reloadExtension: (string) => void,\n sourceDir: string,\n watchFile?: Array<string>,\n watchIgnored?: Array<string>,\n artifactsDir: string,\n onSourceChange?: OnSourceChangeFn,\n ignoreFiles?: Array<string>,\n createFileFilter?: FileFilterCreatorFn,\n|};\n\nexport type WatcherCreatorFn = (params: WatcherCreatorParams) => Watchpack;\n\nexport function defaultWatcherCreator({\n reloadExtension,\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n ignoreFiles,\n onSourceChange = defaultSourceWatcher,\n createFileFilter = defaultFileFilterCreator,\n}: WatcherCreatorParams): Watchpack {\n const fileFilter = createFileFilter({ sourceDir, artifactsDir, ignoreFiles });\n return onSourceChange({\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n onChange: () => reloadExtension(sourceDir),\n shouldWatchFile: (file) => fileFilter.wantFile(file),\n });\n}\n\n// defaultReloadStrategy types and implementation.\n\nexport type ReloadStrategyParams = {|\n extensionRunner: IExtensionRunner,\n sourceDir: string,\n watchFile?: Array<string>,\n watchIgnored?: Array<string>,\n artifactsDir: string,\n ignoreFiles?: Array<string>,\n noInput?: boolean,\n|};\n\nexport type ReloadStrategyOptions = {\n createWatcher?: WatcherCreatorFn,\n stdin?: stream$Readable,\n kill?: (pid: number, signal?: string | number) => void,\n};\n\nexport function defaultReloadStrategy(\n {\n artifactsDir,\n extensionRunner,\n ignoreFiles,\n noInput = false,\n sourceDir,\n watchFile,\n watchIgnored,\n }: ReloadStrategyParams,\n {\n createWatcher = defaultWatcherCreator,\n stdin = process.stdin,\n // $FlowIgnore: ignore method-unbinding.\n kill = process.kill,\n }: ReloadStrategyOptions = {}\n): void {\n const allowInput = !noInput;\n if (!allowInput) {\n log.debug('Input has been disabled because of noInput==true');\n }\n\n const watcher: Watchpack = createWatcher({\n reloadExtension: (watchedSourceDir) => {\n extensionRunner.reloadExtensionBySourceDir(watchedSourceDir);\n },\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n ignoreFiles,\n });\n\n extensionRunner.registerCleanup(() => {\n watcher.close();\n if (allowInput) {\n stdin.pause();\n }\n });\n\n if (allowInput && isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n const keypressUsageInfo = 'Press R to reload (and Ctrl-C to quit)';\n\n // NOTE: this `Promise.resolve().then(...)` is basically used to spawn a \"co-routine\"\n // that is executed before the callback attached to the Promise returned by this function\n // (and it allows the `run` function to not be stuck in the while loop).\n Promise.resolve().then(async function () {\n log.info(keypressUsageInfo);\n\n let userExit = false;\n\n while (!userExit) {\n const keyPressed = await new Promise((resolve) => {\n stdin.once('keypress', (str, key) => resolve(key));\n });\n\n if (keyPressed.ctrl && keyPressed.name === 'c') {\n userExit = true;\n } else if (keyPressed.name === 'z') {\n // Prepare to suspend.\n\n // NOTE: Switch the raw mode off before suspending (needed to make the keypress event\n // to work correctly when the nodejs process is resumed).\n setRawMode(stdin, false);\n\n log.info('\\nweb-ext has been suspended on user request');\n kill(process.pid, 'SIGTSTP');\n\n // Prepare to resume.\n\n log.info(`\\nweb-ext has been resumed. ${keypressUsageInfo}`);\n\n // Switch the raw mode on on resume.\n setRawMode(stdin, true);\n } else if (keyPressed.name === 'r') {\n log.debug('Reloading installed extensions on user request');\n await extensionRunner.reloadAllExtensions().catch((err) => {\n log.warn(`\\nError reloading extension: ${err}`);\n log.debug(`Reloading extension error stack: ${err.stack}`);\n });\n }\n }\n\n log.info('\\nExiting web-ext on user request');\n extensionRunner.exit();\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["readline","WebExtError","showDesktopNotification","defaultDesktopNotifications","createLogger","createFileFilter","defaultFileFilterCreator","isTTY","setRawMode","defaultSourceWatcher","log","import","meta","url","createExtensionRunner","config","target","FirefoxDesktopExtensionRunner","params","FirefoxAndroidExtensionRunner","ChromiumExtensionRunner","MultiExtensionRunner","constructor","extensionRunners","runners","desktopNotifications","getName","run","promises","runner","push","Promise","all","reloadAllExtensions","debug","reloadPromise","then","runnerName","error","reloadError","results","handleReloadResults","reloadExtensionBySourceDir","sourceDir","registerCleanup","cleanupCallback","resolve","exit","Error","message","stack","title","defaultWatcherCreator","reloadExtension","watchFile","watchIgnored","artifactsDir","ignoreFiles","onSourceChange","fileFilter","onChange","shouldWatchFile","file","wantFile","defaultReloadStrategy","extensionRunner","noInput","createWatcher","stdin","process","kill","allowInput","watcher","watchedSourceDir","close","pause","emitKeypressEvents","keypressUsageInfo","info","userExit","keyPressed","once","str","key","ctrl","name","pid","catch","err","warn"],"sources":["../../src/extension-runners/index.js"],"sourcesContent":["/* @flow */\n\nimport readline from 'readline';\n\nimport type Watchpack from 'watchpack';\n\nimport type {\n IExtensionRunner, // eslint-disable-line import/named\n ExtensionRunnerReloadResult,\n} from './base';\nimport { WebExtError } from '../errors.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport type { FirefoxAndroidExtensionRunnerParams } from './firefox-android.js';\nimport type { FirefoxDesktopExtensionRunnerParams } from './firefox-desktop.js';\nimport type { ChromiumExtensionRunnerParams } from './chromium.js';\nimport { createLogger } from '../util/logger.js';\nimport type { FileFilterCreatorFn } from '../util/file-filter.js';\nimport { createFileFilter as defaultFileFilterCreator } from '../util/file-filter.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\nimport defaultSourceWatcher from '../watcher.js';\nimport type { OnSourceChangeFn } from '../watcher';\n\nconst log = createLogger(import.meta.url);\n\nexport type ExtensionRunnerConfig =\n | {|\n target: 'firefox-desktop',\n params: FirefoxDesktopExtensionRunnerParams,\n |}\n | {|\n target: 'firefox-android',\n params: FirefoxAndroidExtensionRunnerParams,\n |}\n | {|\n target: 'chromium',\n params: ChromiumExtensionRunnerParams,\n |};\n\nexport type MultiExtensionRunnerParams = {|\n runners: Array<IExtensionRunner>,\n desktopNotifications: typeof defaultDesktopNotifications,\n|};\n\nexport async function createExtensionRunner(\n config: ExtensionRunnerConfig\n): Promise<IExtensionRunner> {\n switch (config.target) {\n case 'firefox-desktop': {\n const { FirefoxDesktopExtensionRunner } = await import(\n './firefox-desktop.js'\n );\n return new FirefoxDesktopExtensionRunner(config.params);\n }\n case 'firefox-android': {\n const { FirefoxAndroidExtensionRunner } = await import(\n './firefox-android.js'\n );\n return new FirefoxAndroidExtensionRunner(config.params);\n }\n case 'chromium': {\n const { ChromiumExtensionRunner } = await import('./chromium.js');\n return new ChromiumExtensionRunner(config.params);\n }\n default:\n throw new WebExtError(`Unknown target: \"${config.target}\"`);\n }\n}\n\n/**\n * Implements an IExtensionRunner which allow the caller to\n * manage multiple extension runners at the same time (e.g. by running\n * a Firefox Desktop instance alongside to a Firefox for Android instance).\n */\nexport class MultiExtensionRunner {\n extensionRunners: Array<IExtensionRunner>;\n desktopNotifications: typeof defaultDesktopNotifications;\n\n constructor(params: MultiExtensionRunnerParams) {\n this.extensionRunners = params.runners;\n this.desktopNotifications = params.desktopNotifications;\n }\n\n // Method exported from the IExtensionRunner interface.\n\n /**\n * Returns the runner name.\n */\n getName(): string {\n return 'Multi Extension Runner';\n }\n\n /**\n * Call the `run` method on all the managed extension runners,\n * and awaits that all the runners has been successfully started.\n */\n async run(): Promise<void> {\n const promises = [];\n for (const runner of this.extensionRunners) {\n promises.push(runner.run());\n }\n\n await Promise.all(promises);\n }\n\n /**\n * Reloads all the extensions on all the managed extension runners,\n * collect any reload error, and resolves to an array composed by\n * a ExtensionRunnerReloadResult object per managed runner.\n *\n * Any detected reload error is also logged on the terminal and shows as a\n * desktop notification.\n */\n async reloadAllExtensions(): Promise<Array<ExtensionRunnerReloadResult>> {\n log.debug('Reloading all reloadable add-ons');\n\n const promises = [];\n for (const runner of this.extensionRunners) {\n const reloadPromise = runner.reloadAllExtensions().then(\n () => {\n return { runnerName: runner.getName() };\n },\n (error) => {\n return {\n runnerName: runner.getName(),\n reloadError: error,\n };\n }\n );\n\n promises.push(reloadPromise);\n }\n\n return await Promise.all(promises).then((results) => {\n this.handleReloadResults(results);\n return results;\n });\n }\n\n /**\n * Reloads a single extension on all the managed extension runners,\n * collect any reload error and resolves to an array composed by\n * a ExtensionRunnerReloadResult object per managed runner.\n *\n * Any detected reload error is also logged on the terminal and shows as a\n * desktop notification.\n */\n async reloadExtensionBySourceDir(\n sourceDir: string\n ): Promise<Array<ExtensionRunnerReloadResult>> {\n log.debug(`Reloading add-on at ${sourceDir}`);\n\n const promises: Array<Promise<ExtensionRunnerReloadResult>> = [];\n for (const runner of this.extensionRunners) {\n const reloadPromise = runner.reloadExtensionBySourceDir(sourceDir).then(\n () => {\n return { runnerName: runner.getName(), sourceDir };\n },\n (error) => {\n return {\n runnerName: runner.getName(),\n reloadError: error,\n sourceDir,\n };\n }\n );\n\n promises.push(reloadPromise);\n }\n\n return await Promise.all(promises).then((results) => {\n this.handleReloadResults(results);\n return results;\n });\n }\n\n /**\n * Register a callback to be called when all the managed runners has been exited.\n */\n registerCleanup(cleanupCallback: Function): void {\n const promises = [];\n\n // Create a promise for every extension runner managed by this instance,\n // the promise will be resolved when the particular runner calls its\n // registered cleanup callbacks.\n for (const runner of this.extensionRunners) {\n promises.push(\n new Promise((resolve) => {\n runner.registerCleanup(resolve);\n })\n );\n }\n\n // Wait for all the created promises to be resolved or rejected\n // (once each one of the runners has cleaned up) and then call\n // the cleanup callback registered to this runner.\n Promise.all(promises).then(cleanupCallback, cleanupCallback);\n }\n\n /**\n * Exits all the managed runner has been exited.\n */\n async exit(): Promise<void> {\n const promises = [];\n for (const runner of this.extensionRunners) {\n promises.push(runner.exit());\n }\n\n await Promise.all(promises);\n }\n\n // Private helper methods.\n\n handleReloadResults(results: Array<ExtensionRunnerReloadResult>): void {\n for (const { runnerName, reloadError, sourceDir } of results) {\n if (reloadError instanceof Error) {\n let message = 'Error occurred while reloading';\n if (sourceDir) {\n message += ` \"${sourceDir}\" `;\n }\n\n message += `on \"${runnerName}\" - ${reloadError.message}`;\n\n log.error(`\\n${message}`);\n log.debug(reloadError.stack);\n\n this.desktopNotifications({\n title: 'web-ext run: extension reload error',\n message,\n });\n }\n }\n }\n}\n\n// defaultWatcherCreator types and implementation.\n\nexport type WatcherCreatorParams = {|\n reloadExtension: (string) => void,\n sourceDir: string,\n watchFile?: Array<string>,\n watchIgnored?: Array<string>,\n artifactsDir: string,\n onSourceChange?: OnSourceChangeFn,\n ignoreFiles?: Array<string>,\n createFileFilter?: FileFilterCreatorFn,\n|};\n\nexport type WatcherCreatorFn = (params: WatcherCreatorParams) => Watchpack;\n\nexport function defaultWatcherCreator({\n reloadExtension,\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n ignoreFiles,\n onSourceChange = defaultSourceWatcher,\n createFileFilter = defaultFileFilterCreator,\n}: WatcherCreatorParams): Watchpack {\n const fileFilter = createFileFilter({ sourceDir, artifactsDir, ignoreFiles });\n return onSourceChange({\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n onChange: () => reloadExtension(sourceDir),\n shouldWatchFile: (file) => fileFilter.wantFile(file),\n });\n}\n\n// defaultReloadStrategy types and implementation.\n\nexport type ReloadStrategyParams = {|\n extensionRunner: IExtensionRunner,\n sourceDir: string,\n watchFile?: Array<string>,\n watchIgnored?: Array<string>,\n artifactsDir: string,\n ignoreFiles?: Array<string>,\n noInput?: boolean,\n|};\n\nexport type ReloadStrategyOptions = {\n createWatcher?: WatcherCreatorFn,\n stdin?: stream$Readable,\n kill?: (pid: number, signal?: string | number) => void,\n};\n\nexport function defaultReloadStrategy(\n {\n artifactsDir,\n extensionRunner,\n ignoreFiles,\n noInput = false,\n sourceDir,\n watchFile,\n watchIgnored,\n }: ReloadStrategyParams,\n {\n createWatcher = defaultWatcherCreator,\n stdin = process.stdin,\n // $FlowIgnore: ignore method-unbinding.\n kill = process.kill,\n }: ReloadStrategyOptions = {}\n): void {\n const allowInput = !noInput;\n if (!allowInput) {\n log.debug('Input has been disabled because of noInput==true');\n }\n\n const watcher: Watchpack = createWatcher({\n reloadExtension: (watchedSourceDir) => {\n extensionRunner.reloadExtensionBySourceDir(watchedSourceDir);\n },\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n ignoreFiles,\n });\n\n extensionRunner.registerCleanup(() => {\n watcher.close();\n if (allowInput) {\n stdin.pause();\n }\n });\n\n if (allowInput && isTTY(stdin)) {\n readline.emitKeypressEvents(stdin);\n setRawMode(stdin, true);\n\n const keypressUsageInfo = 'Press R to reload (and Ctrl-C to quit)';\n\n // NOTE: this `Promise.resolve().then(...)` is basically used to spawn a \"co-routine\"\n // that is executed before the callback attached to the Promise returned by this function\n // (and it allows the `run` function to not be stuck in the while loop).\n Promise.resolve().then(async function () {\n log.info(keypressUsageInfo);\n\n let userExit = false;\n\n while (!userExit) {\n const keyPressed = await new Promise((resolve) => {\n stdin.once('keypress', (str, key) => resolve(key));\n });\n\n if (keyPressed.ctrl && keyPressed.name === 'c') {\n userExit = true;\n } else if (keyPressed.name === 'z') {\n // Prepare to suspend.\n\n // NOTE: Switch the raw mode off before suspending (needed to make the keypress event\n // to work correctly when the nodejs process is resumed).\n setRawMode(stdin, false);\n\n log.info('\\nweb-ext has been suspended on user request');\n kill(process.pid, 'SIGTSTP');\n\n // Prepare to resume.\n\n log.info(`\\nweb-ext has been resumed. ${keypressUsageInfo}`);\n\n // Switch the raw mode on on resume.\n setRawMode(stdin, true);\n } else if (keyPressed.name === 'r') {\n log.debug('Reloading installed extensions on user request');\n await extensionRunner.reloadAllExtensions().catch((err) => {\n log.warn(`\\nError reloading extension: ${err}`);\n log.debug(`Reloading extension error stack: ${err.stack}`);\n });\n }\n }\n\n log.info('\\nExiting web-ext on user request');\n extensionRunner.exit();\n });\n }\n}\n"],"mappings":"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"}
|
package/lib/firefox/index.js
CHANGED