extension 4.1.21 → 4.1.22
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/dist/{84.cjs → 597.cjs} +78 -1
- package/dist/browsers.cjs +294 -33
- package/dist/cli.cjs +295 -34
- package/dist/extension/browsers/browsers-lib/messages.d.ts +1 -1
- package/dist/extension/browsers/browsers-lib/process-teardown.d.ts +3 -0
- package/dist/extension/browsers/browsers-lib/ready-stamp.d.ts +1 -0
- package/dist/extension/browsers/browsers-lib/resolve-live-pid.d.ts +25 -0
- package/dist/extension/browsers/browsers-types.d.ts +1 -1
- package/dist/extension/browsers/run-chromium/cdp/cdp-extension-controller/index.d.ts +2 -0
- package/dist/extension/browsers/run-chromium/cdp/ensure-developer-mode.d.ts +12 -0
- package/dist/extension/browsers/run-firefox/firefox-launch/index.d.ts +9 -0
- package/dist/extension/browsers/run-firefox/firefox-launch/process-handlers.d.ts +1 -1
- package/dist/extension/helpers/messaging.d.ts +1 -0
- package/dist/extension/helpers/template-catalog.d.ts +1 -1
- package/dist/extension/helpers/template-corpus.generated.d.ts +1 -1
- package/package.json +5 -5
package/dist/{84.cjs → 597.cjs}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
exports.ids = [
|
|
3
|
-
|
|
3
|
+
597
|
|
4
4
|
];
|
|
5
5
|
exports.modules = {
|
|
6
6
|
"./browsers/run-chromium/cdp/cdp-extension-controller/ensure.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -483,6 +483,73 @@ exports.modules = {
|
|
|
483
483
|
this.host = host;
|
|
484
484
|
}
|
|
485
485
|
}
|
|
486
|
+
const EXTENSIONS_PAGE = 'chrome://extensions';
|
|
487
|
+
const READ_DEVELOPER_MODE = "new Promise((resolve) => chrome.developerPrivate.getProfileConfiguration((config) => resolve(!!config.inDeveloperMode)))";
|
|
488
|
+
const ENABLE_DEVELOPER_MODE = "new Promise((resolve) => chrome.developerPrivate.updateProfileConfiguration({inDeveloperMode: true}, () => resolve(!chrome.runtime.lastError)))";
|
|
489
|
+
function developerModeFromProfile(profilePath) {
|
|
490
|
+
try {
|
|
491
|
+
const securePath = external_node_path_.join(profilePath, 'Default', 'Secure Preferences');
|
|
492
|
+
const parsed = JSON.parse(external_node_fs_.readFileSync(securePath, 'utf-8'));
|
|
493
|
+
return parsed?.extensions?.ui?.developer_mode === true;
|
|
494
|
+
} catch {
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
function developerModeFlipIsSafe(browserArgs) {
|
|
499
|
+
return !browserArgs.some((arg)=>arg.startsWith('--no-startup-window'));
|
|
500
|
+
}
|
|
501
|
+
async function evaluateBoolean(transport, sessionId, expression) {
|
|
502
|
+
try {
|
|
503
|
+
const response = await transport.sendCommand('Runtime.evaluate', {
|
|
504
|
+
expression,
|
|
505
|
+
awaitPromise: true,
|
|
506
|
+
returnByValue: true
|
|
507
|
+
}, sessionId);
|
|
508
|
+
const value = response?.result?.value;
|
|
509
|
+
return 'boolean' == typeof value ? value : void 0;
|
|
510
|
+
} catch {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
async function ensureDeveloperMode(options) {
|
|
515
|
+
const { transport } = options;
|
|
516
|
+
const attempts = options.attempts ?? 10;
|
|
517
|
+
const delayMs = options.delayMs ?? 200;
|
|
518
|
+
const sleep = options.sleep ?? ((ms)=>new Promise((r)=>setTimeout(r, ms)));
|
|
519
|
+
let targetId = '';
|
|
520
|
+
try {
|
|
521
|
+
const created = await transport.sendCommand('Target.createTarget', {
|
|
522
|
+
url: EXTENSIONS_PAGE,
|
|
523
|
+
background: true
|
|
524
|
+
});
|
|
525
|
+
targetId = created?.targetId ?? '';
|
|
526
|
+
if (!targetId) return 'unavailable';
|
|
527
|
+
const attached = await transport.sendCommand('Target.attachToTarget', {
|
|
528
|
+
targetId,
|
|
529
|
+
flatten: true
|
|
530
|
+
});
|
|
531
|
+
const sessionId = attached?.sessionId ?? '';
|
|
532
|
+
if (!sessionId) return 'unavailable';
|
|
533
|
+
for(let attempt = 0; attempt < attempts; attempt++){
|
|
534
|
+
const current = await evaluateBoolean(transport, sessionId, READ_DEVELOPER_MODE);
|
|
535
|
+
if (true === current) return 'already-on';
|
|
536
|
+
if (false === current) {
|
|
537
|
+
const enabled = await evaluateBoolean(transport, sessionId, ENABLE_DEVELOPER_MODE);
|
|
538
|
+
return true === enabled ? 'enabled' : 'unavailable';
|
|
539
|
+
}
|
|
540
|
+
await sleep(delayMs);
|
|
541
|
+
}
|
|
542
|
+
return 'unavailable';
|
|
543
|
+
} catch {
|
|
544
|
+
return 'unavailable';
|
|
545
|
+
} finally{
|
|
546
|
+
if (targetId) try {
|
|
547
|
+
await transport.sendCommand('Target.closeTarget', {
|
|
548
|
+
targetId
|
|
549
|
+
});
|
|
550
|
+
} catch {}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
486
553
|
function isRecoverableBootstrapError(error) {
|
|
487
554
|
const msg = String(error?.message || error || '').toLowerCase();
|
|
488
555
|
return msg.includes('econnreset') || msg.includes('websocket is not open') || msg.includes('cdp transport is not open') || msg.includes('cdp connection closed') || msg.includes('cdp pipe closed') || msg.includes('socket hang up') || msg.includes('timed out') || msg.includes('no cdp websocket url');
|
|
@@ -784,6 +851,12 @@ exports.modules = {
|
|
|
784
851
|
if (this.cdp) return;
|
|
785
852
|
await this.connectFreshClient();
|
|
786
853
|
}
|
|
854
|
+
async ensureDeveloperMode() {
|
|
855
|
+
if (!this.cdp) return 'unavailable';
|
|
856
|
+
return ensureDeveloperMode({
|
|
857
|
+
transport: this.cdp
|
|
858
|
+
});
|
|
859
|
+
}
|
|
787
860
|
async openTab(url) {
|
|
788
861
|
if (!this.cdp) return;
|
|
789
862
|
await this.cdp.sendCommand('Target.createTarget', {
|
|
@@ -1110,6 +1183,10 @@ exports.modules = {
|
|
|
1110
1183
|
});
|
|
1111
1184
|
await cdpExtensionController.connect();
|
|
1112
1185
|
if ((0, messaging._o)()) (0, messaging._w)(messages.M3('127.0.0.1', chromeRemoteDebugPort));
|
|
1186
|
+
if (userDataDir && developerModeFlipIsSafe(chromiumArgs) && !developerModeFromProfile(userDataDir)) {
|
|
1187
|
+
const developerMode = await cdpExtensionController.ensureDeveloperMode();
|
|
1188
|
+
if ((0, messaging._o)()) (0, messaging._w)(`[CDP] developer mode: ${developerMode}`);
|
|
1189
|
+
}
|
|
1113
1190
|
try {
|
|
1114
1191
|
if (extensionOutputPath && Number.isFinite(chromeRemoteDebugPort)) {
|
|
1115
1192
|
const readyPath = external_node_path_.join(external_node_path_.dirname(extensionOutputPath), 'extension-js', external_node_path_.basename(extensionOutputPath), 'ready.json');
|
package/dist/browsers.cjs
CHANGED
|
@@ -229,7 +229,7 @@ var __webpack_modules__ = {
|
|
|
229
229
|
(0, _helpers_messaging__rspack_import_3._w)(_messages__rspack_import_5.io());
|
|
230
230
|
}
|
|
231
231
|
} catch {
|
|
232
|
-
const provenanceNote = _messages__rspack_import_5.xX(opts.binaryProvenance);
|
|
232
|
+
const provenanceNote = _messages__rspack_import_5.xX(opts.binaryProvenance, opts.browser);
|
|
233
233
|
(0, _helpers_messaging__rspack_import_3._w)(_messages__rspack_import_5.io());
|
|
234
234
|
(0, _helpers_messaging__rspack_import_3._w)((0, _helpers_messaging__rspack_import_3.Nr)({
|
|
235
235
|
rows: [
|
|
@@ -420,6 +420,7 @@ var __webpack_modules__ = {
|
|
|
420
420
|
var pintor__rspack_import_8 = __webpack_require__("pintor");
|
|
421
421
|
var pintor__rspack_import_8_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_8);
|
|
422
422
|
var _helpers_messaging__rspack_import_9 = __webpack_require__("./helpers/messaging.ts");
|
|
423
|
+
var _browser_family__rspack_import_10 = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
|
|
423
424
|
const require1 = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
|
|
424
425
|
function getLoggingPrefix(type) {
|
|
425
426
|
return (0, _helpers_messaging__rspack_import_9.Pl)(type);
|
|
@@ -828,9 +829,15 @@ var __webpack_modules__ = {
|
|
|
828
829
|
if (rest.startsWith(node_path__rspack_import_3.sep) || rest.startsWith('/')) return `~${rest}`;
|
|
829
830
|
return raw;
|
|
830
831
|
}
|
|
831
|
-
function binaryProvenanceNote(provenance) {
|
|
832
|
-
if ('pinned'
|
|
833
|
-
return
|
|
832
|
+
function binaryProvenanceNote(provenance, browser) {
|
|
833
|
+
if ('pinned' !== provenance) return '';
|
|
834
|
+
return `(pinned with ${pinnedBinaryFlag(browser)})`;
|
|
835
|
+
}
|
|
836
|
+
function pinnedBinaryFlag(browser) {
|
|
837
|
+
const name = String(browser || '');
|
|
838
|
+
if ((0, _browser_family__rspack_import_10.M_)(name)) return '--gecko-binary';
|
|
839
|
+
if ('safari' === name || 'webkit-based' === name) return '--safari-binary';
|
|
840
|
+
return '--chromium-binary';
|
|
834
841
|
}
|
|
835
842
|
function runningInDevelopment(manifest, browser, message, browserVersionLine, updateSuffix, opts) {
|
|
836
843
|
const capitalize = (str)=>str.charAt(0).toUpperCase() + str.slice(1);
|
|
@@ -866,7 +873,7 @@ var __webpack_modules__ = {
|
|
|
866
873
|
const baseBrowserLabel = (0, _helpers_messaging__rspack_import_9.A6)(String(browser || 'unknown'), resolveBrowserVersionLine(browser, browserVersionLine, {
|
|
867
874
|
pinned: opts?.binaryProvenance === 'pinned'
|
|
868
875
|
}));
|
|
869
|
-
const provenanceNote = binaryProvenanceNote(opts?.binaryProvenance);
|
|
876
|
+
const provenanceNote = binaryProvenanceNote(opts?.binaryProvenance, browser);
|
|
870
877
|
const browserLabel = provenanceNote ? `${baseBrowserLabel} ${provenanceNote}` : baseBrowserLabel;
|
|
871
878
|
const cleanId = String(id || '').trim();
|
|
872
879
|
const includeExtensionId = opts?.includeExtensionId !== false;
|
|
@@ -1325,17 +1332,21 @@ var __webpack_modules__ = {
|
|
|
1325
1332
|
var _messages__rspack_import_2 = __webpack_require__("./browsers/browsers-lib/messages.ts");
|
|
1326
1333
|
const FORCE_KILL_GRACE_MS = 5000;
|
|
1327
1334
|
const terminatedByUs = new WeakSet();
|
|
1335
|
+
const terminatedPids = new Set();
|
|
1328
1336
|
function wasTerminatedByUs(child) {
|
|
1329
1337
|
return !!child && terminatedByUs.has(child);
|
|
1330
1338
|
}
|
|
1339
|
+
function wasPidTerminatedByUs(pid) {
|
|
1340
|
+
return 'number' == typeof pid && terminatedPids.has(pid);
|
|
1341
|
+
}
|
|
1331
1342
|
function authorLog(line) {
|
|
1332
1343
|
if (line && (0, _helpers_messaging__rspack_import_1._o)()) (0, _helpers_messaging__rspack_import_1._w)(line);
|
|
1333
1344
|
}
|
|
1334
|
-
function killWindowsTree(
|
|
1335
|
-
if ('win32' !== process.platform) return;
|
|
1345
|
+
function killWindowsTree(pid, sync) {
|
|
1346
|
+
if ('win32' !== process.platform || !pid) return;
|
|
1336
1347
|
const args = [
|
|
1337
1348
|
'/PID',
|
|
1338
|
-
String(
|
|
1349
|
+
String(pid),
|
|
1339
1350
|
'/T',
|
|
1340
1351
|
'/F'
|
|
1341
1352
|
];
|
|
@@ -1350,10 +1361,37 @@ var __webpack_modules__ = {
|
|
|
1350
1361
|
}).on('error', ()=>{});
|
|
1351
1362
|
} catch {}
|
|
1352
1363
|
}
|
|
1364
|
+
function signalPid(pid, signal) {
|
|
1365
|
+
try {
|
|
1366
|
+
process.kill(pid, signal);
|
|
1367
|
+
return true;
|
|
1368
|
+
} catch {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
function gracefulTerminatePid(pid, browser) {
|
|
1373
|
+
if (!pid || terminatedPids.has(pid)) return;
|
|
1374
|
+
terminatedPids.add(pid);
|
|
1375
|
+
killWindowsTree(pid, false);
|
|
1376
|
+
authorLog(_messages__rspack_import_2.XH(browser));
|
|
1377
|
+
signalPid(pid, 'SIGTERM');
|
|
1378
|
+
const killTimer = setTimeout(()=>{
|
|
1379
|
+
authorLog(_messages__rspack_import_2.AG(browser));
|
|
1380
|
+
signalPid(pid, 'SIGKILL');
|
|
1381
|
+
}, FORCE_KILL_GRACE_MS);
|
|
1382
|
+
killTimer.unref?.();
|
|
1383
|
+
}
|
|
1384
|
+
function forceKillPidOnExit(pid, browser) {
|
|
1385
|
+
if (!pid) return;
|
|
1386
|
+
terminatedPids.add(pid);
|
|
1387
|
+
killWindowsTree(pid, true);
|
|
1388
|
+
authorLog(_messages__rspack_import_2.AG(browser));
|
|
1389
|
+
signalPid(pid, 'SIGKILL');
|
|
1390
|
+
}
|
|
1353
1391
|
function gracefulTerminateChild(child, browser) {
|
|
1354
1392
|
if (!child || child.killed) return;
|
|
1355
1393
|
terminatedByUs.add(child);
|
|
1356
|
-
killWindowsTree(child, false);
|
|
1394
|
+
killWindowsTree(child.pid, false);
|
|
1357
1395
|
authorLog(_messages__rspack_import_2.XH(browser));
|
|
1358
1396
|
child.kill('SIGTERM');
|
|
1359
1397
|
const killTimer = setTimeout(()=>{
|
|
@@ -1367,7 +1405,7 @@ var __webpack_modules__ = {
|
|
|
1367
1405
|
function forceKillChildOnExit(child, browser) {
|
|
1368
1406
|
if (!child) return;
|
|
1369
1407
|
terminatedByUs.add(child);
|
|
1370
|
-
killWindowsTree(child, true);
|
|
1408
|
+
killWindowsTree(child.pid, true);
|
|
1371
1409
|
try {
|
|
1372
1410
|
authorLog(_messages__rspack_import_2.AG(browser));
|
|
1373
1411
|
child.kill('SIGKILL');
|
|
@@ -1388,7 +1426,10 @@ var __webpack_modules__ = {
|
|
|
1388
1426
|
$Y: ()=>forceKillChildOnExit,
|
|
1389
1427
|
Df: ()=>gracefulTerminateChild,
|
|
1390
1428
|
FA: ()=>isBenignSocketTeardown,
|
|
1391
|
-
Op: ()=>wasTerminatedByUs
|
|
1429
|
+
Op: ()=>wasTerminatedByUs,
|
|
1430
|
+
PU: ()=>wasPidTerminatedByUs,
|
|
1431
|
+
Qx: ()=>forceKillPidOnExit,
|
|
1432
|
+
_T: ()=>gracefulTerminatePid
|
|
1392
1433
|
});
|
|
1393
1434
|
},
|
|
1394
1435
|
"./browsers/browsers-lib/ready-message.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -1432,6 +1473,7 @@ var __webpack_modules__ = {
|
|
|
1432
1473
|
const profilePath = String(details?.profilePath || '').trim();
|
|
1433
1474
|
if (profilePath) ready.profilePath = profilePath;
|
|
1434
1475
|
if ('number' == typeof details?.browserPid && Number.isFinite(details.browserPid)) ready.browserPid = details.browserPid;
|
|
1476
|
+
if ('number' == typeof details?.launcherPid && Number.isFinite(details.launcherPid)) ready.launcherPid = details.launcherPid;
|
|
1435
1477
|
const extensionId = String(details?.extensionId || '').trim();
|
|
1436
1478
|
if (extensionId) ready.extensionId = extensionId;
|
|
1437
1479
|
const binary = String(details?.binary || '').trim();
|
|
@@ -2695,6 +2737,7 @@ var __webpack_modules__ = {
|
|
|
2695
2737
|
'--enable-features=SidePanelUpdates',
|
|
2696
2738
|
'--disable-features=DisableLoadExtensionCommandLineSwitch',
|
|
2697
2739
|
'--disable-features=ExtensionDisableUnsupportedDeveloper',
|
|
2740
|
+
'--disable-features=SafetyHubExtensionsOffStoreTrigger',
|
|
2698
2741
|
'--enable-unsafe-extension-debugging',
|
|
2699
2742
|
'--silent-debugger-extension-api'
|
|
2700
2743
|
];
|
|
@@ -3523,7 +3566,7 @@ var __webpack_modules__ = {
|
|
|
3523
3566
|
binaryProvenance
|
|
3524
3567
|
};
|
|
3525
3568
|
if (enableCdp) {
|
|
3526
|
-
const mod = await __webpack_require__.e(
|
|
3569
|
+
const mod = await __webpack_require__.e(597).then(__webpack_require__.bind(__webpack_require__, "./browsers/run-chromium/chromium-launch/setup-cdp-after-launch.ts"));
|
|
3527
3570
|
const CDP_SETUP_TIMEOUT_MS = 45000;
|
|
3528
3571
|
await Promise.race([
|
|
3529
3572
|
mod.setupCdpAfterLaunch(compilation, cdpConfig, chromiumConfig, pipeStreams),
|
|
@@ -3814,6 +3857,150 @@ var __webpack_modules__ = {
|
|
|
3814
3857
|
var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
|
|
3815
3858
|
var ready_message = __webpack_require__("./browsers/browsers-lib/ready-message.ts");
|
|
3816
3859
|
var ready_stamp = __webpack_require__("./browsers/browsers-lib/ready-stamp.ts");
|
|
3860
|
+
var external_node_child_process_ = __webpack_require__("node:child_process");
|
|
3861
|
+
const PS_ROW = /^\s*(\d+)\s+(\d+)\s+(.*)$/;
|
|
3862
|
+
const HELPER_PROCESS = /plugin-container|(^|\s)-contentproc(\s|$)|(^|\s)-childID(\s|$)|--type=/;
|
|
3863
|
+
function runQuiet(bin, args) {
|
|
3864
|
+
try {
|
|
3865
|
+
const result = (0, external_node_child_process_.spawnSync)(bin, args, {
|
|
3866
|
+
encoding: 'utf-8',
|
|
3867
|
+
stdio: [
|
|
3868
|
+
'ignore',
|
|
3869
|
+
'pipe',
|
|
3870
|
+
'ignore'
|
|
3871
|
+
],
|
|
3872
|
+
windowsHide: true,
|
|
3873
|
+
maxBuffer: 67108864
|
|
3874
|
+
});
|
|
3875
|
+
if (result.error || 0 !== result.status) return null;
|
|
3876
|
+
return String(result.stdout || '');
|
|
3877
|
+
} catch {
|
|
3878
|
+
return null;
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
function parseProcessRows(output) {
|
|
3882
|
+
const rows = [];
|
|
3883
|
+
for (const line of String(output || '').split(/\r?\n/)){
|
|
3884
|
+
const match = PS_ROW.exec(line.replace(/\r$/, ''));
|
|
3885
|
+
if (!match) continue;
|
|
3886
|
+
const pid = Number(match[1]);
|
|
3887
|
+
const ppid = Number(match[2]);
|
|
3888
|
+
if (Number.isFinite(pid) && Number.isFinite(ppid)) rows.push({
|
|
3889
|
+
pid,
|
|
3890
|
+
ppid,
|
|
3891
|
+
command: match[3].trim()
|
|
3892
|
+
});
|
|
3893
|
+
}
|
|
3894
|
+
return rows;
|
|
3895
|
+
}
|
|
3896
|
+
function appendLinuxProfileEnv(rows) {
|
|
3897
|
+
return rows.map((row)=>{
|
|
3898
|
+
try {
|
|
3899
|
+
const environ = external_node_fs_.readFileSync(`/proc/${row.pid}/environ`, 'utf-8');
|
|
3900
|
+
const entry = environ.split('\0').find((pair)=>pair.startsWith('XRE_PROFILE_PATH='));
|
|
3901
|
+
return entry ? {
|
|
3902
|
+
...row,
|
|
3903
|
+
command: `${row.command} ${entry}`
|
|
3904
|
+
} : row;
|
|
3905
|
+
} catch {
|
|
3906
|
+
return row;
|
|
3907
|
+
}
|
|
3908
|
+
});
|
|
3909
|
+
}
|
|
3910
|
+
function listProcesses(platform = process.platform) {
|
|
3911
|
+
if ('win32' === platform) {
|
|
3912
|
+
const script = 'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId) $($_.ParentProcessId) $($_.CommandLine)" }';
|
|
3913
|
+
const output = runQuiet('powershell.exe', [
|
|
3914
|
+
'-NoProfile',
|
|
3915
|
+
'-NonInteractive',
|
|
3916
|
+
'-Command',
|
|
3917
|
+
script
|
|
3918
|
+
]);
|
|
3919
|
+
return output ? parseProcessRows(output) : [];
|
|
3920
|
+
}
|
|
3921
|
+
if ('darwin' === platform) {
|
|
3922
|
+
const output = runQuiet('ps', [
|
|
3923
|
+
'-axEo',
|
|
3924
|
+
'pid=,ppid=,command='
|
|
3925
|
+
]);
|
|
3926
|
+
return output ? parseProcessRows(output) : [];
|
|
3927
|
+
}
|
|
3928
|
+
const output = runQuiet('ps', [
|
|
3929
|
+
'-axo',
|
|
3930
|
+
'pid=,ppid=,command='
|
|
3931
|
+
]);
|
|
3932
|
+
const rows = output ? parseProcessRows(output) : [];
|
|
3933
|
+
return 'linux' === platform ? appendLinuxProfileEnv(rows) : rows;
|
|
3934
|
+
}
|
|
3935
|
+
function resolve_live_pid_normalizePath(value) {
|
|
3936
|
+
return String(value || '').replace(/\\/g, '/').toLowerCase();
|
|
3937
|
+
}
|
|
3938
|
+
function carriesProfile(command, profilePath) {
|
|
3939
|
+
const haystack = resolve_live_pid_normalizePath(command);
|
|
3940
|
+
const needle = resolve_live_pid_normalizePath(profilePath);
|
|
3941
|
+
let from = 0;
|
|
3942
|
+
for(;;){
|
|
3943
|
+
const at = haystack.indexOf(needle, from);
|
|
3944
|
+
if (at < 0) return false;
|
|
3945
|
+
const before = 0 === at ? ' ' : haystack[at - 1];
|
|
3946
|
+
const after = haystack[at + needle.length] ?? ' ';
|
|
3947
|
+
if (/[\s="']/.test(before) && /[\s"']/.test(after)) return true;
|
|
3948
|
+
from = at + 1;
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
function executableOf(command) {
|
|
3952
|
+
const trimmed = resolve_live_pid_normalizePath(command).trim();
|
|
3953
|
+
if (trimmed.startsWith('"')) {
|
|
3954
|
+
const end = trimmed.indexOf('"', 1);
|
|
3955
|
+
return end > 0 ? trimmed.slice(1, end) : trimmed;
|
|
3956
|
+
}
|
|
3957
|
+
const cut = trimmed.search(/\s(-|[a-z_][a-z0-9_]*=)/);
|
|
3958
|
+
return cut > 0 ? trimmed.slice(0, cut) : trimmed;
|
|
3959
|
+
}
|
|
3960
|
+
function findLiveBrowserPid(input) {
|
|
3961
|
+
const profilePath = String(input.profilePath || '').trim();
|
|
3962
|
+
const binary = resolve_live_pid_normalizePath(input.binary).trim();
|
|
3963
|
+
if (!profilePath || !binary) return null;
|
|
3964
|
+
const candidates = input.rows.filter((row)=>executableOf(row.command) === binary && carriesProfile(row.command, profilePath) && !HELPER_PROCESS.test(row.command));
|
|
3965
|
+
if (0 === candidates.length) return null;
|
|
3966
|
+
const launcher = input.launcherPid ? candidates.find((row)=>row.pid === input.launcherPid) : void 0;
|
|
3967
|
+
if (launcher) {
|
|
3968
|
+
const twin = candidates.find((row)=>row.pid !== launcher.pid);
|
|
3969
|
+
return twin ? twin.pid : launcher.pid;
|
|
3970
|
+
}
|
|
3971
|
+
const pids = new Set(candidates.map((row)=>row.pid));
|
|
3972
|
+
const roots = candidates.filter((row)=>!pids.has(row.ppid));
|
|
3973
|
+
return (roots[0] || candidates[0]).pid;
|
|
3974
|
+
}
|
|
3975
|
+
function isPidAlive(pid) {
|
|
3976
|
+
if (!pid || !Number.isFinite(pid)) return false;
|
|
3977
|
+
try {
|
|
3978
|
+
process.kill(pid, 0);
|
|
3979
|
+
return true;
|
|
3980
|
+
} catch (error) {
|
|
3981
|
+
return error?.code === 'EPERM';
|
|
3982
|
+
}
|
|
3983
|
+
}
|
|
3984
|
+
async function resolveLiveBrowserPid(input) {
|
|
3985
|
+
const list = input.list || listProcesses;
|
|
3986
|
+
const attempts = Math.max(1, input.attempts ?? 6);
|
|
3987
|
+
const intervalMs = input.intervalMs ?? 500;
|
|
3988
|
+
const sleep = input.sleep || ((ms)=>new Promise((r)=>{
|
|
3989
|
+
setTimeout(r, ms).unref?.();
|
|
3990
|
+
}));
|
|
3991
|
+
let last = null;
|
|
3992
|
+
for(let attempt = 0; attempt < attempts; attempt += 1){
|
|
3993
|
+
last = findLiveBrowserPid({
|
|
3994
|
+
profilePath: input.profilePath,
|
|
3995
|
+
binary: input.binary,
|
|
3996
|
+
launcherPid: input.launcherPid,
|
|
3997
|
+
rows: list()
|
|
3998
|
+
});
|
|
3999
|
+
if (last && last !== input.launcherPid) break;
|
|
4000
|
+
if (attempt < attempts - 1) await sleep(intervalMs);
|
|
4001
|
+
}
|
|
4002
|
+
return last;
|
|
4003
|
+
}
|
|
3817
4004
|
var runtime_options = __webpack_require__("./browsers/browsers-lib/runtime-options.ts");
|
|
3818
4005
|
var shared_utils = __webpack_require__("./browsers/browsers-lib/shared-utils.ts");
|
|
3819
4006
|
function parseFlatpakBinary(binary) {
|
|
@@ -4091,7 +4278,12 @@ var __webpack_modules__ = {
|
|
|
4091
4278
|
for (const instance of activeInstances)attemptCleanup(instance);
|
|
4092
4279
|
}
|
|
4093
4280
|
function forceKillAllOnExit() {
|
|
4094
|
-
for (const instance of activeInstances)
|
|
4281
|
+
for (const instance of activeInstances){
|
|
4282
|
+
const child = instance.childRef();
|
|
4283
|
+
const livePid = instance.livePidRef();
|
|
4284
|
+
(0, process_teardown.$Y)(child, instance.browser);
|
|
4285
|
+
if (livePid && livePid !== child?.pid) (0, process_teardown.Qx)(livePid, instance.browser);
|
|
4286
|
+
}
|
|
4095
4287
|
}
|
|
4096
4288
|
function firstBrowserLabel() {
|
|
4097
4289
|
for (const instance of activeInstances)return instance.browser;
|
|
@@ -4123,10 +4315,11 @@ var __webpack_modules__ = {
|
|
|
4123
4315
|
process.exit(1);
|
|
4124
4316
|
});
|
|
4125
4317
|
}
|
|
4126
|
-
function setupFirefoxProcessHandlers(browser, childRef, cleanupInstance) {
|
|
4318
|
+
function setupFirefoxProcessHandlers(browser, childRef, cleanupInstance, livePidRef = ()=>null) {
|
|
4127
4319
|
const instance = {
|
|
4128
4320
|
browser,
|
|
4129
4321
|
childRef,
|
|
4322
|
+
livePidRef,
|
|
4130
4323
|
cleanupInstance,
|
|
4131
4324
|
isCleaningUp: false
|
|
4132
4325
|
};
|
|
@@ -5212,7 +5405,6 @@ var __webpack_modules__ = {
|
|
|
5212
5405
|
} catch {}
|
|
5213
5406
|
return controller;
|
|
5214
5407
|
}
|
|
5215
|
-
var external_node_child_process_ = __webpack_require__("node:child_process");
|
|
5216
5408
|
var wsl_support = __webpack_require__("./browsers/browsers-lib/wsl-support.ts");
|
|
5217
5409
|
const LINUX_FIREFOX_PATHS = [
|
|
5218
5410
|
'/usr/bin/firefox',
|
|
@@ -5482,13 +5674,12 @@ var __webpack_modules__ = {
|
|
|
5482
5674
|
browserPid: this.child?.pid,
|
|
5483
5675
|
extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
|
|
5484
5676
|
});
|
|
5485
|
-
this.child.on('close', ()=>{
|
|
5486
|
-
(0, shared_utils.sW)(profilePath);
|
|
5487
|
-
});
|
|
5488
5677
|
this.wireChildLifecycle();
|
|
5678
|
+
this.trackLiveBrowserPid();
|
|
5489
5679
|
let ctrl;
|
|
5490
5680
|
try {
|
|
5491
5681
|
ctrl = await setupRdpAfterLaunch(this.host, compilation, debugPort);
|
|
5682
|
+
this.trackLiveBrowserPid(1);
|
|
5492
5683
|
} catch (error) {
|
|
5493
5684
|
const reason = error?.extensionLoadRefusedReason;
|
|
5494
5685
|
if (!reason) {
|
|
@@ -5583,24 +5774,89 @@ var __webpack_modules__ = {
|
|
|
5583
5774
|
if (process.env.VITEST || process.env.VITEST_WORKER_ID) throw new Error('Firefox startup timed out');
|
|
5584
5775
|
process.exit(1);
|
|
5585
5776
|
});
|
|
5586
|
-
let disposeProcessHandlers;
|
|
5587
5777
|
child.on('close', (code)=>{
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
}
|
|
5592
|
-
if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
|
|
5593
|
-
if (!(0, process_teardown.Op)(child)) {
|
|
5594
|
-
this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (code ${code ?? 'unknown'}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
|
|
5595
|
-
(0, ready_stamp.Wi)(this.extensionOutputPath, code);
|
|
5596
|
-
}
|
|
5597
|
-
this.cleanupInstance().catch((err)=>{
|
|
5598
|
-
if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
|
|
5599
|
-
});
|
|
5600
|
-
disposeProcessHandlers?.();
|
|
5778
|
+
const expected = (0, process_teardown.Op)(child);
|
|
5779
|
+
if (!expected && this.adoptHandedOffBrowser()) return;
|
|
5780
|
+
this.onBrowserGone(code, expected);
|
|
5601
5781
|
});
|
|
5602
5782
|
this.pipeChildOutput(child);
|
|
5603
|
-
disposeProcessHandlers = setupFirefoxProcessHandlers(this.host.browser, ()=>this.child, ()=>this.cleanupInstance());
|
|
5783
|
+
this.disposeProcessHandlers = setupFirefoxProcessHandlers(this.host.browser, ()=>this.child, ()=>this.cleanupInstance(), ()=>this.livePid);
|
|
5784
|
+
}
|
|
5785
|
+
onBrowserGone(code, expected) {
|
|
5786
|
+
if (this.browserGone) return;
|
|
5787
|
+
this.browserGone = true;
|
|
5788
|
+
if (this.watchTimeout) {
|
|
5789
|
+
clearTimeout(this.watchTimeout);
|
|
5790
|
+
this.watchTimeout = void 0;
|
|
5791
|
+
}
|
|
5792
|
+
if (this.liveExitWatcher) {
|
|
5793
|
+
clearInterval(this.liveExitWatcher);
|
|
5794
|
+
this.liveExitWatcher = void 0;
|
|
5795
|
+
}
|
|
5796
|
+
if (this.host.launchProfilePath) (0, shared_utils.sW)(this.host.launchProfilePath);
|
|
5797
|
+
if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
|
|
5798
|
+
if (!expected) {
|
|
5799
|
+
this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (code ${code ?? 'unknown'}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
|
|
5800
|
+
(0, ready_stamp.Wi)(this.extensionOutputPath, code);
|
|
5801
|
+
}
|
|
5802
|
+
this.cleanupInstance().catch((err)=>{
|
|
5803
|
+
if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
|
|
5804
|
+
});
|
|
5805
|
+
this.disposeProcessHandlers?.();
|
|
5806
|
+
this.disposeProcessHandlers = void 0;
|
|
5807
|
+
}
|
|
5808
|
+
async trackLiveBrowserPid(attempts) {
|
|
5809
|
+
const child = this.child;
|
|
5810
|
+
const profilePath = this.host.launchProfilePath;
|
|
5811
|
+
if (!child?.pid || !profilePath || this.browserGone) return;
|
|
5812
|
+
try {
|
|
5813
|
+
const pid = await resolveLiveBrowserPid({
|
|
5814
|
+
profilePath,
|
|
5815
|
+
binary: child.spawnfile,
|
|
5816
|
+
launcherPid: child.pid,
|
|
5817
|
+
attempts
|
|
5818
|
+
});
|
|
5819
|
+
if (pid && pid !== child.pid && this.child === child) this.adoptLivePid(pid);
|
|
5820
|
+
} catch {}
|
|
5821
|
+
}
|
|
5822
|
+
adoptHandedOffBrowser() {
|
|
5823
|
+
const profilePath = this.host.launchProfilePath;
|
|
5824
|
+
const child = this.child;
|
|
5825
|
+
if (!profilePath || !child || this.browserGone) return false;
|
|
5826
|
+
try {
|
|
5827
|
+
const pid = this.livePid || findLiveBrowserPid({
|
|
5828
|
+
profilePath,
|
|
5829
|
+
binary: child.spawnfile,
|
|
5830
|
+
launcherPid: child.pid,
|
|
5831
|
+
rows: listProcesses()
|
|
5832
|
+
});
|
|
5833
|
+
if (!pid || pid === this.child?.pid || !isPidAlive(pid)) return false;
|
|
5834
|
+
this.adoptLivePid(pid);
|
|
5835
|
+
return true;
|
|
5836
|
+
} catch {
|
|
5837
|
+
return false;
|
|
5838
|
+
}
|
|
5839
|
+
}
|
|
5840
|
+
adoptLivePid(pid) {
|
|
5841
|
+
if (this.livePid === pid) return;
|
|
5842
|
+
this.livePid = pid;
|
|
5843
|
+
(0, ready_stamp.M)(this.extensionOutputPath, {
|
|
5844
|
+
browserPid: pid,
|
|
5845
|
+
launcherPid: this.child?.pid
|
|
5846
|
+
});
|
|
5847
|
+
if ((0, messaging._o)()) this.ctx.logger?.info?.(`[browser] ${this.host.browser} handed the session to pid ${pid} (launcher pid ${this.child?.pid}).`);
|
|
5848
|
+
this.watchLivePidExit();
|
|
5849
|
+
}
|
|
5850
|
+
watchLivePidExit() {
|
|
5851
|
+
if (this.liveExitWatcher) clearInterval(this.liveExitWatcher);
|
|
5852
|
+
this.liveExitWatcher = setInterval(()=>{
|
|
5853
|
+
const pid = this.livePid;
|
|
5854
|
+
if (!pid || isPidAlive(pid)) return;
|
|
5855
|
+
clearInterval(this.liveExitWatcher);
|
|
5856
|
+
this.liveExitWatcher = void 0;
|
|
5857
|
+
this.onBrowserGone(null, (0, process_teardown.PU)(pid));
|
|
5858
|
+
}, 1000);
|
|
5859
|
+
this.liveExitWatcher.unref?.();
|
|
5604
5860
|
}
|
|
5605
5861
|
async retryAddonInstall(compilation, debugPort) {
|
|
5606
5862
|
try {
|
|
@@ -5635,6 +5891,7 @@ var __webpack_modules__ = {
|
|
|
5635
5891
|
}
|
|
5636
5892
|
async cleanupInstance() {
|
|
5637
5893
|
(0, process_teardown.Df)(this.child, this.host.browser);
|
|
5894
|
+
if (this.livePid && this.livePid !== this.child?.pid) (0, process_teardown._T)(this.livePid, this.host.browser);
|
|
5638
5895
|
}
|
|
5639
5896
|
scheduleWatchTimeout() {
|
|
5640
5897
|
if (this.watchTimeout) return;
|
|
@@ -5669,6 +5926,10 @@ var __webpack_modules__ = {
|
|
|
5669
5926
|
firefox_launch_define_property(this, "child", null);
|
|
5670
5927
|
firefox_launch_define_property(this, "watchTimeout", void 0);
|
|
5671
5928
|
firefox_launch_define_property(this, "extensionOutputPath", void 0);
|
|
5929
|
+
firefox_launch_define_property(this, "livePid", null);
|
|
5930
|
+
firefox_launch_define_property(this, "liveExitWatcher", void 0);
|
|
5931
|
+
firefox_launch_define_property(this, "browserGone", false);
|
|
5932
|
+
firefox_launch_define_property(this, "disposeProcessHandlers", void 0);
|
|
5672
5933
|
this.host = host;
|
|
5673
5934
|
this.ctx = ctx;
|
|
5674
5935
|
}
|
package/dist/cli.cjs
CHANGED
|
@@ -230,7 +230,7 @@ var __webpack_modules__ = {
|
|
|
230
230
|
(0, _helpers_messaging__rspack_import_3._w)(_messages__rspack_import_5.io());
|
|
231
231
|
}
|
|
232
232
|
} catch {
|
|
233
|
-
const provenanceNote = _messages__rspack_import_5.xX(opts.binaryProvenance);
|
|
233
|
+
const provenanceNote = _messages__rspack_import_5.xX(opts.binaryProvenance, opts.browser);
|
|
234
234
|
(0, _helpers_messaging__rspack_import_3._w)(_messages__rspack_import_5.io());
|
|
235
235
|
(0, _helpers_messaging__rspack_import_3._w)((0, _helpers_messaging__rspack_import_3.Nr)({
|
|
236
236
|
rows: [
|
|
@@ -421,6 +421,7 @@ var __webpack_modules__ = {
|
|
|
421
421
|
var pintor__rspack_import_8 = __webpack_require__("pintor");
|
|
422
422
|
var pintor__rspack_import_8_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_8);
|
|
423
423
|
var _helpers_messaging__rspack_import_9 = __webpack_require__("./helpers/messaging.ts");
|
|
424
|
+
var _browser_family__rspack_import_10 = __webpack_require__("./browsers/browsers-lib/browser-family.ts");
|
|
424
425
|
const require1 = (0, node_module__rspack_import_1.createRequire)(__rslib_import_meta_url__);
|
|
425
426
|
function getLoggingPrefix(type) {
|
|
426
427
|
return (0, _helpers_messaging__rspack_import_9.Pl)(type);
|
|
@@ -829,9 +830,15 @@ var __webpack_modules__ = {
|
|
|
829
830
|
if (rest.startsWith(node_path__rspack_import_3.sep) || rest.startsWith('/')) return `~${rest}`;
|
|
830
831
|
return raw;
|
|
831
832
|
}
|
|
832
|
-
function binaryProvenanceNote(provenance) {
|
|
833
|
-
if ('pinned'
|
|
834
|
-
return
|
|
833
|
+
function binaryProvenanceNote(provenance, browser) {
|
|
834
|
+
if ('pinned' !== provenance) return '';
|
|
835
|
+
return `(pinned with ${pinnedBinaryFlag(browser)})`;
|
|
836
|
+
}
|
|
837
|
+
function pinnedBinaryFlag(browser) {
|
|
838
|
+
const name = String(browser || '');
|
|
839
|
+
if ((0, _browser_family__rspack_import_10.M_)(name)) return '--gecko-binary';
|
|
840
|
+
if ('safari' === name || 'webkit-based' === name) return '--safari-binary';
|
|
841
|
+
return '--chromium-binary';
|
|
835
842
|
}
|
|
836
843
|
function runningInDevelopment(manifest, browser, message, browserVersionLine, updateSuffix, opts) {
|
|
837
844
|
const capitalize = (str)=>str.charAt(0).toUpperCase() + str.slice(1);
|
|
@@ -867,7 +874,7 @@ var __webpack_modules__ = {
|
|
|
867
874
|
const baseBrowserLabel = (0, _helpers_messaging__rspack_import_9.A6)(String(browser || 'unknown'), resolveBrowserVersionLine(browser, browserVersionLine, {
|
|
868
875
|
pinned: opts?.binaryProvenance === 'pinned'
|
|
869
876
|
}));
|
|
870
|
-
const provenanceNote = binaryProvenanceNote(opts?.binaryProvenance);
|
|
877
|
+
const provenanceNote = binaryProvenanceNote(opts?.binaryProvenance, browser);
|
|
871
878
|
const browserLabel = provenanceNote ? `${baseBrowserLabel} ${provenanceNote}` : baseBrowserLabel;
|
|
872
879
|
const cleanId = String(id || '').trim();
|
|
873
880
|
const includeExtensionId = opts?.includeExtensionId !== false;
|
|
@@ -1326,17 +1333,21 @@ var __webpack_modules__ = {
|
|
|
1326
1333
|
var _messages__rspack_import_2 = __webpack_require__("./browsers/browsers-lib/messages.ts");
|
|
1327
1334
|
const FORCE_KILL_GRACE_MS = 5000;
|
|
1328
1335
|
const terminatedByUs = new WeakSet();
|
|
1336
|
+
const terminatedPids = new Set();
|
|
1329
1337
|
function wasTerminatedByUs(child) {
|
|
1330
1338
|
return !!child && terminatedByUs.has(child);
|
|
1331
1339
|
}
|
|
1340
|
+
function wasPidTerminatedByUs(pid) {
|
|
1341
|
+
return 'number' == typeof pid && terminatedPids.has(pid);
|
|
1342
|
+
}
|
|
1332
1343
|
function authorLog(line) {
|
|
1333
1344
|
if (line && (0, _helpers_messaging__rspack_import_1._o)()) (0, _helpers_messaging__rspack_import_1._w)(line);
|
|
1334
1345
|
}
|
|
1335
|
-
function killWindowsTree(
|
|
1336
|
-
if ('win32' !== process.platform) return;
|
|
1346
|
+
function killWindowsTree(pid, sync) {
|
|
1347
|
+
if ('win32' !== process.platform || !pid) return;
|
|
1337
1348
|
const args = [
|
|
1338
1349
|
'/PID',
|
|
1339
|
-
String(
|
|
1350
|
+
String(pid),
|
|
1340
1351
|
'/T',
|
|
1341
1352
|
'/F'
|
|
1342
1353
|
];
|
|
@@ -1351,10 +1362,37 @@ var __webpack_modules__ = {
|
|
|
1351
1362
|
}).on('error', ()=>{});
|
|
1352
1363
|
} catch {}
|
|
1353
1364
|
}
|
|
1365
|
+
function signalPid(pid, signal) {
|
|
1366
|
+
try {
|
|
1367
|
+
process.kill(pid, signal);
|
|
1368
|
+
return true;
|
|
1369
|
+
} catch {
|
|
1370
|
+
return false;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
function gracefulTerminatePid(pid, browser) {
|
|
1374
|
+
if (!pid || terminatedPids.has(pid)) return;
|
|
1375
|
+
terminatedPids.add(pid);
|
|
1376
|
+
killWindowsTree(pid, false);
|
|
1377
|
+
authorLog(_messages__rspack_import_2.XH(browser));
|
|
1378
|
+
signalPid(pid, 'SIGTERM');
|
|
1379
|
+
const killTimer = setTimeout(()=>{
|
|
1380
|
+
authorLog(_messages__rspack_import_2.AG(browser));
|
|
1381
|
+
signalPid(pid, 'SIGKILL');
|
|
1382
|
+
}, FORCE_KILL_GRACE_MS);
|
|
1383
|
+
killTimer.unref?.();
|
|
1384
|
+
}
|
|
1385
|
+
function forceKillPidOnExit(pid, browser) {
|
|
1386
|
+
if (!pid) return;
|
|
1387
|
+
terminatedPids.add(pid);
|
|
1388
|
+
killWindowsTree(pid, true);
|
|
1389
|
+
authorLog(_messages__rspack_import_2.AG(browser));
|
|
1390
|
+
signalPid(pid, 'SIGKILL');
|
|
1391
|
+
}
|
|
1354
1392
|
function gracefulTerminateChild(child, browser) {
|
|
1355
1393
|
if (!child || child.killed) return;
|
|
1356
1394
|
terminatedByUs.add(child);
|
|
1357
|
-
killWindowsTree(child, false);
|
|
1395
|
+
killWindowsTree(child.pid, false);
|
|
1358
1396
|
authorLog(_messages__rspack_import_2.XH(browser));
|
|
1359
1397
|
child.kill('SIGTERM');
|
|
1360
1398
|
const killTimer = setTimeout(()=>{
|
|
@@ -1368,7 +1406,7 @@ var __webpack_modules__ = {
|
|
|
1368
1406
|
function forceKillChildOnExit(child, browser) {
|
|
1369
1407
|
if (!child) return;
|
|
1370
1408
|
terminatedByUs.add(child);
|
|
1371
|
-
killWindowsTree(child, true);
|
|
1409
|
+
killWindowsTree(child.pid, true);
|
|
1372
1410
|
try {
|
|
1373
1411
|
authorLog(_messages__rspack_import_2.AG(browser));
|
|
1374
1412
|
child.kill('SIGKILL');
|
|
@@ -1389,7 +1427,10 @@ var __webpack_modules__ = {
|
|
|
1389
1427
|
$Y: ()=>forceKillChildOnExit,
|
|
1390
1428
|
Df: ()=>gracefulTerminateChild,
|
|
1391
1429
|
FA: ()=>isBenignSocketTeardown,
|
|
1392
|
-
Op: ()=>wasTerminatedByUs
|
|
1430
|
+
Op: ()=>wasTerminatedByUs,
|
|
1431
|
+
PU: ()=>wasPidTerminatedByUs,
|
|
1432
|
+
Qx: ()=>forceKillPidOnExit,
|
|
1433
|
+
_T: ()=>gracefulTerminatePid
|
|
1393
1434
|
});
|
|
1394
1435
|
},
|
|
1395
1436
|
"./browsers/browsers-lib/ready-message.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -1433,6 +1474,7 @@ var __webpack_modules__ = {
|
|
|
1433
1474
|
const profilePath = String(details?.profilePath || '').trim();
|
|
1434
1475
|
if (profilePath) ready.profilePath = profilePath;
|
|
1435
1476
|
if ('number' == typeof details?.browserPid && Number.isFinite(details.browserPid)) ready.browserPid = details.browserPid;
|
|
1477
|
+
if ('number' == typeof details?.launcherPid && Number.isFinite(details.launcherPid)) ready.launcherPid = details.launcherPid;
|
|
1436
1478
|
const extensionId = String(details?.extensionId || '').trim();
|
|
1437
1479
|
if (extensionId) ready.extensionId = extensionId;
|
|
1438
1480
|
const binary = String(details?.binary || '').trim();
|
|
@@ -2686,6 +2728,7 @@ var __webpack_modules__ = {
|
|
|
2686
2728
|
'--enable-features=SidePanelUpdates',
|
|
2687
2729
|
'--disable-features=DisableLoadExtensionCommandLineSwitch',
|
|
2688
2730
|
'--disable-features=ExtensionDisableUnsupportedDeveloper',
|
|
2731
|
+
'--disable-features=SafetyHubExtensionsOffStoreTrigger',
|
|
2689
2732
|
'--enable-unsafe-extension-debugging',
|
|
2690
2733
|
'--silent-debugger-extension-api'
|
|
2691
2734
|
];
|
|
@@ -3514,7 +3557,7 @@ var __webpack_modules__ = {
|
|
|
3514
3557
|
binaryProvenance
|
|
3515
3558
|
};
|
|
3516
3559
|
if (enableCdp) {
|
|
3517
|
-
const mod = await __webpack_require__.e(
|
|
3560
|
+
const mod = await __webpack_require__.e(597).then(__webpack_require__.bind(__webpack_require__, "./browsers/run-chromium/chromium-launch/setup-cdp-after-launch.ts"));
|
|
3518
3561
|
const CDP_SETUP_TIMEOUT_MS = 45000;
|
|
3519
3562
|
await Promise.race([
|
|
3520
3563
|
mod.setupCdpAfterLaunch(compilation, cdpConfig, chromiumConfig, pipeStreams),
|
|
@@ -3805,6 +3848,150 @@ var __webpack_modules__ = {
|
|
|
3805
3848
|
var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
|
|
3806
3849
|
var ready_message = __webpack_require__("./browsers/browsers-lib/ready-message.ts");
|
|
3807
3850
|
var ready_stamp = __webpack_require__("./browsers/browsers-lib/ready-stamp.ts");
|
|
3851
|
+
var external_node_child_process_ = __webpack_require__("node:child_process");
|
|
3852
|
+
const PS_ROW = /^\s*(\d+)\s+(\d+)\s+(.*)$/;
|
|
3853
|
+
const HELPER_PROCESS = /plugin-container|(^|\s)-contentproc(\s|$)|(^|\s)-childID(\s|$)|--type=/;
|
|
3854
|
+
function runQuiet(bin, args) {
|
|
3855
|
+
try {
|
|
3856
|
+
const result = (0, external_node_child_process_.spawnSync)(bin, args, {
|
|
3857
|
+
encoding: 'utf-8',
|
|
3858
|
+
stdio: [
|
|
3859
|
+
'ignore',
|
|
3860
|
+
'pipe',
|
|
3861
|
+
'ignore'
|
|
3862
|
+
],
|
|
3863
|
+
windowsHide: true,
|
|
3864
|
+
maxBuffer: 67108864
|
|
3865
|
+
});
|
|
3866
|
+
if (result.error || 0 !== result.status) return null;
|
|
3867
|
+
return String(result.stdout || '');
|
|
3868
|
+
} catch {
|
|
3869
|
+
return null;
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
function parseProcessRows(output) {
|
|
3873
|
+
const rows = [];
|
|
3874
|
+
for (const line of String(output || '').split(/\r?\n/)){
|
|
3875
|
+
const match = PS_ROW.exec(line.replace(/\r$/, ''));
|
|
3876
|
+
if (!match) continue;
|
|
3877
|
+
const pid = Number(match[1]);
|
|
3878
|
+
const ppid = Number(match[2]);
|
|
3879
|
+
if (Number.isFinite(pid) && Number.isFinite(ppid)) rows.push({
|
|
3880
|
+
pid,
|
|
3881
|
+
ppid,
|
|
3882
|
+
command: match[3].trim()
|
|
3883
|
+
});
|
|
3884
|
+
}
|
|
3885
|
+
return rows;
|
|
3886
|
+
}
|
|
3887
|
+
function appendLinuxProfileEnv(rows) {
|
|
3888
|
+
return rows.map((row)=>{
|
|
3889
|
+
try {
|
|
3890
|
+
const environ = external_node_fs_.readFileSync(`/proc/${row.pid}/environ`, 'utf-8');
|
|
3891
|
+
const entry = environ.split('\0').find((pair)=>pair.startsWith('XRE_PROFILE_PATH='));
|
|
3892
|
+
return entry ? {
|
|
3893
|
+
...row,
|
|
3894
|
+
command: `${row.command} ${entry}`
|
|
3895
|
+
} : row;
|
|
3896
|
+
} catch {
|
|
3897
|
+
return row;
|
|
3898
|
+
}
|
|
3899
|
+
});
|
|
3900
|
+
}
|
|
3901
|
+
function listProcesses(platform = process.platform) {
|
|
3902
|
+
if ('win32' === platform) {
|
|
3903
|
+
const script = 'Get-CimInstance Win32_Process | ForEach-Object { "$($_.ProcessId) $($_.ParentProcessId) $($_.CommandLine)" }';
|
|
3904
|
+
const output = runQuiet('powershell.exe', [
|
|
3905
|
+
'-NoProfile',
|
|
3906
|
+
'-NonInteractive',
|
|
3907
|
+
'-Command',
|
|
3908
|
+
script
|
|
3909
|
+
]);
|
|
3910
|
+
return output ? parseProcessRows(output) : [];
|
|
3911
|
+
}
|
|
3912
|
+
if ('darwin' === platform) {
|
|
3913
|
+
const output = runQuiet('ps', [
|
|
3914
|
+
'-axEo',
|
|
3915
|
+
'pid=,ppid=,command='
|
|
3916
|
+
]);
|
|
3917
|
+
return output ? parseProcessRows(output) : [];
|
|
3918
|
+
}
|
|
3919
|
+
const output = runQuiet('ps', [
|
|
3920
|
+
'-axo',
|
|
3921
|
+
'pid=,ppid=,command='
|
|
3922
|
+
]);
|
|
3923
|
+
const rows = output ? parseProcessRows(output) : [];
|
|
3924
|
+
return 'linux' === platform ? appendLinuxProfileEnv(rows) : rows;
|
|
3925
|
+
}
|
|
3926
|
+
function resolve_live_pid_normalizePath(value) {
|
|
3927
|
+
return String(value || '').replace(/\\/g, '/').toLowerCase();
|
|
3928
|
+
}
|
|
3929
|
+
function carriesProfile(command, profilePath) {
|
|
3930
|
+
const haystack = resolve_live_pid_normalizePath(command);
|
|
3931
|
+
const needle = resolve_live_pid_normalizePath(profilePath);
|
|
3932
|
+
let from = 0;
|
|
3933
|
+
for(;;){
|
|
3934
|
+
const at = haystack.indexOf(needle, from);
|
|
3935
|
+
if (at < 0) return false;
|
|
3936
|
+
const before = 0 === at ? ' ' : haystack[at - 1];
|
|
3937
|
+
const after = haystack[at + needle.length] ?? ' ';
|
|
3938
|
+
if (/[\s="']/.test(before) && /[\s"']/.test(after)) return true;
|
|
3939
|
+
from = at + 1;
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
function executableOf(command) {
|
|
3943
|
+
const trimmed = resolve_live_pid_normalizePath(command).trim();
|
|
3944
|
+
if (trimmed.startsWith('"')) {
|
|
3945
|
+
const end = trimmed.indexOf('"', 1);
|
|
3946
|
+
return end > 0 ? trimmed.slice(1, end) : trimmed;
|
|
3947
|
+
}
|
|
3948
|
+
const cut = trimmed.search(/\s(-|[a-z_][a-z0-9_]*=)/);
|
|
3949
|
+
return cut > 0 ? trimmed.slice(0, cut) : trimmed;
|
|
3950
|
+
}
|
|
3951
|
+
function findLiveBrowserPid(input) {
|
|
3952
|
+
const profilePath = String(input.profilePath || '').trim();
|
|
3953
|
+
const binary = resolve_live_pid_normalizePath(input.binary).trim();
|
|
3954
|
+
if (!profilePath || !binary) return null;
|
|
3955
|
+
const candidates = input.rows.filter((row)=>executableOf(row.command) === binary && carriesProfile(row.command, profilePath) && !HELPER_PROCESS.test(row.command));
|
|
3956
|
+
if (0 === candidates.length) return null;
|
|
3957
|
+
const launcher = input.launcherPid ? candidates.find((row)=>row.pid === input.launcherPid) : void 0;
|
|
3958
|
+
if (launcher) {
|
|
3959
|
+
const twin = candidates.find((row)=>row.pid !== launcher.pid);
|
|
3960
|
+
return twin ? twin.pid : launcher.pid;
|
|
3961
|
+
}
|
|
3962
|
+
const pids = new Set(candidates.map((row)=>row.pid));
|
|
3963
|
+
const roots = candidates.filter((row)=>!pids.has(row.ppid));
|
|
3964
|
+
return (roots[0] || candidates[0]).pid;
|
|
3965
|
+
}
|
|
3966
|
+
function isPidAlive(pid) {
|
|
3967
|
+
if (!pid || !Number.isFinite(pid)) return false;
|
|
3968
|
+
try {
|
|
3969
|
+
process.kill(pid, 0);
|
|
3970
|
+
return true;
|
|
3971
|
+
} catch (error) {
|
|
3972
|
+
return error?.code === 'EPERM';
|
|
3973
|
+
}
|
|
3974
|
+
}
|
|
3975
|
+
async function resolveLiveBrowserPid(input) {
|
|
3976
|
+
const list = input.list || listProcesses;
|
|
3977
|
+
const attempts = Math.max(1, input.attempts ?? 6);
|
|
3978
|
+
const intervalMs = input.intervalMs ?? 500;
|
|
3979
|
+
const sleep = input.sleep || ((ms)=>new Promise((r)=>{
|
|
3980
|
+
setTimeout(r, ms).unref?.();
|
|
3981
|
+
}));
|
|
3982
|
+
let last = null;
|
|
3983
|
+
for(let attempt = 0; attempt < attempts; attempt += 1){
|
|
3984
|
+
last = findLiveBrowserPid({
|
|
3985
|
+
profilePath: input.profilePath,
|
|
3986
|
+
binary: input.binary,
|
|
3987
|
+
launcherPid: input.launcherPid,
|
|
3988
|
+
rows: list()
|
|
3989
|
+
});
|
|
3990
|
+
if (last && last !== input.launcherPid) break;
|
|
3991
|
+
if (attempt < attempts - 1) await sleep(intervalMs);
|
|
3992
|
+
}
|
|
3993
|
+
return last;
|
|
3994
|
+
}
|
|
3808
3995
|
var runtime_options = __webpack_require__("./browsers/browsers-lib/runtime-options.ts");
|
|
3809
3996
|
var shared_utils = __webpack_require__("./browsers/browsers-lib/shared-utils.ts");
|
|
3810
3997
|
function parseFlatpakBinary(binary) {
|
|
@@ -4082,7 +4269,12 @@ var __webpack_modules__ = {
|
|
|
4082
4269
|
for (const instance of activeInstances)attemptCleanup(instance);
|
|
4083
4270
|
}
|
|
4084
4271
|
function forceKillAllOnExit() {
|
|
4085
|
-
for (const instance of activeInstances)
|
|
4272
|
+
for (const instance of activeInstances){
|
|
4273
|
+
const child = instance.childRef();
|
|
4274
|
+
const livePid = instance.livePidRef();
|
|
4275
|
+
(0, process_teardown.$Y)(child, instance.browser);
|
|
4276
|
+
if (livePid && livePid !== child?.pid) (0, process_teardown.Qx)(livePid, instance.browser);
|
|
4277
|
+
}
|
|
4086
4278
|
}
|
|
4087
4279
|
function firstBrowserLabel() {
|
|
4088
4280
|
for (const instance of activeInstances)return instance.browser;
|
|
@@ -4114,10 +4306,11 @@ var __webpack_modules__ = {
|
|
|
4114
4306
|
process.exit(1);
|
|
4115
4307
|
});
|
|
4116
4308
|
}
|
|
4117
|
-
function setupFirefoxProcessHandlers(browser, childRef, cleanupInstance) {
|
|
4309
|
+
function setupFirefoxProcessHandlers(browser, childRef, cleanupInstance, livePidRef = ()=>null) {
|
|
4118
4310
|
const instance = {
|
|
4119
4311
|
browser,
|
|
4120
4312
|
childRef,
|
|
4313
|
+
livePidRef,
|
|
4121
4314
|
cleanupInstance,
|
|
4122
4315
|
isCleaningUp: false
|
|
4123
4316
|
};
|
|
@@ -5203,7 +5396,6 @@ var __webpack_modules__ = {
|
|
|
5203
5396
|
} catch {}
|
|
5204
5397
|
return controller;
|
|
5205
5398
|
}
|
|
5206
|
-
var external_node_child_process_ = __webpack_require__("node:child_process");
|
|
5207
5399
|
var wsl_support = __webpack_require__("./browsers/browsers-lib/wsl-support.ts");
|
|
5208
5400
|
const LINUX_FIREFOX_PATHS = [
|
|
5209
5401
|
'/usr/bin/firefox',
|
|
@@ -5473,13 +5665,12 @@ var __webpack_modules__ = {
|
|
|
5473
5665
|
browserPid: this.child?.pid,
|
|
5474
5666
|
extensionId: this.extensionOutputPath ? (0, banner.MT)(this.extensionOutputPath) : void 0
|
|
5475
5667
|
});
|
|
5476
|
-
this.child.on('close', ()=>{
|
|
5477
|
-
(0, shared_utils.sW)(profilePath);
|
|
5478
|
-
});
|
|
5479
5668
|
this.wireChildLifecycle();
|
|
5669
|
+
this.trackLiveBrowserPid();
|
|
5480
5670
|
let ctrl;
|
|
5481
5671
|
try {
|
|
5482
5672
|
ctrl = await setupRdpAfterLaunch(this.host, compilation, debugPort);
|
|
5673
|
+
this.trackLiveBrowserPid(1);
|
|
5483
5674
|
} catch (error) {
|
|
5484
5675
|
const reason = error?.extensionLoadRefusedReason;
|
|
5485
5676
|
if (!reason) {
|
|
@@ -5574,24 +5765,89 @@ var __webpack_modules__ = {
|
|
|
5574
5765
|
if (process.env.VITEST || process.env.VITEST_WORKER_ID) throw new Error('Firefox startup timed out');
|
|
5575
5766
|
process.exit(1);
|
|
5576
5767
|
});
|
|
5577
|
-
let disposeProcessHandlers;
|
|
5578
5768
|
child.on('close', (code)=>{
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
}
|
|
5583
|
-
if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
|
|
5584
|
-
if (!(0, process_teardown.Op)(child)) {
|
|
5585
|
-
this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (code ${code ?? 'unknown'}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
|
|
5586
|
-
(0, ready_stamp.Wi)(this.extensionOutputPath, code);
|
|
5587
|
-
}
|
|
5588
|
-
this.cleanupInstance().catch((err)=>{
|
|
5589
|
-
if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
|
|
5590
|
-
});
|
|
5591
|
-
disposeProcessHandlers?.();
|
|
5769
|
+
const expected = (0, process_teardown.Op)(child);
|
|
5770
|
+
if (!expected && this.adoptHandedOffBrowser()) return;
|
|
5771
|
+
this.onBrowserGone(code, expected);
|
|
5592
5772
|
});
|
|
5593
5773
|
this.pipeChildOutput(child);
|
|
5594
|
-
disposeProcessHandlers = setupFirefoxProcessHandlers(this.host.browser, ()=>this.child, ()=>this.cleanupInstance());
|
|
5774
|
+
this.disposeProcessHandlers = setupFirefoxProcessHandlers(this.host.browser, ()=>this.child, ()=>this.cleanupInstance(), ()=>this.livePid);
|
|
5775
|
+
}
|
|
5776
|
+
onBrowserGone(code, expected) {
|
|
5777
|
+
if (this.browserGone) return;
|
|
5778
|
+
this.browserGone = true;
|
|
5779
|
+
if (this.watchTimeout) {
|
|
5780
|
+
clearTimeout(this.watchTimeout);
|
|
5781
|
+
this.watchTimeout = void 0;
|
|
5782
|
+
}
|
|
5783
|
+
if (this.liveExitWatcher) {
|
|
5784
|
+
clearInterval(this.liveExitWatcher);
|
|
5785
|
+
this.liveExitWatcher = void 0;
|
|
5786
|
+
}
|
|
5787
|
+
if (this.host.launchProfilePath) (0, shared_utils.sW)(this.host.launchProfilePath);
|
|
5788
|
+
if ((0, messaging._o)()) this.ctx.logger?.info?.(messages.Th(this.host.browser));
|
|
5789
|
+
if (!expected) {
|
|
5790
|
+
this.ctx.logger?.error?.(`[browser] ${this.host.browser} exited (code ${code ?? 'unknown'}) without being asked to. The add-on may have been rejected or the browser crashed; the session cannot be driven.`);
|
|
5791
|
+
(0, ready_stamp.Wi)(this.extensionOutputPath, code);
|
|
5792
|
+
}
|
|
5793
|
+
this.cleanupInstance().catch((err)=>{
|
|
5794
|
+
if ((0, messaging._o)()) this.ctx.logger?.error?.(`[browser] Cleanup error on child close: ${err?.message || err}`);
|
|
5795
|
+
});
|
|
5796
|
+
this.disposeProcessHandlers?.();
|
|
5797
|
+
this.disposeProcessHandlers = void 0;
|
|
5798
|
+
}
|
|
5799
|
+
async trackLiveBrowserPid(attempts) {
|
|
5800
|
+
const child = this.child;
|
|
5801
|
+
const profilePath = this.host.launchProfilePath;
|
|
5802
|
+
if (!child?.pid || !profilePath || this.browserGone) return;
|
|
5803
|
+
try {
|
|
5804
|
+
const pid = await resolveLiveBrowserPid({
|
|
5805
|
+
profilePath,
|
|
5806
|
+
binary: child.spawnfile,
|
|
5807
|
+
launcherPid: child.pid,
|
|
5808
|
+
attempts
|
|
5809
|
+
});
|
|
5810
|
+
if (pid && pid !== child.pid && this.child === child) this.adoptLivePid(pid);
|
|
5811
|
+
} catch {}
|
|
5812
|
+
}
|
|
5813
|
+
adoptHandedOffBrowser() {
|
|
5814
|
+
const profilePath = this.host.launchProfilePath;
|
|
5815
|
+
const child = this.child;
|
|
5816
|
+
if (!profilePath || !child || this.browserGone) return false;
|
|
5817
|
+
try {
|
|
5818
|
+
const pid = this.livePid || findLiveBrowserPid({
|
|
5819
|
+
profilePath,
|
|
5820
|
+
binary: child.spawnfile,
|
|
5821
|
+
launcherPid: child.pid,
|
|
5822
|
+
rows: listProcesses()
|
|
5823
|
+
});
|
|
5824
|
+
if (!pid || pid === this.child?.pid || !isPidAlive(pid)) return false;
|
|
5825
|
+
this.adoptLivePid(pid);
|
|
5826
|
+
return true;
|
|
5827
|
+
} catch {
|
|
5828
|
+
return false;
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
adoptLivePid(pid) {
|
|
5832
|
+
if (this.livePid === pid) return;
|
|
5833
|
+
this.livePid = pid;
|
|
5834
|
+
(0, ready_stamp.M)(this.extensionOutputPath, {
|
|
5835
|
+
browserPid: pid,
|
|
5836
|
+
launcherPid: this.child?.pid
|
|
5837
|
+
});
|
|
5838
|
+
if ((0, messaging._o)()) this.ctx.logger?.info?.(`[browser] ${this.host.browser} handed the session to pid ${pid} (launcher pid ${this.child?.pid}).`);
|
|
5839
|
+
this.watchLivePidExit();
|
|
5840
|
+
}
|
|
5841
|
+
watchLivePidExit() {
|
|
5842
|
+
if (this.liveExitWatcher) clearInterval(this.liveExitWatcher);
|
|
5843
|
+
this.liveExitWatcher = setInterval(()=>{
|
|
5844
|
+
const pid = this.livePid;
|
|
5845
|
+
if (!pid || isPidAlive(pid)) return;
|
|
5846
|
+
clearInterval(this.liveExitWatcher);
|
|
5847
|
+
this.liveExitWatcher = void 0;
|
|
5848
|
+
this.onBrowserGone(null, (0, process_teardown.PU)(pid));
|
|
5849
|
+
}, 1000);
|
|
5850
|
+
this.liveExitWatcher.unref?.();
|
|
5595
5851
|
}
|
|
5596
5852
|
async retryAddonInstall(compilation, debugPort) {
|
|
5597
5853
|
try {
|
|
@@ -5626,6 +5882,7 @@ var __webpack_modules__ = {
|
|
|
5626
5882
|
}
|
|
5627
5883
|
async cleanupInstance() {
|
|
5628
5884
|
(0, process_teardown.Df)(this.child, this.host.browser);
|
|
5885
|
+
if (this.livePid && this.livePid !== this.child?.pid) (0, process_teardown._T)(this.livePid, this.host.browser);
|
|
5629
5886
|
}
|
|
5630
5887
|
scheduleWatchTimeout() {
|
|
5631
5888
|
if (this.watchTimeout) return;
|
|
@@ -5660,6 +5917,10 @@ var __webpack_modules__ = {
|
|
|
5660
5917
|
firefox_launch_define_property(this, "child", null);
|
|
5661
5918
|
firefox_launch_define_property(this, "watchTimeout", void 0);
|
|
5662
5919
|
firefox_launch_define_property(this, "extensionOutputPath", void 0);
|
|
5920
|
+
firefox_launch_define_property(this, "livePid", null);
|
|
5921
|
+
firefox_launch_define_property(this, "liveExitWatcher", void 0);
|
|
5922
|
+
firefox_launch_define_property(this, "browserGone", false);
|
|
5923
|
+
firefox_launch_define_property(this, "disposeProcessHandlers", void 0);
|
|
5663
5924
|
this.host = host;
|
|
5664
5925
|
this.ctx = ctx;
|
|
5665
5926
|
}
|
|
@@ -7198,7 +7459,7 @@ var __webpack_modules__ = {
|
|
|
7198
7459
|
return Math.min(Math.max(n, min), max);
|
|
7199
7460
|
}
|
|
7200
7461
|
const TEMPLATE_CORPUS_REPO = 'extension-js/examples';
|
|
7201
|
-
const TEMPLATE_CORPUS_REF = '
|
|
7462
|
+
const TEMPLATE_CORPUS_REF = 'f8087f012cf195cba9aa2e3c32fd5a6729da33f0';
|
|
7202
7463
|
const TEMPLATE_CORPUS_SLUGS = [
|
|
7203
7464
|
'action',
|
|
7204
7465
|
'action-locales',
|
|
@@ -120,7 +120,7 @@ export interface DevClientMessage {
|
|
|
120
120
|
};
|
|
121
121
|
}
|
|
122
122
|
export declare function collapseHomeDirInCardValue(value: string): string;
|
|
123
|
-
export declare function binaryProvenanceNote(provenance?: 'managed' | 'pinned' | 'system' | 'snapshot'): string;
|
|
123
|
+
export declare function binaryProvenanceNote(provenance?: 'managed' | 'pinned' | 'system' | 'snapshot', browser?: BrowserType | string): string;
|
|
124
124
|
export declare function runningInDevelopment(manifest: DevManifestInfo, browser: BrowserType, message: DevClientMessage, browserVersionLine?: string, updateSuffix?: string, opts?: {
|
|
125
125
|
includeExtensionId?: boolean;
|
|
126
126
|
runLabel?: string;
|
|
@@ -2,6 +2,9 @@ import { type ChildProcess } from 'node:child_process';
|
|
|
2
2
|
import type { BrowserType } from '../browsers-types.js';
|
|
3
3
|
export declare const FORCE_KILL_GRACE_MS = 5000;
|
|
4
4
|
export declare function wasTerminatedByUs(child: ChildProcess | null): boolean;
|
|
5
|
+
export declare function wasPidTerminatedByUs(pid: number | null | undefined): boolean;
|
|
6
|
+
export declare function gracefulTerminatePid(pid: number | null | undefined, browser: BrowserType): void;
|
|
7
|
+
export declare function forceKillPidOnExit(pid: number | null | undefined, browser: BrowserType): void;
|
|
5
8
|
export declare function gracefulTerminateChild(child: ChildProcess | null, browser: BrowserType): void;
|
|
6
9
|
export declare function forceKillChildOnExit(child: ChildProcess | null, browser: BrowserType): void;
|
|
7
10
|
export declare function isBenignSocketTeardown(value: unknown): boolean;
|
|
@@ -2,6 +2,7 @@ export declare function stampReadyRdpPort(extensionOutputPath: string | undefine
|
|
|
2
2
|
export declare function stampReadyBrowserLaunch(extensionOutputPath: string | undefined, details: {
|
|
3
3
|
profilePath?: string;
|
|
4
4
|
browserPid?: number;
|
|
5
|
+
launcherPid?: number;
|
|
5
6
|
extensionId?: string;
|
|
6
7
|
binary?: string;
|
|
7
8
|
binaryProvenance?: 'managed' | 'pinned' | 'system' | 'snapshot';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ProcessRow {
|
|
2
|
+
pid: number;
|
|
3
|
+
ppid: number;
|
|
4
|
+
command: string;
|
|
5
|
+
}
|
|
6
|
+
export type ProcessLister = () => ProcessRow[];
|
|
7
|
+
export declare function parseProcessRows(output: string): ProcessRow[];
|
|
8
|
+
export declare function listProcesses(platform?: NodeJS.Platform): ProcessRow[];
|
|
9
|
+
export declare function executableOf(command: string): string;
|
|
10
|
+
export declare function findLiveBrowserPid(input: {
|
|
11
|
+
profilePath: string;
|
|
12
|
+
binary: string;
|
|
13
|
+
launcherPid?: number;
|
|
14
|
+
rows: ProcessRow[];
|
|
15
|
+
}): number | null;
|
|
16
|
+
export declare function isPidAlive(pid: number | null | undefined): boolean;
|
|
17
|
+
export declare function resolveLiveBrowserPid(input: {
|
|
18
|
+
profilePath: string;
|
|
19
|
+
binary: string;
|
|
20
|
+
launcherPid?: number;
|
|
21
|
+
list?: ProcessLister;
|
|
22
|
+
attempts?: number;
|
|
23
|
+
intervalMs?: number;
|
|
24
|
+
sleep?: (ms: number) => Promise<void>;
|
|
25
|
+
}): Promise<number | null>;
|
|
@@ -29,7 +29,7 @@ export interface BrowserConfig {
|
|
|
29
29
|
browserFlags: string[];
|
|
30
30
|
startingUrl: string | undefined;
|
|
31
31
|
}
|
|
32
|
-
export type DefaultBrowserFlags = '--no-first-run' | '--disable-client-side-phishing-detection' | '--disable-component-extensions-with-background-pages' | '--disable-default-apps' | '--disable-features=InterestFeedContentSuggestions' | '--disable-features=Translate' | '--hide-scrollbars' | '--mute-audio' | '--no-default-browser-check' | '--ash-no-nudges' | '--disable-search-engine-choice-screen' | '--disable-features=MediaRoute' | '--use-mock-keychain' | '--disable-background-networking' | '--disable-breakpad' | '--disable-component-update' | '--disable-domain-reliability' | '--disable-features=AutofillServerCommunicatio' | '--disable-features=CertificateTransparencyComponentUpdate' | '--disable-sync' | '--disable-features=OptimizationHints' | '--disable-features=DialMediaRouteProvider' | '--no-pings' | '--enable-features=SidePanelUpdates' | '--disable-features=DisableLoadExtensionCommandLineSwitch' | '--disable-features=ExtensionDisableUnsupportedDeveloper' | '--enable-unsafe-extension-debugging' | '--silent-debugger-extension-api';
|
|
32
|
+
export type DefaultBrowserFlags = '--no-first-run' | '--disable-client-side-phishing-detection' | '--disable-component-extensions-with-background-pages' | '--disable-default-apps' | '--disable-features=InterestFeedContentSuggestions' | '--disable-features=Translate' | '--hide-scrollbars' | '--mute-audio' | '--no-default-browser-check' | '--ash-no-nudges' | '--disable-search-engine-choice-screen' | '--disable-features=MediaRoute' | '--use-mock-keychain' | '--disable-background-networking' | '--disable-breakpad' | '--disable-component-update' | '--disable-domain-reliability' | '--disable-features=AutofillServerCommunicatio' | '--disable-features=CertificateTransparencyComponentUpdate' | '--disable-sync' | '--disable-features=OptimizationHints' | '--disable-features=DialMediaRouteProvider' | '--no-pings' | '--enable-features=SidePanelUpdates' | '--disable-features=DisableLoadExtensionCommandLineSwitch' | '--disable-features=ExtensionDisableUnsupportedDeveloper' | '--disable-features=SafetyHubExtensionsOffStoreTrigger' | '--enable-unsafe-extension-debugging' | '--silent-debugger-extension-api';
|
|
33
33
|
export interface PluginOptions {
|
|
34
34
|
/**
|
|
35
35
|
* @default false
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Readable, Writable } from 'node:stream';
|
|
2
2
|
import type { BrowserLogSink } from '../../../browsers-types.js';
|
|
3
3
|
import type { CdpProtocolMessage } from '../../chromium-types.js';
|
|
4
|
+
import { type DeveloperModeOutcome } from '../ensure-developer-mode.js';
|
|
4
5
|
import { type LoadUnpackedOutcome } from './ensure.js';
|
|
5
6
|
interface ExtensionInfoResult {
|
|
6
7
|
extensionId: string;
|
|
@@ -29,6 +30,7 @@ export declare class CDPExtensionController {
|
|
|
29
30
|
logSink?: BrowserLogSink;
|
|
30
31
|
});
|
|
31
32
|
connect(): Promise<void>;
|
|
33
|
+
ensureDeveloperMode(): Promise<DeveloperModeOutcome>;
|
|
32
34
|
openTab(url: string): Promise<void>;
|
|
33
35
|
closeSelfOpenedTabs(): Promise<number>;
|
|
34
36
|
verifyGuestLoaded(): Promise<LoadUnpackedOutcome>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type DeveloperModeOutcome = 'already-on' | 'enabled' | 'skipped' | 'unavailable';
|
|
2
|
+
export interface DeveloperModeTransport {
|
|
3
|
+
sendCommand(method: string, params?: Record<string, unknown>, sessionId?: string): Promise<unknown>;
|
|
4
|
+
}
|
|
5
|
+
export declare function developerModeFromProfile(profilePath: string): boolean;
|
|
6
|
+
export declare function developerModeFlipIsSafe(browserArgs: string[]): boolean;
|
|
7
|
+
export declare function ensureDeveloperMode(options: {
|
|
8
|
+
transport: DeveloperModeTransport;
|
|
9
|
+
attempts?: number;
|
|
10
|
+
delayMs?: number;
|
|
11
|
+
sleep?: (ms: number) => Promise<void>;
|
|
12
|
+
}): Promise<DeveloperModeOutcome>;
|
|
@@ -18,6 +18,10 @@ export declare class FirefoxLaunchPlugin {
|
|
|
18
18
|
private child;
|
|
19
19
|
private watchTimeout?;
|
|
20
20
|
private extensionOutputPath?;
|
|
21
|
+
private livePid;
|
|
22
|
+
private liveExitWatcher?;
|
|
23
|
+
private browserGone;
|
|
24
|
+
private disposeProcessHandlers?;
|
|
21
25
|
constructor(host: FirefoxPluginRuntime, ctx: FirefoxContext);
|
|
22
26
|
runOnce(compilation: CompilationLike, options: LaunchOptions): Promise<void>;
|
|
23
27
|
apply(compiler: unknown): void;
|
|
@@ -27,6 +31,11 @@ export declare class FirefoxLaunchPlugin {
|
|
|
27
31
|
private spawnFirefoxChild;
|
|
28
32
|
private pipeChildOutput;
|
|
29
33
|
private wireChildLifecycle;
|
|
34
|
+
private onBrowserGone;
|
|
35
|
+
private trackLiveBrowserPid;
|
|
36
|
+
private adoptHandedOffBrowser;
|
|
37
|
+
private adoptLivePid;
|
|
38
|
+
private watchLivePidExit;
|
|
30
39
|
private retryAddonInstall;
|
|
31
40
|
private reportAddonLoadRefused;
|
|
32
41
|
private cleanupInstance;
|
|
@@ -2,4 +2,4 @@ import type { ChildProcess } from 'node:child_process';
|
|
|
2
2
|
export type FirefoxBrowserKind = 'firefox' | 'chrome' | 'edge' | 'chromium-based';
|
|
3
3
|
export declare function __activeFirefoxInstanceCount(): number;
|
|
4
4
|
export declare function __resetFirefoxProcessHandlersForTest(): void;
|
|
5
|
-
export declare function setupFirefoxProcessHandlers(browser: FirefoxBrowserKind, childRef: () => ChildProcess | null, cleanupInstance: () => Promise<void
|
|
5
|
+
export declare function setupFirefoxProcessHandlers(browser: FirefoxBrowserKind, childRef: () => ChildProcess | null, cleanupInstance: () => Promise<void>, livePidRef?: () => number | null): () => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type Channel = 'info' | 'success' | 'warn' | 'error' | 'debug';
|
|
2
2
|
export declare function isDebug(): boolean;
|
|
3
3
|
export declare function prefix(type: Channel): string;
|
|
4
|
+
export declare function hasChannelPrefix(text: string): boolean;
|
|
4
5
|
export declare function isMachineOutput(): boolean;
|
|
5
6
|
export declare function humanLine(...parts: unknown[]): void;
|
|
6
7
|
export declare function humanWarn(...parts: unknown[]): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const DEFAULT_TEMPLATE = "typescript";
|
|
2
2
|
export declare const BUNDLED_TEMPLATES: readonly string[];
|
|
3
|
-
export declare const TEMPLATE_CATALOG_URL = "https://github.com/extension-js/examples/tree/
|
|
3
|
+
export declare const TEMPLATE_CATALOG_URL = "https://github.com/extension-js/examples/tree/f8087f012cf195cba9aa2e3c32fd5a6729da33f0/examples";
|
|
4
4
|
export interface TemplateGroup {
|
|
5
5
|
title: string;
|
|
6
6
|
summary: string;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const TEMPLATE_CORPUS_REPO = "extension-js/examples";
|
|
2
|
-
export declare const TEMPLATE_CORPUS_REF = "
|
|
2
|
+
export declare const TEMPLATE_CORPUS_REF = "f8087f012cf195cba9aa2e3c32fd5a6729da33f0";
|
|
3
3
|
export declare const TEMPLATE_CORPUS_SLUGS: readonly string[];
|
package/package.json
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"extension": "./bin/extension.cjs"
|
|
39
39
|
},
|
|
40
40
|
"name": "extension",
|
|
41
|
-
"version": "4.1.
|
|
41
|
+
"version": "4.1.22",
|
|
42
42
|
"description": "The cross-browser extension framework. Build Chrome, Edge, Firefox, and Safari extensions with no build configuration.",
|
|
43
43
|
"homepage": "https://extension.js.org/",
|
|
44
44
|
"bugs": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"registry": "https://registry.npmjs.org"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
|
-
"pretest": "pnpm run compile",
|
|
57
|
+
"pretest": "node ../../scripts/ensure-workspace-deps.mjs && pnpm run compile",
|
|
58
58
|
"prepublishOnly": "pnpm run compile",
|
|
59
59
|
"compile": "rslib build",
|
|
60
60
|
"watch": "rslib build --watch",
|
|
@@ -105,9 +105,9 @@
|
|
|
105
105
|
"vivaldi-location2": "2.1.1",
|
|
106
106
|
"waterfox-location": "2.1.1",
|
|
107
107
|
"yandex-location": "2.1.1",
|
|
108
|
-
"extension-create": "4.1.
|
|
109
|
-
"extension-develop": "4.1.
|
|
110
|
-
"extension-install": "4.1.
|
|
108
|
+
"extension-create": "4.1.22",
|
|
109
|
+
"extension-develop": "4.1.22",
|
|
110
|
+
"extension-install": "4.1.22",
|
|
111
111
|
"commander": "^15.0.0",
|
|
112
112
|
"pintor": "0.3.0",
|
|
113
113
|
"semver": "^7.7.3",
|