web-ext 8.7.1 → 8.9.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/run.js +2 -0
- package/lib/cmd/run.js.map +1 -1
- package/lib/extension-runners/chromium.js +344 -131
- package/lib/extension-runners/chromium.js.map +1 -1
- package/lib/util/submit-addon.js +15 -21
- package/lib/util/submit-addon.js.map +1 -1
- package/package.json +14 -15
package/lib/cmd/run.js
CHANGED
|
@@ -27,6 +27,7 @@ export default async function run({
|
|
|
27
27
|
noReload = false,
|
|
28
28
|
preInstall = false,
|
|
29
29
|
sourceDir,
|
|
30
|
+
verbose = false,
|
|
30
31
|
watchFile,
|
|
31
32
|
watchIgnored,
|
|
32
33
|
startUrl,
|
|
@@ -155,6 +156,7 @@ export default async function run({
|
|
|
155
156
|
if (target && target.includes('chromium')) {
|
|
156
157
|
const chromiumRunnerParams = {
|
|
157
158
|
...commonRunnerParams,
|
|
159
|
+
verbose,
|
|
158
160
|
chromiumBinary,
|
|
159
161
|
chromiumProfile
|
|
160
162
|
};
|
package/lib/cmd/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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":"AAAA,OAAOA,IAAI,MAAM,MAAM;AACvB,OAAOC,EAAE,MAAM,aAAa;AAC5B,OAAOC,MAAM,MAAM,IAAI;AAEvB,OAAOC,qBAAqB,MAAM,YAAY;AAC9C,SAASC,uBAAuB,IAAIC,2BAA2B,QAAQ,6BAA6B;AACpG,OAAO,KAAKC,iBAAiB,MAAM,qBAAqB;AACxD,SAASC,qBAAqB,IAAIC,oBAAoB,QAAQ,sBAAsB;AACpF,SAASC,YAAY,QAAQ,mBAAmB;AAChD,OAAOC,2BAA2B,MAAM,qBAAqB;AAC7D,SAASC,UAAU,QAAQ,cAAc;AACzC,SACEC,qBAAqB,EACrBC,qBAAqB,EACrBC,oBAAoB,IAAIC,2BAA2B,QAC9C,+BAA+B;AAEtC,MAAMC,GAAG,GAAGP,YAAY,CAACQ,MAAM,CAACC,IAAI,CAACC,GAAG,CAAC;;AAEzC;;AAEA,eAAe,eAAeC,GAAGA,CAC/B;EACEC,YAAY;EACZC,cAAc,GAAG,KAAK;EACtBC,QAAQ,GAAG,KAAK;EAChBC,IAAI;EACJC,OAAO;EACPC,cAAc;EACdC,sBAAsB;EACtBC,kBAAkB,GAAG,KAAK;EAC1BC,WAAW;EACXC,OAAO,GAAG,KAAK;EACfC,QAAQ,GAAG,KAAK;EAChBC,UAAU,GAAG,KAAK;EAClBC,SAAS;EACTC,SAAS;EACTC,YAAY;EACZC,QAAQ;EACRC,MAAM;EACNC,IAAI;EACJ;EACAC,MAAM;EACNC,OAAO;EACPC,OAAO;EACPC,SAAS;EACTC,mBAAmB;EACnBC,qBAAqB;EACrBC,UAAU;EACVC,mBAAmB;EACnB;EACAC,cAAc;EACdC;AACF,CAAC,EACD;EACEC,cAAc,GAAG9C,qBAAqB;EACtC+C,oBAAoB,GAAG7C,2BAA2B;EAClD8C,UAAU,GAAG7C,iBAAiB;EAC9B8C,aAAa,GAAG5C,oBAAoB;EACpC6C,cAAc,GAAGxC,qBAAqB;EACtCC,oBAAoB,GAAGC,2BAA2B;EAClDuC,oBAAoB,GAAG5C;AACzB,CAAC,GAAG,CAAC,CAAC,EACN;EACAuB,SAAS,GAAGjC,IAAI,CAACuD,OAAO,CAACtB,SAAS,CAAC;EACnCjB,GAAG,CAACwC,IAAI,CAAC,8BAA8BvB,SAAS,EAAE,CAAC;EACnD,IAAID,UAAU,EAAE;IACdhB,GAAG,CAACwC,IAAI,CACN,yDAAyD,GACvD,eACJ,CAAC;IACDzB,QAAQ,GAAG,IAAI;EACjB;EAEA,IACEG,SAAS,IAAI,IAAI,KAChB,CAACuB,KAAK,CAACC,OAAO,CAACxB,SAAS,CAAC,IACxB,CAACA,SAAS,CAACyB,KAAK,CAAEC,EAAE,IAAK,OAAOA,EAAE,KAAK,QAAQ,CAAC,CAAC,EACnD;IACA,MAAM,IAAIjD,UAAU,CAAC,2BAA2B,CAAC;EACnD;;EAEA;EACA;EACA,MAAMkD,WAAW,GAAGrC,IAAI;EACxB,MAAMsC,YAAY,GAAG,MAAMR,oBAAoB,CAACrB,SAAS,CAAC;EAE1D,MAAM8B,UAAU,GAAGrC,cAAc,IAAIsB,eAAe;EAEpD,IAAIrB,sBAAsB,EAAE;IAC1B,IAAI,CAACoC,UAAU,EAAE;MACf,MAAM,IAAIpD,UAAU,CAClB,uCAAuC,GACrC,yCACJ,CAAC;IACH;IACA,MAAMqD,KAAK,GAAG9D,MAAM,CAAC+D,UAAU,CAACF,UAAU,CAAC;IAC3C,IAAIC,KAAK,EAAE;MACThD,GAAG,CAACwC,IAAI,CAAC,qBAAqBO,UAAU,iBAAiB,CAAC;IAC5D,CAAC,MAAM;MACL/C,GAAG,CAACwC,IAAI,CAAC,mDAAmDO,UAAU,EAAE,CAAC;MACzE,MAAM9D,EAAE,CAACiE,KAAK,CAACH,UAAU,CAAC;IAC5B;EACF;EAEA,MAAMI,OAAO,GAAG,EAAE;EAElB,MAAMC,kBAAkB,GAAG;IACzB;IACAC,UAAU,EAAE,CAAC;MAAEpC,SAAS;MAAE6B;IAAa,CAAC,CAAC;IACzClC,kBAAkB;IAClBQ,QAAQ;IACRE,IAAI;IACJY;EACF,CAAC;EAED,IAAI,CAACb,MAAM,IAAIA,MAAM,CAACiC,MAAM,KAAK,CAAC,IAAIjC,MAAM,CAACkC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;IACxE,MAAMC,0BAA0B,GAAG;MACjC,GAAGJ,kBAAkB;MAErB;MACAK,aAAa,EAAEhD,OAAO;MACtBiD,WAAW,EAAEhD,cAAc;MAC3BmC,WAAW;MACXvC,cAAc;MACdC,QAAQ;MACRS,UAAU;MAEV;MACAmB,UAAU;MACVC;IACF,CAAC;IAED,MAAMuB,oBAAoB,GAAG,MAAM/D,qBAAqB,CAAC;MACvDyB,MAAM,EAAE,iBAAiB;MACzBuC,MAAM,EAAEJ;IACV,CAAC,CAAC;IACFL,OAAO,CAACU,IAAI,CAACF,oBAAoB,CAAC;EACpC;EAEA,IAAItC,MAAM,IAAIA,MAAM,CAACkC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;IAChD,MAAMO,0BAA0B,GAAG;MACjC,GAAGV,kBAAkB;MAErB;MACAM,WAAW,EAAEhD,cAAc;MAC3BmC,WAAW;MACXvC,cAAc;MACdU,UAAU;MACVa,UAAU;MACVC,mBAAmB;MACnBJ,SAAS;MACTF,OAAO;MACPC,OAAO;MACPF,MAAM;MACNI,mBAAmB;MACnBC,qBAAqB;MAErB;MACAO,UAAU;MACVC,aAAa;MACbF,oBAAoB,EAAE7C,2BAA2B;MACjD0E,cAAc,EAAEA,CAACC,kBAAkB,EAAEC,eAAe,KAAK;QACvD,OAAOhC,cAAc,CACnB;UACEhB,SAAS,EAAE+C,kBAAkB;UAC7BnD,WAAW;UACXqD,QAAQ,EAAE,KAAK;UACf;UACA;UACA7D,YAAY,EAAE4D;QAChB,CAAC,EACD;UACE;UACAE,gBAAgB,EAAE;QACpB,CACF,CAAC;MACH;IACF,CAAC;IAED,MAAMC,oBAAoB,GAAG,MAAMxE,qBAAqB,CAAC;MACvDyB,MAAM,EAAE,iBAAiB;MACzBuC,MAAM,EAAEE;IACV,CAAC,CAAC;IACFX,OAAO,CAACU,IAAI,CAACO,oBAAoB,CAAC;EACpC;EAEA,IAAI/C,MAAM,IAAIA,MAAM,CAACkC,QAAQ,CAAC,UAAU,CAAC,EAAE;IACzC,MAAMc,oBAAoB,GAAG;MAC3B,GAAGjB,kBAAkB;MACrBrB,cAAc;MACdC;IACF,CAAC;IAED,MAAMsC,cAAc,GAAG,MAAM1E,qBAAqB,CAAC;MACjDyB,MAAM,EAAE,UAAU;MAClBuC,MAAM,EAAES;IACV,CAAC,CAAC;IACFlB,OAAO,CAACU,IAAI,CAACS,cAAc,CAAC;EAC9B;EAEA,MAAMC,eAAe,GAAG,IAAIzE,oBAAoB,CAAC;IAC/CoC,oBAAoB;IACpBiB;EACF,CAAC,CAAC;EAEF,MAAMoB,eAAe,CAACnE,GAAG,CAAC,CAAC;EAE3B,IAAIW,QAAQ,EAAE;IACZf,GAAG,CAACwC,IAAI,CAAC,iDAAiD,CAAC;EAC7D,CAAC,MAAM;IACLxC,GAAG,CAACwC,IAAI,CAAC,sDAAsD,CAAC;IAEhEH,cAAc,CAAC;MACbkC,eAAe;MACftD,SAAS;MACTC,SAAS;MACTC,YAAY;MACZd,YAAY;MACZQ,WAAW;MACXC;IACF,CAAC,CAAC;EACJ;EAEA,OAAOyD,eAAe;AACxB","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","verbose","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 verbose = false,\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 verbose,\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,3 +1,12 @@
|
|
|
1
|
+
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
|
|
2
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
|
|
6
|
+
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
7
|
+
function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
|
|
8
|
+
function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
|
|
9
|
+
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
1
10
|
/**
|
|
2
11
|
* This module provide an ExtensionRunner subclass that manage an extension executed
|
|
3
12
|
* in a Chromium-based browser instance.
|
|
@@ -6,7 +15,6 @@
|
|
|
6
15
|
import fs from 'fs/promises';
|
|
7
16
|
import path from 'path';
|
|
8
17
|
import { Launcher as ChromeLauncher, launch as defaultChromiumLaunch } from 'chrome-launcher';
|
|
9
|
-
import WebSocket, { WebSocketServer } from 'ws';
|
|
10
18
|
import { createLogger } from '../util/logger.js';
|
|
11
19
|
import { TempDir } from '../util/temp-dir.js';
|
|
12
20
|
import isDirectory from '../util/is-directory.js';
|
|
@@ -15,16 +23,148 @@ const log = createLogger(import.meta.url);
|
|
|
15
23
|
const EXCLUDED_CHROME_FLAGS = ['--disable-extensions', '--mute-audio', '--disable-component-update'];
|
|
16
24
|
export const DEFAULT_CHROME_FLAGS = ChromeLauncher.defaultFlags().filter(flag => !EXCLUDED_CHROME_FLAGS.includes(flag));
|
|
17
25
|
|
|
26
|
+
// This is a client for the Chrome Devtools protocol. The methods and results
|
|
27
|
+
// are documented at https://chromedevtools.github.io/devtools-protocol/tot/
|
|
28
|
+
var _receivedData = /*#__PURE__*/new WeakMap();
|
|
29
|
+
var _isProcessingMessage = /*#__PURE__*/new WeakMap();
|
|
30
|
+
var _lastId = /*#__PURE__*/new WeakMap();
|
|
31
|
+
var _deferredResponses = /*#__PURE__*/new WeakMap();
|
|
32
|
+
var _disconnected = /*#__PURE__*/new WeakMap();
|
|
33
|
+
var _disconnectedPromise = /*#__PURE__*/new WeakMap();
|
|
34
|
+
var _resolveDisconnectedPromise = /*#__PURE__*/new WeakMap();
|
|
35
|
+
var _ChromeDevtoolsProtocolClient_brand = /*#__PURE__*/new WeakSet();
|
|
36
|
+
class ChromeDevtoolsProtocolClient {
|
|
37
|
+
constructor(chromiumInstance) {
|
|
38
|
+
_classPrivateMethodInitSpec(this, _ChromeDevtoolsProtocolClient_brand);
|
|
39
|
+
_classPrivateFieldInitSpec(this, _receivedData, '');
|
|
40
|
+
_classPrivateFieldInitSpec(this, _isProcessingMessage, false);
|
|
41
|
+
_classPrivateFieldInitSpec(this, _lastId, 0);
|
|
42
|
+
_classPrivateFieldInitSpec(this, _deferredResponses, new Map());
|
|
43
|
+
_classPrivateFieldInitSpec(this, _disconnected, false);
|
|
44
|
+
_classPrivateFieldInitSpec(this, _disconnectedPromise, void 0);
|
|
45
|
+
_classPrivateFieldInitSpec(this, _resolveDisconnectedPromise, void 0);
|
|
46
|
+
// Print all exchanged CDP messages to ease debugging.
|
|
47
|
+
_defineProperty(this, "TEST_LOG_VERBOSE_CDP", process.env.TEST_LOG_VERBOSE_CDP);
|
|
48
|
+
// remoteDebuggingPipes is from chrome-launcher, see
|
|
49
|
+
// https://github.com/GoogleChrome/chrome-launcher/pull/347
|
|
50
|
+
const {
|
|
51
|
+
incoming,
|
|
52
|
+
outgoing
|
|
53
|
+
} = chromiumInstance.remoteDebuggingPipes;
|
|
54
|
+
_classPrivateFieldSet(_disconnectedPromise, this, new Promise(resolve => {
|
|
55
|
+
_classPrivateFieldSet(_resolveDisconnectedPromise, this, resolve);
|
|
56
|
+
}));
|
|
57
|
+
if (incoming.closed) {
|
|
58
|
+
// Strange. Did Chrome fail to start, or exit on startup?
|
|
59
|
+
log.warn('CDP already disconnected at initialization');
|
|
60
|
+
_assertClassBrand(_ChromeDevtoolsProtocolClient_brand, this, _finalizeDisconnect).call(this);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
incoming.on('data', data => {
|
|
64
|
+
_classPrivateFieldSet(_receivedData, this, _classPrivateFieldGet(_receivedData, this) + data);
|
|
65
|
+
_assertClassBrand(_ChromeDevtoolsProtocolClient_brand, this, _processNextMessage).call(this);
|
|
66
|
+
});
|
|
67
|
+
incoming.on('error', error => {
|
|
68
|
+
log.error(error);
|
|
69
|
+
_assertClassBrand(_ChromeDevtoolsProtocolClient_brand, this, _finalizeDisconnect).call(this);
|
|
70
|
+
});
|
|
71
|
+
incoming.on('close', () => _assertClassBrand(_ChromeDevtoolsProtocolClient_brand, this, _finalizeDisconnect).call(this));
|
|
72
|
+
this.outgoingPipe = outgoing;
|
|
73
|
+
}
|
|
74
|
+
waitUntilDisconnected() {
|
|
75
|
+
return _classPrivateFieldGet(_disconnectedPromise, this);
|
|
76
|
+
}
|
|
77
|
+
async sendCommand(method, params, sessionId = undefined) {
|
|
78
|
+
var _this$lastId;
|
|
79
|
+
if (_classPrivateFieldGet(_disconnected, this)) {
|
|
80
|
+
throw new Error(`CDP disconnected, cannot send: command ${method}`);
|
|
81
|
+
}
|
|
82
|
+
const message = {
|
|
83
|
+
id: _classPrivateFieldSet(_lastId, this, (_this$lastId = _classPrivateFieldGet(_lastId, this), ++_this$lastId)),
|
|
84
|
+
method,
|
|
85
|
+
params,
|
|
86
|
+
sessionId
|
|
87
|
+
};
|
|
88
|
+
const rawMessage = `${JSON.stringify(message)}\x00`;
|
|
89
|
+
if (this.TEST_LOG_VERBOSE_CDP) {
|
|
90
|
+
process.stderr.write(`[CDP] [SEND] ${rawMessage}\n`);
|
|
91
|
+
}
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
// CDP will always send a response.
|
|
94
|
+
_classPrivateFieldGet(_deferredResponses, this).set(message.id, {
|
|
95
|
+
method,
|
|
96
|
+
resolve,
|
|
97
|
+
reject
|
|
98
|
+
});
|
|
99
|
+
this.outgoingPipe.write(rawMessage);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
18
104
|
/**
|
|
19
105
|
* Implements an IExtensionRunner which manages a Chromium instance.
|
|
20
106
|
*/
|
|
107
|
+
function _processNextMessage() {
|
|
108
|
+
if (_classPrivateFieldGet(_isProcessingMessage, this)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
_classPrivateFieldSet(_isProcessingMessage, this, true);
|
|
112
|
+
let end = _classPrivateFieldGet(_receivedData, this).indexOf('\x00');
|
|
113
|
+
while (end !== -1) {
|
|
114
|
+
const rawMessage = _classPrivateFieldGet(_receivedData, this).slice(0, end);
|
|
115
|
+
_classPrivateFieldSet(_receivedData, this, _classPrivateFieldGet(_receivedData, this).slice(end + 1)); // +1 skips \x00.
|
|
116
|
+
try {
|
|
117
|
+
if (this.TEST_LOG_VERBOSE_CDP) {
|
|
118
|
+
process.stderr.write(`[CDP] [RECV] ${rawMessage}\n`);
|
|
119
|
+
}
|
|
120
|
+
const {
|
|
121
|
+
id,
|
|
122
|
+
error,
|
|
123
|
+
result
|
|
124
|
+
} = JSON.parse(rawMessage);
|
|
125
|
+
const deferredResponse = _classPrivateFieldGet(_deferredResponses, this).get(id);
|
|
126
|
+
if (deferredResponse) {
|
|
127
|
+
_classPrivateFieldGet(_deferredResponses, this).delete(id);
|
|
128
|
+
if (error) {
|
|
129
|
+
const err = new Error(error.message || 'Unexpected CDP response');
|
|
130
|
+
deferredResponse.reject(err);
|
|
131
|
+
} else {
|
|
132
|
+
deferredResponse.resolve(result);
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
// Dropping events and non-response messages since we don't need it.
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {
|
|
138
|
+
log.error(e);
|
|
139
|
+
}
|
|
140
|
+
end = _classPrivateFieldGet(_receivedData, this).indexOf('\x00');
|
|
141
|
+
}
|
|
142
|
+
_classPrivateFieldSet(_isProcessingMessage, this, false);
|
|
143
|
+
if (_classPrivateFieldGet(_disconnected, this)) {
|
|
144
|
+
for (const {
|
|
145
|
+
method,
|
|
146
|
+
reject
|
|
147
|
+
} of _classPrivateFieldGet(_deferredResponses, this).values()) {
|
|
148
|
+
reject(new Error(`CDP connection closed before response to ${method}`));
|
|
149
|
+
}
|
|
150
|
+
_classPrivateFieldGet(_deferredResponses, this).clear();
|
|
151
|
+
_classPrivateFieldGet(_resolveDisconnectedPromise, this).call(this);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function _finalizeDisconnect() {
|
|
155
|
+
if (!_classPrivateFieldGet(_disconnected, this)) {
|
|
156
|
+
_classPrivateFieldSet(_disconnected, this, true);
|
|
157
|
+
_assertClassBrand(_ChromeDevtoolsProtocolClient_brand, this, _processNextMessage).call(this);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
21
160
|
export class ChromiumExtensionRunner {
|
|
22
161
|
cleanupCallbacks;
|
|
23
162
|
params;
|
|
24
163
|
chromiumInstance;
|
|
25
164
|
chromiumLaunch;
|
|
26
|
-
|
|
27
|
-
|
|
165
|
+
// --load-extension is deprecated, but only supported in Chrome 126+, see:
|
|
166
|
+
// https://github.com/mozilla/web-ext/issues/3388#issuecomment-2906982117
|
|
167
|
+
forceUseDeprecatedLoadExtension;
|
|
28
168
|
exiting;
|
|
29
169
|
_promiseSetupDone;
|
|
30
170
|
constructor(params) {
|
|
@@ -33,6 +173,9 @@ export class ChromiumExtensionRunner {
|
|
|
33
173
|
} = params;
|
|
34
174
|
this.params = params;
|
|
35
175
|
this.chromiumLaunch = chromiumLaunch;
|
|
176
|
+
// We will try to use Extensions.loadUnpacked first (Chrome 126+), and if
|
|
177
|
+
// that does not work fall back to --load-extension.
|
|
178
|
+
this.forceUseDeprecatedLoadExtension = false;
|
|
36
179
|
this.cleanupCallbacks = new Set();
|
|
37
180
|
}
|
|
38
181
|
|
|
@@ -88,36 +231,16 @@ export class ChromiumExtensionRunner {
|
|
|
88
231
|
* Setup the Chromium Profile and run a Chromium instance.
|
|
89
232
|
*/
|
|
90
233
|
async setupInstance() {
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
{
|
|
97
|
-
port: 0,
|
|
98
|
-
host: '127.0.0.1',
|
|
99
|
-
clientTracking: true
|
|
100
|
-
},
|
|
101
|
-
// Wait the server to be listening (so that the extension
|
|
102
|
-
// runner can successfully retrieve server address and port).
|
|
103
|
-
() => resolve(server));
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// Prevent unhandled socket error (e.g. when chrome
|
|
107
|
-
// is exiting, See https://github.com/websockets/ws/issues/1256).
|
|
108
|
-
this.wss.on('connection', function (socket) {
|
|
109
|
-
socket.on('error', err => {
|
|
110
|
-
log.debug(`websocket connection error: ${err}`);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Create the extension that will manage the addon reloads
|
|
115
|
-
this.reloadManagerExtension = await this.createReloadManagerExtension();
|
|
234
|
+
// NOTE: This function may be called twice, if the user is using an old
|
|
235
|
+
// Chrome version (before Chrome 126), because then we have to add a
|
|
236
|
+
// command-line flag (--load-extension) to load the extension. For details,
|
|
237
|
+
// see:
|
|
238
|
+
// https://github.com/mozilla/web-ext/issues/3388#issuecomment-2906982117
|
|
116
239
|
|
|
117
240
|
// Start chrome pointing it to a given profile dir
|
|
118
|
-
const extensions =
|
|
241
|
+
const extensions = this.params.extensions.map(({
|
|
119
242
|
sourceDir
|
|
120
|
-
}) => sourceDir)
|
|
243
|
+
}) => sourceDir);
|
|
121
244
|
const {
|
|
122
245
|
chromiumBinary
|
|
123
246
|
} = this.params;
|
|
@@ -126,7 +249,12 @@ export class ChromiumExtensionRunner {
|
|
|
126
249
|
log.debug(`(chromiumBinary: ${chromiumBinary})`);
|
|
127
250
|
}
|
|
128
251
|
const chromeFlags = [...DEFAULT_CHROME_FLAGS];
|
|
129
|
-
chromeFlags.push(
|
|
252
|
+
chromeFlags.push('--remote-debugging-pipe');
|
|
253
|
+
if (!this.forceUseDeprecatedLoadExtension) {
|
|
254
|
+
chromeFlags.push('--enable-unsafe-extension-debugging');
|
|
255
|
+
} else {
|
|
256
|
+
chromeFlags.push(`--load-extension=${extensions.join(',')}`);
|
|
257
|
+
}
|
|
130
258
|
if (this.params.args) {
|
|
131
259
|
chromeFlags.push(...this.params.args);
|
|
132
260
|
}
|
|
@@ -169,109 +297,60 @@ export class ChromiumExtensionRunner {
|
|
|
169
297
|
chromeFlags.push(...startingUrls);
|
|
170
298
|
}
|
|
171
299
|
this.chromiumInstance = await this.chromiumLaunch({
|
|
172
|
-
enableExtensions: true,
|
|
173
300
|
chromePath: chromiumBinary,
|
|
174
301
|
chromeFlags,
|
|
175
302
|
startingUrl,
|
|
176
303
|
userDataDir,
|
|
304
|
+
logLevel: this.params.verbose ? 'verbose' : 'silent',
|
|
177
305
|
// Ignore default flags to keep the extension enabled.
|
|
178
306
|
ignoreDefaultFlags: true
|
|
179
307
|
});
|
|
308
|
+
this.cdp = new ChromeDevtoolsProtocolClient(this.chromiumInstance);
|
|
309
|
+
const initialChromiumInstance = this.chromiumInstance;
|
|
180
310
|
this.chromiumInstance.process.once('close', () => {
|
|
311
|
+
if (this.chromiumInstance !== initialChromiumInstance) {
|
|
312
|
+
// This happens when we restart Chrome to fall back to --load-extension.
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
181
315
|
this.chromiumInstance = null;
|
|
182
316
|
if (!this.exiting) {
|
|
183
317
|
log.info('Exiting on Chromium instance disconnected.');
|
|
184
318
|
this.exit();
|
|
185
319
|
}
|
|
186
320
|
});
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
cleanWebExtReloadComplete.call(client);
|
|
321
|
+
if (!this.forceUseDeprecatedLoadExtension) {
|
|
322
|
+
// Assume that the required Extensions.loadUnpacked CDP method is
|
|
323
|
+
// supported. If it is not, we will fall back to --load-extension.
|
|
324
|
+
let cdpSupportsExtensionsLoadUnpacked = true;
|
|
325
|
+
for (const sourceDir of extensions) {
|
|
326
|
+
try {
|
|
327
|
+
await this.cdp.sendCommand('Extensions.loadUnpacked', {
|
|
328
|
+
path: sourceDir
|
|
329
|
+
});
|
|
330
|
+
} catch (e) {
|
|
331
|
+
// Chrome 125- will emit the following message:
|
|
332
|
+
if (e.message === "'Extensions.loadUnpacked' wasn't found") {
|
|
333
|
+
cdpSupportsExtensionsLoadUnpacked = false;
|
|
334
|
+
break;
|
|
202
335
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
client.addEventListener('message', webExtReloadComplete);
|
|
209
|
-
client.addEventListener('close', cleanWebExtReloadComplete);
|
|
210
|
-
client.send(JSON.stringify(data));
|
|
211
|
-
} else {
|
|
212
|
-
clients.delete(client);
|
|
336
|
+
log.error(`Failed to load extension at ${sourceDir}: ${e.message}`);
|
|
337
|
+
// We do not have to throw - the extension can work again when
|
|
338
|
+
// auto-reload is used. But users may like a hard fail, and this is
|
|
339
|
+
// consistent with the firefox runner.
|
|
340
|
+
throw e;
|
|
213
341
|
}
|
|
214
342
|
}
|
|
215
|
-
if (
|
|
216
|
-
|
|
343
|
+
if (!cdpSupportsExtensionsLoadUnpacked) {
|
|
344
|
+
// Retry once, now with --load-extension.
|
|
345
|
+
log.warn('Cannot load extension via CDP, falling back to old method');
|
|
346
|
+
this.forceUseDeprecatedLoadExtension = true;
|
|
347
|
+
this.chromiumInstance = null;
|
|
348
|
+
await initialChromiumInstance.kill();
|
|
349
|
+
await this.cdp.waitUntilDisconnected();
|
|
350
|
+
this.cdp = null;
|
|
351
|
+
return this.setupInstance();
|
|
217
352
|
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
async createReloadManagerExtension() {
|
|
221
|
-
const tmpDir = new TempDir();
|
|
222
|
-
await tmpDir.create();
|
|
223
|
-
this.registerCleanup(() => tmpDir.remove());
|
|
224
|
-
const extPath = path.join(tmpDir.path(), `reload-manager-extension-${Date.now()}`);
|
|
225
|
-
log.debug(`Creating reload-manager-extension in ${extPath}`);
|
|
226
|
-
await fs.mkdir(extPath, {
|
|
227
|
-
recursive: true
|
|
228
|
-
});
|
|
229
|
-
await fs.writeFile(path.join(extPath, 'manifest.json'), JSON.stringify({
|
|
230
|
-
manifest_version: 2,
|
|
231
|
-
name: 'web-ext Reload Manager Extension',
|
|
232
|
-
version: '1.0',
|
|
233
|
-
permissions: ['management', 'tabs'],
|
|
234
|
-
background: {
|
|
235
|
-
scripts: ['bg.js']
|
|
236
|
-
}
|
|
237
|
-
}));
|
|
238
|
-
const wssInfo = this.wss.address();
|
|
239
|
-
const bgPage = `(function bgPage() {
|
|
240
|
-
async function getAllDevExtensions() {
|
|
241
|
-
const allExtensions = await new Promise(
|
|
242
|
-
r => chrome.management.getAll(r));
|
|
243
|
-
|
|
244
|
-
return allExtensions.filter((extension) => {
|
|
245
|
-
return extension.enabled &&
|
|
246
|
-
extension.installType === "development" &&
|
|
247
|
-
extension.id !== chrome.runtime.id;
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const setEnabled = (extensionId, value) =>
|
|
252
|
-
chrome.runtime.id == extensionId ?
|
|
253
|
-
new Promise.resolve() :
|
|
254
|
-
new Promise(r => chrome.management.setEnabled(extensionId, value, r));
|
|
255
|
-
|
|
256
|
-
async function reloadExtension(extensionId) {
|
|
257
|
-
await setEnabled(extensionId, false);
|
|
258
|
-
await setEnabled(extensionId, true);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const ws = new window.WebSocket(
|
|
262
|
-
"ws://${wssInfo.address}:${wssInfo.port}");
|
|
263
|
-
|
|
264
|
-
ws.onmessage = async (evt) => {
|
|
265
|
-
const msg = JSON.parse(evt.data);
|
|
266
|
-
if (msg.type === 'webExtReloadAllExtensions') {
|
|
267
|
-
const devExtensions = await getAllDevExtensions();
|
|
268
|
-
await Promise.all(devExtensions.map(ext => reloadExtension(ext.id)));
|
|
269
|
-
ws.send(JSON.stringify({ type: 'webExtReloadExtensionComplete' }));
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
})()`;
|
|
273
|
-
await fs.writeFile(path.join(extPath, 'bg.js'), bgPage);
|
|
274
|
-
return extPath;
|
|
353
|
+
}
|
|
275
354
|
}
|
|
276
355
|
|
|
277
356
|
/**
|
|
@@ -280,15 +359,158 @@ export class ChromiumExtensionRunner {
|
|
|
280
359
|
*/
|
|
281
360
|
async reloadAllExtensions() {
|
|
282
361
|
const runnerName = this.getName();
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
362
|
+
if (this.forceUseDeprecatedLoadExtension) {
|
|
363
|
+
this.reloadAllExtensionsFallbackForChrome125andEarlier();
|
|
364
|
+
} else {
|
|
365
|
+
for (const {
|
|
366
|
+
sourceDir
|
|
367
|
+
} of this.params.extensions) {
|
|
368
|
+
try {
|
|
369
|
+
await this.cdp.sendCommand('Extensions.loadUnpacked', {
|
|
370
|
+
path: sourceDir
|
|
371
|
+
});
|
|
372
|
+
} catch (e) {
|
|
373
|
+
log.error(`Failed to load extension at ${sourceDir}: ${e.message}`);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
286
377
|
process.stdout.write(`\rLast extension reload: ${new Date().toTimeString()}`);
|
|
287
378
|
log.debug('\n');
|
|
288
379
|
return [{
|
|
289
380
|
runnerName
|
|
290
381
|
}];
|
|
291
382
|
}
|
|
383
|
+
async reloadAllExtensionsFallbackForChrome125andEarlier() {
|
|
384
|
+
// Ideally, we'd like to use the "Extensions.loadUnpacked" CDP command to
|
|
385
|
+
// reload an extension, but that is unsupported in Chrome 125 and earlier.
|
|
386
|
+
//
|
|
387
|
+
// As a fallback, connect to chrome://extensions/ and reload from there.
|
|
388
|
+
// Since we are targeting old Chrome versions, we can safely use the
|
|
389
|
+
// chrome.developerPrivate APIs, because these are never going to change
|
|
390
|
+
// for the old browser versions. Do NOT use this for newer versions!
|
|
391
|
+
//
|
|
392
|
+
// Target.* CDP methods documented at: https://chromedevtools.github.io/devtools-protocol/tot/Target/
|
|
393
|
+
// developerPrivate documented at:
|
|
394
|
+
// https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl
|
|
395
|
+
//
|
|
396
|
+
// Specific revision that exposed developerPrivate to chrome://extensions/:
|
|
397
|
+
// https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl;drc=69bf75316e7ae533c0a0dccc1a56ca019aa95a1e
|
|
398
|
+
// https://chromium.googlesource.com/chromium/src.git/+/69bf75316e7ae533c0a0dccc1a56ca019aa95a1e
|
|
399
|
+
//
|
|
400
|
+
// Specific revision that introduced developerPrivate.getExtensionsInfo:
|
|
401
|
+
// https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl;drc=69bf75316e7ae533c0a0dccc1a56ca019aa95a1e
|
|
402
|
+
//
|
|
403
|
+
// The above changes are from 2015; The --remote-debugging-pipe feature
|
|
404
|
+
// that we rely on for CDP was added in 2018; this is the version of the
|
|
405
|
+
// developerPrivate API at that time:
|
|
406
|
+
// https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl;drc=c9ae59c8f37d487f1f01c222deb6b7d1f51c99c2
|
|
407
|
+
|
|
408
|
+
// Find an existing chrome://extensions/ tab, if it exists.
|
|
409
|
+
let {
|
|
410
|
+
targetInfos: targets
|
|
411
|
+
} = await this.cdp.sendCommand('Target.getTargets', {
|
|
412
|
+
filter: [{
|
|
413
|
+
type: 'tab'
|
|
414
|
+
}]
|
|
415
|
+
});
|
|
416
|
+
targets = targets.filter(t => t.url.startsWith('chrome://extensions/'));
|
|
417
|
+
let targetId;
|
|
418
|
+
const hasExistingTarget = targets.length > 0;
|
|
419
|
+
if (hasExistingTarget) {
|
|
420
|
+
targetId = targets[0].targetId;
|
|
421
|
+
} else {
|
|
422
|
+
const result = await this.cdp.sendCommand('Target.createTarget', {
|
|
423
|
+
url: 'chrome://extensions/',
|
|
424
|
+
newWindow: true,
|
|
425
|
+
background: true,
|
|
426
|
+
windowState: 'minimized'
|
|
427
|
+
});
|
|
428
|
+
targetId = result.targetId;
|
|
429
|
+
}
|
|
430
|
+
const codeToEvaluateInChrome = async () => {
|
|
431
|
+
// This function is serialized and executed in Chrome. Designed for
|
|
432
|
+
// compatibility with Chrome 69 - 125. Do not use JS syntax of functions
|
|
433
|
+
// that are not supported in these versions!
|
|
434
|
+
|
|
435
|
+
// eslint-disable-next-line no-undef
|
|
436
|
+
const developerPrivate = chrome.developerPrivate;
|
|
437
|
+
if (!developerPrivate || !developerPrivate.getExtensionsInfo) {
|
|
438
|
+
// When chrome://extensions/ is still loading, its document URL may be
|
|
439
|
+
// about:blank and the chrome.developerPrivate API is not exposed.
|
|
440
|
+
return 'NOT_READY_PLEASE_RETRY';
|
|
441
|
+
}
|
|
442
|
+
const extensionIds = [];
|
|
443
|
+
await new Promise(resolve => {
|
|
444
|
+
developerPrivate.getExtensionsInfo(extensions => {
|
|
445
|
+
for (const extension of extensions || []) {
|
|
446
|
+
if (extension.location === 'UNPACKED') {
|
|
447
|
+
// We only care about those loaded via --load-extension.
|
|
448
|
+
extensionIds.push(extension.id);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
resolve();
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
const reloadPromises = extensionIds.map(extensionId => {
|
|
455
|
+
return new Promise((resolve, reject) => {
|
|
456
|
+
developerPrivate.reload(extensionId,
|
|
457
|
+
// Suppress alert dialog when load fails.
|
|
458
|
+
{
|
|
459
|
+
failQuietly: true,
|
|
460
|
+
populateErrorForUnpacked: true
|
|
461
|
+
}, loadError => {
|
|
462
|
+
if (loadError) {
|
|
463
|
+
reject(new Error(loadError.error));
|
|
464
|
+
} else {
|
|
465
|
+
resolve();
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
await Promise.all(reloadPromises);
|
|
471
|
+
return reloadPromises.length;
|
|
472
|
+
};
|
|
473
|
+
try {
|
|
474
|
+
const targetResult = await this.cdp.sendCommand('Target.attachToTarget', {
|
|
475
|
+
targetId,
|
|
476
|
+
flatten: true
|
|
477
|
+
});
|
|
478
|
+
if (!targetResult.sessionId) {
|
|
479
|
+
throw new Error('Unexpectedly, no sessionId from attachToTarget');
|
|
480
|
+
}
|
|
481
|
+
// In practice, we're going to run the logic only once. But if we are
|
|
482
|
+
// unlucky, chrome://extensions is still loading, so we will then retry.
|
|
483
|
+
for (let i = 0; i < 3; ++i) {
|
|
484
|
+
var _evalResult$result;
|
|
485
|
+
const evalResult = await this.cdp.sendCommand('Runtime.evaluate', {
|
|
486
|
+
expression: `(${codeToEvaluateInChrome})();`,
|
|
487
|
+
awaitPromise: true
|
|
488
|
+
}, targetResult.sessionId);
|
|
489
|
+
const evalResultReturnValue = (_evalResult$result = evalResult.result) === null || _evalResult$result === void 0 ? void 0 : _evalResult$result.value;
|
|
490
|
+
if (evalResultReturnValue === 'NOT_READY_PLEASE_RETRY') {
|
|
491
|
+
await new Promise(r => setTimeout(r, 200 * i));
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
if (evalResult.exceptionDetails) {
|
|
495
|
+
log.error(`Failed to reload: ${evalResult.exceptionDetails.text}`);
|
|
496
|
+
}
|
|
497
|
+
if (evalResultReturnValue !== this.params.extensions.length) {
|
|
498
|
+
log.warn(`Failed to reload extensions: ${evalResultReturnValue}`);
|
|
499
|
+
}
|
|
500
|
+
break;
|
|
501
|
+
}
|
|
502
|
+
} finally {
|
|
503
|
+
if (!hasExistingTarget && targetId) {
|
|
504
|
+
try {
|
|
505
|
+
await this.cdp.sendCommand('Target.closeTarget', {
|
|
506
|
+
targetId
|
|
507
|
+
});
|
|
508
|
+
} catch (e) {
|
|
509
|
+
log.error(e);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
292
514
|
|
|
293
515
|
/**
|
|
294
516
|
* Reloads a single extension, collect any reload error and resolves to
|
|
@@ -329,18 +551,9 @@ export class ChromiumExtensionRunner {
|
|
|
329
551
|
await this.chromiumInstance.kill();
|
|
330
552
|
this.chromiumInstance = null;
|
|
331
553
|
}
|
|
332
|
-
if (this.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// resolve until all of the existing connections are closed.
|
|
336
|
-
for (const wssClient of ((_this$wss = this.wss) === null || _this$wss === void 0 ? void 0 : _this$wss.clients) || []) {
|
|
337
|
-
var _this$wss;
|
|
338
|
-
if (wssClient.readyState === WebSocket.OPEN) {
|
|
339
|
-
wssClient.terminate();
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
await new Promise(resolve => this.wss ? this.wss.close(resolve) : resolve());
|
|
343
|
-
this.wss = null;
|
|
554
|
+
if (this.cdp) {
|
|
555
|
+
await this.cdp.waitUntilDisconnected();
|
|
556
|
+
this.cdp = null;
|
|
344
557
|
}
|
|
345
558
|
|
|
346
559
|
// Call all the registered cleanup callbacks.
|
|
@@ -1 +1 @@
|
|
|
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 = [\n '--disable-extensions',\n '--mute-audio',\n '--disable-component-update',\n];\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":[]}
|
|
1
|
+
{"version":3,"file":"chromium.js","names":["fs","path","Launcher","ChromeLauncher","launch","defaultChromiumLaunch","createLogger","TempDir","isDirectory","fileExists","log","import","meta","url","EXCLUDED_CHROME_FLAGS","DEFAULT_CHROME_FLAGS","defaultFlags","filter","flag","includes","_receivedData","WeakMap","_isProcessingMessage","_lastId","_deferredResponses","_disconnected","_disconnectedPromise","_resolveDisconnectedPromise","_ChromeDevtoolsProtocolClient_brand","WeakSet","ChromeDevtoolsProtocolClient","constructor","chromiumInstance","_classPrivateMethodInitSpec","_classPrivateFieldInitSpec","Map","_defineProperty","process","env","TEST_LOG_VERBOSE_CDP","incoming","outgoing","remoteDebuggingPipes","_classPrivateFieldSet","Promise","resolve","closed","warn","_assertClassBrand","_finalizeDisconnect","call","on","data","_classPrivateFieldGet","_processNextMessage","error","outgoingPipe","waitUntilDisconnected","sendCommand","method","params","sessionId","undefined","_this$lastId","Error","message","id","rawMessage","JSON","stringify","stderr","write","reject","set","end","indexOf","slice","result","parse","deferredResponse","get","delete","err","e","values","clear","ChromiumExtensionRunner","cleanupCallbacks","chromiumLaunch","forceUseDeprecatedLoadExtension","exiting","_promiseSetupDone","Set","getName","run","setupInstance","isUserDataDir","dirPath","localStatePath","join","defaultPath","isProfileDir","securePreferencesPath","getProfilePaths","chromiumProfile","userDataDir","profileDirName","isProfileDirAndNotUserData","dir","base","extensions","map","sourceDir","chromiumBinary","debug","chromeFlags","push","args","keepProfileChanges","tmpDir","create","tmpDirPath","cp","recursive","startingUrl","startUrl","startingUrls","Array","isArray","shift","chromePath","logLevel","verbose","ignoreDefaultFlags","cdp","initialChromiumInstance","once","info","exit","cdpSupportsExtensionsLoadUnpacked","kill","reloadAllExtensions","runnerName","reloadAllExtensionsFallbackForChrome125andEarlier","stdout","Date","toTimeString","targetInfos","targets","type","t","startsWith","targetId","hasExistingTarget","length","newWindow","background","windowState","codeToEvaluateInChrome","developerPrivate","chrome","getExtensionsInfo","extensionIds","extension","location","reloadPromises","extensionId","reload","failQuietly","populateErrorForUnpacked","loadError","all","targetResult","flatten","i","_evalResult$result","evalResult","expression","awaitPromise","evalResultReturnValue","value","r","setTimeout","exceptionDetails","text","reloadExtensionBySourceDir","extensionSourceDir","registerCleanup","fn","add","catch"],"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';\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 = [\n '--disable-extensions',\n '--mute-audio',\n '--disable-component-update',\n];\n\nexport const DEFAULT_CHROME_FLAGS = ChromeLauncher.defaultFlags().filter(\n (flag) => !EXCLUDED_CHROME_FLAGS.includes(flag),\n);\n\n// This is a client for the Chrome Devtools protocol. The methods and results\n// are documented at https://chromedevtools.github.io/devtools-protocol/tot/\nclass ChromeDevtoolsProtocolClient {\n #receivedData = '';\n #isProcessingMessage = false;\n #lastId = 0;\n #deferredResponses = new Map();\n #disconnected = false;\n #disconnectedPromise;\n #resolveDisconnectedPromise;\n\n // Print all exchanged CDP messages to ease debugging.\n TEST_LOG_VERBOSE_CDP = process.env.TEST_LOG_VERBOSE_CDP;\n\n constructor(chromiumInstance) {\n // remoteDebuggingPipes is from chrome-launcher, see\n // https://github.com/GoogleChrome/chrome-launcher/pull/347\n const { incoming, outgoing } = chromiumInstance.remoteDebuggingPipes;\n this.#disconnectedPromise = new Promise((resolve) => {\n this.#resolveDisconnectedPromise = resolve;\n });\n if (incoming.closed) {\n // Strange. Did Chrome fail to start, or exit on startup?\n log.warn('CDP already disconnected at initialization');\n this.#finalizeDisconnect();\n return;\n }\n incoming.on('data', (data) => {\n this.#receivedData += data;\n this.#processNextMessage();\n });\n incoming.on('error', (error) => {\n log.error(error);\n this.#finalizeDisconnect();\n });\n incoming.on('close', () => this.#finalizeDisconnect());\n this.outgoingPipe = outgoing;\n }\n\n waitUntilDisconnected() {\n return this.#disconnectedPromise;\n }\n\n async sendCommand(method, params, sessionId = undefined) {\n if (this.#disconnected) {\n throw new Error(`CDP disconnected, cannot send: command ${method}`);\n }\n const message = {\n id: ++this.#lastId,\n method,\n params,\n sessionId,\n };\n const rawMessage = `${JSON.stringify(message)}\\x00`;\n if (this.TEST_LOG_VERBOSE_CDP) {\n process.stderr.write(`[CDP] [SEND] ${rawMessage}\\n`);\n }\n return new Promise((resolve, reject) => {\n // CDP will always send a response.\n this.#deferredResponses.set(message.id, { method, resolve, reject });\n this.outgoingPipe.write(rawMessage);\n });\n }\n\n #processNextMessage() {\n if (this.#isProcessingMessage) {\n return;\n }\n this.#isProcessingMessage = true;\n let end = this.#receivedData.indexOf('\\x00');\n while (end !== -1) {\n const rawMessage = this.#receivedData.slice(0, end);\n this.#receivedData = this.#receivedData.slice(end + 1); // +1 skips \\x00.\n try {\n if (this.TEST_LOG_VERBOSE_CDP) {\n process.stderr.write(`[CDP] [RECV] ${rawMessage}\\n`);\n }\n const { id, error, result } = JSON.parse(rawMessage);\n const deferredResponse = this.#deferredResponses.get(id);\n if (deferredResponse) {\n this.#deferredResponses.delete(id);\n if (error) {\n const err = new Error(error.message || 'Unexpected CDP response');\n deferredResponse.reject(err);\n } else {\n deferredResponse.resolve(result);\n }\n } else {\n // Dropping events and non-response messages since we don't need it.\n }\n } catch (e) {\n log.error(e);\n }\n end = this.#receivedData.indexOf('\\x00');\n }\n this.#isProcessingMessage = false;\n if (this.#disconnected) {\n for (const { method, reject } of this.#deferredResponses.values()) {\n reject(new Error(`CDP connection closed before response to ${method}`));\n }\n this.#deferredResponses.clear();\n this.#resolveDisconnectedPromise();\n }\n }\n\n #finalizeDisconnect() {\n if (!this.#disconnected) {\n this.#disconnected = true;\n this.#processNextMessage();\n }\n }\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 // --load-extension is deprecated, but only supported in Chrome 126+, see:\n // https://github.com/mozilla/web-ext/issues/3388#issuecomment-2906982117\n forceUseDeprecatedLoadExtension;\n exiting;\n _promiseSetupDone;\n\n constructor(params) {\n const { chromiumLaunch = defaultChromiumLaunch } = params;\n this.params = params;\n this.chromiumLaunch = chromiumLaunch;\n // We will try to use Extensions.loadUnpacked first (Chrome 126+), and if\n // that does not work fall back to --load-extension.\n this.forceUseDeprecatedLoadExtension = false;\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 // NOTE: This function may be called twice, if the user is using an old\n // Chrome version (before Chrome 126), because then we have to add a\n // command-line flag (--load-extension) to load the extension. For details,\n // see:\n // https://github.com/mozilla/web-ext/issues/3388#issuecomment-2906982117\n\n // Start chrome pointing it to a given profile dir\n const extensions = this.params.extensions.map(({ sourceDir }) => sourceDir);\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 chromeFlags.push('--remote-debugging-pipe');\n\n if (!this.forceUseDeprecatedLoadExtension) {\n chromeFlags.push('--enable-unsafe-extension-debugging');\n } else {\n chromeFlags.push(`--load-extension=${extensions.join(',')}`);\n }\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 chromePath: chromiumBinary,\n chromeFlags,\n startingUrl,\n userDataDir,\n logLevel: this.params.verbose ? 'verbose' : 'silent',\n // Ignore default flags to keep the extension enabled.\n ignoreDefaultFlags: true,\n });\n this.cdp = new ChromeDevtoolsProtocolClient(this.chromiumInstance);\n\n const initialChromiumInstance = this.chromiumInstance;\n this.chromiumInstance.process.once('close', () => {\n if (this.chromiumInstance !== initialChromiumInstance) {\n // This happens when we restart Chrome to fall back to --load-extension.\n return;\n }\n this.chromiumInstance = null;\n\n if (!this.exiting) {\n log.info('Exiting on Chromium instance disconnected.');\n this.exit();\n }\n });\n\n if (!this.forceUseDeprecatedLoadExtension) {\n // Assume that the required Extensions.loadUnpacked CDP method is\n // supported. If it is not, we will fall back to --load-extension.\n let cdpSupportsExtensionsLoadUnpacked = true;\n for (const sourceDir of extensions) {\n try {\n await this.cdp.sendCommand('Extensions.loadUnpacked', {\n path: sourceDir,\n });\n } catch (e) {\n // Chrome 125- will emit the following message:\n if (e.message === \"'Extensions.loadUnpacked' wasn't found\") {\n cdpSupportsExtensionsLoadUnpacked = false;\n break;\n }\n log.error(`Failed to load extension at ${sourceDir}: ${e.message}`);\n // We do not have to throw - the extension can work again when\n // auto-reload is used. But users may like a hard fail, and this is\n // consistent with the firefox runner.\n throw e;\n }\n }\n if (!cdpSupportsExtensionsLoadUnpacked) {\n // Retry once, now with --load-extension.\n log.warn('Cannot load extension via CDP, falling back to old method');\n this.forceUseDeprecatedLoadExtension = true;\n this.chromiumInstance = null;\n await initialChromiumInstance.kill();\n await this.cdp.waitUntilDisconnected();\n this.cdp = null;\n return this.setupInstance();\n }\n }\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 if (this.forceUseDeprecatedLoadExtension) {\n this.reloadAllExtensionsFallbackForChrome125andEarlier();\n } else {\n for (const { sourceDir } of this.params.extensions) {\n try {\n await this.cdp.sendCommand('Extensions.loadUnpacked', {\n path: sourceDir,\n });\n } catch (e) {\n log.error(`Failed to load extension at ${sourceDir}: ${e.message}`);\n }\n }\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 async reloadAllExtensionsFallbackForChrome125andEarlier() {\n // Ideally, we'd like to use the \"Extensions.loadUnpacked\" CDP command to\n // reload an extension, but that is unsupported in Chrome 125 and earlier.\n //\n // As a fallback, connect to chrome://extensions/ and reload from there.\n // Since we are targeting old Chrome versions, we can safely use the\n // chrome.developerPrivate APIs, because these are never going to change\n // for the old browser versions. Do NOT use this for newer versions!\n //\n // Target.* CDP methods documented at: https://chromedevtools.github.io/devtools-protocol/tot/Target/\n // developerPrivate documented at:\n // https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl\n //\n // Specific revision that exposed developerPrivate to chrome://extensions/:\n // https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl;drc=69bf75316e7ae533c0a0dccc1a56ca019aa95a1e\n // https://chromium.googlesource.com/chromium/src.git/+/69bf75316e7ae533c0a0dccc1a56ca019aa95a1e\n //\n // Specific revision that introduced developerPrivate.getExtensionsInfo:\n // https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl;drc=69bf75316e7ae533c0a0dccc1a56ca019aa95a1e\n //\n // The above changes are from 2015; The --remote-debugging-pipe feature\n // that we rely on for CDP was added in 2018; this is the version of the\n // developerPrivate API at that time:\n // https://source.chromium.org/chromium/chromium/src/+/main:chrome/common/extensions/api/developer_private.idl;drc=c9ae59c8f37d487f1f01c222deb6b7d1f51c99c2\n\n // Find an existing chrome://extensions/ tab, if it exists.\n let { targetInfos: targets } = await this.cdp.sendCommand(\n 'Target.getTargets',\n { filter: [{ type: 'tab' }] },\n );\n targets = targets.filter((t) => t.url.startsWith('chrome://extensions/'));\n let targetId;\n const hasExistingTarget = targets.length > 0;\n if (hasExistingTarget) {\n targetId = targets[0].targetId;\n } else {\n const result = await this.cdp.sendCommand('Target.createTarget', {\n url: 'chrome://extensions/',\n newWindow: true,\n background: true,\n windowState: 'minimized',\n });\n targetId = result.targetId;\n }\n const codeToEvaluateInChrome = async () => {\n // This function is serialized and executed in Chrome. Designed for\n // compatibility with Chrome 69 - 125. Do not use JS syntax of functions\n // that are not supported in these versions!\n\n // eslint-disable-next-line no-undef\n const developerPrivate = chrome.developerPrivate;\n if (!developerPrivate || !developerPrivate.getExtensionsInfo) {\n // When chrome://extensions/ is still loading, its document URL may be\n // about:blank and the chrome.developerPrivate API is not exposed.\n return 'NOT_READY_PLEASE_RETRY';\n }\n const extensionIds = [];\n await new Promise((resolve) => {\n developerPrivate.getExtensionsInfo((extensions) => {\n for (const extension of extensions || []) {\n if (extension.location === 'UNPACKED') {\n // We only care about those loaded via --load-extension.\n extensionIds.push(extension.id);\n }\n }\n resolve();\n });\n });\n const reloadPromises = extensionIds.map((extensionId) => {\n return new Promise((resolve, reject) => {\n developerPrivate.reload(\n extensionId,\n // Suppress alert dialog when load fails.\n { failQuietly: true, populateErrorForUnpacked: true },\n (loadError) => {\n if (loadError) {\n reject(new Error(loadError.error));\n } else {\n resolve();\n }\n },\n );\n });\n });\n await Promise.all(reloadPromises);\n return reloadPromises.length;\n };\n try {\n const targetResult = await this.cdp.sendCommand('Target.attachToTarget', {\n targetId,\n flatten: true,\n });\n if (!targetResult.sessionId) {\n throw new Error('Unexpectedly, no sessionId from attachToTarget');\n }\n // In practice, we're going to run the logic only once. But if we are\n // unlucky, chrome://extensions is still loading, so we will then retry.\n for (let i = 0; i < 3; ++i) {\n const evalResult = await this.cdp.sendCommand(\n 'Runtime.evaluate',\n {\n expression: `(${codeToEvaluateInChrome})();`,\n awaitPromise: true,\n },\n targetResult.sessionId,\n );\n const evalResultReturnValue = evalResult.result?.value;\n if (evalResultReturnValue === 'NOT_READY_PLEASE_RETRY') {\n await new Promise((r) => setTimeout(r, 200 * i));\n continue;\n }\n if (evalResult.exceptionDetails) {\n log.error(`Failed to reload: ${evalResult.exceptionDetails.text}`);\n }\n if (evalResultReturnValue !== this.params.extensions.length) {\n log.warn(`Failed to reload extensions: ${evalResultReturnValue}`);\n }\n break;\n }\n } finally {\n if (!hasExistingTarget && targetId) {\n try {\n await this.cdp.sendCommand('Target.closeTarget', { targetId });\n } catch (e) {\n log.error(e);\n }\n }\n }\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.cdp) {\n await this.cdp.waitUntilDisconnected();\n this.cdp = 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":[]}
|
package/lib/util/submit-addon.js
CHANGED
|
@@ -9,26 +9,6 @@ import { isErrorWithCode } from '../errors.js';
|
|
|
9
9
|
import { createLogger } from './../util/logger.js';
|
|
10
10
|
const log = createLogger(import.meta.url);
|
|
11
11
|
export const defaultAsyncFsReadFile = fsPromises.readFile;
|
|
12
|
-
|
|
13
|
-
// Used by fileFromSync method to make sure the form-data entry will
|
|
14
|
-
// include a filename derived from the file path.
|
|
15
|
-
//
|
|
16
|
-
// TODO: Get rid of this hack when we will bump the web-ext nodejs
|
|
17
|
-
// version required to nodejs v20 (where the native File constructor
|
|
18
|
-
// exists).
|
|
19
|
-
export class FileBlob extends Blob {
|
|
20
|
-
#name = '';
|
|
21
|
-
constructor(fileBits, fileName, options) {
|
|
22
|
-
super(fileBits, options);
|
|
23
|
-
this.#name = String(fileName);
|
|
24
|
-
}
|
|
25
|
-
get name() {
|
|
26
|
-
return this.#name;
|
|
27
|
-
}
|
|
28
|
-
get [Symbol.toStringTag]() {
|
|
29
|
-
return 'File';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
12
|
export class JwtApiAuth {
|
|
33
13
|
#apiKey;
|
|
34
14
|
#apiSecret;
|
|
@@ -103,7 +83,21 @@ export default class Client {
|
|
|
103
83
|
// submitted and fail with the error message:
|
|
104
84
|
// "Unsupported file type, please upload a supported file (.crx, .xpi, .zip)."
|
|
105
85
|
const fileData = readFileSync(filePath);
|
|
106
|
-
|
|
86
|
+
// eslint-disable-next-line no-shadow -- File is in Node v20.0.0+.
|
|
87
|
+
let File = global.File;
|
|
88
|
+
// TODO: Use the File global directly without the fallback when we drop
|
|
89
|
+
// support for Node versions before v20.
|
|
90
|
+
if (typeof File === 'undefined') {
|
|
91
|
+
// Even without File being public, its interface and constructor could
|
|
92
|
+
// be accessed indirectly from the FormData interface. According to the
|
|
93
|
+
// FormData spec (that Node.js implements, via undici), the entry value
|
|
94
|
+
// of a FormData is always a scalar value or a File:
|
|
95
|
+
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-entry-value
|
|
96
|
+
const fd = new FormData();
|
|
97
|
+
fd.set('x', new Blob([]));
|
|
98
|
+
File = fd.get('x').constructor;
|
|
99
|
+
}
|
|
100
|
+
return new File([fileData], basename(filePath));
|
|
107
101
|
}
|
|
108
102
|
nodeFetch(url, {
|
|
109
103
|
method,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-addon.js","names":["basename","createHash","createWriteStream","promises","fsPromises","readFileSync","streamPromises","SignJWT","JSZip","HttpsProxyAgent","isErrorWithCode","createLogger","log","import","meta","url","defaultAsyncFsReadFile","readFile","FileBlob","Blob","name","constructor","fileBits","fileName","options","String","Symbol","toStringTag","JwtApiAuth","apiKey","apiSecret","apiJwtExpiresIn","signJWT","iss","setProtectedHeader","alg","setIssuedAt","setExpirationTime","sign","Uint8Array","from","Buffer","getAuthHeader","authToken","Client","apiAuth","apiProxy","apiUr","validationCheckInterval","validationCheckTimeout","approvalCheckInterval","approvalCheckTimeout","downloadDir","userAgentString","baseUrl","process","cwd","pathname","endsWith","URL","href","apiUrl","fileFromSync","filePath","fileData","nodeFetch","method","headers","body","agent","fetch","doUploadSubmit","xpiPath","channel","formData","FormData","set","uuid","fetchJson","waitForValidation","waitRetry","successFunc","checkUrl","checkInterval","abortInterval","context","editUrl","checkTimeout","Promise","resolve","reject","abortTimeout","setTimeout","clearTimeout","errorMessage","Error","pollStatus","responseData","undefined","success","err","info","detailResponseData","processed","debug","validation","valid","JSON","stringify","join","doNewAddonSubmit","metaDataJson","jsonData","version","upload","doNewAddonOrVersionSubmit","addonId","doFormDataPatch","data","versionId","patchUrl","field","response","ok","status","error","warn","Object","keys","doAfterSubmit","newVersionId","patchData","returnResult","fileUrl","waitForApproval","downloadSignedFile","file","errorMsg","statusText","json","Authorization","Accept","downloadedFiles","id","filename","split","pop","dest","saveToFile","contents","destPath","pipeline","hashXpiCrcs","asyncFsReadFile","zip","loadAsync","createFolders","hash","entries","forEach","relativePath","entry","_entry$_data","path","replace","dir","push","crc32","_data","sort","a","b","update","digest","getPreviousUuidOrUploadXpi","savedUploadUuidPath","saveUploadUuidToFileFunc","saveUploadUuidToFile","getUploadUuidFromFileFunc","getUploadUuidFromFile","uploadUuid","previousUuid","previousChannel","xpiCrcHash","previousHash","all","postNewAddon","savedIdPath","saveIdToFileFunc","saveIdToFile","guid","edit_url","putVersion","signAddon","amoBaseUrl","submissionSource","SubmitClient","ApiAuthClass","stats","stat","isFile","statError","client","stats2","source","writeFile","toString","content","parse"],"sources":["../../src/util/submit-addon.js"],"sourcesContent":["import { basename } from 'path';\nimport { createHash } from 'crypto';\nimport { createWriteStream, promises as fsPromises, readFileSync } from 'fs';\nimport { promises as streamPromises } from 'stream';\n\nimport { SignJWT } from 'jose';\nimport JSZip from 'jszip';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\n\nimport { isErrorWithCode } from '../errors.js';\nimport { createLogger } from './../util/logger.js';\n\nconst log = createLogger(import.meta.url);\n\nexport const defaultAsyncFsReadFile = fsPromises.readFile;\n\n// Used by fileFromSync method to make sure the form-data entry will\n// include a filename derived from the file path.\n//\n// TODO: Get rid of this hack when we will bump the web-ext nodejs\n// version required to nodejs v20 (where the native File constructor\n// exists).\nexport class FileBlob extends Blob {\n #name = '';\n\n constructor(fileBits, fileName, options) {\n super(fileBits, options);\n this.#name = String(fileName);\n }\n\n get name() {\n return this.#name;\n }\n\n get [Symbol.toStringTag]() {\n return 'File';\n }\n}\n\nexport class JwtApiAuth {\n #apiKey;\n #apiSecret;\n #apiJwtExpiresIn;\n\n constructor({\n apiKey,\n apiSecret,\n apiJwtExpiresIn = 60 * 5, // 5 minutes\n }) {\n this.#apiKey = apiKey;\n this.#apiSecret = apiSecret;\n this.#apiJwtExpiresIn = apiJwtExpiresIn;\n }\n\n async signJWT() {\n return (\n new SignJWT({ iss: this.#apiKey })\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n // jose expects either:\n // a number, which is treated an absolute timestamp - so must be after now, or\n // a string, which is parsed as a relative time from now.\n .setExpirationTime(`${this.#apiJwtExpiresIn}seconds`)\n .sign(Uint8Array.from(Buffer.from(this.#apiSecret, 'utf8')))\n );\n }\n\n async getAuthHeader() {\n const authToken = await this.signJWT();\n return `JWT ${authToken}`;\n }\n}\n\nexport default class Client {\n apiAuth;\n apiProxy;\n apiUr;\n validationCheckInterval;\n validationCheckTimeout;\n approvalCheckInterval;\n approvalCheckTimeout;\n downloadDir;\n userAgentString;\n\n constructor({\n apiAuth,\n apiProxy,\n baseUrl,\n validationCheckInterval = 1000,\n validationCheckTimeout = 300000, // 5 minutes.\n approvalCheckInterval = 1000,\n approvalCheckTimeout = 900000, // 15 minutes.\n downloadDir = process.cwd(),\n userAgentString = 'web-ext-lib',\n }) {\n this.apiAuth = apiAuth;\n if (apiProxy) {\n this.apiProxy = apiProxy;\n }\n if (!baseUrl.pathname.endsWith('/')) {\n baseUrl = new URL(baseUrl.href);\n baseUrl.pathname += '/';\n }\n this.apiUrl = new URL('addons/', baseUrl);\n this.validationCheckInterval = validationCheckInterval;\n this.validationCheckTimeout = validationCheckTimeout;\n this.approvalCheckInterval = approvalCheckInterval;\n this.approvalCheckTimeout = approvalCheckTimeout;\n this.downloadDir = downloadDir;\n this.userAgentString = userAgentString;\n }\n\n fileFromSync(filePath) {\n // create a File blob from a file path, and ensure it to have the file path basename\n // as the associated filename, the AMO server API will be checking it on the form-data\n // submitted and fail with the error message:\n // \"Unsupported file type, please upload a supported file (.crx, .xpi, .zip).\"\n const fileData = readFileSync(filePath);\n return new FileBlob([fileData], basename(filePath));\n }\n\n nodeFetch(url, { method, headers, body, agent }) {\n return fetch(url, { method, headers, body, agent });\n }\n\n async doUploadSubmit(xpiPath, channel) {\n const url = new URL('upload/', this.apiUrl);\n const formData = new FormData();\n formData.set('channel', channel);\n formData.set('upload', this.fileFromSync(xpiPath));\n const { uuid } = await this.fetchJson(\n url,\n 'POST',\n formData,\n 'Upload failed',\n );\n return this.waitForValidation(uuid);\n }\n\n waitRetry(\n successFunc,\n checkUrl,\n checkInterval,\n abortInterval,\n context,\n editUrl = null,\n ) {\n let checkTimeout;\n\n return new Promise((resolve, reject) => {\n const abortTimeout = setTimeout(() => {\n clearTimeout(checkTimeout);\n\n let errorMessage = `${context}: timeout exceeded.`;\n if (editUrl) {\n errorMessage += ` When approved the signed XPI file can be downloaded from ${editUrl}`;\n }\n\n reject(new Error(errorMessage));\n }, abortInterval);\n\n const pollStatus = async () => {\n try {\n const responseData = await this.fetchJson(\n checkUrl,\n 'GET',\n undefined,\n 'Getting details failed',\n );\n\n const success = successFunc(responseData);\n if (success) {\n clearTimeout(abortTimeout);\n resolve(success);\n } else {\n // Still in progress, so wait for a while and try again.\n checkTimeout = setTimeout(pollStatus, checkInterval);\n }\n } catch (err) {\n clearTimeout(abortTimeout);\n reject(err);\n }\n };\n\n pollStatus();\n });\n }\n\n waitForValidation(uuid) {\n log.info('Waiting for validation...');\n return this.waitRetry(\n (detailResponseData) => {\n if (!detailResponseData.processed) {\n return null;\n }\n\n log.debug('Validation results:', detailResponseData.validation);\n if (detailResponseData.valid) {\n return detailResponseData.uuid;\n }\n\n throw new Error(\n [\n 'Validation failed:\\n',\n JSON.stringify(detailResponseData.validation, null, 2),\n ].join(''),\n );\n },\n new URL(`upload/${uuid}/`, this.apiUrl),\n this.validationCheckInterval,\n this.validationCheckTimeout,\n 'Validation',\n );\n }\n\n async doNewAddonSubmit(uuid, metaDataJson) {\n const url = new URL('addon/', this.apiUrl);\n const jsonData = {\n ...metaDataJson,\n version: { upload: uuid, ...metaDataJson.version },\n };\n return this.fetchJson(\n url,\n 'POST',\n JSON.stringify(jsonData),\n 'Submission failed (1)',\n );\n }\n\n doNewAddonOrVersionSubmit(addonId, uuid, metaDataJson) {\n const url = new URL(`addon/${addonId}/`, this.apiUrl);\n const jsonData = {\n ...metaDataJson,\n version: { upload: uuid, ...metaDataJson.version },\n };\n return this.fetchJson(\n url,\n 'PUT',\n JSON.stringify(jsonData),\n 'Submission failed (2)',\n );\n }\n\n async doFormDataPatch(data, addonId, versionId) {\n const patchUrl = new URL(\n `addon/${addonId}/versions/${versionId}/`,\n this.apiUrl,\n );\n try {\n const formData = new FormData();\n for (const field in data) {\n formData.set(field, data[field]);\n }\n\n const response = await this.fetch(patchUrl, 'PATCH', formData);\n if (!response.ok) {\n throw new Error(`response status was ${response.status}`);\n }\n } catch (error) {\n log.warn(`Upload of ${Object.keys(data)} failed: ${error}.`);\n throw new Error(`Uploading ${Object.keys(data)} failed`);\n }\n }\n\n async doAfterSubmit(addonId, newVersionId, editUrl, patchData) {\n if (patchData && patchData.version) {\n log.info(`Submitting ${Object.keys(patchData.version)} to version`);\n await this.doFormDataPatch(patchData.version, addonId, newVersionId);\n }\n\n if (this.approvalCheckTimeout === 0) {\n log.info(\n [\n 'Waiting for approval and download of signed XPI skipped.',\n `When approved the signed XPI file can be downloaded from ${editUrl}`,\n ].join(' '),\n );\n return this.returnResult(addonId);\n }\n\n const fileUrl = new URL(\n await this.waitForApproval(addonId, newVersionId, editUrl),\n );\n return this.downloadSignedFile(fileUrl, addonId);\n }\n\n waitForApproval(addonId, versionId, editUrl) {\n log.info('Waiting for approval...');\n return this.waitRetry(\n (detailResponseData) => {\n const { file } = detailResponseData;\n if (file && file.status === 'public') {\n return file.url;\n }\n\n return null;\n },\n new URL(`addon/${addonId}/versions/${versionId}/`, this.apiUrl),\n this.approvalCheckInterval,\n this.approvalCheckTimeout,\n 'Approval',\n editUrl,\n );\n }\n\n async fetchJson(url, method = 'GET', body, errorMsg = 'Bad Request') {\n const response = await this.fetch(url, method, body);\n if (response.status < 200 || response.status >= 500) {\n throw new Error(\n `${errorMsg}: ${response.statusText || response.status}.`,\n );\n }\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(\n [\n `${errorMsg}: ${response.statusText || response.status}`,\n JSON.stringify(data, null, 2),\n ].join('\\n'),\n );\n }\n return data;\n }\n\n async fetch(url, method = 'GET', body) {\n log.debug(`${method}ing URL: ${url.href}`);\n let headers = {\n Authorization: await this.apiAuth.getAuthHeader(),\n Accept: 'application/json',\n 'User-Agent': this.userAgentString,\n };\n if (typeof body === 'string') {\n headers = {\n ...headers,\n 'Content-Type': 'application/json',\n };\n }\n let agent;\n if (this.apiProxy) {\n agent = new HttpsProxyAgent(this.apiProxy);\n }\n return this.nodeFetch(url, { method, body, headers, agent });\n }\n\n returnResult(addonId, downloadedFiles) {\n return {\n id: addonId,\n downloadedFiles,\n };\n }\n\n async downloadSignedFile(fileUrl, addonId) {\n const filename = fileUrl.pathname.split('/').pop(); // get the name from fileUrl\n const dest = `${this.downloadDir}/${filename}`;\n try {\n const response = await this.fetch(fileUrl);\n if (!response.ok || !response.body) {\n throw new Error(`response status was ${response.status}`);\n }\n await this.saveToFile(response.body, dest);\n } catch (error) {\n log.info(`Download of signed xpi failed: ${error}.`);\n throw new Error(`Downloading ${filename} failed`);\n }\n log.info(`Signed xpi downloaded: ${dest}`);\n return this.returnResult(addonId, [filename]);\n }\n\n async saveToFile(contents, destPath) {\n return streamPromises.pipeline(contents, createWriteStream(destPath));\n }\n\n /*\n This function aims to quickly hash the contents of the zip file that's being uploaded,\n to compare it to the previous zip file that was uploaded, so we can skip the upload for\n efficiency.\n\n CRCs are used from the zip to avoid having to extract and hash all the files.\n\n Two zips that have different byte contents in their files must have a different hash;\n but returning a different hash when the contents are the same in some cases is acceptable\n - a false mismatch does not result in lost data.\n */\n async hashXpiCrcs(filePath, asyncFsReadFile = defaultAsyncFsReadFile) {\n const zip = await JSZip.loadAsync(\n asyncFsReadFile(filePath, { createFolders: true }),\n );\n const hash = createHash('sha256');\n const entries = [];\n zip.forEach((relativePath, entry) => {\n let path = relativePath.replace(/\\/+$/, '');\n if (entry.dir) {\n path += '/';\n }\n // if the file is 0 bytes or a dir `_data` is missing so assume crc is 0\n entries.push({ path, crc32: entry._data?.crc32 || 0 });\n });\n entries.sort((a, b) => (a.path === b.path ? 0 : a.path > b.path ? 1 : -1));\n hash.update(JSON.stringify(entries));\n return hash.digest('hex');\n }\n\n async getPreviousUuidOrUploadXpi(\n xpiPath,\n channel,\n savedUploadUuidPath,\n saveUploadUuidToFileFunc = saveUploadUuidToFile,\n getUploadUuidFromFileFunc = getUploadUuidFromFile,\n ) {\n const [\n {\n uploadUuid: previousUuid,\n channel: previousChannel,\n xpiCrcHash: previousHash,\n },\n xpiCrcHash,\n ] = await Promise.all([\n getUploadUuidFromFileFunc(savedUploadUuidPath),\n this.hashXpiCrcs(xpiPath),\n ]);\n\n let uploadUuid;\n if (previousChannel !== channel || xpiCrcHash !== previousHash) {\n uploadUuid = await this.doUploadSubmit(xpiPath, channel);\n await saveUploadUuidToFileFunc(savedUploadUuidPath, {\n uploadUuid,\n channel,\n xpiCrcHash,\n });\n } else {\n uploadUuid = previousUuid;\n }\n return uploadUuid;\n }\n\n async postNewAddon(\n uploadUuid,\n savedIdPath,\n metaDataJson,\n patchData,\n saveIdToFileFunc = saveIdToFile,\n ) {\n const {\n guid: addonId,\n version: { id: newVersionId, edit_url: editUrl },\n } = await this.doNewAddonSubmit(uploadUuid, metaDataJson);\n\n await saveIdToFileFunc(savedIdPath, addonId);\n log.info(`Generated extension ID: ${addonId}.`);\n log.info('You must add the following to your manifest:');\n log.info(`\"browser_specific_settings\": {\"gecko\": {\"id\": \"${addonId}\"}}`);\n\n return this.doAfterSubmit(addonId, newVersionId, editUrl, patchData);\n }\n\n async putVersion(uploadUuid, addonId, metaDataJson, patchData) {\n const {\n version: { id: newVersionId, edit_url: editUrl },\n } = await this.doNewAddonOrVersionSubmit(addonId, uploadUuid, metaDataJson);\n\n return this.doAfterSubmit(addonId, newVersionId, editUrl, patchData);\n }\n}\n\nexport async function signAddon({\n apiKey,\n apiSecret,\n apiProxy,\n amoBaseUrl,\n validationCheckTimeout,\n approvalCheckTimeout,\n id,\n xpiPath,\n downloadDir,\n channel,\n savedIdPath,\n savedUploadUuidPath,\n metaDataJson = {},\n submissionSource,\n userAgentString = 'web-ext-lib',\n SubmitClient = Client,\n ApiAuthClass = JwtApiAuth,\n}) {\n try {\n const stats = await fsPromises.stat(xpiPath);\n\n if (!stats.isFile()) {\n throw new Error('not a file');\n }\n } catch (statError) {\n throw new Error(`error with ${xpiPath}: ${statError}`);\n }\n\n let baseUrl;\n try {\n baseUrl = new URL(amoBaseUrl);\n } catch (err) {\n throw new Error(`Invalid AMO API base URL: ${amoBaseUrl}`);\n }\n\n const client = new SubmitClient({\n apiAuth: new ApiAuthClass({ apiKey, apiSecret }),\n apiProxy,\n baseUrl,\n validationCheckTimeout,\n approvalCheckTimeout,\n downloadDir,\n userAgentString,\n });\n const uploadUuid = await client.getPreviousUuidOrUploadXpi(\n xpiPath,\n channel,\n savedUploadUuidPath,\n );\n const patchData = {};\n // if we have a source file we need to upload we patch after the create\n if (submissionSource) {\n try {\n const stats2 = await fsPromises.stat(submissionSource);\n\n if (!stats2.isFile()) {\n throw new Error('not a file');\n }\n } catch (statError) {\n throw new Error(`error with ${submissionSource}: ${statError}`);\n }\n patchData.version = { source: client.fileFromSync(submissionSource) };\n }\n\n // We specifically need to know if `id` has not been passed as a parameter because\n // it's the indication that a new add-on should be created, rather than a new version.\n if (id === undefined) {\n return client.postNewAddon(\n uploadUuid,\n savedIdPath,\n metaDataJson,\n patchData,\n );\n }\n\n return client.putVersion(uploadUuid, id, metaDataJson, patchData);\n}\n\nexport async function saveIdToFile(filePath, id) {\n await fsPromises.writeFile(\n filePath,\n [\n '# This file was created by https://github.com/mozilla/web-ext',\n '# Your auto-generated extension ID for addons.mozilla.org is:',\n id.toString(),\n ].join('\\n'),\n );\n\n log.debug(`Saved auto-generated ID ${id} to ${filePath}`);\n}\n\nexport async function saveUploadUuidToFile(\n filePath,\n { uploadUuid, channel, xpiCrcHash },\n) {\n await fsPromises.writeFile(\n filePath,\n JSON.stringify({ uploadUuid, channel, xpiCrcHash }),\n );\n log.debug(\n `Saved upload UUID ${uploadUuid}, xpi crc hash ${xpiCrcHash}, and channel ${channel} to ${filePath}`,\n );\n}\n\nexport async function getUploadUuidFromFile(\n filePath,\n asyncFsReadFile = defaultAsyncFsReadFile,\n) {\n try {\n const content = await asyncFsReadFile(filePath, 'utf-8');\n const { uploadUuid, channel, xpiCrcHash } = JSON.parse(content);\n log.debug(\n `Found upload uuid:${uploadUuid}, channel:${channel}, hash:${xpiCrcHash} in ${filePath}`,\n );\n return { uploadUuid, channel, xpiCrcHash };\n } catch (error) {\n if (isErrorWithCode('ENOENT', error)) {\n log.debug(`No upload uuid file found at: ${filePath}`);\n } else {\n log.debug(`Invalid upload uuid file contents in ${filePath}: ${error}`);\n }\n }\n\n return { uploadUuid: '', channel: '', xpiCrcHash: '' };\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"submit-addon.js","names":["basename","createHash","createWriteStream","promises","fsPromises","readFileSync","streamPromises","SignJWT","JSZip","HttpsProxyAgent","isErrorWithCode","createLogger","log","import","meta","url","defaultAsyncFsReadFile","readFile","JwtApiAuth","apiKey","apiSecret","apiJwtExpiresIn","constructor","signJWT","iss","setProtectedHeader","alg","setIssuedAt","setExpirationTime","sign","Uint8Array","from","Buffer","getAuthHeader","authToken","Client","apiAuth","apiProxy","apiUr","validationCheckInterval","validationCheckTimeout","approvalCheckInterval","approvalCheckTimeout","downloadDir","userAgentString","baseUrl","process","cwd","pathname","endsWith","URL","href","apiUrl","fileFromSync","filePath","fileData","File","global","fd","FormData","set","Blob","get","nodeFetch","method","headers","body","agent","fetch","doUploadSubmit","xpiPath","channel","formData","uuid","fetchJson","waitForValidation","waitRetry","successFunc","checkUrl","checkInterval","abortInterval","context","editUrl","checkTimeout","Promise","resolve","reject","abortTimeout","setTimeout","clearTimeout","errorMessage","Error","pollStatus","responseData","undefined","success","err","info","detailResponseData","processed","debug","validation","valid","JSON","stringify","join","doNewAddonSubmit","metaDataJson","jsonData","version","upload","doNewAddonOrVersionSubmit","addonId","doFormDataPatch","data","versionId","patchUrl","field","response","ok","status","error","warn","Object","keys","doAfterSubmit","newVersionId","patchData","returnResult","fileUrl","waitForApproval","downloadSignedFile","file","errorMsg","statusText","json","Authorization","Accept","downloadedFiles","id","filename","split","pop","dest","saveToFile","contents","destPath","pipeline","hashXpiCrcs","asyncFsReadFile","zip","loadAsync","createFolders","hash","entries","forEach","relativePath","entry","_entry$_data","path","replace","dir","push","crc32","_data","sort","a","b","update","digest","getPreviousUuidOrUploadXpi","savedUploadUuidPath","saveUploadUuidToFileFunc","saveUploadUuidToFile","getUploadUuidFromFileFunc","getUploadUuidFromFile","uploadUuid","previousUuid","previousChannel","xpiCrcHash","previousHash","all","postNewAddon","savedIdPath","saveIdToFileFunc","saveIdToFile","guid","edit_url","putVersion","signAddon","amoBaseUrl","submissionSource","SubmitClient","ApiAuthClass","stats","stat","isFile","statError","client","stats2","source","writeFile","toString","content","parse"],"sources":["../../src/util/submit-addon.js"],"sourcesContent":["import { basename } from 'path';\nimport { createHash } from 'crypto';\nimport { createWriteStream, promises as fsPromises, readFileSync } from 'fs';\nimport { promises as streamPromises } from 'stream';\n\nimport { SignJWT } from 'jose';\nimport JSZip from 'jszip';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\n\nimport { isErrorWithCode } from '../errors.js';\nimport { createLogger } from './../util/logger.js';\n\nconst log = createLogger(import.meta.url);\n\nexport const defaultAsyncFsReadFile = fsPromises.readFile;\n\nexport class JwtApiAuth {\n #apiKey;\n #apiSecret;\n #apiJwtExpiresIn;\n\n constructor({\n apiKey,\n apiSecret,\n apiJwtExpiresIn = 60 * 5, // 5 minutes\n }) {\n this.#apiKey = apiKey;\n this.#apiSecret = apiSecret;\n this.#apiJwtExpiresIn = apiJwtExpiresIn;\n }\n\n async signJWT() {\n return (\n new SignJWT({ iss: this.#apiKey })\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n // jose expects either:\n // a number, which is treated an absolute timestamp - so must be after now, or\n // a string, which is parsed as a relative time from now.\n .setExpirationTime(`${this.#apiJwtExpiresIn}seconds`)\n .sign(Uint8Array.from(Buffer.from(this.#apiSecret, 'utf8')))\n );\n }\n\n async getAuthHeader() {\n const authToken = await this.signJWT();\n return `JWT ${authToken}`;\n }\n}\n\nexport default class Client {\n apiAuth;\n apiProxy;\n apiUr;\n validationCheckInterval;\n validationCheckTimeout;\n approvalCheckInterval;\n approvalCheckTimeout;\n downloadDir;\n userAgentString;\n\n constructor({\n apiAuth,\n apiProxy,\n baseUrl,\n validationCheckInterval = 1000,\n validationCheckTimeout = 300000, // 5 minutes.\n approvalCheckInterval = 1000,\n approvalCheckTimeout = 900000, // 15 minutes.\n downloadDir = process.cwd(),\n userAgentString = 'web-ext-lib',\n }) {\n this.apiAuth = apiAuth;\n if (apiProxy) {\n this.apiProxy = apiProxy;\n }\n if (!baseUrl.pathname.endsWith('/')) {\n baseUrl = new URL(baseUrl.href);\n baseUrl.pathname += '/';\n }\n this.apiUrl = new URL('addons/', baseUrl);\n this.validationCheckInterval = validationCheckInterval;\n this.validationCheckTimeout = validationCheckTimeout;\n this.approvalCheckInterval = approvalCheckInterval;\n this.approvalCheckTimeout = approvalCheckTimeout;\n this.downloadDir = downloadDir;\n this.userAgentString = userAgentString;\n }\n\n fileFromSync(filePath) {\n // create a File blob from a file path, and ensure it to have the file path basename\n // as the associated filename, the AMO server API will be checking it on the form-data\n // submitted and fail with the error message:\n // \"Unsupported file type, please upload a supported file (.crx, .xpi, .zip).\"\n const fileData = readFileSync(filePath);\n // eslint-disable-next-line no-shadow -- File is in Node v20.0.0+.\n let File = global.File;\n // TODO: Use the File global directly without the fallback when we drop\n // support for Node versions before v20.\n if (typeof File === 'undefined') {\n // Even without File being public, its interface and constructor could\n // be accessed indirectly from the FormData interface. According to the\n // FormData spec (that Node.js implements, via undici), the entry value\n // of a FormData is always a scalar value or a File:\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-entry-value\n const fd = new FormData();\n fd.set('x', new Blob([]));\n File = fd.get('x').constructor;\n }\n return new File([fileData], basename(filePath));\n }\n\n nodeFetch(url, { method, headers, body, agent }) {\n return fetch(url, { method, headers, body, agent });\n }\n\n async doUploadSubmit(xpiPath, channel) {\n const url = new URL('upload/', this.apiUrl);\n const formData = new FormData();\n formData.set('channel', channel);\n formData.set('upload', this.fileFromSync(xpiPath));\n const { uuid } = await this.fetchJson(\n url,\n 'POST',\n formData,\n 'Upload failed',\n );\n return this.waitForValidation(uuid);\n }\n\n waitRetry(\n successFunc,\n checkUrl,\n checkInterval,\n abortInterval,\n context,\n editUrl = null,\n ) {\n let checkTimeout;\n\n return new Promise((resolve, reject) => {\n const abortTimeout = setTimeout(() => {\n clearTimeout(checkTimeout);\n\n let errorMessage = `${context}: timeout exceeded.`;\n if (editUrl) {\n errorMessage += ` When approved the signed XPI file can be downloaded from ${editUrl}`;\n }\n\n reject(new Error(errorMessage));\n }, abortInterval);\n\n const pollStatus = async () => {\n try {\n const responseData = await this.fetchJson(\n checkUrl,\n 'GET',\n undefined,\n 'Getting details failed',\n );\n\n const success = successFunc(responseData);\n if (success) {\n clearTimeout(abortTimeout);\n resolve(success);\n } else {\n // Still in progress, so wait for a while and try again.\n checkTimeout = setTimeout(pollStatus, checkInterval);\n }\n } catch (err) {\n clearTimeout(abortTimeout);\n reject(err);\n }\n };\n\n pollStatus();\n });\n }\n\n waitForValidation(uuid) {\n log.info('Waiting for validation...');\n return this.waitRetry(\n (detailResponseData) => {\n if (!detailResponseData.processed) {\n return null;\n }\n\n log.debug('Validation results:', detailResponseData.validation);\n if (detailResponseData.valid) {\n return detailResponseData.uuid;\n }\n\n throw new Error(\n [\n 'Validation failed:\\n',\n JSON.stringify(detailResponseData.validation, null, 2),\n ].join(''),\n );\n },\n new URL(`upload/${uuid}/`, this.apiUrl),\n this.validationCheckInterval,\n this.validationCheckTimeout,\n 'Validation',\n );\n }\n\n async doNewAddonSubmit(uuid, metaDataJson) {\n const url = new URL('addon/', this.apiUrl);\n const jsonData = {\n ...metaDataJson,\n version: { upload: uuid, ...metaDataJson.version },\n };\n return this.fetchJson(\n url,\n 'POST',\n JSON.stringify(jsonData),\n 'Submission failed (1)',\n );\n }\n\n doNewAddonOrVersionSubmit(addonId, uuid, metaDataJson) {\n const url = new URL(`addon/${addonId}/`, this.apiUrl);\n const jsonData = {\n ...metaDataJson,\n version: { upload: uuid, ...metaDataJson.version },\n };\n return this.fetchJson(\n url,\n 'PUT',\n JSON.stringify(jsonData),\n 'Submission failed (2)',\n );\n }\n\n async doFormDataPatch(data, addonId, versionId) {\n const patchUrl = new URL(\n `addon/${addonId}/versions/${versionId}/`,\n this.apiUrl,\n );\n try {\n const formData = new FormData();\n for (const field in data) {\n formData.set(field, data[field]);\n }\n\n const response = await this.fetch(patchUrl, 'PATCH', formData);\n if (!response.ok) {\n throw new Error(`response status was ${response.status}`);\n }\n } catch (error) {\n log.warn(`Upload of ${Object.keys(data)} failed: ${error}.`);\n throw new Error(`Uploading ${Object.keys(data)} failed`);\n }\n }\n\n async doAfterSubmit(addonId, newVersionId, editUrl, patchData) {\n if (patchData && patchData.version) {\n log.info(`Submitting ${Object.keys(patchData.version)} to version`);\n await this.doFormDataPatch(patchData.version, addonId, newVersionId);\n }\n\n if (this.approvalCheckTimeout === 0) {\n log.info(\n [\n 'Waiting for approval and download of signed XPI skipped.',\n `When approved the signed XPI file can be downloaded from ${editUrl}`,\n ].join(' '),\n );\n return this.returnResult(addonId);\n }\n\n const fileUrl = new URL(\n await this.waitForApproval(addonId, newVersionId, editUrl),\n );\n return this.downloadSignedFile(fileUrl, addonId);\n }\n\n waitForApproval(addonId, versionId, editUrl) {\n log.info('Waiting for approval...');\n return this.waitRetry(\n (detailResponseData) => {\n const { file } = detailResponseData;\n if (file && file.status === 'public') {\n return file.url;\n }\n\n return null;\n },\n new URL(`addon/${addonId}/versions/${versionId}/`, this.apiUrl),\n this.approvalCheckInterval,\n this.approvalCheckTimeout,\n 'Approval',\n editUrl,\n );\n }\n\n async fetchJson(url, method = 'GET', body, errorMsg = 'Bad Request') {\n const response = await this.fetch(url, method, body);\n if (response.status < 200 || response.status >= 500) {\n throw new Error(\n `${errorMsg}: ${response.statusText || response.status}.`,\n );\n }\n const data = await response.json();\n\n if (!response.ok) {\n throw new Error(\n [\n `${errorMsg}: ${response.statusText || response.status}`,\n JSON.stringify(data, null, 2),\n ].join('\\n'),\n );\n }\n return data;\n }\n\n async fetch(url, method = 'GET', body) {\n log.debug(`${method}ing URL: ${url.href}`);\n let headers = {\n Authorization: await this.apiAuth.getAuthHeader(),\n Accept: 'application/json',\n 'User-Agent': this.userAgentString,\n };\n if (typeof body === 'string') {\n headers = {\n ...headers,\n 'Content-Type': 'application/json',\n };\n }\n let agent;\n if (this.apiProxy) {\n agent = new HttpsProxyAgent(this.apiProxy);\n }\n return this.nodeFetch(url, { method, body, headers, agent });\n }\n\n returnResult(addonId, downloadedFiles) {\n return {\n id: addonId,\n downloadedFiles,\n };\n }\n\n async downloadSignedFile(fileUrl, addonId) {\n const filename = fileUrl.pathname.split('/').pop(); // get the name from fileUrl\n const dest = `${this.downloadDir}/${filename}`;\n try {\n const response = await this.fetch(fileUrl);\n if (!response.ok || !response.body) {\n throw new Error(`response status was ${response.status}`);\n }\n await this.saveToFile(response.body, dest);\n } catch (error) {\n log.info(`Download of signed xpi failed: ${error}.`);\n throw new Error(`Downloading ${filename} failed`);\n }\n log.info(`Signed xpi downloaded: ${dest}`);\n return this.returnResult(addonId, [filename]);\n }\n\n async saveToFile(contents, destPath) {\n return streamPromises.pipeline(contents, createWriteStream(destPath));\n }\n\n /*\n This function aims to quickly hash the contents of the zip file that's being uploaded,\n to compare it to the previous zip file that was uploaded, so we can skip the upload for\n efficiency.\n\n CRCs are used from the zip to avoid having to extract and hash all the files.\n\n Two zips that have different byte contents in their files must have a different hash;\n but returning a different hash when the contents are the same in some cases is acceptable\n - a false mismatch does not result in lost data.\n */\n async hashXpiCrcs(filePath, asyncFsReadFile = defaultAsyncFsReadFile) {\n const zip = await JSZip.loadAsync(\n asyncFsReadFile(filePath, { createFolders: true }),\n );\n const hash = createHash('sha256');\n const entries = [];\n zip.forEach((relativePath, entry) => {\n let path = relativePath.replace(/\\/+$/, '');\n if (entry.dir) {\n path += '/';\n }\n // if the file is 0 bytes or a dir `_data` is missing so assume crc is 0\n entries.push({ path, crc32: entry._data?.crc32 || 0 });\n });\n entries.sort((a, b) => (a.path === b.path ? 0 : a.path > b.path ? 1 : -1));\n hash.update(JSON.stringify(entries));\n return hash.digest('hex');\n }\n\n async getPreviousUuidOrUploadXpi(\n xpiPath,\n channel,\n savedUploadUuidPath,\n saveUploadUuidToFileFunc = saveUploadUuidToFile,\n getUploadUuidFromFileFunc = getUploadUuidFromFile,\n ) {\n const [\n {\n uploadUuid: previousUuid,\n channel: previousChannel,\n xpiCrcHash: previousHash,\n },\n xpiCrcHash,\n ] = await Promise.all([\n getUploadUuidFromFileFunc(savedUploadUuidPath),\n this.hashXpiCrcs(xpiPath),\n ]);\n\n let uploadUuid;\n if (previousChannel !== channel || xpiCrcHash !== previousHash) {\n uploadUuid = await this.doUploadSubmit(xpiPath, channel);\n await saveUploadUuidToFileFunc(savedUploadUuidPath, {\n uploadUuid,\n channel,\n xpiCrcHash,\n });\n } else {\n uploadUuid = previousUuid;\n }\n return uploadUuid;\n }\n\n async postNewAddon(\n uploadUuid,\n savedIdPath,\n metaDataJson,\n patchData,\n saveIdToFileFunc = saveIdToFile,\n ) {\n const {\n guid: addonId,\n version: { id: newVersionId, edit_url: editUrl },\n } = await this.doNewAddonSubmit(uploadUuid, metaDataJson);\n\n await saveIdToFileFunc(savedIdPath, addonId);\n log.info(`Generated extension ID: ${addonId}.`);\n log.info('You must add the following to your manifest:');\n log.info(`\"browser_specific_settings\": {\"gecko\": {\"id\": \"${addonId}\"}}`);\n\n return this.doAfterSubmit(addonId, newVersionId, editUrl, patchData);\n }\n\n async putVersion(uploadUuid, addonId, metaDataJson, patchData) {\n const {\n version: { id: newVersionId, edit_url: editUrl },\n } = await this.doNewAddonOrVersionSubmit(addonId, uploadUuid, metaDataJson);\n\n return this.doAfterSubmit(addonId, newVersionId, editUrl, patchData);\n }\n}\n\nexport async function signAddon({\n apiKey,\n apiSecret,\n apiProxy,\n amoBaseUrl,\n validationCheckTimeout,\n approvalCheckTimeout,\n id,\n xpiPath,\n downloadDir,\n channel,\n savedIdPath,\n savedUploadUuidPath,\n metaDataJson = {},\n submissionSource,\n userAgentString = 'web-ext-lib',\n SubmitClient = Client,\n ApiAuthClass = JwtApiAuth,\n}) {\n try {\n const stats = await fsPromises.stat(xpiPath);\n\n if (!stats.isFile()) {\n throw new Error('not a file');\n }\n } catch (statError) {\n throw new Error(`error with ${xpiPath}: ${statError}`);\n }\n\n let baseUrl;\n try {\n baseUrl = new URL(amoBaseUrl);\n } catch (err) {\n throw new Error(`Invalid AMO API base URL: ${amoBaseUrl}`);\n }\n\n const client = new SubmitClient({\n apiAuth: new ApiAuthClass({ apiKey, apiSecret }),\n apiProxy,\n baseUrl,\n validationCheckTimeout,\n approvalCheckTimeout,\n downloadDir,\n userAgentString,\n });\n const uploadUuid = await client.getPreviousUuidOrUploadXpi(\n xpiPath,\n channel,\n savedUploadUuidPath,\n );\n const patchData = {};\n // if we have a source file we need to upload we patch after the create\n if (submissionSource) {\n try {\n const stats2 = await fsPromises.stat(submissionSource);\n\n if (!stats2.isFile()) {\n throw new Error('not a file');\n }\n } catch (statError) {\n throw new Error(`error with ${submissionSource}: ${statError}`);\n }\n patchData.version = { source: client.fileFromSync(submissionSource) };\n }\n\n // We specifically need to know if `id` has not been passed as a parameter because\n // it's the indication that a new add-on should be created, rather than a new version.\n if (id === undefined) {\n return client.postNewAddon(\n uploadUuid,\n savedIdPath,\n metaDataJson,\n patchData,\n );\n }\n\n return client.putVersion(uploadUuid, id, metaDataJson, patchData);\n}\n\nexport async function saveIdToFile(filePath, id) {\n await fsPromises.writeFile(\n filePath,\n [\n '# This file was created by https://github.com/mozilla/web-ext',\n '# Your auto-generated extension ID for addons.mozilla.org is:',\n id.toString(),\n ].join('\\n'),\n );\n\n log.debug(`Saved auto-generated ID ${id} to ${filePath}`);\n}\n\nexport async function saveUploadUuidToFile(\n filePath,\n { uploadUuid, channel, xpiCrcHash },\n) {\n await fsPromises.writeFile(\n filePath,\n JSON.stringify({ uploadUuid, channel, xpiCrcHash }),\n );\n log.debug(\n `Saved upload UUID ${uploadUuid}, xpi crc hash ${xpiCrcHash}, and channel ${channel} to ${filePath}`,\n );\n}\n\nexport async function getUploadUuidFromFile(\n filePath,\n asyncFsReadFile = defaultAsyncFsReadFile,\n) {\n try {\n const content = await asyncFsReadFile(filePath, 'utf-8');\n const { uploadUuid, channel, xpiCrcHash } = JSON.parse(content);\n log.debug(\n `Found upload uuid:${uploadUuid}, channel:${channel}, hash:${xpiCrcHash} in ${filePath}`,\n );\n return { uploadUuid, channel, xpiCrcHash };\n } catch (error) {\n if (isErrorWithCode('ENOENT', error)) {\n log.debug(`No upload uuid file found at: ${filePath}`);\n } else {\n log.debug(`Invalid upload uuid file contents in ${filePath}: ${error}`);\n }\n }\n\n return { uploadUuid: '', channel: '', xpiCrcHash: '' };\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "web-ext",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.9.0",
|
|
4
4
|
"description": "A command line tool to help build, run, and test web extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"opera"
|
|
60
60
|
],
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@babel/runtime": "7.27.
|
|
62
|
+
"@babel/runtime": "7.27.6",
|
|
63
63
|
"@devicefarmer/adbkit": "3.3.8",
|
|
64
|
-
"addons-linter": "7.
|
|
64
|
+
"addons-linter": "7.18.0",
|
|
65
65
|
"camelcase": "8.0.0",
|
|
66
66
|
"chrome-launcher": "1.2.0",
|
|
67
67
|
"debounce": "1.2.1",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"jszip": "3.10.1",
|
|
75
75
|
"multimatch": "6.0.0",
|
|
76
76
|
"node-notifier": "10.0.1",
|
|
77
|
-
"open": "10.
|
|
77
|
+
"open": "10.2.0",
|
|
78
78
|
"parse-json": "7.1.1",
|
|
79
79
|
"pino": "9.7.0",
|
|
80
80
|
"promise-toolbox": "0.21.0",
|
|
@@ -84,21 +84,20 @@
|
|
|
84
84
|
"tmp": "0.2.3",
|
|
85
85
|
"update-notifier": "7.3.1",
|
|
86
86
|
"watchpack": "2.4.4",
|
|
87
|
-
"ws": "8.18.2",
|
|
88
87
|
"yargs": "17.7.2",
|
|
89
88
|
"zip-dir": "2.0.0"
|
|
90
89
|
},
|
|
91
90
|
"devDependencies": {
|
|
92
|
-
"@babel/cli": "7.
|
|
93
|
-
"@babel/core": "7.
|
|
94
|
-
"@babel/eslint-parser": "7.
|
|
95
|
-
"@babel/preset-env": "7.
|
|
91
|
+
"@babel/cli": "7.28.0",
|
|
92
|
+
"@babel/core": "7.28.0",
|
|
93
|
+
"@babel/eslint-parser": "7.28.0",
|
|
94
|
+
"@babel/preset-env": "7.28.0",
|
|
96
95
|
"@babel/register": "7.27.1",
|
|
97
96
|
"@commitlint/cli": "19.8.1",
|
|
98
97
|
"@commitlint/config-conventional": "19.8.1",
|
|
99
98
|
"babel-plugin-istanbul": "7.0.0",
|
|
100
99
|
"babel-plugin-transform-inline-environment-variables": "0.4.4",
|
|
101
|
-
"chai": "5.2.
|
|
100
|
+
"chai": "5.2.1",
|
|
102
101
|
"chai-as-promised": "8.0.1",
|
|
103
102
|
"copy-dir": "1.3.0",
|
|
104
103
|
"crc-32": "1.2.2",
|
|
@@ -106,17 +105,17 @@
|
|
|
106
105
|
"deepcopy": "2.1.0",
|
|
107
106
|
"eslint": "8.57.0",
|
|
108
107
|
"eslint-plugin-async-await": "0.0.0",
|
|
109
|
-
"eslint-plugin-import": "2.
|
|
108
|
+
"eslint-plugin-import": "2.32.0",
|
|
110
109
|
"fs-extra": "11.3.0",
|
|
111
110
|
"git-rev-sync": "3.0.2",
|
|
112
111
|
"html-entities": "2.6.0",
|
|
113
|
-
"mocha": "11.
|
|
112
|
+
"mocha": "11.7.1",
|
|
114
113
|
"nyc": "17.1.0",
|
|
115
|
-
"prettier": "3.
|
|
116
|
-
"pretty-quick": "4.
|
|
114
|
+
"prettier": "3.6.2",
|
|
115
|
+
"pretty-quick": "4.2.2",
|
|
117
116
|
"prettyjson": "1.2.5",
|
|
118
117
|
"shelljs": "0.8.5",
|
|
119
|
-
"sinon": "
|
|
118
|
+
"sinon": "21.0.0",
|
|
120
119
|
"testdouble": "3.20.2",
|
|
121
120
|
"yauzl": "2.10.0"
|
|
122
121
|
},
|