web-ext 8.2.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/cmd/build.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import path from 'path';
2
2
  import { createWriteStream } from 'fs';
3
- import { fs } from 'mz';
3
+ import fs from 'fs/promises';
4
4
  import parseJSON from 'parse-json';
5
5
  import stripBom from 'strip-bom';
6
6
  import defaultFromEvent from 'promise-toolbox/fromEvent';
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","names":["path","createWriteStream","fs","parseJSON","stripBom","defaultFromEvent","zipDir","defaultSourceWatcher","getValidatedManifest","getManifestId","prepareArtifactsDir","createLogger","UsageError","isErrorWithCode","createFileFilter","defaultFileFilterCreator","log","import","meta","url","DEFAULT_FILENAME_TEMPLATE","safeFileName","name","toLowerCase","replace","getDefaultLocalizedName","messageFile","manifestData","messageData","messageContents","extensionName","readFile","encoding","error","default","stripJsonComments","match","messageName","message","Promise","resolve","getStringPropertyValue","prop","obj","properties","split","value","reduce","prev","curr","includes","stringValue","length","getPackageNameFromTemplate","filenameTemplate","packageName","manifestProperty","parsed","parse","dir","ext","defaultPackageCreator","sourceDir","fileFilter","artifactsDir","overwriteDest","showReadyMessage","filename","fromEvent","id","debug","buffer","filter","args","wantFile","default_locale","join","extensionPath","stream","flags","write","end","info","overwriteStream","build","asNeeded","ignoreFiles","onSourceChange","packageCreator","rebuildAsNeeded","createPackage","result","onChange","catch","stack","shouldWatchFile"],"sources":["../../src/cmd/build.js"],"sourcesContent":["import path from 'path';\nimport { createWriteStream } from 'fs';\n\nimport { fs } from 'mz';\nimport parseJSON from 'parse-json';\nimport stripBom from 'strip-bom';\nimport defaultFromEvent from 'promise-toolbox/fromEvent';\nimport zipDir from 'zip-dir';\n\nimport defaultSourceWatcher from '../watcher.js';\nimport getValidatedManifest, { getManifestId } from '../util/manifest.js';\nimport { prepareArtifactsDir } from '../util/artifacts.js';\nimport { createLogger } from '../util/logger.js';\nimport { UsageError, isErrorWithCode } from '../errors.js';\nimport { createFileFilter as defaultFileFilterCreator } from '../util/file-filter.js';\n\nconst log = createLogger(import.meta.url);\nconst DEFAULT_FILENAME_TEMPLATE = '{name}-{version}.zip';\n\nexport function safeFileName(name) {\n return name.toLowerCase().replace(/[^a-z0-9.-]+/g, '_');\n}\n\n// defaultPackageCreator types and implementation.\n\n// This defines the _locales/messages.json type. See:\n// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Internationalization#Providing_localized_strings_in__locales\n\nexport async function getDefaultLocalizedName({ messageFile, manifestData }) {\n let messageData;\n let messageContents;\n let extensionName = manifestData.name;\n\n try {\n messageContents = await fs.readFile(messageFile, { encoding: 'utf-8' });\n } catch (error) {\n throw new UsageError(\n `Error reading messages.json file at ${messageFile}: ${error}`,\n );\n }\n\n messageContents = stripBom(messageContents);\n\n const { default: stripJsonComments } = await import('strip-json-comments');\n try {\n messageData = parseJSON(stripJsonComments(messageContents));\n } catch (error) {\n throw new UsageError(\n `Error parsing messages.json file at ${messageFile}: ${error}`,\n );\n }\n\n extensionName = manifestData.name.replace(\n /__MSG_([A-Za-z0-9@_]+?)__/g,\n (match, messageName) => {\n if (!(messageData[messageName] && messageData[messageName].message)) {\n const error = new UsageError(\n `The locale file ${messageFile} ` + `is missing key: ${messageName}`,\n );\n throw error;\n } else {\n return messageData[messageName].message;\n }\n },\n );\n return Promise.resolve(extensionName);\n}\n\n// https://stackoverflow.com/a/22129960\nexport function getStringPropertyValue(prop, obj) {\n const properties = prop.split('.');\n const value = properties.reduce((prev, curr) => prev && prev[curr], obj);\n if (!['string', 'number'].includes(typeof value)) {\n throw new UsageError(\n `Manifest key \"${prop}\" is missing or has an invalid type: ${value}`,\n );\n }\n const stringValue = `${value}`;\n if (!stringValue.length) {\n throw new UsageError(`Manifest key \"${prop}\" value is an empty string`);\n }\n return stringValue;\n}\n\nfunction getPackageNameFromTemplate(filenameTemplate, manifestData) {\n const packageName = filenameTemplate.replace(\n /{([A-Za-z0-9._]+?)}/g,\n (match, manifestProperty) => {\n return safeFileName(\n getStringPropertyValue(manifestProperty, manifestData),\n );\n },\n );\n\n // Validate the resulting packageName string, after interpolating the manifest property\n // specified in the template string.\n const parsed = path.parse(packageName);\n if (parsed.dir) {\n throw new UsageError(\n `Invalid filename template \"${filenameTemplate}\". ` +\n `Filename \"${packageName}\" should not contain a path`,\n );\n }\n if (!['.zip', '.xpi'].includes(parsed.ext)) {\n throw new UsageError(\n `Invalid filename template \"${filenameTemplate}\". ` +\n `Filename \"${packageName}\" should have a zip or xpi extension`,\n );\n }\n\n return packageName;\n}\n\nexport async function defaultPackageCreator(\n {\n manifestData,\n sourceDir,\n fileFilter,\n artifactsDir,\n overwriteDest,\n showReadyMessage,\n filename = DEFAULT_FILENAME_TEMPLATE,\n },\n { fromEvent = defaultFromEvent } = {},\n) {\n let id;\n if (manifestData) {\n id = getManifestId(manifestData);\n log.debug(`Using manifest id=${id || '[not specified]'}`);\n } else {\n manifestData = await getValidatedManifest(sourceDir);\n }\n\n const buffer = await zipDir(sourceDir, {\n filter: (...args) => fileFilter.wantFile(...args),\n });\n\n let filenameTemplate = filename;\n\n let { default_locale } = manifestData;\n if (default_locale) {\n default_locale = default_locale.replace(/-/g, '_');\n const messageFile = path.join(\n sourceDir,\n '_locales',\n default_locale,\n 'messages.json',\n );\n log.debug('Manifest declared default_locale, localizing extension name');\n const extensionName = await getDefaultLocalizedName({\n messageFile,\n manifestData,\n });\n // allow for a localized `{name}`, without mutating `manifestData`\n filenameTemplate = filenameTemplate.replace(/{name}/g, extensionName);\n }\n\n const packageName = safeFileName(\n getPackageNameFromTemplate(filenameTemplate, manifestData),\n );\n const extensionPath = path.join(artifactsDir, packageName);\n\n // Added 'wx' flags to avoid overwriting of existing package.\n const stream = createWriteStream(extensionPath, { flags: 'wx' });\n\n stream.write(buffer, () => {\n stream.end();\n });\n\n try {\n await fromEvent(stream, 'close');\n } catch (error) {\n if (!isErrorWithCode('EEXIST', error)) {\n throw error;\n }\n if (!overwriteDest) {\n throw new UsageError(\n `Extension exists at the destination path: ${extensionPath}\\n` +\n 'Use --overwrite-dest to enable overwriting.',\n );\n }\n log.info(`Destination exists, overwriting: ${extensionPath}`);\n const overwriteStream = createWriteStream(extensionPath);\n overwriteStream.write(buffer, () => {\n overwriteStream.end();\n });\n await fromEvent(overwriteStream, 'close');\n }\n\n if (showReadyMessage) {\n log.info(`Your web extension is ready: ${extensionPath}`);\n }\n return { extensionPath };\n}\n\n// Build command types and implementation.\n\nexport default async function build(\n {\n sourceDir,\n artifactsDir,\n asNeeded = false,\n overwriteDest = false,\n ignoreFiles = [],\n filename = DEFAULT_FILENAME_TEMPLATE,\n },\n {\n manifestData,\n createFileFilter = defaultFileFilterCreator,\n fileFilter = createFileFilter({\n sourceDir,\n artifactsDir,\n ignoreFiles,\n }),\n onSourceChange = defaultSourceWatcher,\n packageCreator = defaultPackageCreator,\n showReadyMessage = true,\n } = {},\n) {\n const rebuildAsNeeded = asNeeded; // alias for `build --as-needed`\n log.info(`Building web extension from ${sourceDir}`);\n\n const createPackage = () =>\n packageCreator({\n manifestData,\n sourceDir,\n fileFilter,\n artifactsDir,\n overwriteDest,\n showReadyMessage,\n filename,\n });\n\n await prepareArtifactsDir(artifactsDir);\n const result = await createPackage();\n\n if (rebuildAsNeeded) {\n log.info('Rebuilding when files change...');\n onSourceChange({\n sourceDir,\n artifactsDir,\n onChange: () => {\n return createPackage().catch((error) => {\n log.error(error.stack);\n throw error;\n });\n },\n shouldWatchFile: (...args) => fileFilter.wantFile(...args),\n });\n }\n\n return result;\n}\n"],"mappings":"AAAA,OAAOA,IAAI,MAAM,MAAM;AACvB,SAASC,iBAAiB,QAAQ,IAAI;AAEtC,SAASC,EAAE,QAAQ,IAAI;AACvB,OAAOC,SAAS,MAAM,YAAY;AAClC,OAAOC,QAAQ,MAAM,WAAW;AAChC,OAAOC,gBAAgB,MAAM,2BAA2B;AACxD,OAAOC,MAAM,MAAM,SAAS;AAE5B,OAAOC,oBAAoB,MAAM,eAAe;AAChD,OAAOC,oBAAoB,IAAIC,aAAa,QAAQ,qBAAqB;AACzE,SAASC,mBAAmB,QAAQ,sBAAsB;AAC1D,SAASC,YAAY,QAAQ,mBAAmB;AAChD,SAASC,UAAU,EAAEC,eAAe,QAAQ,cAAc;AAC1D,SAASC,gBAAgB,IAAIC,wBAAwB,QAAQ,wBAAwB;AAErF,MAAMC,GAAG,GAAGL,YAAY,CAACM,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC;AACzC,MAAMC,yBAAyB,GAAG,sBAAsB;AAExD,OAAO,SAASC,YAAYA,CAACC,IAAI,EAAE;EACjC,OAAOA,IAAI,CAACC,WAAW,CAAC,CAAC,CAACC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;AACzD;;AAEA;;AAEA;AACA;;AAEA,OAAO,eAAeC,uBAAuBA,CAAC;EAAEC,WAAW;EAAEC;AAAa,CAAC,EAAE;EAC3E,IAAIC,WAAW;EACf,IAAIC,eAAe;EACnB,IAAIC,aAAa,GAAGH,YAAY,CAACL,IAAI;EAErC,IAAI;IACFO,eAAe,GAAG,MAAM3B,EAAE,CAAC6B,QAAQ,CAACL,WAAW,EAAE;MAAEM,QAAQ,EAAE;IAAQ,CAAC,CAAC;EACzE,CAAC,CAAC,OAAOC,KAAK,EAAE;IACd,MAAM,IAAIrB,UAAU,CAClB,uCAAuCc,WAAW,KAAKO,KAAK,EAC9D,CAAC;EACH;EAEAJ,eAAe,GAAGzB,QAAQ,CAACyB,eAAe,CAAC;EAE3C,MAAM;IAAEK,OAAO,EAAEC;EAAkB,CAAC,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC;EAC1E,IAAI;IACFP,WAAW,GAAGzB,SAAS,CAACgC,iBAAiB,CAACN,eAAe,CAAC,CAAC;EAC7D,CAAC,CAAC,OAAOI,KAAK,EAAE;IACd,MAAM,IAAIrB,UAAU,CAClB,uCAAuCc,WAAW,KAAKO,KAAK,EAC9D,CAAC;EACH;EAEAH,aAAa,GAAGH,YAAY,CAACL,IAAI,CAACE,OAAO,CACvC,4BAA4B,EAC5B,CAACY,KAAK,EAAEC,WAAW,KAAK;IACtB,IAAI,EAAET,WAAW,CAACS,WAAW,CAAC,IAAIT,WAAW,CAACS,WAAW,CAAC,CAACC,OAAO,CAAC,EAAE;MACnE,MAAML,KAAK,GAAG,IAAIrB,UAAU,CAC1B,mBAAmBc,WAAW,GAAG,GAAG,mBAAmBW,WAAW,EACpE,CAAC;MACD,MAAMJ,KAAK;IACb,CAAC,MAAM;MACL,OAAOL,WAAW,CAACS,WAAW,CAAC,CAACC,OAAO;IACzC;EACF,CACF,CAAC;EACD,OAAOC,OAAO,CAACC,OAAO,CAACV,aAAa,CAAC;AACvC;;AAEA;AACA,OAAO,SAASW,sBAAsBA,CAACC,IAAI,EAAEC,GAAG,EAAE;EAChD,MAAMC,UAAU,GAAGF,IAAI,CAACG,KAAK,CAAC,GAAG,CAAC;EAClC,MAAMC,KAAK,GAAGF,UAAU,CAACG,MAAM,CAAC,CAACC,IAAI,EAAEC,IAAI,KAAKD,IAAI,IAAIA,IAAI,CAACC,IAAI,CAAC,EAAEN,GAAG,CAAC;EACxE,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAACO,QAAQ,CAAC,OAAOJ,KAAK,CAAC,EAAE;IAChD,MAAM,IAAIlC,UAAU,CAClB,iBAAiB8B,IAAI,wCAAwCI,KAAK,EACpE,CAAC;EACH;EACA,MAAMK,WAAW,GAAG,GAAGL,KAAK,EAAE;EAC9B,IAAI,CAACK,WAAW,CAACC,MAAM,EAAE;IACvB,MAAM,IAAIxC,UAAU,CAAC,iBAAiB8B,IAAI,4BAA4B,CAAC;EACzE;EACA,OAAOS,WAAW;AACpB;AAEA,SAASE,0BAA0BA,CAACC,gBAAgB,EAAE3B,YAAY,EAAE;EAClE,MAAM4B,WAAW,GAAGD,gBAAgB,CAAC9B,OAAO,CAC1C,sBAAsB,EACtB,CAACY,KAAK,EAAEoB,gBAAgB,KAAK;IAC3B,OAAOnC,YAAY,CACjBoB,sBAAsB,CAACe,gBAAgB,EAAE7B,YAAY,CACvD,CAAC;EACH,CACF,CAAC;;EAED;EACA;EACA,MAAM8B,MAAM,GAAGzD,IAAI,CAAC0D,KAAK,CAACH,WAAW,CAAC;EACtC,IAAIE,MAAM,CAACE,GAAG,EAAE;IACd,MAAM,IAAI/C,UAAU,CAClB,8BAA8B0C,gBAAgB,KAAK,GACjD,aAAaC,WAAW,6BAC5B,CAAC;EACH;EACA,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAACL,QAAQ,CAACO,MAAM,CAACG,GAAG,CAAC,EAAE;IAC1C,MAAM,IAAIhD,UAAU,CAClB,8BAA8B0C,gBAAgB,KAAK,GACjD,aAAaC,WAAW,sCAC5B,CAAC;EACH;EAEA,OAAOA,WAAW;AACpB;AAEA,OAAO,eAAeM,qBAAqBA,CACzC;EACElC,YAAY;EACZmC,SAAS;EACTC,UAAU;EACVC,YAAY;EACZC,aAAa;EACbC,gBAAgB;EAChBC,QAAQ,GAAG/C;AACb,CAAC,EACD;EAAEgD,SAAS,GAAG/D;AAAiB,CAAC,GAAG,CAAC,CAAC,EACrC;EACA,IAAIgE,EAAE;EACN,IAAI1C,YAAY,EAAE;IAChB0C,EAAE,GAAG5D,aAAa,CAACkB,YAAY,CAAC;IAChCX,GAAG,CAACsD,KAAK,CAAC,qBAAqBD,EAAE,IAAI,iBAAiB,EAAE,CAAC;EAC3D,CAAC,MAAM;IACL1C,YAAY,GAAG,MAAMnB,oBAAoB,CAACsD,SAAS,CAAC;EACtD;EAEA,MAAMS,MAAM,GAAG,MAAMjE,MAAM,CAACwD,SAAS,EAAE;IACrCU,MAAM,EAAEA,CAAC,GAAGC,IAAI,KAAKV,UAAU,CAACW,QAAQ,CAAC,GAAGD,IAAI;EAClD,CAAC,CAAC;EAEF,IAAInB,gBAAgB,GAAGa,QAAQ;EAE/B,IAAI;IAAEQ;EAAe,CAAC,GAAGhD,YAAY;EACrC,IAAIgD,cAAc,EAAE;IAClBA,cAAc,GAAGA,cAAc,CAACnD,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;IAClD,MAAME,WAAW,GAAG1B,IAAI,CAAC4E,IAAI,CAC3Bd,SAAS,EACT,UAAU,EACVa,cAAc,EACd,eACF,CAAC;IACD3D,GAAG,CAACsD,KAAK,CAAC,6DAA6D,CAAC;IACxE,MAAMxC,aAAa,GAAG,MAAML,uBAAuB,CAAC;MAClDC,WAAW;MACXC;IACF,CAAC,CAAC;IACF;IACA2B,gBAAgB,GAAGA,gBAAgB,CAAC9B,OAAO,CAAC,SAAS,EAAEM,aAAa,CAAC;EACvE;EAEA,MAAMyB,WAAW,GAAGlC,YAAY,CAC9BgC,0BAA0B,CAACC,gBAAgB,EAAE3B,YAAY,CAC3D,CAAC;EACD,MAAMkD,aAAa,GAAG7E,IAAI,CAAC4E,IAAI,CAACZ,YAAY,EAAET,WAAW,CAAC;;EAE1D;EACA,MAAMuB,MAAM,GAAG7E,iBAAiB,CAAC4E,aAAa,EAAE;IAAEE,KAAK,EAAE;EAAK,CAAC,CAAC;EAEhED,MAAM,CAACE,KAAK,CAACT,MAAM,EAAE,MAAM;IACzBO,MAAM,CAACG,GAAG,CAAC,CAAC;EACd,CAAC,CAAC;EAEF,IAAI;IACF,MAAMb,SAAS,CAACU,MAAM,EAAE,OAAO,CAAC;EAClC,CAAC,CAAC,OAAO7C,KAAK,EAAE;IACd,IAAI,CAACpB,eAAe,CAAC,QAAQ,EAAEoB,KAAK,CAAC,EAAE;MACrC,MAAMA,KAAK;IACb;IACA,IAAI,CAACgC,aAAa,EAAE;MAClB,MAAM,IAAIrD,UAAU,CAClB,6CAA6CiE,aAAa,IAAI,GAC5D,6CACJ,CAAC;IACH;IACA7D,GAAG,CAACkE,IAAI,CAAC,oCAAoCL,aAAa,EAAE,CAAC;IAC7D,MAAMM,eAAe,GAAGlF,iBAAiB,CAAC4E,aAAa,CAAC;IACxDM,eAAe,CAACH,KAAK,CAACT,MAAM,EAAE,MAAM;MAClCY,eAAe,CAACF,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC;IACF,MAAMb,SAAS,CAACe,eAAe,EAAE,OAAO,CAAC;EAC3C;EAEA,IAAIjB,gBAAgB,EAAE;IACpBlD,GAAG,CAACkE,IAAI,CAAC,gCAAgCL,aAAa,EAAE,CAAC;EAC3D;EACA,OAAO;IAAEA;EAAc,CAAC;AAC1B;;AAEA;;AAEA,eAAe,eAAeO,KAAKA,CACjC;EACEtB,SAAS;EACTE,YAAY;EACZqB,QAAQ,GAAG,KAAK;EAChBpB,aAAa,GAAG,KAAK;EACrBqB,WAAW,GAAG,EAAE;EAChBnB,QAAQ,GAAG/C;AACb,CAAC,EACD;EACEO,YAAY;EACZb,gBAAgB,GAAGC,wBAAwB;EAC3CgD,UAAU,GAAGjD,gBAAgB,CAAC;IAC5BgD,SAAS;IACTE,YAAY;IACZsB;EACF,CAAC,CAAC;EACFC,cAAc,GAAGhF,oBAAoB;EACrCiF,cAAc,GAAG3B,qBAAqB;EACtCK,gBAAgB,GAAG;AACrB,CAAC,GAAG,CAAC,CAAC,EACN;EACA,MAAMuB,eAAe,GAAGJ,QAAQ,CAAC,CAAC;EAClCrE,GAAG,CAACkE,IAAI,CAAC,+BAA+BpB,SAAS,EAAE,CAAC;EAEpD,MAAM4B,aAAa,GAAGA,CAAA,KACpBF,cAAc,CAAC;IACb7D,YAAY;IACZmC,SAAS;IACTC,UAAU;IACVC,YAAY;IACZC,aAAa;IACbC,gBAAgB;IAChBC;EACF,CAAC,CAAC;EAEJ,MAAMzD,mBAAmB,CAACsD,YAAY,CAAC;EACvC,MAAM2B,MAAM,GAAG,MAAMD,aAAa,CAAC,CAAC;EAEpC,IAAID,eAAe,EAAE;IACnBzE,GAAG,CAACkE,IAAI,CAAC,iCAAiC,CAAC;IAC3CK,cAAc,CAAC;MACbzB,SAAS;MACTE,YAAY;MACZ4B,QAAQ,EAAEA,CAAA,KAAM;QACd,OAAOF,aAAa,CAAC,CAAC,CAACG,KAAK,CAAE5D,KAAK,IAAK;UACtCjB,GAAG,CAACiB,KAAK,CAACA,KAAK,CAAC6D,KAAK,CAAC;UACtB,MAAM7D,KAAK;QACb,CAAC,CAAC;MACJ,CAAC;MACD8D,eAAe,EAAEA,CAAC,GAAGtB,IAAI,KAAKV,UAAU,CAACW,QAAQ,CAAC,GAAGD,IAAI;IAC3D,CAAC,CAAC;EACJ;EAEA,OAAOkB,MAAM;AACf","ignoreList":[]}
1
+ {"version":3,"file":"build.js","names":["path","createWriteStream","fs","parseJSON","stripBom","defaultFromEvent","zipDir","defaultSourceWatcher","getValidatedManifest","getManifestId","prepareArtifactsDir","createLogger","UsageError","isErrorWithCode","createFileFilter","defaultFileFilterCreator","log","import","meta","url","DEFAULT_FILENAME_TEMPLATE","safeFileName","name","toLowerCase","replace","getDefaultLocalizedName","messageFile","manifestData","messageData","messageContents","extensionName","readFile","encoding","error","default","stripJsonComments","match","messageName","message","Promise","resolve","getStringPropertyValue","prop","obj","properties","split","value","reduce","prev","curr","includes","stringValue","length","getPackageNameFromTemplate","filenameTemplate","packageName","manifestProperty","parsed","parse","dir","ext","defaultPackageCreator","sourceDir","fileFilter","artifactsDir","overwriteDest","showReadyMessage","filename","fromEvent","id","debug","buffer","filter","args","wantFile","default_locale","join","extensionPath","stream","flags","write","end","info","overwriteStream","build","asNeeded","ignoreFiles","onSourceChange","packageCreator","rebuildAsNeeded","createPackage","result","onChange","catch","stack","shouldWatchFile"],"sources":["../../src/cmd/build.js"],"sourcesContent":["import path from 'path';\nimport { createWriteStream } from 'fs';\nimport fs from 'fs/promises';\n\nimport parseJSON from 'parse-json';\nimport stripBom from 'strip-bom';\nimport defaultFromEvent from 'promise-toolbox/fromEvent';\nimport zipDir from 'zip-dir';\n\nimport defaultSourceWatcher from '../watcher.js';\nimport getValidatedManifest, { getManifestId } from '../util/manifest.js';\nimport { prepareArtifactsDir } from '../util/artifacts.js';\nimport { createLogger } from '../util/logger.js';\nimport { UsageError, isErrorWithCode } from '../errors.js';\nimport { createFileFilter as defaultFileFilterCreator } from '../util/file-filter.js';\n\nconst log = createLogger(import.meta.url);\nconst DEFAULT_FILENAME_TEMPLATE = '{name}-{version}.zip';\n\nexport function safeFileName(name) {\n return name.toLowerCase().replace(/[^a-z0-9.-]+/g, '_');\n}\n\n// defaultPackageCreator types and implementation.\n\n// This defines the _locales/messages.json type. See:\n// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Internationalization#Providing_localized_strings_in__locales\n\nexport async function getDefaultLocalizedName({ messageFile, manifestData }) {\n let messageData;\n let messageContents;\n let extensionName = manifestData.name;\n\n try {\n messageContents = await fs.readFile(messageFile, { encoding: 'utf-8' });\n } catch (error) {\n throw new UsageError(\n `Error reading messages.json file at ${messageFile}: ${error}`,\n );\n }\n\n messageContents = stripBom(messageContents);\n\n const { default: stripJsonComments } = await import('strip-json-comments');\n try {\n messageData = parseJSON(stripJsonComments(messageContents));\n } catch (error) {\n throw new UsageError(\n `Error parsing messages.json file at ${messageFile}: ${error}`,\n );\n }\n\n extensionName = manifestData.name.replace(\n /__MSG_([A-Za-z0-9@_]+?)__/g,\n (match, messageName) => {\n if (!(messageData[messageName] && messageData[messageName].message)) {\n const error = new UsageError(\n `The locale file ${messageFile} ` + `is missing key: ${messageName}`,\n );\n throw error;\n } else {\n return messageData[messageName].message;\n }\n },\n );\n return Promise.resolve(extensionName);\n}\n\n// https://stackoverflow.com/a/22129960\nexport function getStringPropertyValue(prop, obj) {\n const properties = prop.split('.');\n const value = properties.reduce((prev, curr) => prev && prev[curr], obj);\n if (!['string', 'number'].includes(typeof value)) {\n throw new UsageError(\n `Manifest key \"${prop}\" is missing or has an invalid type: ${value}`,\n );\n }\n const stringValue = `${value}`;\n if (!stringValue.length) {\n throw new UsageError(`Manifest key \"${prop}\" value is an empty string`);\n }\n return stringValue;\n}\n\nfunction getPackageNameFromTemplate(filenameTemplate, manifestData) {\n const packageName = filenameTemplate.replace(\n /{([A-Za-z0-9._]+?)}/g,\n (match, manifestProperty) => {\n return safeFileName(\n getStringPropertyValue(manifestProperty, manifestData),\n );\n },\n );\n\n // Validate the resulting packageName string, after interpolating the manifest property\n // specified in the template string.\n const parsed = path.parse(packageName);\n if (parsed.dir) {\n throw new UsageError(\n `Invalid filename template \"${filenameTemplate}\". ` +\n `Filename \"${packageName}\" should not contain a path`,\n );\n }\n if (!['.zip', '.xpi'].includes(parsed.ext)) {\n throw new UsageError(\n `Invalid filename template \"${filenameTemplate}\". ` +\n `Filename \"${packageName}\" should have a zip or xpi extension`,\n );\n }\n\n return packageName;\n}\n\nexport async function defaultPackageCreator(\n {\n manifestData,\n sourceDir,\n fileFilter,\n artifactsDir,\n overwriteDest,\n showReadyMessage,\n filename = DEFAULT_FILENAME_TEMPLATE,\n },\n { fromEvent = defaultFromEvent } = {},\n) {\n let id;\n if (manifestData) {\n id = getManifestId(manifestData);\n log.debug(`Using manifest id=${id || '[not specified]'}`);\n } else {\n manifestData = await getValidatedManifest(sourceDir);\n }\n\n const buffer = await zipDir(sourceDir, {\n filter: (...args) => fileFilter.wantFile(...args),\n });\n\n let filenameTemplate = filename;\n\n let { default_locale } = manifestData;\n if (default_locale) {\n default_locale = default_locale.replace(/-/g, '_');\n const messageFile = path.join(\n sourceDir,\n '_locales',\n default_locale,\n 'messages.json',\n );\n log.debug('Manifest declared default_locale, localizing extension name');\n const extensionName = await getDefaultLocalizedName({\n messageFile,\n manifestData,\n });\n // allow for a localized `{name}`, without mutating `manifestData`\n filenameTemplate = filenameTemplate.replace(/{name}/g, extensionName);\n }\n\n const packageName = safeFileName(\n getPackageNameFromTemplate(filenameTemplate, manifestData),\n );\n const extensionPath = path.join(artifactsDir, packageName);\n\n // Added 'wx' flags to avoid overwriting of existing package.\n const stream = createWriteStream(extensionPath, { flags: 'wx' });\n\n stream.write(buffer, () => {\n stream.end();\n });\n\n try {\n await fromEvent(stream, 'close');\n } catch (error) {\n if (!isErrorWithCode('EEXIST', error)) {\n throw error;\n }\n if (!overwriteDest) {\n throw new UsageError(\n `Extension exists at the destination path: ${extensionPath}\\n` +\n 'Use --overwrite-dest to enable overwriting.',\n );\n }\n log.info(`Destination exists, overwriting: ${extensionPath}`);\n const overwriteStream = createWriteStream(extensionPath);\n overwriteStream.write(buffer, () => {\n overwriteStream.end();\n });\n await fromEvent(overwriteStream, 'close');\n }\n\n if (showReadyMessage) {\n log.info(`Your web extension is ready: ${extensionPath}`);\n }\n return { extensionPath };\n}\n\n// Build command types and implementation.\n\nexport default async function build(\n {\n sourceDir,\n artifactsDir,\n asNeeded = false,\n overwriteDest = false,\n ignoreFiles = [],\n filename = DEFAULT_FILENAME_TEMPLATE,\n },\n {\n manifestData,\n createFileFilter = defaultFileFilterCreator,\n fileFilter = createFileFilter({\n sourceDir,\n artifactsDir,\n ignoreFiles,\n }),\n onSourceChange = defaultSourceWatcher,\n packageCreator = defaultPackageCreator,\n showReadyMessage = true,\n } = {},\n) {\n const rebuildAsNeeded = asNeeded; // alias for `build --as-needed`\n log.info(`Building web extension from ${sourceDir}`);\n\n const createPackage = () =>\n packageCreator({\n manifestData,\n sourceDir,\n fileFilter,\n artifactsDir,\n overwriteDest,\n showReadyMessage,\n filename,\n });\n\n await prepareArtifactsDir(artifactsDir);\n const result = await createPackage();\n\n if (rebuildAsNeeded) {\n log.info('Rebuilding when files change...');\n onSourceChange({\n sourceDir,\n artifactsDir,\n onChange: () => {\n return createPackage().catch((error) => {\n log.error(error.stack);\n throw error;\n });\n },\n shouldWatchFile: (...args) => fileFilter.wantFile(...args),\n });\n }\n\n return result;\n}\n"],"mappings":"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","ignoreList":[]}
package/lib/cmd/run.js CHANGED
@@ -1,4 +1,6 @@
1
- import { fs } from 'mz';
1
+ import path from 'path';
2
+ import fs from 'fs/promises';
3
+ import nodeFs from 'fs';
2
4
  import defaultBuildExtension from './build.js';
3
5
  import { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';
4
6
  import * as defaultFirefoxApp from '../firefox/index.js';
@@ -51,6 +53,7 @@ export default async function run({
51
53
  MultiExtensionRunner = DefaultMultiExtensionRunner,
52
54
  getValidatedManifest = defaultGetValidatedManifest
53
55
  } = {}) {
56
+ sourceDir = path.resolve(sourceDir);
54
57
  log.info(`Running web extension from ${sourceDir}`);
55
58
  if (preInstall) {
56
59
  log.info("Disabled auto-reloading because it's not possible with " + '--pre-install');
@@ -71,7 +74,7 @@ export default async function run({
71
74
  if (!profileDir) {
72
75
  throw new UsageError('--profile-create-if-missing requires ' + '--firefox-profile or --chromium-profile');
73
76
  }
74
- const isDir = fs.existsSync(profileDir);
77
+ const isDir = nodeFs.existsSync(profileDir);
75
78
  if (isDir) {
76
79
  log.info(`Profile directory ${profileDir} already exists`);
77
80
  } else {
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","names":["fs","defaultBuildExtension","showDesktopNotification","defaultDesktopNotifications","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxClient","createLogger","defaultGetValidatedManifest","UsageError","createExtensionRunner","defaultReloadStrategy","MultiExtensionRunner","DefaultMultiExtensionRunner","log","import","meta","url","run","artifactsDir","browserConsole","devtools","pref","firefox","firefoxProfile","profileCreateIfMissing","keepProfileChanges","ignoreFiles","noInput","noReload","preInstall","sourceDir","watchFile","watchIgnored","startUrl","target","args","adbBin","adbHost","adbPort","adbDevice","adbDiscoveryTimeout","adbRemoveOldArtifacts","firefoxApk","firefoxApkComponent","chromiumBinary","chromiumProfile","buildExtension","desktopNotifications","firefoxApp","firefoxClient","reloadStrategy","getValidatedManifest","info","Array","isArray","every","el","customPrefs","manifestData","profileDir","isDir","existsSync","mkdir","runners","commonRunnerParams","extensions","length","includes","firefoxDesktopRunnerParams","firefoxBinary","profilePath","firefoxDesktopRunner","params","push","firefoxAndroidRunnerParams","buildSourceDir","extensionSourceDir","tmpArtifactsDir","asNeeded","showReadyMessage","firefoxAndroidRunner","chromiumRunnerParams","chromiumRunner","extensionRunner"],"sources":["../../src/cmd/run.js"],"sourcesContent":["import { fs } from 'mz';\n\nimport defaultBuildExtension from './build.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport { connectWithMaxRetries as defaultFirefoxClient } from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport defaultGetValidatedManifest from '../util/manifest.js';\nimport { UsageError } from '../errors.js';\nimport {\n createExtensionRunner,\n defaultReloadStrategy,\n MultiExtensionRunner as DefaultMultiExtensionRunner,\n} from '../extension-runners/index.js';\n\nconst log = createLogger(import.meta.url);\n\n// Run command types and implementation.\n\nexport default async function run(\n {\n artifactsDir,\n browserConsole = false,\n devtools = false,\n pref,\n firefox,\n firefoxProfile,\n profileCreateIfMissing,\n keepProfileChanges = false,\n ignoreFiles,\n noInput = false,\n noReload = false,\n preInstall = false,\n sourceDir,\n watchFile,\n watchIgnored,\n startUrl,\n target,\n args,\n // Android CLI options.\n adbBin,\n adbHost,\n adbPort,\n adbDevice,\n adbDiscoveryTimeout,\n adbRemoveOldArtifacts,\n firefoxApk,\n firefoxApkComponent,\n // Chromium CLI options.\n chromiumBinary,\n chromiumProfile,\n },\n {\n buildExtension = defaultBuildExtension,\n desktopNotifications = defaultDesktopNotifications,\n firefoxApp = defaultFirefoxApp,\n firefoxClient = defaultFirefoxClient,\n reloadStrategy = defaultReloadStrategy,\n MultiExtensionRunner = DefaultMultiExtensionRunner,\n getValidatedManifest = defaultGetValidatedManifest,\n } = {},\n) {\n log.info(`Running web extension from ${sourceDir}`);\n if (preInstall) {\n log.info(\n \"Disabled auto-reloading because it's not possible with \" +\n '--pre-install',\n );\n noReload = true;\n }\n\n if (\n watchFile != null &&\n (!Array.isArray(watchFile) ||\n !watchFile.every((el) => typeof el === 'string'))\n ) {\n throw new UsageError('Unexpected watchFile type');\n }\n\n // Create an alias for --pref since it has been transformed into an\n // object containing one or more preferences.\n const customPrefs = { ...pref };\n const manifestData = await getValidatedManifest(sourceDir);\n\n const profileDir = firefoxProfile || chromiumProfile;\n\n if (profileCreateIfMissing) {\n if (!profileDir) {\n throw new UsageError(\n '--profile-create-if-missing requires ' +\n '--firefox-profile or --chromium-profile',\n );\n }\n const isDir = fs.existsSync(profileDir);\n if (isDir) {\n log.info(`Profile directory ${profileDir} already exists`);\n } else {\n log.info(`Profile directory not found. Creating directory ${profileDir}`);\n await fs.mkdir(profileDir);\n }\n }\n\n const runners = [];\n\n const commonRunnerParams = {\n // Common options.\n extensions: [{ sourceDir, manifestData }],\n keepProfileChanges,\n startUrl,\n args,\n desktopNotifications,\n };\n\n if (!target || target.length === 0 || target.includes('firefox-desktop')) {\n const firefoxDesktopRunnerParams = {\n ...commonRunnerParams,\n\n // Firefox specific CLI options.\n firefoxBinary: firefox,\n profilePath: firefoxProfile,\n customPrefs,\n browserConsole,\n devtools,\n preInstall,\n\n // Firefox runner injected dependencies.\n firefoxApp,\n firefoxClient,\n };\n\n const firefoxDesktopRunner = await createExtensionRunner({\n target: 'firefox-desktop',\n params: firefoxDesktopRunnerParams,\n });\n runners.push(firefoxDesktopRunner);\n }\n\n if (target && target.includes('firefox-android')) {\n const firefoxAndroidRunnerParams = {\n ...commonRunnerParams,\n\n // Firefox specific CLI options.\n profilePath: firefoxProfile,\n customPrefs,\n browserConsole,\n preInstall,\n firefoxApk,\n firefoxApkComponent,\n adbDevice,\n adbHost,\n adbPort,\n adbBin,\n adbDiscoveryTimeout,\n adbRemoveOldArtifacts,\n\n // Injected dependencies.\n firefoxApp,\n firefoxClient,\n desktopNotifications: defaultDesktopNotifications,\n buildSourceDir: (extensionSourceDir, tmpArtifactsDir) => {\n return buildExtension(\n {\n sourceDir: extensionSourceDir,\n ignoreFiles,\n asNeeded: false,\n // Use a separate temporary directory for building the extension zip file\n // that we are going to upload on the android device.\n artifactsDir: tmpArtifactsDir,\n },\n {\n // Suppress the message usually logged by web-ext build.\n showReadyMessage: false,\n },\n );\n },\n };\n\n const firefoxAndroidRunner = await createExtensionRunner({\n target: 'firefox-android',\n params: firefoxAndroidRunnerParams,\n });\n runners.push(firefoxAndroidRunner);\n }\n\n if (target && target.includes('chromium')) {\n const chromiumRunnerParams = {\n ...commonRunnerParams,\n chromiumBinary,\n chromiumProfile,\n };\n\n const chromiumRunner = await createExtensionRunner({\n target: 'chromium',\n params: chromiumRunnerParams,\n });\n runners.push(chromiumRunner);\n }\n\n const extensionRunner = new MultiExtensionRunner({\n desktopNotifications,\n runners,\n });\n\n await extensionRunner.run();\n\n if (noReload) {\n log.info('Automatic extension reloading has been disabled');\n } else {\n log.info('The extension will reload if any source file changes');\n\n reloadStrategy({\n extensionRunner,\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n ignoreFiles,\n noInput,\n });\n }\n\n return extensionRunner;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"run.js","names":["path","fs","nodeFs","defaultBuildExtension","showDesktopNotification","defaultDesktopNotifications","defaultFirefoxApp","connectWithMaxRetries","defaultFirefoxClient","createLogger","defaultGetValidatedManifest","UsageError","createExtensionRunner","defaultReloadStrategy","MultiExtensionRunner","DefaultMultiExtensionRunner","log","import","meta","url","run","artifactsDir","browserConsole","devtools","pref","firefox","firefoxProfile","profileCreateIfMissing","keepProfileChanges","ignoreFiles","noInput","noReload","preInstall","sourceDir","watchFile","watchIgnored","startUrl","target","args","adbBin","adbHost","adbPort","adbDevice","adbDiscoveryTimeout","adbRemoveOldArtifacts","firefoxApk","firefoxApkComponent","chromiumBinary","chromiumProfile","buildExtension","desktopNotifications","firefoxApp","firefoxClient","reloadStrategy","getValidatedManifest","resolve","info","Array","isArray","every","el","customPrefs","manifestData","profileDir","isDir","existsSync","mkdir","runners","commonRunnerParams","extensions","length","includes","firefoxDesktopRunnerParams","firefoxBinary","profilePath","firefoxDesktopRunner","params","push","firefoxAndroidRunnerParams","buildSourceDir","extensionSourceDir","tmpArtifactsDir","asNeeded","showReadyMessage","firefoxAndroidRunner","chromiumRunnerParams","chromiumRunner","extensionRunner"],"sources":["../../src/cmd/run.js"],"sourcesContent":["import path from 'path';\nimport fs from 'fs/promises';\nimport nodeFs from 'fs';\n\nimport defaultBuildExtension from './build.js';\nimport { showDesktopNotification as defaultDesktopNotifications } from '../util/desktop-notifier.js';\nimport * as defaultFirefoxApp from '../firefox/index.js';\nimport { connectWithMaxRetries as defaultFirefoxClient } from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport defaultGetValidatedManifest from '../util/manifest.js';\nimport { UsageError } from '../errors.js';\nimport {\n createExtensionRunner,\n defaultReloadStrategy,\n MultiExtensionRunner as DefaultMultiExtensionRunner,\n} from '../extension-runners/index.js';\n\nconst log = createLogger(import.meta.url);\n\n// Run command types and implementation.\n\nexport default async function run(\n {\n artifactsDir,\n browserConsole = false,\n devtools = false,\n pref,\n firefox,\n firefoxProfile,\n profileCreateIfMissing,\n keepProfileChanges = false,\n ignoreFiles,\n noInput = false,\n noReload = false,\n preInstall = false,\n sourceDir,\n watchFile,\n watchIgnored,\n startUrl,\n target,\n args,\n // Android CLI options.\n adbBin,\n adbHost,\n adbPort,\n adbDevice,\n adbDiscoveryTimeout,\n adbRemoveOldArtifacts,\n firefoxApk,\n firefoxApkComponent,\n // Chromium CLI options.\n chromiumBinary,\n chromiumProfile,\n },\n {\n buildExtension = defaultBuildExtension,\n desktopNotifications = defaultDesktopNotifications,\n firefoxApp = defaultFirefoxApp,\n firefoxClient = defaultFirefoxClient,\n reloadStrategy = defaultReloadStrategy,\n MultiExtensionRunner = DefaultMultiExtensionRunner,\n getValidatedManifest = defaultGetValidatedManifest,\n } = {},\n) {\n sourceDir = path.resolve(sourceDir);\n log.info(`Running web extension from ${sourceDir}`);\n if (preInstall) {\n log.info(\n \"Disabled auto-reloading because it's not possible with \" +\n '--pre-install',\n );\n noReload = true;\n }\n\n if (\n watchFile != null &&\n (!Array.isArray(watchFile) ||\n !watchFile.every((el) => typeof el === 'string'))\n ) {\n throw new UsageError('Unexpected watchFile type');\n }\n\n // Create an alias for --pref since it has been transformed into an\n // object containing one or more preferences.\n const customPrefs = { ...pref };\n const manifestData = await getValidatedManifest(sourceDir);\n\n const profileDir = firefoxProfile || chromiumProfile;\n\n if (profileCreateIfMissing) {\n if (!profileDir) {\n throw new UsageError(\n '--profile-create-if-missing requires ' +\n '--firefox-profile or --chromium-profile',\n );\n }\n const isDir = nodeFs.existsSync(profileDir);\n if (isDir) {\n log.info(`Profile directory ${profileDir} already exists`);\n } else {\n log.info(`Profile directory not found. Creating directory ${profileDir}`);\n await fs.mkdir(profileDir);\n }\n }\n\n const runners = [];\n\n const commonRunnerParams = {\n // Common options.\n extensions: [{ sourceDir, manifestData }],\n keepProfileChanges,\n startUrl,\n args,\n desktopNotifications,\n };\n\n if (!target || target.length === 0 || target.includes('firefox-desktop')) {\n const firefoxDesktopRunnerParams = {\n ...commonRunnerParams,\n\n // Firefox specific CLI options.\n firefoxBinary: firefox,\n profilePath: firefoxProfile,\n customPrefs,\n browserConsole,\n devtools,\n preInstall,\n\n // Firefox runner injected dependencies.\n firefoxApp,\n firefoxClient,\n };\n\n const firefoxDesktopRunner = await createExtensionRunner({\n target: 'firefox-desktop',\n params: firefoxDesktopRunnerParams,\n });\n runners.push(firefoxDesktopRunner);\n }\n\n if (target && target.includes('firefox-android')) {\n const firefoxAndroidRunnerParams = {\n ...commonRunnerParams,\n\n // Firefox specific CLI options.\n profilePath: firefoxProfile,\n customPrefs,\n browserConsole,\n preInstall,\n firefoxApk,\n firefoxApkComponent,\n adbDevice,\n adbHost,\n adbPort,\n adbBin,\n adbDiscoveryTimeout,\n adbRemoveOldArtifacts,\n\n // Injected dependencies.\n firefoxApp,\n firefoxClient,\n desktopNotifications: defaultDesktopNotifications,\n buildSourceDir: (extensionSourceDir, tmpArtifactsDir) => {\n return buildExtension(\n {\n sourceDir: extensionSourceDir,\n ignoreFiles,\n asNeeded: false,\n // Use a separate temporary directory for building the extension zip file\n // that we are going to upload on the android device.\n artifactsDir: tmpArtifactsDir,\n },\n {\n // Suppress the message usually logged by web-ext build.\n showReadyMessage: false,\n },\n );\n },\n };\n\n const firefoxAndroidRunner = await createExtensionRunner({\n target: 'firefox-android',\n params: firefoxAndroidRunnerParams,\n });\n runners.push(firefoxAndroidRunner);\n }\n\n if (target && target.includes('chromium')) {\n const chromiumRunnerParams = {\n ...commonRunnerParams,\n chromiumBinary,\n chromiumProfile,\n };\n\n const chromiumRunner = await createExtensionRunner({\n target: 'chromium',\n params: chromiumRunnerParams,\n });\n runners.push(chromiumRunner);\n }\n\n const extensionRunner = new MultiExtensionRunner({\n desktopNotifications,\n runners,\n });\n\n await extensionRunner.run();\n\n if (noReload) {\n log.info('Automatic extension reloading has been disabled');\n } else {\n log.info('The extension will reload if any source file changes');\n\n reloadStrategy({\n extensionRunner,\n sourceDir,\n watchFile,\n watchIgnored,\n artifactsDir,\n ignoreFiles,\n noInput,\n });\n }\n\n return extensionRunner;\n}\n"],"mappings":"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","ignoreList":[]}
package/lib/config.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import os from 'os';
2
2
  import path from 'path';
3
+ import fs from 'fs/promises';
3
4
  import camelCase from 'camelcase';
4
5
  import decamelize from 'decamelize';
5
- import { fs } from 'mz';
6
6
  import parseJSON from 'parse-json';
7
7
  import fileExists from './util/file-exists.js';
8
8
  import { createLogger } from './util/logger.js';
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":["os","path","camelCase","decamelize","fs","parseJSON","fileExists","createLogger","UsageError","WebExtError","log","import","meta","url","WARN_LEGACY_JS_EXT","join","HELP_ERR_MODULE_FROM_ESM","HELP_ERR_IMPORTEXPORT_CJS","ERR_IMPORT_FROM_CJS","ERR_EXPORT_FROM_CJS","ERR_MODULE_FROM_ESM","applyConfigToArgv","argv","argvFromCLI","configObject","options","configFileName","newArgv","option","Object","keys","Array","isArray","decamelizedOptName","separator","type","undefined","expectedType","optionType","defaultValue","default","wasValueSetOnCLI","debug","coerce","loadJSConfigFile","filePath","resolvedFilePath","resolve","endsWith","warn","nonce","Date","now","Math","random","configModule","readFile","encoding","configDefault","esmConfigMod","error","errorMessage","message","startsWith","includes","webExt","length","discoverConfigFiles","getHomeDir","homedir","magicConfigName","possibleConfigs","process","cwd","configs","Promise","all","map","fileName","resolvedFileName","existingConfigs","forEach","f","push"],"sources":["../src/config.js"],"sourcesContent":["import os from 'os';\nimport path from 'path';\n\nimport camelCase from 'camelcase';\nimport decamelize from 'decamelize';\nimport { fs } from 'mz';\nimport parseJSON from 'parse-json';\n\nimport fileExists from './util/file-exists.js';\nimport { createLogger } from './util/logger.js';\nimport { UsageError, WebExtError } from './errors.js';\n\nconst log = createLogger(import.meta.url);\n\n// NOTE: this error message is used in an interpolated string (while the other two help\n// messages are being logged as is).\nexport const WARN_LEGACY_JS_EXT = [\n 'should be renamed to \".cjs\" or \".mjs\" file extension to ensure its format is not ambiguous.',\n 'Config files with the \".js\" file extension are deprecated and will not be loaded anymore',\n 'in a future web-ext major version.',\n].join(' ');\n\nexport const HELP_ERR_MODULE_FROM_ESM = [\n 'This config file belongs to a package.json file with \"type\" set to \"module\".',\n 'Change the file extension to \".cjs\" or rewrite it as an ES module and use the \".mjs\" file extension.',\n].join(' ');\n\nexport const HELP_ERR_IMPORTEXPORT_CJS = [\n 'This config file is defined as an ES module, but it belongs to either a project directory',\n 'with a package.json file with \"type\" set to \"commonjs\" or one without any package.json file.',\n 'Change the file extension to \".mjs\" to fix the config loading error.',\n].join(' ');\n\nconst ERR_IMPORT_FROM_CJS = 'Cannot use import statement outside a module';\nconst ERR_EXPORT_FROM_CJS = \"Unexpected token 'export'\";\nconst ERR_MODULE_FROM_ESM = 'module is not defined in ES module scope';\n\nexport function applyConfigToArgv({\n argv,\n argvFromCLI,\n configObject,\n options,\n configFileName,\n}) {\n let newArgv = { ...argv };\n\n for (const option of Object.keys(configObject)) {\n if (camelCase(option) !== option) {\n throw new UsageError(\n `The config option \"${option}\" must be ` +\n `specified in camel case: \"${camelCase(option)}\"`,\n );\n }\n\n // A config option cannot be a sub-command config\n // object if it is an array.\n if (\n !Array.isArray(configObject[option]) &&\n typeof options[option] === 'object' &&\n typeof configObject[option] === 'object'\n ) {\n // Descend into the nested configuration for a sub-command.\n newArgv = applyConfigToArgv({\n argv: newArgv,\n argvFromCLI,\n configObject: configObject[option],\n options: options[option],\n configFileName,\n });\n continue;\n }\n\n const decamelizedOptName = decamelize(option, { separator: '-' });\n\n if (typeof options[decamelizedOptName] !== 'object') {\n throw new UsageError(\n `The config file at ${configFileName} specified ` +\n `an unknown option: \"${option}\"`,\n );\n }\n if (options[decamelizedOptName].type === undefined) {\n // This means yargs option type wasn't not defined correctly\n throw new WebExtError(`Option: ${option} was defined without a type.`);\n }\n\n const expectedType =\n options[decamelizedOptName].type === 'count'\n ? 'number'\n : options[decamelizedOptName].type;\n\n const optionType = Array.isArray(configObject[option])\n ? 'array'\n : typeof configObject[option];\n\n if (optionType !== expectedType) {\n throw new UsageError(\n `The config file at ${configFileName} specified ` +\n `the type of \"${option}\" incorrectly as \"${optionType}\"` +\n ` (expected type \"${expectedType}\")`,\n );\n }\n\n let defaultValue;\n if (options[decamelizedOptName]) {\n if (options[decamelizedOptName].default !== undefined) {\n defaultValue = options[decamelizedOptName].default;\n } else if (expectedType === 'boolean') {\n defaultValue = false;\n }\n }\n\n // This is our best effort (without patching yargs) to detect\n // if a value was set on the CLI instead of in the config.\n // It looks for a default value and if the argv value is\n // different, it assumes that the value was configured on the CLI.\n\n const wasValueSetOnCLI =\n typeof argvFromCLI[option] !== 'undefined' &&\n argvFromCLI[option] !== defaultValue;\n if (wasValueSetOnCLI) {\n log.debug(\n `Favoring CLI: ${option}=${argvFromCLI[option]} over ` +\n `configuration: ${option}=${configObject[option]}`,\n );\n newArgv[option] = argvFromCLI[option];\n continue;\n }\n\n newArgv[option] = configObject[option];\n\n const coerce = options[decamelizedOptName].coerce;\n if (coerce) {\n log.debug(`Calling coerce() on configured value for ${option}`);\n newArgv[option] = coerce(newArgv[option]);\n }\n\n newArgv[decamelizedOptName] = newArgv[option];\n }\n return newArgv;\n}\n\nexport async function loadJSConfigFile(filePath) {\n const resolvedFilePath = path.resolve(filePath);\n log.debug(\n `Loading JS config file: \"${filePath}\" ` +\n `(resolved to \"${resolvedFilePath}\")`,\n );\n if (filePath.endsWith('.js')) {\n log.warn(`WARNING: config file ${filePath} ${WARN_LEGACY_JS_EXT}`);\n }\n let configObject;\n try {\n const nonce = `${Date.now()}-${Math.random()}`;\n let configModule;\n if (resolvedFilePath.endsWith('package.json')) {\n configModule = parseJSON(\n await fs.readFile(resolvedFilePath, { encoding: 'utf-8' }),\n );\n } else {\n configModule = await import(`file://${resolvedFilePath}?nonce=${nonce}`);\n }\n\n if (configModule.default) {\n const { default: configDefault, ...esmConfigMod } = configModule;\n // ES modules may expose both a default and named exports and so\n // we merge the named exports on top of what may have been set in\n // the default export.\n configObject = { ...configDefault, ...esmConfigMod };\n } else {\n configObject = { ...configModule };\n }\n } catch (error) {\n log.debug('Handling error:', error);\n let errorMessage = error.message;\n if (error.message.startsWith(ERR_MODULE_FROM_ESM)) {\n errorMessage = HELP_ERR_MODULE_FROM_ESM;\n } else if (\n [ERR_IMPORT_FROM_CJS, ERR_EXPORT_FROM_CJS].includes(error.message)\n ) {\n errorMessage = HELP_ERR_IMPORTEXPORT_CJS;\n }\n throw new UsageError(\n `Cannot read config file: ${resolvedFilePath}\\n` +\n `Error: ${errorMessage}`,\n );\n }\n if (filePath.endsWith('package.json')) {\n log.debug('Looking for webExt key inside package.json file');\n configObject = configObject.webExt || {};\n }\n if (Object.keys(configObject).length === 0) {\n log.debug(\n `Config file ${resolvedFilePath} did not define any options. ` +\n 'Did you set module.exports = {...}?',\n );\n }\n return configObject;\n}\n\nexport async function discoverConfigFiles({ getHomeDir = os.homedir } = {}) {\n const magicConfigName = 'web-ext-config';\n\n // Config files will be loaded in this order.\n const possibleConfigs = [\n // Look for a magic hidden config (preceded by dot) in home dir.\n path.join(getHomeDir(), `.${magicConfigName}.mjs`),\n path.join(getHomeDir(), `.${magicConfigName}.cjs`),\n path.join(getHomeDir(), `.${magicConfigName}.js`),\n // Look for webExt key inside package.json file\n path.join(process.cwd(), 'package.json'),\n // Look for a magic config in the current working directory.\n path.join(process.cwd(), `${magicConfigName}.mjs`),\n path.join(process.cwd(), `${magicConfigName}.cjs`),\n path.join(process.cwd(), `${magicConfigName}.js`),\n // Look for a magic hidden config (preceded by dot) the current working directory.\n path.join(process.cwd(), `.${magicConfigName}.mjs`),\n path.join(process.cwd(), `.${magicConfigName}.cjs`),\n path.join(process.cwd(), `.${magicConfigName}.js`),\n ];\n\n const configs = await Promise.all(\n possibleConfigs.map(async (fileName) => {\n const resolvedFileName = path.resolve(fileName);\n if (await fileExists(resolvedFileName)) {\n return resolvedFileName;\n } else {\n log.debug(\n `Discovered config \"${resolvedFileName}\" does not ` +\n 'exist or is not readable',\n );\n return undefined;\n }\n }),\n );\n\n const existingConfigs = [];\n configs.forEach((f) => {\n if (typeof f === 'string') {\n existingConfigs.push(f);\n }\n });\n return existingConfigs;\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"config.js","names":["os","path","fs","camelCase","decamelize","parseJSON","fileExists","createLogger","UsageError","WebExtError","log","import","meta","url","WARN_LEGACY_JS_EXT","join","HELP_ERR_MODULE_FROM_ESM","HELP_ERR_IMPORTEXPORT_CJS","ERR_IMPORT_FROM_CJS","ERR_EXPORT_FROM_CJS","ERR_MODULE_FROM_ESM","applyConfigToArgv","argv","argvFromCLI","configObject","options","configFileName","newArgv","option","Object","keys","Array","isArray","decamelizedOptName","separator","type","undefined","expectedType","optionType","defaultValue","default","wasValueSetOnCLI","debug","coerce","loadJSConfigFile","filePath","resolvedFilePath","resolve","endsWith","warn","nonce","Date","now","Math","random","configModule","readFile","encoding","configDefault","esmConfigMod","error","errorMessage","message","startsWith","includes","webExt","length","discoverConfigFiles","getHomeDir","homedir","magicConfigName","possibleConfigs","process","cwd","configs","Promise","all","map","fileName","resolvedFileName","existingConfigs","forEach","f","push"],"sources":["../src/config.js"],"sourcesContent":["import os from 'os';\nimport path from 'path';\nimport fs from 'fs/promises';\n\nimport camelCase from 'camelcase';\nimport decamelize from 'decamelize';\nimport parseJSON from 'parse-json';\n\nimport fileExists from './util/file-exists.js';\nimport { createLogger } from './util/logger.js';\nimport { UsageError, WebExtError } from './errors.js';\n\nconst log = createLogger(import.meta.url);\n\n// NOTE: this error message is used in an interpolated string (while the other two help\n// messages are being logged as is).\nexport const WARN_LEGACY_JS_EXT = [\n 'should be renamed to \".cjs\" or \".mjs\" file extension to ensure its format is not ambiguous.',\n 'Config files with the \".js\" file extension are deprecated and will not be loaded anymore',\n 'in a future web-ext major version.',\n].join(' ');\n\nexport const HELP_ERR_MODULE_FROM_ESM = [\n 'This config file belongs to a package.json file with \"type\" set to \"module\".',\n 'Change the file extension to \".cjs\" or rewrite it as an ES module and use the \".mjs\" file extension.',\n].join(' ');\n\nexport const HELP_ERR_IMPORTEXPORT_CJS = [\n 'This config file is defined as an ES module, but it belongs to either a project directory',\n 'with a package.json file with \"type\" set to \"commonjs\" or one without any package.json file.',\n 'Change the file extension to \".mjs\" to fix the config loading error.',\n].join(' ');\n\nconst ERR_IMPORT_FROM_CJS = 'Cannot use import statement outside a module';\nconst ERR_EXPORT_FROM_CJS = \"Unexpected token 'export'\";\nconst ERR_MODULE_FROM_ESM = 'module is not defined in ES module scope';\n\nexport function applyConfigToArgv({\n argv,\n argvFromCLI,\n configObject,\n options,\n configFileName,\n}) {\n let newArgv = { ...argv };\n\n for (const option of Object.keys(configObject)) {\n if (camelCase(option) !== option) {\n throw new UsageError(\n `The config option \"${option}\" must be ` +\n `specified in camel case: \"${camelCase(option)}\"`,\n );\n }\n\n // A config option cannot be a sub-command config\n // object if it is an array.\n if (\n !Array.isArray(configObject[option]) &&\n typeof options[option] === 'object' &&\n typeof configObject[option] === 'object'\n ) {\n // Descend into the nested configuration for a sub-command.\n newArgv = applyConfigToArgv({\n argv: newArgv,\n argvFromCLI,\n configObject: configObject[option],\n options: options[option],\n configFileName,\n });\n continue;\n }\n\n const decamelizedOptName = decamelize(option, { separator: '-' });\n\n if (typeof options[decamelizedOptName] !== 'object') {\n throw new UsageError(\n `The config file at ${configFileName} specified ` +\n `an unknown option: \"${option}\"`,\n );\n }\n if (options[decamelizedOptName].type === undefined) {\n // This means yargs option type wasn't not defined correctly\n throw new WebExtError(`Option: ${option} was defined without a type.`);\n }\n\n const expectedType =\n options[decamelizedOptName].type === 'count'\n ? 'number'\n : options[decamelizedOptName].type;\n\n const optionType = Array.isArray(configObject[option])\n ? 'array'\n : typeof configObject[option];\n\n if (optionType !== expectedType) {\n throw new UsageError(\n `The config file at ${configFileName} specified ` +\n `the type of \"${option}\" incorrectly as \"${optionType}\"` +\n ` (expected type \"${expectedType}\")`,\n );\n }\n\n let defaultValue;\n if (options[decamelizedOptName]) {\n if (options[decamelizedOptName].default !== undefined) {\n defaultValue = options[decamelizedOptName].default;\n } else if (expectedType === 'boolean') {\n defaultValue = false;\n }\n }\n\n // This is our best effort (without patching yargs) to detect\n // if a value was set on the CLI instead of in the config.\n // It looks for a default value and if the argv value is\n // different, it assumes that the value was configured on the CLI.\n\n const wasValueSetOnCLI =\n typeof argvFromCLI[option] !== 'undefined' &&\n argvFromCLI[option] !== defaultValue;\n if (wasValueSetOnCLI) {\n log.debug(\n `Favoring CLI: ${option}=${argvFromCLI[option]} over ` +\n `configuration: ${option}=${configObject[option]}`,\n );\n newArgv[option] = argvFromCLI[option];\n continue;\n }\n\n newArgv[option] = configObject[option];\n\n const coerce = options[decamelizedOptName].coerce;\n if (coerce) {\n log.debug(`Calling coerce() on configured value for ${option}`);\n newArgv[option] = coerce(newArgv[option]);\n }\n\n newArgv[decamelizedOptName] = newArgv[option];\n }\n return newArgv;\n}\n\nexport async function loadJSConfigFile(filePath) {\n const resolvedFilePath = path.resolve(filePath);\n log.debug(\n `Loading JS config file: \"${filePath}\" ` +\n `(resolved to \"${resolvedFilePath}\")`,\n );\n if (filePath.endsWith('.js')) {\n log.warn(`WARNING: config file ${filePath} ${WARN_LEGACY_JS_EXT}`);\n }\n let configObject;\n try {\n const nonce = `${Date.now()}-${Math.random()}`;\n let configModule;\n if (resolvedFilePath.endsWith('package.json')) {\n configModule = parseJSON(\n await fs.readFile(resolvedFilePath, { encoding: 'utf-8' }),\n );\n } else {\n configModule = await import(`file://${resolvedFilePath}?nonce=${nonce}`);\n }\n\n if (configModule.default) {\n const { default: configDefault, ...esmConfigMod } = configModule;\n // ES modules may expose both a default and named exports and so\n // we merge the named exports on top of what may have been set in\n // the default export.\n configObject = { ...configDefault, ...esmConfigMod };\n } else {\n configObject = { ...configModule };\n }\n } catch (error) {\n log.debug('Handling error:', error);\n let errorMessage = error.message;\n if (error.message.startsWith(ERR_MODULE_FROM_ESM)) {\n errorMessage = HELP_ERR_MODULE_FROM_ESM;\n } else if (\n [ERR_IMPORT_FROM_CJS, ERR_EXPORT_FROM_CJS].includes(error.message)\n ) {\n errorMessage = HELP_ERR_IMPORTEXPORT_CJS;\n }\n throw new UsageError(\n `Cannot read config file: ${resolvedFilePath}\\n` +\n `Error: ${errorMessage}`,\n );\n }\n if (filePath.endsWith('package.json')) {\n log.debug('Looking for webExt key inside package.json file');\n configObject = configObject.webExt || {};\n }\n if (Object.keys(configObject).length === 0) {\n log.debug(\n `Config file ${resolvedFilePath} did not define any options. ` +\n 'Did you set module.exports = {...}?',\n );\n }\n return configObject;\n}\n\nexport async function discoverConfigFiles({ getHomeDir = os.homedir } = {}) {\n const magicConfigName = 'web-ext-config';\n\n // Config files will be loaded in this order.\n const possibleConfigs = [\n // Look for a magic hidden config (preceded by dot) in home dir.\n path.join(getHomeDir(), `.${magicConfigName}.mjs`),\n path.join(getHomeDir(), `.${magicConfigName}.cjs`),\n path.join(getHomeDir(), `.${magicConfigName}.js`),\n // Look for webExt key inside package.json file\n path.join(process.cwd(), 'package.json'),\n // Look for a magic config in the current working directory.\n path.join(process.cwd(), `${magicConfigName}.mjs`),\n path.join(process.cwd(), `${magicConfigName}.cjs`),\n path.join(process.cwd(), `${magicConfigName}.js`),\n // Look for a magic hidden config (preceded by dot) the current working directory.\n path.join(process.cwd(), `.${magicConfigName}.mjs`),\n path.join(process.cwd(), `.${magicConfigName}.cjs`),\n path.join(process.cwd(), `.${magicConfigName}.js`),\n ];\n\n const configs = await Promise.all(\n possibleConfigs.map(async (fileName) => {\n const resolvedFileName = path.resolve(fileName);\n if (await fileExists(resolvedFileName)) {\n return resolvedFileName;\n } else {\n log.debug(\n `Discovered config \"${resolvedFileName}\" does not ` +\n 'exist or is not readable',\n );\n return undefined;\n }\n }),\n );\n\n const existingConfigs = [];\n configs.forEach((f) => {\n if (typeof f === 'string') {\n existingConfigs.push(f);\n }\n });\n return existingConfigs;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -3,9 +3,8 @@
3
3
  * in a Chromium-based browser instance.
4
4
  */
5
5
 
6
+ import fs from 'fs/promises';
6
7
  import path from 'path';
7
- import fs from 'fs-extra';
8
- import { mkdirp as asyncMkdirp } from 'mkdirp';
9
8
  import { Launcher as ChromeLauncher, launch as defaultChromiumLaunch } from 'chrome-launcher';
10
9
  import WebSocket, { WebSocketServer } from 'ws';
11
10
  import { createLogger } from '../util/logger.js';
@@ -150,9 +149,13 @@ export class ChromiumExtensionRunner {
150
149
  const tmpDirPath = tmpDir.path();
151
150
  if (userDataDir && profileDirName) {
152
151
  // copy profile dir to this temp user data dir.
153
- await fs.copy(path.join(userDataDir, profileDirName), path.join(tmpDirPath, profileDirName));
152
+ await fs.cp(path.join(userDataDir, profileDirName), path.join(tmpDirPath, profileDirName), {
153
+ recursive: true
154
+ });
154
155
  } else if (userDataDir) {
155
- await fs.copy(userDataDir, tmpDirPath);
156
+ await fs.cp(userDataDir, tmpDirPath, {
157
+ recursive: true
158
+ });
156
159
  }
157
160
  userDataDir = tmpDirPath;
158
161
  }
@@ -220,7 +223,9 @@ export class ChromiumExtensionRunner {
220
223
  this.registerCleanup(() => tmpDir.remove());
221
224
  const extPath = path.join(tmpDir.path(), `reload-manager-extension-${Date.now()}`);
222
225
  log.debug(`Creating reload-manager-extension in ${extPath}`);
223
- await asyncMkdirp(extPath);
226
+ await fs.mkdir(extPath, {
227
+ recursive: true
228
+ });
224
229
  await fs.writeFile(path.join(extPath, 'manifest.json'), JSON.stringify({
225
230
  manifest_version: 2,
226
231
  name: 'web-ext Reload Manager Extension',
@@ -1 +1 @@
1
- {"version":3,"file":"chromium.js","names":["path","fs","mkdirp","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","cleanupCallbacks","params","chromiumInstance","chromiumLaunch","reloadManagerExtension","wss","exiting","_promiseSetupDone","constructor","Set","getName","run","setupInstance","isUserDataDir","dirPath","localStatePath","join","defaultPath","isProfileDir","securePreferencesPath","getProfilePaths","chromiumProfile","userDataDir","profileDirName","isProfileDirAndNotUserData","dir","base","parse","Promise","resolve","server","port","host","clientTracking","on","socket","err","debug","createReloadManagerExtension","extensions","concat","map","sourceDir","chromiumBinary","chromeFlags","push","args","keepProfileChanges","Error","tmpDir","create","tmpDirPath","copy","startingUrl","startUrl","startingUrls","Array","isArray","shift","enableExtensions","chromePath","ignoreDefaultFlags","process","once","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":["/**\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 { mkdirp as 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 isDirectory from '../util/is-directory.js';\nimport fileExists from '../util/file-exists.js';\n\nconst log = createLogger(import.meta.url);\n\nconst EXCLUDED_CHROME_FLAGS = ['--disable-extensions', '--mute-audio'];\n\nexport const DEFAULT_CHROME_FLAGS = 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;\n params;\n chromiumInstance;\n chromiumLaunch;\n reloadManagerExtension;\n wss;\n exiting;\n _promiseSetupDone;\n\n constructor(params) {\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() {\n return 'Chromium';\n }\n\n async run() {\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) {\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) {\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) {\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() {\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) {\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() {\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 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() {\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, // eslint-disable-line no-unused-vars\n ) {\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) {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Chromium instance.\n */\n async exit() {\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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","ignoreList":[]}
1
+ {"version":3,"file":"chromium.js","names":["fs","path","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","cleanupCallbacks","params","chromiumInstance","chromiumLaunch","reloadManagerExtension","wss","exiting","_promiseSetupDone","constructor","Set","getName","run","setupInstance","isUserDataDir","dirPath","localStatePath","join","defaultPath","isProfileDir","securePreferencesPath","getProfilePaths","chromiumProfile","userDataDir","profileDirName","isProfileDirAndNotUserData","dir","base","parse","Promise","resolve","server","port","host","clientTracking","on","socket","err","debug","createReloadManagerExtension","extensions","concat","map","sourceDir","chromiumBinary","chromeFlags","push","args","keepProfileChanges","Error","tmpDir","create","tmpDirPath","cp","recursive","startingUrl","startUrl","startingUrls","Array","isArray","shift","enableExtensions","chromePath","ignoreDefaultFlags","process","once","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","mkdir","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":["/**\n * This module provide an ExtensionRunner subclass that manage an extension executed\n * in a Chromium-based browser instance.\n */\n\nimport fs from 'fs/promises';\nimport path from 'path';\n\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 isDirectory from '../util/is-directory.js';\nimport fileExists from '../util/file-exists.js';\n\nconst log = createLogger(import.meta.url);\n\nconst EXCLUDED_CHROME_FLAGS = ['--disable-extensions', '--mute-audio'];\n\nexport const DEFAULT_CHROME_FLAGS = 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;\n params;\n chromiumInstance;\n chromiumLaunch;\n reloadManagerExtension;\n wss;\n exiting;\n _promiseSetupDone;\n\n constructor(params) {\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() {\n return 'Chromium';\n }\n\n async run() {\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) {\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) {\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) {\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() {\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.cp(\n path.join(userDataDir, profileDirName),\n path.join(tmpDirPath, profileDirName),\n { recursive: true },\n );\n } else if (userDataDir) {\n await fs.cp(userDataDir, tmpDirPath, { recursive: true });\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) {\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() {\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 fs.mkdir(extPath, { recursive: true });\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 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() {\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, // eslint-disable-line no-unused-vars\n ) {\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) {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Chromium instance.\n */\n async exit() {\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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","ignoreList":[]}
@@ -418,7 +418,7 @@ export class FirefoxAndroidExtensionRunner {
418
418
  log.debug(`RDP Socket File selected: ${this.selectedRDPSocketFile}`);
419
419
  const tcpPort = await findFreeTcpPort();
420
420
 
421
- // Log the choosen tcp port at info level (useful to the user to be able
421
+ // Log the chosen tcp port at info level (useful to the user to be able
422
422
  // to connect the Firefox DevTools to the Firefox for Android instance).
423
423
  log.info(`You can connect to this Android device on TCP port ${tcpPort}`);
424
424
  const forwardSocketSpec = this.selectedRDPSocketFile.startsWith('@') ? `localabstract:${this.selectedRDPSocketFile.substr(1)}` : `localfilesystem:${this.selectedRDPSocketFile}`;
@@ -1 +1 @@
1
- {"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","MultiExtensionsReloadError","UsageError","WebExtError","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","params","adbUtils","exiting","selectedAdbDevice","selectedFirefoxApk","selectedArtifactsDir","selectedRDPSocketFile","selectedTCPPort","cleanupCallbacks","adbExtensionsPathBySourceDir","reloadableExtensions","remoteFirefox","constructor","Set","Map","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","reloadAddon","error","registerCleanup","fn","add","exit","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","filteredPackages","line","pkgsList","amForceStopAPK","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","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/**\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 {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport { findFreeTcpPort } from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\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\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 = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime = 3 * 60 * 1000;\n\n params;\n adbUtils;\n exiting;\n selectedAdbDevice;\n selectedFirefoxApk;\n selectedArtifactsDir;\n selectedRDPSocketFile;\n selectedTCPPort;\n cleanupCallbacks;\n adbExtensionsPathBySourceDir;\n reloadableExtensions;\n remoteFirefox;\n\n constructor(params) {\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() {\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.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() {\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() {\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(extensionSourceDir) {\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) {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit() {\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() {\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 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 =\n await adbUtils.getOrCreateArtifactsDir(selectedAdbDevice);\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) {\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) => {\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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","ignoreList":[]}
1
+ {"version":3,"file":"firefox-android.js","names":["path","readline","withTempDir","DefaultADBUtils","MultiExtensionsReloadError","UsageError","WebExtError","findFreeTcpPort","createLogger","isTTY","setRawMode","log","import","meta","url","ignoredParams","profilePath","keepProfileChanges","browserConsole","preInstall","startUrl","args","DEFAULT_ADB_HOST","getIgnoredParamsWarningsMessage","optionName","FirefoxAndroidExtensionRunner","unixSocketDiscoveryRetryInterval","unixSocketDiscoveryMaxTime","params","adbUtils","exiting","selectedAdbDevice","selectedFirefoxApk","selectedArtifactsDir","selectedRDPSocketFile","selectedTCPPort","cleanupCallbacks","adbExtensionsPathBySourceDir","reloadableExtensions","remoteFirefox","constructor","Set","Map","printIgnoredParamsWarnings","run","adbBin","adbHost","adbPort","ADBUtils","adbDevicesDiscoveryAndSelect","apkPackagesDiscoveryAndSelect","adbForceStopSelectedPackage","adbPrepareProfileDir","Promise","all","adbStartSelectedPackage","buildAndPushExtensions","adbDiscoveryAndForwardRDPUnixSocket","rdpInstallExtensions","getName","reloadAllExtensions","runnerName","reloadErrors","sourceDir","extensions","res","reloadExtensionBySourceDir","reloadError","Error","set","size","extensionSourceDir","addonId","get","buildAndPushExtension","reloadAddon","error","registerCleanup","fn","add","exit","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","filteredPackages","line","pkgsList","amForceStopAPK","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","discoverRDPUnixSocket","maxDiscoveryTime","retryInterval","removeListener","tcpPort","forwardSocketSpec","startsWith","substr","setupForward","firefoxClient","port","client","extension","installTemporaryAddon","then","installResult","addon","id"],"sources":["../../src/extension-runners/firefox-android.js"],"sourcesContent":["/**\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 {\n MultiExtensionsReloadError,\n UsageError,\n WebExtError,\n} from '../errors.js';\nimport { findFreeTcpPort } from '../firefox/remote.js';\nimport { createLogger } from '../util/logger.js';\nimport { isTTY, setRawMode } from '../util/stdin.js';\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\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 = 3 * 1000;\n // Wait for at most 3 minutes before giving up.\n static unixSocketDiscoveryMaxTime = 3 * 60 * 1000;\n\n params;\n adbUtils;\n exiting;\n selectedAdbDevice;\n selectedFirefoxApk;\n selectedArtifactsDir;\n selectedRDPSocketFile;\n selectedTCPPort;\n cleanupCallbacks;\n adbExtensionsPathBySourceDir;\n reloadableExtensions;\n remoteFirefox;\n\n constructor(params) {\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() {\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.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() {\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() {\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(extensionSourceDir) {\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) {\n this.cleanupCallbacks.add(fn);\n }\n\n /**\n * Exits the runner, by closing the managed Firefox instance.\n */\n async exit() {\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() {\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 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 =\n await adbUtils.getOrCreateArtifactsDir(selectedAdbDevice);\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) {\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 chosen 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) => {\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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","ignoreList":[]}