extension 4.0.7 → 4.0.8
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/876.cjs +10 -1
- package/dist/browsers.cjs +43 -6
- package/dist/cli.cjs +43 -6
- package/dist/extension/browsers/browsers-lib/manifest-refusal.d.ts +16 -11
- package/dist/extension/browsers/browsers-lib/process-teardown.d.ts +1 -0
- package/dist/extension/browsers/run-chromium/cdp/cdp-client.d.ts +1 -0
- package/dist/extension/browsers/run-chromium/chromium-launch/index.d.ts +2 -0
- package/package.json +4 -4
package/dist/876.cjs
CHANGED
|
@@ -177,7 +177,7 @@ exports.modules = {
|
|
|
177
177
|
if ('pipe' === this.transport) {
|
|
178
178
|
try {
|
|
179
179
|
this.pipeIn?.removeAllListeners();
|
|
180
|
-
this.
|
|
180
|
+
this.pipeIn?.resume();
|
|
181
181
|
} catch {}
|
|
182
182
|
this.pipeIn = null;
|
|
183
183
|
this.pipeOut = null;
|
|
@@ -195,7 +195,15 @@ exports.modules = {
|
|
|
195
195
|
if (!this.isConnected()) return void this.stopHeartbeat();
|
|
196
196
|
try {
|
|
197
197
|
await this.getBrowserVersion();
|
|
198
|
+
this.heartbeatStallWarned = false;
|
|
198
199
|
} catch {
|
|
200
|
+
if ('pipe' === this.transport) {
|
|
201
|
+
if (!this.heartbeatStallWarned) {
|
|
202
|
+
this.heartbeatStallWarned = true;
|
|
203
|
+
console.warn('[CDP] Browser is not answering CDP commands (heartbeat timed out). Keeping the session — it resumes automatically if the browser recovers.');
|
|
204
|
+
}
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
199
207
|
if (this.isDev()) console.warn('[CDP] Heartbeat failed, connection appears dead');
|
|
200
208
|
this.disconnect();
|
|
201
209
|
}
|
|
@@ -331,6 +339,7 @@ exports.modules = {
|
|
|
331
339
|
_define_property(this, "messageId", 0);
|
|
332
340
|
_define_property(this, "pendingRequests", new Map());
|
|
333
341
|
_define_property(this, "heartbeatTimer", null);
|
|
342
|
+
_define_property(this, "heartbeatStallWarned", false);
|
|
334
343
|
this.port = port;
|
|
335
344
|
this.host = host;
|
|
336
345
|
}
|
package/dist/browsers.cjs
CHANGED
|
@@ -466,7 +466,7 @@ var __webpack_modules__ = {
|
|
|
466
466
|
function chromiumInvalidMatchPatterns(extensionPath, patterns) {
|
|
467
467
|
const shown = patterns.slice(0, 6);
|
|
468
468
|
const more = patterns.length - shown.length;
|
|
469
|
-
return `${getLoggingPrefix('warn')} ${pintor__rspack_import_4_default().brightYellow('This extension declares match patterns Chrome refuses — the whole extension will not load.')}\n${pintor__rspack_import_4_default().gray('PATH')} ${pintor__rspack_import_4_default().underline(extensionPath)}\n` + shown.map((pattern)=>`${pintor__rspack_import_4_default().gray('PATTERN')} ${pintor__rspack_import_4_default().red(pattern)}\n`).join('') + (more > 0 ? `${pintor__rspack_import_4_default().gray(`…and ${more} more`)}\n` : '') +
|
|
469
|
+
return `${getLoggingPrefix('warn')} ${pintor__rspack_import_4_default().brightYellow('This extension declares match patterns Chrome refuses — the whole extension will not load.')}\n${pintor__rspack_import_4_default().gray('PATH')} ${pintor__rspack_import_4_default().underline(extensionPath)}\n` + shown.map((pattern)=>`${pintor__rspack_import_4_default().gray('PATTERN')} ${pintor__rspack_import_4_default().red(pattern)}\n`).join('') + (more > 0 ? `${pintor__rspack_import_4_default().gray(`…and ${more} more`)}\n` : '') + `A match pattern's host wildcard must be ${pintor__rspack_import_4_default().blue('*')} or ${pintor__rspack_import_4_default().blue('*.domain.tld')} — ` + "a wildcard anywhere else in the host is invalid. " + `Replace the host with ${pintor__rspack_import_4_default().blue('*')} or ${pintor__rspack_import_4_default().blue('*.domain.tld')} in the source manifest.`;
|
|
470
470
|
}
|
|
471
471
|
function chromiumManifestLoadBlockers(extensionPath, blockers) {
|
|
472
472
|
return `${getLoggingPrefix('warn')} ${pintor__rspack_import_4_default().brightYellow('This manifest declares shapes Chrome refuses — the whole extension will not load.')}\n${pintor__rspack_import_4_default().gray('PATH')} ${pintor__rspack_import_4_default().underline(extensionPath)}\n` + blockers.map((blocker)=>`${pintor__rspack_import_4_default().gray('REASON')} ${pintor__rspack_import_4_default().red(blocker)}\n`).join('') + "Chrome rejects the extension at load, so no service worker or content script ever runs. Fix these in the source manifest.";
|
|
@@ -1003,6 +1003,10 @@ var __webpack_modules__ = {
|
|
|
1003
1003
|
var child_process__rspack_import_0 = __webpack_require__("child_process");
|
|
1004
1004
|
var _messages__rspack_import_1 = __webpack_require__("./browsers/browsers-lib/messages.ts");
|
|
1005
1005
|
const FORCE_KILL_GRACE_MS = 5000;
|
|
1006
|
+
const terminatedByUs = new WeakSet();
|
|
1007
|
+
function wasTerminatedByUs(child) {
|
|
1008
|
+
return !!child && terminatedByUs.has(child);
|
|
1009
|
+
}
|
|
1006
1010
|
function authorLog(line) {
|
|
1007
1011
|
if (line && 'true' === process.env.EXTENSION_AUTHOR_MODE) console.log(line);
|
|
1008
1012
|
}
|
|
@@ -1027,6 +1031,7 @@ var __webpack_modules__ = {
|
|
|
1027
1031
|
}
|
|
1028
1032
|
function gracefulTerminateChild(child, browser) {
|
|
1029
1033
|
if (!child || child.killed) return;
|
|
1034
|
+
terminatedByUs.add(child);
|
|
1030
1035
|
killWindowsTree(child, false);
|
|
1031
1036
|
authorLog(_messages__rspack_import_1.XH(browser));
|
|
1032
1037
|
child.kill('SIGTERM');
|
|
@@ -1040,6 +1045,7 @@ var __webpack_modules__ = {
|
|
|
1040
1045
|
}
|
|
1041
1046
|
function forceKillChildOnExit(child, browser) {
|
|
1042
1047
|
if (!child) return;
|
|
1048
|
+
terminatedByUs.add(child);
|
|
1043
1049
|
killWindowsTree(child, true);
|
|
1044
1050
|
try {
|
|
1045
1051
|
authorLog(_messages__rspack_import_1.AG(browser));
|
|
@@ -1060,7 +1066,8 @@ var __webpack_modules__ = {
|
|
|
1060
1066
|
__webpack_require__.d(__webpack_exports__, {
|
|
1061
1067
|
$Y: ()=>forceKillChildOnExit,
|
|
1062
1068
|
Df: ()=>gracefulTerminateChild,
|
|
1063
|
-
FA: ()=>isBenignSocketTeardown
|
|
1069
|
+
FA: ()=>isBenignSocketTeardown,
|
|
1070
|
+
Op: ()=>wasTerminatedByUs
|
|
1064
1071
|
});
|
|
1065
1072
|
},
|
|
1066
1073
|
"./browsers/browsers-lib/ready-message.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -1775,15 +1782,24 @@ var __webpack_modules__ = {
|
|
|
1775
1782
|
contentScript?.exclude_matches
|
|
1776
1783
|
])if (Array.isArray(list)) patterns.push(...list);
|
|
1777
1784
|
for (const resource of Array.isArray(m?.web_accessible_resources) ? m.web_accessible_resources : [])if (Array.isArray(resource?.matches)) patterns.push(...resource.matches);
|
|
1778
|
-
const invalid = patterns.filter((pattern)=>'string' == typeof pattern && '<all_urls>' !== pattern &&
|
|
1785
|
+
const invalid = patterns.filter((pattern)=>'string' == typeof pattern && '<all_urls>' !== pattern && hasInvalidHostWildcard(pattern));
|
|
1779
1786
|
return [
|
|
1780
1787
|
...new Set(invalid)
|
|
1781
1788
|
];
|
|
1782
1789
|
}
|
|
1783
1790
|
function hasInvalidHostWildcard(pattern) {
|
|
1784
1791
|
const match = /^[a-zA-Z*]+:\/\/([^/]*)/.exec(pattern);
|
|
1785
|
-
const
|
|
1786
|
-
if (!
|
|
1792
|
+
const authority = match?.[1];
|
|
1793
|
+
if (!authority) return false;
|
|
1794
|
+
let host = authority;
|
|
1795
|
+
if (authority.startsWith('[')) {
|
|
1796
|
+
const end = authority.indexOf(']');
|
|
1797
|
+
if (-1 !== end) host = authority.slice(0, end + 1);
|
|
1798
|
+
} else {
|
|
1799
|
+
const colon = authority.indexOf(':');
|
|
1800
|
+
if (-1 !== colon) host = authority.slice(0, colon);
|
|
1801
|
+
}
|
|
1802
|
+
if (!host.includes('*')) return false;
|
|
1787
1803
|
return '*' !== host && !/^\*\.[^*]+$/.test(host);
|
|
1788
1804
|
}
|
|
1789
1805
|
function findChromiumLoadBlockers(manifest) {
|
|
@@ -1848,6 +1864,7 @@ var __webpack_modules__ = {
|
|
|
1848
1864
|
var ready_message = __webpack_require__("./browsers/browsers-lib/ready-message.ts");
|
|
1849
1865
|
var runtime_options = __webpack_require__("./browsers/browsers-lib/runtime-options.ts");
|
|
1850
1866
|
var shared_utils = __webpack_require__("./browsers/browsers-lib/shared-utils.ts");
|
|
1867
|
+
var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
|
|
1851
1868
|
var discovery = __webpack_require__("./browsers/run-chromium/cdp/discovery.ts");
|
|
1852
1869
|
var manifest_readiness = __webpack_require__("./browsers/run-chromium/manifest-readiness.ts");
|
|
1853
1870
|
var resolve_profile = __webpack_require__("./browsers/browsers-lib/resolve-profile.ts");
|
|
@@ -2087,7 +2104,6 @@ var __webpack_modules__ = {
|
|
|
2087
2104
|
console.log(messages.E8(chromiumConfig.join(' ')));
|
|
2088
2105
|
}
|
|
2089
2106
|
var extension_output_path = __webpack_require__("./browsers/run-chromium/chromium-launch/extension-output-path.ts");
|
|
2090
|
-
var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
|
|
2091
2107
|
const activeInstances = new Set();
|
|
2092
2108
|
let globalHandlersInstalled = false;
|
|
2093
2109
|
function cleanupOne(instance) {
|
|
@@ -2288,6 +2304,17 @@ var __webpack_modules__ = {
|
|
|
2288
2304
|
browserVersionLine: args.browserVersionLine
|
|
2289
2305
|
});
|
|
2290
2306
|
}
|
|
2307
|
+
function stampReadyBrowserExited(extensionOutputPath, code) {
|
|
2308
|
+
try {
|
|
2309
|
+
if (!extensionOutputPath) return;
|
|
2310
|
+
const readyPath = external_path_.join(external_path_.dirname(extensionOutputPath), 'extension-js', external_path_.basename(extensionOutputPath), 'ready.json');
|
|
2311
|
+
if (!external_fs_.existsSync(readyPath)) return;
|
|
2312
|
+
const ready = JSON.parse(external_fs_.readFileSync(readyPath, 'utf-8'));
|
|
2313
|
+
ready.browserExitedAt = new Date().toISOString();
|
|
2314
|
+
ready.browserExitCode = code;
|
|
2315
|
+
external_fs_.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
|
|
2316
|
+
} catch {}
|
|
2317
|
+
}
|
|
2291
2318
|
class ChromiumLaunchPlugin {
|
|
2292
2319
|
async runOnce(compilation, opts) {
|
|
2293
2320
|
if (!this.logger) this.logger = {
|
|
@@ -2658,6 +2685,10 @@ var __webpack_modules__ = {
|
|
|
2658
2685
|
});
|
|
2659
2686
|
if (this.options.dryRun) return void logChromiumDryRun(browserBinaryLocation, chromiumConfig);
|
|
2660
2687
|
const usePipe = chromiumConfig.includes('--remote-debugging-pipe');
|
|
2688
|
+
this.closeHandlerContext = {
|
|
2689
|
+
isDevMode: 'development' === compilation.options.mode,
|
|
2690
|
+
extensionOutputPath: (0, extension_output_path.W)(compilation, chromiumConfig.find((flag)=>flag.startsWith('--load-extension='))) || void 0
|
|
2691
|
+
};
|
|
2661
2692
|
const child = await this.launchWithDirectSpawn(browserBinaryLocation, chromiumConfig, usePipe);
|
|
2662
2693
|
const pipeStreams = usePipe && child?.stdio?.[3] && child?.stdio?.[4] ? {
|
|
2663
2694
|
input: child.stdio[4],
|
|
@@ -2760,6 +2791,10 @@ var __webpack_modules__ = {
|
|
|
2760
2791
|
let disposeSignalHandlers;
|
|
2761
2792
|
child.on('close', (code)=>{
|
|
2762
2793
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) this.logger.info(messages.nn(code || 0));
|
|
2794
|
+
if (!(0, process_teardown.Op)(child) && this.closeHandlerContext?.isDevMode) {
|
|
2795
|
+
this.logger.error(`[browser] ${this.options.browser} exited mid-session (code ${code ?? 'unknown'}). The dev server is still running but reloads cannot be delivered — restart "extension dev" to relaunch the browser.`);
|
|
2796
|
+
stampReadyBrowserExited(this.closeHandlerContext.extensionOutputPath, code);
|
|
2797
|
+
}
|
|
2763
2798
|
disposeSignalHandlers?.();
|
|
2764
2799
|
const userDataDir = launchArgs.find((arg)=>arg.startsWith('--user-data-dir='))?.slice('--user-data-dir='.length).replace(/^"|"$/g, '');
|
|
2765
2800
|
shared_utils.sW(userDataDir);
|
|
@@ -2794,10 +2829,12 @@ var __webpack_modules__ = {
|
|
|
2794
2829
|
_define_property(this, "didLaunch", void 0);
|
|
2795
2830
|
_define_property(this, "didReportReady", void 0);
|
|
2796
2831
|
_define_property(this, "logger", void 0);
|
|
2832
|
+
_define_property(this, "closeHandlerContext", void 0);
|
|
2797
2833
|
this.options = options;
|
|
2798
2834
|
this.ctx = ctx;
|
|
2799
2835
|
this.didLaunch = false;
|
|
2800
2836
|
this.didReportReady = false;
|
|
2837
|
+
this.closeHandlerContext = null;
|
|
2801
2838
|
}
|
|
2802
2839
|
}
|
|
2803
2840
|
},
|
package/dist/cli.cjs
CHANGED
|
@@ -467,7 +467,7 @@ var __webpack_modules__ = {
|
|
|
467
467
|
function chromiumInvalidMatchPatterns(extensionPath, patterns) {
|
|
468
468
|
const shown = patterns.slice(0, 6);
|
|
469
469
|
const more = patterns.length - shown.length;
|
|
470
|
-
return `${getLoggingPrefix('warn')} ${pintor__rspack_import_4_default().brightYellow('This extension declares match patterns Chrome refuses — the whole extension will not load.')}\n${pintor__rspack_import_4_default().gray('PATH')} ${pintor__rspack_import_4_default().underline(extensionPath)}\n` + shown.map((pattern)=>`${pintor__rspack_import_4_default().gray('PATTERN')} ${pintor__rspack_import_4_default().red(pattern)}\n`).join('') + (more > 0 ? `${pintor__rspack_import_4_default().gray(`…and ${more} more`)}\n` : '') +
|
|
470
|
+
return `${getLoggingPrefix('warn')} ${pintor__rspack_import_4_default().brightYellow('This extension declares match patterns Chrome refuses — the whole extension will not load.')}\n${pintor__rspack_import_4_default().gray('PATH')} ${pintor__rspack_import_4_default().underline(extensionPath)}\n` + shown.map((pattern)=>`${pintor__rspack_import_4_default().gray('PATTERN')} ${pintor__rspack_import_4_default().red(pattern)}\n`).join('') + (more > 0 ? `${pintor__rspack_import_4_default().gray(`…and ${more} more`)}\n` : '') + `A match pattern's host wildcard must be ${pintor__rspack_import_4_default().blue('*')} or ${pintor__rspack_import_4_default().blue('*.domain.tld')} — ` + "a wildcard anywhere else in the host is invalid. " + `Replace the host with ${pintor__rspack_import_4_default().blue('*')} or ${pintor__rspack_import_4_default().blue('*.domain.tld')} in the source manifest.`;
|
|
471
471
|
}
|
|
472
472
|
function chromiumManifestLoadBlockers(extensionPath, blockers) {
|
|
473
473
|
return `${getLoggingPrefix('warn')} ${pintor__rspack_import_4_default().brightYellow('This manifest declares shapes Chrome refuses — the whole extension will not load.')}\n${pintor__rspack_import_4_default().gray('PATH')} ${pintor__rspack_import_4_default().underline(extensionPath)}\n` + blockers.map((blocker)=>`${pintor__rspack_import_4_default().gray('REASON')} ${pintor__rspack_import_4_default().red(blocker)}\n`).join('') + "Chrome rejects the extension at load, so no service worker or content script ever runs. Fix these in the source manifest.";
|
|
@@ -1090,6 +1090,10 @@ var __webpack_modules__ = {
|
|
|
1090
1090
|
var child_process__rspack_import_0 = __webpack_require__("child_process");
|
|
1091
1091
|
var _messages__rspack_import_1 = __webpack_require__("./browsers/browsers-lib/messages.ts");
|
|
1092
1092
|
const FORCE_KILL_GRACE_MS = 5000;
|
|
1093
|
+
const terminatedByUs = new WeakSet();
|
|
1094
|
+
function wasTerminatedByUs(child) {
|
|
1095
|
+
return !!child && terminatedByUs.has(child);
|
|
1096
|
+
}
|
|
1093
1097
|
function authorLog(line) {
|
|
1094
1098
|
if (line && 'true' === process.env.EXTENSION_AUTHOR_MODE) console.log(line);
|
|
1095
1099
|
}
|
|
@@ -1114,6 +1118,7 @@ var __webpack_modules__ = {
|
|
|
1114
1118
|
}
|
|
1115
1119
|
function gracefulTerminateChild(child, browser) {
|
|
1116
1120
|
if (!child || child.killed) return;
|
|
1121
|
+
terminatedByUs.add(child);
|
|
1117
1122
|
killWindowsTree(child, false);
|
|
1118
1123
|
authorLog(_messages__rspack_import_1.XH(browser));
|
|
1119
1124
|
child.kill('SIGTERM');
|
|
@@ -1127,6 +1132,7 @@ var __webpack_modules__ = {
|
|
|
1127
1132
|
}
|
|
1128
1133
|
function forceKillChildOnExit(child, browser) {
|
|
1129
1134
|
if (!child) return;
|
|
1135
|
+
terminatedByUs.add(child);
|
|
1130
1136
|
killWindowsTree(child, true);
|
|
1131
1137
|
try {
|
|
1132
1138
|
authorLog(_messages__rspack_import_1.AG(browser));
|
|
@@ -1147,7 +1153,8 @@ var __webpack_modules__ = {
|
|
|
1147
1153
|
__webpack_require__.d(__webpack_exports__, {
|
|
1148
1154
|
$Y: ()=>forceKillChildOnExit,
|
|
1149
1155
|
Df: ()=>gracefulTerminateChild,
|
|
1150
|
-
FA: ()=>isBenignSocketTeardown
|
|
1156
|
+
FA: ()=>isBenignSocketTeardown,
|
|
1157
|
+
Op: ()=>wasTerminatedByUs
|
|
1151
1158
|
});
|
|
1152
1159
|
},
|
|
1153
1160
|
"./browsers/browsers-lib/ready-message.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -1860,15 +1867,24 @@ var __webpack_modules__ = {
|
|
|
1860
1867
|
contentScript?.exclude_matches
|
|
1861
1868
|
])if (Array.isArray(list)) patterns.push(...list);
|
|
1862
1869
|
for (const resource of Array.isArray(m?.web_accessible_resources) ? m.web_accessible_resources : [])if (Array.isArray(resource?.matches)) patterns.push(...resource.matches);
|
|
1863
|
-
const invalid = patterns.filter((pattern)=>'string' == typeof pattern && '<all_urls>' !== pattern &&
|
|
1870
|
+
const invalid = patterns.filter((pattern)=>'string' == typeof pattern && '<all_urls>' !== pattern && hasInvalidHostWildcard(pattern));
|
|
1864
1871
|
return [
|
|
1865
1872
|
...new Set(invalid)
|
|
1866
1873
|
];
|
|
1867
1874
|
}
|
|
1868
1875
|
function hasInvalidHostWildcard(pattern) {
|
|
1869
1876
|
const match = /^[a-zA-Z*]+:\/\/([^/]*)/.exec(pattern);
|
|
1870
|
-
const
|
|
1871
|
-
if (!
|
|
1877
|
+
const authority = match?.[1];
|
|
1878
|
+
if (!authority) return false;
|
|
1879
|
+
let host = authority;
|
|
1880
|
+
if (authority.startsWith('[')) {
|
|
1881
|
+
const end = authority.indexOf(']');
|
|
1882
|
+
if (-1 !== end) host = authority.slice(0, end + 1);
|
|
1883
|
+
} else {
|
|
1884
|
+
const colon = authority.indexOf(':');
|
|
1885
|
+
if (-1 !== colon) host = authority.slice(0, colon);
|
|
1886
|
+
}
|
|
1887
|
+
if (!host.includes('*')) return false;
|
|
1872
1888
|
return '*' !== host && !/^\*\.[^*]+$/.test(host);
|
|
1873
1889
|
}
|
|
1874
1890
|
function findChromiumLoadBlockers(manifest) {
|
|
@@ -1933,6 +1949,7 @@ var __webpack_modules__ = {
|
|
|
1933
1949
|
var ready_message = __webpack_require__("./browsers/browsers-lib/ready-message.ts");
|
|
1934
1950
|
var runtime_options = __webpack_require__("./browsers/browsers-lib/runtime-options.ts");
|
|
1935
1951
|
var shared_utils = __webpack_require__("./browsers/browsers-lib/shared-utils.ts");
|
|
1952
|
+
var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
|
|
1936
1953
|
var discovery = __webpack_require__("./browsers/run-chromium/cdp/discovery.ts");
|
|
1937
1954
|
var manifest_readiness = __webpack_require__("./browsers/run-chromium/manifest-readiness.ts");
|
|
1938
1955
|
var resolve_profile = __webpack_require__("./browsers/browsers-lib/resolve-profile.ts");
|
|
@@ -2172,7 +2189,6 @@ var __webpack_modules__ = {
|
|
|
2172
2189
|
console.log(messages.E8(chromiumConfig.join(' ')));
|
|
2173
2190
|
}
|
|
2174
2191
|
var extension_output_path = __webpack_require__("./browsers/run-chromium/chromium-launch/extension-output-path.ts");
|
|
2175
|
-
var process_teardown = __webpack_require__("./browsers/browsers-lib/process-teardown.ts");
|
|
2176
2192
|
const activeInstances = new Set();
|
|
2177
2193
|
let globalHandlersInstalled = false;
|
|
2178
2194
|
function cleanupOne(instance) {
|
|
@@ -2373,6 +2389,17 @@ var __webpack_modules__ = {
|
|
|
2373
2389
|
browserVersionLine: args.browserVersionLine
|
|
2374
2390
|
});
|
|
2375
2391
|
}
|
|
2392
|
+
function stampReadyBrowserExited(extensionOutputPath, code) {
|
|
2393
|
+
try {
|
|
2394
|
+
if (!extensionOutputPath) return;
|
|
2395
|
+
const readyPath = external_path_.join(external_path_.dirname(extensionOutputPath), 'extension-js', external_path_.basename(extensionOutputPath), 'ready.json');
|
|
2396
|
+
if (!external_fs_.existsSync(readyPath)) return;
|
|
2397
|
+
const ready = JSON.parse(external_fs_.readFileSync(readyPath, 'utf-8'));
|
|
2398
|
+
ready.browserExitedAt = new Date().toISOString();
|
|
2399
|
+
ready.browserExitCode = code;
|
|
2400
|
+
external_fs_.writeFileSync(readyPath, JSON.stringify(ready, null, 2));
|
|
2401
|
+
} catch {}
|
|
2402
|
+
}
|
|
2376
2403
|
class ChromiumLaunchPlugin {
|
|
2377
2404
|
async runOnce(compilation, opts) {
|
|
2378
2405
|
if (!this.logger) this.logger = {
|
|
@@ -2743,6 +2770,10 @@ var __webpack_modules__ = {
|
|
|
2743
2770
|
});
|
|
2744
2771
|
if (this.options.dryRun) return void logChromiumDryRun(browserBinaryLocation, chromiumConfig);
|
|
2745
2772
|
const usePipe = chromiumConfig.includes('--remote-debugging-pipe');
|
|
2773
|
+
this.closeHandlerContext = {
|
|
2774
|
+
isDevMode: 'development' === compilation.options.mode,
|
|
2775
|
+
extensionOutputPath: (0, extension_output_path.W)(compilation, chromiumConfig.find((flag)=>flag.startsWith('--load-extension='))) || void 0
|
|
2776
|
+
};
|
|
2746
2777
|
const child = await this.launchWithDirectSpawn(browserBinaryLocation, chromiumConfig, usePipe);
|
|
2747
2778
|
const pipeStreams = usePipe && child?.stdio?.[3] && child?.stdio?.[4] ? {
|
|
2748
2779
|
input: child.stdio[4],
|
|
@@ -2845,6 +2876,10 @@ var __webpack_modules__ = {
|
|
|
2845
2876
|
let disposeSignalHandlers;
|
|
2846
2877
|
child.on('close', (code)=>{
|
|
2847
2878
|
if ('true' === process.env.EXTENSION_AUTHOR_MODE) this.logger.info(messages.nn(code || 0));
|
|
2879
|
+
if (!(0, process_teardown.Op)(child) && this.closeHandlerContext?.isDevMode) {
|
|
2880
|
+
this.logger.error(`[browser] ${this.options.browser} exited mid-session (code ${code ?? 'unknown'}). The dev server is still running but reloads cannot be delivered — restart "extension dev" to relaunch the browser.`);
|
|
2881
|
+
stampReadyBrowserExited(this.closeHandlerContext.extensionOutputPath, code);
|
|
2882
|
+
}
|
|
2848
2883
|
disposeSignalHandlers?.();
|
|
2849
2884
|
const userDataDir = launchArgs.find((arg)=>arg.startsWith('--user-data-dir='))?.slice('--user-data-dir='.length).replace(/^"|"$/g, '');
|
|
2850
2885
|
shared_utils.sW(userDataDir);
|
|
@@ -2879,10 +2914,12 @@ var __webpack_modules__ = {
|
|
|
2879
2914
|
_define_property(this, "didLaunch", void 0);
|
|
2880
2915
|
_define_property(this, "didReportReady", void 0);
|
|
2881
2916
|
_define_property(this, "logger", void 0);
|
|
2917
|
+
_define_property(this, "closeHandlerContext", void 0);
|
|
2882
2918
|
this.options = options;
|
|
2883
2919
|
this.ctx = ctx;
|
|
2884
2920
|
this.didLaunch = false;
|
|
2885
2921
|
this.didReportReady = false;
|
|
2922
|
+
this.closeHandlerContext = null;
|
|
2886
2923
|
}
|
|
2887
2924
|
}
|
|
2888
2925
|
},
|
|
@@ -7,18 +7,23 @@
|
|
|
7
7
|
export type ChromiumManifestRefusal = 'mv2' | 'mv3-background-scripts' | null;
|
|
8
8
|
export declare function diagnoseChromiumManifestRefusal(manifest: unknown): ChromiumManifestRefusal;
|
|
9
9
|
/**
|
|
10
|
-
* Match patterns Chrome's grammar refuses
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* refuse
|
|
14
|
-
*
|
|
15
|
-
* identically, so this is extension-own — but dev must say so instead of
|
|
16
|
-
* printing an ID for an extension that never loads.
|
|
10
|
+
* Match patterns Chrome's grammar refuses. ONE invalid pattern in
|
|
11
|
+
* content_scripts matches, host_permissions, or web_accessible_resources
|
|
12
|
+
* makes Chrome refuse the WHOLE extension at load. The only shape verified
|
|
13
|
+
* to actually refuse is an invalid HOST WILDCARD (wild: CarbonWise's
|
|
14
|
+
* `*carbonwise*` — CDP loadUnpacked reports "Invalid host wildcard").
|
|
17
15
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* `
|
|
21
|
-
*
|
|
16
|
+
* NOT flagged, all verified live on Chrome 150 (2026-07-11, both CDP
|
|
17
|
+
* loadUnpacked and --load-extension, install ENABLED):
|
|
18
|
+
* - explicit ports (`http://localhost:3000/*`; wild memux loads fine)
|
|
19
|
+
* - WILDCARD ports (`ws://localhost:<star>` with a wildcard port; wild
|
|
20
|
+
* BinaryBeastMaster/chat-relay installs ENABLED with a live service
|
|
21
|
+
* worker) — the port is not part of the host
|
|
22
|
+
* - query strings / fragments in the path (`?`, `#` are literal path
|
|
23
|
+
* characters: `.../gcpd/730?tab=majors` and `/page#section` both load;
|
|
24
|
+
* wild SN-Utils ships a query-string exclude_matches on the store) —
|
|
25
|
+
* flagging them warned "the whole extension will not load" on extensions
|
|
26
|
+
* that load fine.
|
|
22
27
|
*/
|
|
23
28
|
export declare function findInvalidMatchPatterns(manifest: unknown): string[];
|
|
24
29
|
/**
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ChildProcess } from 'child_process';
|
|
2
2
|
import type { BrowserType } from '../browsers-types';
|
|
3
3
|
export declare const FORCE_KILL_GRACE_MS = 5000;
|
|
4
|
+
export declare function wasTerminatedByUs(child: ChildProcess | null): boolean;
|
|
4
5
|
export declare function gracefulTerminateChild(child: ChildProcess | null, browser: BrowserType): void;
|
|
5
6
|
export declare function forceKillChildOnExit(child: ChildProcess | null, browser: BrowserType): void;
|
|
6
7
|
export declare function isBenignSocketTeardown(value: unknown): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CompilationLike } from '../../browsers-types';
|
|
2
2
|
import type { ChromiumContext } from '../chromium-context';
|
|
3
3
|
import type { ChromiumLaunchOptions } from '../chromium-types';
|
|
4
|
+
export declare function stampReadyBrowserExited(extensionOutputPath: string | undefined, code: number | null): void;
|
|
4
5
|
/**
|
|
5
6
|
* ChromiumLaunchPlugin
|
|
6
7
|
*
|
|
@@ -16,6 +17,7 @@ export declare class ChromiumLaunchPlugin {
|
|
|
16
17
|
private didLaunch;
|
|
17
18
|
private didReportReady;
|
|
18
19
|
private logger;
|
|
20
|
+
private closeHandlerContext;
|
|
19
21
|
constructor(options: ChromiumLaunchOptions, ctx: ChromiumContext);
|
|
20
22
|
/**
|
|
21
23
|
* Run the Chromium launch flow without requiring a bundler compiler instance.
|
package/package.json
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"extension": "./bin/extension.cjs"
|
|
39
39
|
},
|
|
40
40
|
"name": "extension",
|
|
41
|
-
"version": "4.0.
|
|
41
|
+
"version": "4.0.8",
|
|
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": {
|
|
@@ -109,9 +109,9 @@
|
|
|
109
109
|
"vivaldi-location2": "2.1.0",
|
|
110
110
|
"waterfox-location": "2.1.0",
|
|
111
111
|
"yandex-location": "2.1.0",
|
|
112
|
-
"extension-create": "4.0.
|
|
113
|
-
"extension-develop": "4.0.
|
|
114
|
-
"extension-install": "4.0.
|
|
112
|
+
"extension-create": "4.0.8",
|
|
113
|
+
"extension-develop": "4.0.8",
|
|
114
|
+
"extension-install": "4.0.8",
|
|
115
115
|
"commander": "^15.0.0",
|
|
116
116
|
"pintor": "0.3.0",
|
|
117
117
|
"semver": "^7.7.3",
|