extension 4.1.21 → 4.1.23
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 +410 -37
- 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/messages.d.ts +1 -0
- package/dist/extension/helpers/messaging.d.ts +1 -0
- package/dist/extension/helpers/project-cli-version.d.ts +26 -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
|
}
|