extension-develop 4.0.32 → 4.0.34

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.
@@ -4,7 +4,7 @@ import { createRequire } from "node:module";
4
4
  import pintor from "pintor";
5
5
  import core, { Compilation as core_Compilation, DefinePlugin, ProvidePlugin, WebpackError as core_WebpackError, rspack, sources as core_sources } from "@rspack/core";
6
6
  import case_sensitive_paths_webpack_plugin from "case-sensitive-paths-webpack-plugin";
7
- import adm_zip from "adm-zip";
7
+ import { zipSync } from "fflate";
8
8
  import ignore from "ignore";
9
9
  import tiny_glob from "tiny-glob";
10
10
  import { pathToFileURL } from "node:url";
@@ -676,7 +676,7 @@ function contentSecurityPolicy(manifest) {
676
676
  content_security_policy: manifest.content_security_policy
677
677
  };
678
678
  }
679
- function devtoolsPage(manifest, manifestPath) {
679
+ function devtools_page_devtoolsPage(manifest, manifestPath) {
680
680
  return manifest.devtools_page && {
681
681
  devtools_page: (()=>{
682
682
  const raw = String(manifest.devtools_page);
@@ -810,7 +810,7 @@ function manifestCommon(manifest, manifestPath) {
810
810
  ...backgroundPage(manifest),
811
811
  ...chromeUrlOverrides(manifest, manifestPath),
812
812
  ...content_scripts_contentScripts(manifest, manifestPath),
813
- ...devtoolsPage(manifest, manifestPath),
813
+ ...devtools_page_devtoolsPage(manifest, manifestPath),
814
814
  ...icons_icons(manifest),
815
815
  ...commands_commands(manifest),
816
816
  ...permissions(manifest),
@@ -1319,6 +1319,46 @@ function resolveManifestName(rawName, manifest, searchRoots, fallback) {
1319
1319
  return fallback;
1320
1320
  }
1321
1321
  const toPosix = (p)=>p.replace(/\\/g, '/');
1322
+ function zipEntryFor(absPath) {
1323
+ const stat = __rspack_external_node_fs_5ea92f0c.statSync(absPath);
1324
+ return [
1325
+ new Uint8Array(__rspack_external_node_fs_5ea92f0c.readFileSync(absPath)),
1326
+ {
1327
+ mtime: stat.mtime,
1328
+ os: 3,
1329
+ attrs: (4095 & stat.mode | 32768) << 16 >>> 0
1330
+ }
1331
+ ];
1332
+ }
1333
+ function writeZipFile(zipPath, entries) {
1334
+ const zippable = {};
1335
+ for (const entry of entries)zippable[toPosix(entry.name)] = zipEntryFor(entry.absPath);
1336
+ __rspack_external_node_fs_5ea92f0c.writeFileSync(zipPath, zipSync(zippable));
1337
+ }
1338
+ function listFilesUnder(root, skipNames) {
1339
+ const out = [];
1340
+ const stack = [
1341
+ ''
1342
+ ];
1343
+ while(stack.length){
1344
+ const relDir = stack.pop();
1345
+ const absDir = __rspack_external_node_path_c5b9b54f.join(root, relDir);
1346
+ let entries = [];
1347
+ try {
1348
+ entries = __rspack_external_node_fs_5ea92f0c.readdirSync(absDir, {
1349
+ withFileTypes: true
1350
+ });
1351
+ } catch {
1352
+ continue;
1353
+ }
1354
+ for (const entry of entries){
1355
+ const rel = relDir ? __rspack_external_node_path_c5b9b54f.join(relDir, entry.name) : entry.name;
1356
+ if (entry.isDirectory()) stack.push(rel);
1357
+ else if (entry.isFile() && !skipNames.has(toPosix(rel))) out.push(rel);
1358
+ }
1359
+ }
1360
+ return out.sort();
1361
+ }
1322
1362
  const COMPANION_DIR = 'extensions';
1323
1363
  function isCompanionExtension(file) {
1324
1364
  const [first] = toPosix(file).split('/');
@@ -1334,10 +1374,12 @@ function isDeniedEnvFile(basename) {
1334
1374
  if (!basename.startsWith('.env')) return false;
1335
1375
  return !basename.endsWith('.example');
1336
1376
  }
1377
+ const STAGING_DIR_PREFIX = '.extension-build-';
1337
1378
  function isDeniedFromSourceZip(file) {
1338
1379
  const posix = toPosix(file);
1339
1380
  const segments = posix.split('/');
1340
1381
  if (segments.some((segment)=>DENIED_SEGMENTS.has(segment))) return true;
1382
+ if (segments.some((segment)=>segment.startsWith(STAGING_DIR_PREFIX))) return true;
1341
1383
  if (isDeniedEnvFile(segments[segments.length - 1])) return true;
1342
1384
  return posix === SESSION_ARTIFACTS_PREFIX || posix.startsWith(`${SESSION_ARTIFACTS_PREFIX}/`);
1343
1385
  }
@@ -1386,27 +1428,28 @@ class ZipPlugin {
1386
1428
  ], __rspack_external_node_path_c5b9b54f.basename(packageJsonDir)));
1387
1429
  const name = `${base}-${manifest.version || '0.0.0'}`;
1388
1430
  if (this.zipData.zipSource) {
1389
- const sourceZip = new adm_zip();
1390
1431
  const files = await getFilesToZip(packageJsonDir);
1391
- files.forEach((file)=>{
1392
- const root = __rspack_external_node_path_c5b9b54f.dirname(file);
1393
- sourceZip.addLocalFile(__rspack_external_node_path_c5b9b54f.join(packageJsonDir, file), '.' === root ? '' : toPosix(root));
1394
- });
1395
1432
  const sourcePath = __rspack_external_node_path_c5b9b54f.join(__rspack_external_node_path_c5b9b54f.dirname(outPath), `${name}-source.zip`);
1396
1433
  if (isDebug()) console.log(packagingSourceFiles(sourcePath));
1397
- sourceZip.writeZip(sourcePath);
1434
+ writeZipFile(sourcePath, files.map((file)=>({
1435
+ name: file,
1436
+ absPath: __rspack_external_node_path_c5b9b54f.join(packageJsonDir, file)
1437
+ })));
1398
1438
  created.push({
1399
1439
  kind: 'source',
1400
1440
  path: sourcePath
1401
1441
  });
1402
1442
  }
1403
1443
  if (this.zipData.zip) {
1404
- const distZip = new adm_zip();
1405
- distZip.addLocalFolder(outPath);
1406
1444
  const zipName = this.zipData.zipFilename ? explicitZipFilename(this.zipData.zipFilename) : `${name}.zip`;
1407
1445
  const distPath = __rspack_external_node_path_c5b9b54f.join(outPath, zipName);
1408
1446
  if (isDebug()) console.log(packagingDistributionFiles(distPath));
1409
- distZip.writeZip(distPath);
1447
+ writeZipFile(distPath, listFilesUnder(outPath, new Set([
1448
+ toPosix(zipName)
1449
+ ])).map((file)=>({
1450
+ name: file,
1451
+ absPath: __rspack_external_node_path_c5b9b54f.join(outPath, file)
1452
+ })));
1410
1453
  created.push({
1411
1454
  kind: 'dist',
1412
1455
  path: distPath
@@ -3545,13 +3588,33 @@ class JsFrameworksPlugin {
3545
3588
  manifestDir,
3546
3589
  ...resolveTranspilePackageDirs(projectPath, this.transpilePackages)
3547
3590
  ]));
3591
+ const expandWithRealpaths = (dirs)=>{
3592
+ const out = new Set();
3593
+ for (const dir of dirs)if (dir) {
3594
+ out.add(dir);
3595
+ try {
3596
+ out.add(__rspack_external_node_fs_5ea92f0c.realpathSync(dir));
3597
+ } catch {}
3598
+ }
3599
+ return Array.from(out);
3600
+ };
3601
+ const addBothPathForms = (set, absPath)=>{
3602
+ set.add(toResourceKey(absPath));
3603
+ try {
3604
+ set.add(toResourceKey(__rspack_external_node_fs_5ea92f0c.realpathSync(absPath)));
3605
+ } catch {}
3606
+ };
3548
3607
  const contentScriptLikePaths = new Set();
3549
- const scriptsDir = toResourceKey(__rspack_external_node_path_c5b9b54f.resolve(projectPath, "scripts"));
3608
+ const scriptsDirs = expandWithRealpaths([
3609
+ __rspack_external_node_path_c5b9b54f.resolve(projectPath, "scripts")
3610
+ ]).map(toResourceKey);
3550
3611
  const isfeatureScriptsContentLike = (resourcePath)=>{
3551
3612
  const normalized = toResourceKey(resourcePath);
3552
3613
  if (contentScriptLikePaths.has(normalized)) return true;
3553
- const relToScripts = __rspack_external_node_path_c5b9b54f.relative(scriptsDir, normalized);
3554
- return !!relToScripts && !relToScripts.startsWith('..') && !__rspack_external_node_path_c5b9b54f.isAbsolute(relToScripts);
3614
+ return scriptsDirs.some((scriptsDir)=>{
3615
+ const relToScripts = __rspack_external_node_path_c5b9b54f.relative(scriptsDir, normalized);
3616
+ return !!relToScripts && !relToScripts.startsWith('..') && !__rspack_external_node_path_c5b9b54f.isAbsolute(relToScripts);
3617
+ });
3555
3618
  };
3556
3619
  const devtool = compiler.options.devtool;
3557
3620
  const wantsSourceMaps = false !== devtool && ('development' === mode || null != devtool);
@@ -3562,13 +3625,13 @@ class JsFrameworksPlugin {
3562
3625
  const contentScripts = Array.isArray(manifest?.content_scripts) ? manifest.content_scripts : [];
3563
3626
  for (const contentScript of contentScripts){
3564
3627
  const jsList = Array.isArray(contentScript?.js) ? contentScript.js : [];
3565
- for (const jsFile of jsList)contentScriptLikePaths.add(toResourceKey(__rspack_external_node_path_c5b9b54f.resolve(manifestDir, jsFile)));
3628
+ for (const jsFile of jsList)addBothPathForms(contentScriptLikePaths, __rspack_external_node_path_c5b9b54f.resolve(manifestDir, jsFile));
3566
3629
  }
3567
3630
  const platformModulePaths = new Set();
3568
3631
  try {
3569
3632
  const browserManifest = external_browser_extension_manifest_fields_filterKeysForThisBrowser(manifest, this.browser);
3570
3633
  const background = browserManifest?.background;
3571
- if (background?.type === 'module' && 'string' == typeof background?.service_worker) platformModulePaths.add(toResourceKey(__rspack_external_node_path_c5b9b54f.resolve(manifestDir, background.service_worker)));
3634
+ if (background?.type === 'module' && 'string' == typeof background?.service_worker) addBothPathForms(platformModulePaths, __rspack_external_node_path_c5b9b54f.resolve(manifestDir, background.service_worker));
3572
3635
  const htmlPages = {
3573
3636
  ...getManifestFieldsData({
3574
3637
  manifestPath: this.manifestPath,
@@ -3576,7 +3639,7 @@ class JsFrameworksPlugin {
3576
3639
  }).html,
3577
3640
  ...getSpecialFoldersDataForCompiler(compiler).pages
3578
3641
  };
3579
- for (const htmlPage of Object.values(htmlPages))if ('string' == typeof htmlPage) for (const moduleScript of getAssetsFromHtml(htmlPage)?.moduleJs || [])platformModulePaths.add(toResourceKey(moduleScript));
3642
+ for (const htmlPage of Object.values(htmlPages))if ('string' == typeof htmlPage) for (const moduleScript of getAssetsFromHtml(htmlPage)?.moduleJs || [])addBothPathForms(platformModulePaths, moduleScript);
3580
3643
  } catch {}
3581
3644
  const maybeInstallReact = await maybeUseReact(projectPath, {
3582
3645
  disableRefresh: 'development' !== mode,
@@ -3588,7 +3651,7 @@ class JsFrameworksPlugin {
3588
3651
  const tsConfigPath = getUserTypeScriptConfigFile(projectPath);
3589
3652
  const tsRoot = tsConfigPath ? __rspack_external_node_path_c5b9b54f.dirname(tsConfigPath) : manifestDir;
3590
3653
  const transpilePackageDirs = swcIncludeDirs.filter((dir)=>dir !== projectPath && dir !== manifestDir);
3591
- const preferTypeScript = !!tsConfigPath || isUsingTypeScript(projectPath);
3654
+ const preferTypeScript = !!tsConfigPath;
3592
3655
  let targets = [
3593
3656
  'chrome >= 100'
3594
3657
  ];
@@ -3623,10 +3686,10 @@ class JsFrameworksPlugin {
3623
3686
  const swcRuleBase = {
3624
3687
  test: /\.(js|cjs|mjs|jsx|mjsx|ts|mts|tsx|mtsx)$/,
3625
3688
  type: "javascript/auto",
3626
- include: Array.from(new Set([
3689
+ include: expandWithRealpaths(Array.from(new Set([
3627
3690
  tsRoot,
3628
3691
  ...swcIncludeDirs
3629
- ])),
3692
+ ]))),
3630
3693
  exclude: [
3631
3694
  (resourcePath)=>{
3632
3695
  const isInNodeModules = /[\\/]node_modules[\\/]/.test(resourcePath);
@@ -3675,10 +3738,10 @@ class JsFrameworksPlugin {
3675
3738
  {
3676
3739
  ...swcRuleBase,
3677
3740
  layer: EXTENSIONJS_CONTENT_SCRIPT_LAYER,
3678
- include: (resourcePath)=>Array.from(new Set([
3741
+ include: (resourcePath)=>expandWithRealpaths(Array.from(new Set([
3679
3742
  tsRoot,
3680
3743
  ...swcIncludeDirs
3681
- ])).some((dir)=>isSubPath(resourcePath, dir)) && isfeatureScriptsContentLike(resourcePath),
3744
+ ]))).some((dir)=>isSubPath(resourcePath, dir)) && isfeatureScriptsContentLike(resourcePath),
3682
3745
  use: {
3683
3746
  ...swcLoaderBase,
3684
3747
  options: {
@@ -3832,12 +3895,14 @@ function categorizeAsset(rawName) {
3832
3895
  if (/(^|\/)content_scripts\//.test(name)) return "content-script";
3833
3896
  if (/(^|\/)background\//.test(name) || /(^|\/)service[-_]?worker\.(js|css|wasm)$/i.test(name)) return 'service-worker';
3834
3897
  for (const dir of PAGE_DIRS)if (new RegExp(`(^|\\/)${dir}\\/`).test(name)) return 'page';
3898
+ if (!name.includes('/') || /\.wasm$/i.test(name)) return 'runtime';
3835
3899
  return 'ignored';
3836
3900
  }
3837
3901
  const BUDGET_BYTES = {
3838
3902
  "content-script": 524288,
3839
3903
  'service-worker': 524288,
3840
3904
  page: 1048576,
3905
+ runtime: 1048576,
3841
3906
  ignored: 1 / 0
3842
3907
  };
3843
3908
  function fmtKiB(bytes) {
@@ -3863,6 +3928,8 @@ function categoryRole(c) {
3863
3928
  return 'service worker / background, wakes from cold each session';
3864
3929
  case 'page':
3865
3930
  return 'UI page, opened on demand';
3931
+ case 'runtime':
3932
+ return 'runtime payload, shipped at the output root';
3866
3933
  default:
3867
3934
  return 'asset';
3868
3935
  }
@@ -7036,10 +7103,6 @@ function manifestDeclaredSourcePaths(manifest) {
7036
7103
  add(manifest.side_panel?.default_path);
7037
7104
  add(manifest.sidebar_action?.default_panel);
7038
7105
  for (const page of Object.values(manifest.chrome_url_overrides ?? {}))add(page);
7039
- for (const contentScript of manifest.content_scripts ?? []){
7040
- for (const js of contentScript?.js ?? [])add(js);
7041
- for (const css of contentScript?.css ?? [])add(css);
7042
- }
7043
7106
  return declared;
7044
7107
  }
7045
7108
  function extractGetURLLiterals(source) {
@@ -7518,7 +7581,7 @@ class SpecialFoldersPlugin {
7518
7581
  });
7519
7582
  });
7520
7583
  const copyIgnore = [
7521
- 'manifest.json'
7584
+ __rspack_external_node_path_c5b9b54f.join(publicDir, 'manifest.json').replace(/\\/g, '/')
7522
7585
  ];
7523
7586
  new rspack.CopyRspackPlugin({
7524
7587
  patterns: [
@@ -7690,12 +7753,30 @@ class WasmPlugin {
7690
7753
  this.manifestPath = options.manifestPath;
7691
7754
  this.mode = options.mode;
7692
7755
  }
7756
+ collectSearchRoots(projectRoot) {
7757
+ const roots = [];
7758
+ const seen = new Set();
7759
+ const addAncestors = (startDir)=>{
7760
+ let current = __rspack_external_node_path_c5b9b54f.resolve(startDir);
7761
+ while(true){
7762
+ if (!seen.has(current)) {
7763
+ seen.add(current);
7764
+ roots.push(current);
7765
+ }
7766
+ const parent = __rspack_external_node_path_c5b9b54f.dirname(current);
7767
+ if (parent === current) break;
7768
+ current = parent;
7769
+ }
7770
+ };
7771
+ addAncestors(projectRoot);
7772
+ addAncestors(process.cwd());
7773
+ return roots;
7774
+ }
7693
7775
  resolveAssetPath(projectRoot, relativePath) {
7694
- const candidates = [
7695
- __rspack_external_node_path_c5b9b54f.join(projectRoot, 'node_modules', relativePath),
7696
- __rspack_external_node_path_c5b9b54f.join(process.cwd(), 'node_modules', relativePath)
7697
- ];
7698
- for (const candidate of candidates)if (__rspack_external_node_fs_5ea92f0c.existsSync(candidate)) return candidate;
7776
+ for (const root of this.collectSearchRoots(projectRoot)){
7777
+ const candidate = __rspack_external_node_path_c5b9b54f.join(root, 'node_modules', relativePath);
7778
+ if (__rspack_external_node_fs_5ea92f0c.existsSync(candidate)) return candidate;
7779
+ }
7699
7780
  return null;
7700
7781
  }
7701
7782
  buildAssetAliases(projectRoot) {
@@ -9871,7 +9952,9 @@ function patchWebResourcesV2(manifest) {
9871
9952
  '/*.gif',
9872
9953
  '/*.webp',
9873
9954
  '/*.ico',
9874
- '/*.avif'
9955
+ '/*.avif',
9956
+ '/*.wasm',
9957
+ '/*.bin'
9875
9958
  ];
9876
9959
  const resources = manifest.web_accessible_resources;
9877
9960
  if (!resources || 0 === resources.length) return defaultResources;
@@ -9898,7 +9981,9 @@ function patchWebResourcesV3(manifest) {
9898
9981
  '/*.gif',
9899
9982
  '/*.webp',
9900
9983
  '/*.ico',
9901
- '/*.avif'
9984
+ '/*.avif',
9985
+ '/*.wasm',
9986
+ '/*.bin'
9902
9987
  ];
9903
9988
  return [
9904
9989
  ...manifest.web_accessible_resources || [],
@@ -10157,7 +10242,33 @@ class ManifestLegacyWarnings {
10157
10242
  });
10158
10243
  }
10159
10244
  }
10245
+ function toFileArray(value) {
10246
+ if (!value) return [];
10247
+ return Array.isArray(value) ? value : Array.from(value);
10248
+ }
10160
10249
  const EMITTED_ASSET_REF_PATTERN = /assets\/[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*/g;
10250
+ function isExcludedFromWar(fileName) {
10251
+ const name = String(fileName || '');
10252
+ if (!name || 'manifest.json' === name) return true;
10253
+ if (name.endsWith('.js') || name.endsWith('.map')) return true;
10254
+ if (/(^|\/)hot\//.test(name)) return true;
10255
+ return false;
10256
+ }
10257
+ function listEmittedAssetNames(compilation) {
10258
+ if ('function' == typeof compilation.getAssets) try {
10259
+ return compilation.getAssets().map((asset)=>String(asset.name));
10260
+ } catch {}
10261
+ return Object.keys(compilation.assets || {});
10262
+ }
10263
+ function collectReferencedRuntimePayloads(source, emittedAssetNames) {
10264
+ if (!source) return [];
10265
+ const found = new Set();
10266
+ const patternHits = source.match(EMITTED_ASSET_REF_PATTERN) || [];
10267
+ for (const hit of patternHits)if (!isExcludedFromWar(hit)) found.add(hit);
10268
+ const eligible = emittedAssetNames.filter((name)=>!isExcludedFromWar(name)).sort((a, b)=>b.length - a.length);
10269
+ for (const asset of eligible)if (source.includes(asset)) found.add(unixify(asset));
10270
+ return Array.from(found);
10271
+ }
10161
10272
  function forEachStringKey(objectOrMap, callback) {
10162
10273
  if (!objectOrMap) return;
10163
10274
  if (objectOrMap instanceof Map) {
@@ -10200,10 +10311,9 @@ function collectContentScriptEntryImports(compilation, includeList) {
10200
10311
  }
10201
10312
  entry.chunks.forEach((chunk)=>{
10202
10313
  const currentChunk = chunk;
10203
- const chunkFilesArray = Array.isArray(currentChunk.files) ? currentChunk.files : [];
10314
+ const chunkFilesArray = toFileArray(currentChunk.files);
10204
10315
  for(let i = 0; i < chunkFilesArray.length; i++)addFileIfRelevant(chunkFilesArray[i]);
10205
- let chunkAuxFilesArray = [];
10206
- if (Array.isArray(currentChunk.auxiliaryFiles)) chunkAuxFilesArray = currentChunk.auxiliaryFiles;
10316
+ const chunkAuxFilesArray = toFileArray(currentChunk.auxiliaryFiles);
10207
10317
  for(let i = 0; i < chunkAuxFilesArray.length; i++)addFileIfRelevant(chunkAuxFilesArray[i]);
10208
10318
  const modulesArray = Array.from(chunkGraph.getChunkModulesIterable(chunk));
10209
10319
  for(let j = 0; j < modulesArray.length; j++){
@@ -10211,7 +10321,7 @@ function collectContentScriptEntryImports(compilation, includeList) {
10211
10321
  const moduleChunksArray = Array.from(chunkGraph.getModuleChunks(moduleObj));
10212
10322
  for(let k = 0; k < moduleChunksArray.length; k++){
10213
10323
  const mk = moduleChunksArray[k];
10214
- const mkAuxFilesArr = Array.isArray(mk.auxiliaryFiles) ? mk.auxiliaryFiles : [];
10324
+ const mkAuxFilesArr = toFileArray(mk.auxiliaryFiles);
10215
10325
  for(let l = 0; l < mkAuxFilesArr.length; l++)addFileIfRelevant(mkAuxFilesArr[l]);
10216
10326
  }
10217
10327
  const moduleWithBuildInfo = moduleObj;
@@ -10223,20 +10333,21 @@ function collectContentScriptEntryImports(compilation, includeList) {
10223
10333
  addFileIfRelevant(key);
10224
10334
  });
10225
10335
  }
10336
+ const emittedAssetNames = listEmittedAssetNames(compilation);
10226
10337
  for(let i = 0; i < chunkFilesArray.length; i++){
10227
10338
  const chunkFileName = chunkFilesArray[i];
10228
10339
  if (!String(chunkFileName).endsWith('.js')) continue;
10229
10340
  const jsSource = getAssetSource(compilation, chunkFileName);
10230
10341
  if (!jsSource) continue;
10231
- const matchedStrings = jsSource.match(EMITTED_ASSET_REF_PATTERN) || [];
10232
- for(let m = 0; m < matchedStrings.length; m++)addFileIfRelevant(matchedStrings[m]);
10342
+ const referenced = collectReferencedRuntimePayloads(jsSource, emittedAssetNames);
10343
+ for(let m = 0; m < referenced.length; m++)addFileIfRelevant(referenced[m]);
10233
10344
  }
10234
10345
  });
10235
10346
  const logicalJsAssetName = `${entryName}.js`;
10236
10347
  const logicalJsAssetSource = getAssetSource(compilation, logicalJsAssetName);
10237
10348
  if (logicalJsAssetSource) {
10238
- const matchedStrings = logicalJsAssetSource.match(EMITTED_ASSET_REF_PATTERN) || [];
10239
- for(let n = 0; n < matchedStrings.length; n++)addFileIfRelevant(matchedStrings[n]);
10349
+ const referenced = collectReferencedRuntimePayloads(logicalJsAssetSource, listEmittedAssetNames(compilation));
10350
+ for(let n = 0; n < referenced.length; n++)addFileIfRelevant(referenced[n]);
10240
10351
  }
10241
10352
  entryImports[entryName] = Array.from(collectedFilesSet);
10242
10353
  });
@@ -10555,6 +10666,10 @@ function generate_manifest_getAssetSource(compilation, filename) {
10555
10666
  const source = asset.source;
10556
10667
  if (!source) return '';
10557
10668
  if ('string' == typeof source) return source;
10669
+ if ('function' == typeof source) {
10670
+ const out = source();
10671
+ return 'string' == typeof out ? out : '';
10672
+ }
10558
10673
  if ('function' == typeof source.source) {
10559
10674
  const out = source.source();
10560
10675
  return 'string' == typeof out ? out : '';
@@ -10629,22 +10744,28 @@ function generateManifestPatches(compilation, manifestPath, entryImports, browse
10629
10744
  resources: Array.from(g.resources)
10630
10745
  })) : [];
10631
10746
  const webAccessibleResourcesV2 = 2 === canonicalManifest.manifest_version ? Array.from(resolved.v2) : [];
10632
- if (3 === canonicalManifest.manifest_version && Array.isArray(canonicalManifest.content_scripts)) for (const contentScript of canonicalManifest.content_scripts){
10633
- const matches = contentScript.matches || [];
10634
- const normalizedMatches = cleanMatches(matches);
10635
- const jsFiles = Array.isArray(contentScript.js) ? contentScript.js : [];
10636
- for (const jsFile of jsFiles){
10637
- const assetForCache = 'function' == typeof compilation.getAsset ? compilation.getAsset(jsFile) : void 0;
10638
- const cacheKey = assetForCache && 'object' == typeof assetForCache.source ? assetForCache.source : void 0;
10639
- let filtered = cacheKey ? assetScanCache.get(cacheKey) : void 0;
10640
- if (!filtered) {
10641
- const source = generate_manifest_getAssetSource(compilation, jsFile);
10642
- if (!source) continue;
10643
- const found = source.match(EMITTED_ASSET_REF_PATTERN) || [];
10644
- filtered = Array.from(new Set(found.filter((r)=>!r.endsWith('.js') && !r.endsWith('.map')))).sort();
10645
- if (cacheKey) assetScanCache.set(cacheKey, filtered);
10747
+ if (Array.isArray(canonicalManifest.content_scripts)) {
10748
+ const emittedAssetNames = listEmittedAssetNames(compilation);
10749
+ for (const contentScript of canonicalManifest.content_scripts){
10750
+ const matches = contentScript.matches || [];
10751
+ const jsFiles = Array.isArray(contentScript.js) ? contentScript.js : [];
10752
+ const referenced = [];
10753
+ for (const jsFile of jsFiles){
10754
+ const assetForCache = 'function' == typeof compilation.getAsset ? compilation.getAsset(jsFile) : void 0;
10755
+ const cacheKey = assetForCache && 'object' == typeof assetForCache.source ? assetForCache.source : void 0;
10756
+ let filtered = cacheKey ? assetScanCache.get(cacheKey) : void 0;
10757
+ if (!filtered) {
10758
+ const source = generate_manifest_getAssetSource(compilation, jsFile);
10759
+ if (!source) continue;
10760
+ filtered = collectReferencedRuntimePayloads(source, emittedAssetNames);
10761
+ if (cacheKey) assetScanCache.set(cacheKey, filtered);
10762
+ }
10763
+ for (const resource of filtered)referenced.push(resource);
10764
+ }
10765
+ if (0 !== referenced.length) {
10766
+ if (3 === canonicalManifest.manifest_version) mergeIntoV3Group(webAccessibleResourcesV3, cleanMatches(matches), referenced);
10767
+ else for (const resource of referenced)if (!webAccessibleResourcesV2.includes(resource)) webAccessibleResourcesV2.push(resource);
10646
10768
  }
10647
- if (0 !== filtered.length) mergeIntoV3Group(webAccessibleResourcesV3, normalizedMatches, filtered);
10648
10769
  }
10649
10770
  }
10650
10771
  for (const [entryName, resources] of Object.entries(entryImports)){
@@ -12463,7 +12584,9 @@ class AddScripts {
12463
12584
  createSequentialEntryModule(feature, scriptImports),
12464
12585
  ...cssImports
12465
12586
  ] : entryImports;
12466
- if (finalEntryImports.length) newEntries[feature] = 'background/service_worker' === feature ? {
12587
+ if (!finalEntryImports.length) continue;
12588
+ const runsAsWorker = 'background/service_worker' === feature || isBackgroundScriptsFeature(feature) && 3 === Number(manifestJson.manifest_version) && !isGeckoBasedBrowser(String(this.browser));
12589
+ newEntries[feature] = runsAsWorker ? {
12467
12590
  import: finalEntryImports,
12468
12591
  ...manifestJson.background?.type === 'module' ? {} : {
12469
12592
  chunkLoading: "import-scripts"
@@ -12620,6 +12743,102 @@ class WebResourcesPlugin {
12620
12743
  }).apply(compiler);
12621
12744
  }
12622
12745
  }
12746
+ const PANELS_CREATE_PATTERN = /panels\s*\.\s*create\s*\(\s*(['"`])(?:(?!\1).)*\1\s*,\s*(['"`])(?:(?!\2).)*\2\s*,\s*(['"`])((?:(?!\3).)*)\3/g;
12747
+ const SCRIPT_SRC_PATTERN = /<script[^>]*\ssrc\s*=\s*["']([^"']+)["']/gi;
12748
+ const RELATIVE_IMPORT_PATTERN = /(?:import\s[^'"]*|import\s*\(\s*|require\s*\(\s*|from\s*)['"](\.{1,2}\/[^'"]+)['"]/g;
12749
+ const discover_devtools_panels_SOURCE_SIBLING_EXTENSIONS = [
12750
+ '.ts',
12751
+ '.mts',
12752
+ '.tsx',
12753
+ '.jsx',
12754
+ '.mjs'
12755
+ ];
12756
+ const MAX_IMPORT_DEPTH = 3;
12757
+ function readIfFile(absPath) {
12758
+ try {
12759
+ if (__rspack_external_node_fs_5ea92f0c.statSync(absPath).isFile()) return __rspack_external_node_fs_5ea92f0c.readFileSync(absPath, 'utf-8');
12760
+ } catch {}
12761
+ }
12762
+ function readScriptSource(absPath) {
12763
+ const direct = readIfFile(absPath);
12764
+ if (void 0 !== direct) return direct;
12765
+ const parsed = __rspack_external_node_path_c5b9b54f.parse(absPath);
12766
+ for (const ext of discover_devtools_panels_SOURCE_SIBLING_EXTENSIONS){
12767
+ const sibling = readIfFile(__rspack_external_node_path_c5b9b54f.join(parsed.dir, parsed.name + ext));
12768
+ if (void 0 !== sibling) return sibling;
12769
+ }
12770
+ }
12771
+ function collectPanelLiterals(source) {
12772
+ const literals = [];
12773
+ for (const match of source.matchAll(PANELS_CREATE_PATTERN)){
12774
+ const literal = String(match[4] || '').trim();
12775
+ if (literal) literals.push(literal);
12776
+ }
12777
+ return literals;
12778
+ }
12779
+ function collectRelativeImports(source) {
12780
+ const specifiers = [];
12781
+ for (const match of source.matchAll(RELATIVE_IMPORT_PATTERN))specifiers.push(match[1]);
12782
+ return specifiers;
12783
+ }
12784
+ function scanScriptGraph(entryAbsPath, found) {
12785
+ const queue = [
12786
+ {
12787
+ file: entryAbsPath,
12788
+ depth: 0
12789
+ }
12790
+ ];
12791
+ const seen = new Set();
12792
+ while(queue.length){
12793
+ const { file, depth } = queue.shift();
12794
+ if (seen.has(file)) continue;
12795
+ seen.add(file);
12796
+ const source = readScriptSource(file);
12797
+ if (void 0 === source) continue;
12798
+ found.push(...collectPanelLiterals(source));
12799
+ if (depth >= MAX_IMPORT_DEPTH) continue;
12800
+ for (const specifier of collectRelativeImports(source)){
12801
+ const resolved = __rspack_external_node_path_c5b9b54f.resolve(__rspack_external_node_path_c5b9b54f.dirname(file), specifier);
12802
+ const withExt = __rspack_external_node_path_c5b9b54f.extname(resolved) ? resolved : `${resolved}.js`;
12803
+ queue.push({
12804
+ file: withExt,
12805
+ depth: depth + 1
12806
+ });
12807
+ }
12808
+ }
12809
+ }
12810
+ function discoverDevtoolsPanelPages(manifestPath) {
12811
+ const projectDir = __rspack_external_node_path_c5b9b54f.dirname(manifestPath);
12812
+ let devtoolsPage = '';
12813
+ try {
12814
+ const manifest = JSON.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(manifestPath, 'utf-8'));
12815
+ if ('string' == typeof manifest?.devtools_page) devtoolsPage = manifest.devtools_page;
12816
+ } catch {}
12817
+ if (!devtoolsPage) return {};
12818
+ const devtoolsHtmlPath = __rspack_external_node_path_c5b9b54f.join(projectDir, devtoolsPage.replace(/^\/+/, ''));
12819
+ const devtoolsHtml = readIfFile(devtoolsHtmlPath);
12820
+ if (void 0 === devtoolsHtml) return {};
12821
+ const literals = [];
12822
+ literals.push(...collectPanelLiterals(devtoolsHtml));
12823
+ for (const match of devtoolsHtml.matchAll(SCRIPT_SRC_PATTERN)){
12824
+ const src = String(match[1] || '');
12825
+ if (/^(https?:)?\/\//i.test(src)) continue;
12826
+ const scriptAbs = src.startsWith('/') ? __rspack_external_node_path_c5b9b54f.join(projectDir, src.slice(1)) : __rspack_external_node_path_c5b9b54f.resolve(__rspack_external_node_path_c5b9b54f.dirname(devtoolsHtmlPath), src);
12827
+ scanScriptGraph(scriptAbs, literals);
12828
+ }
12829
+ const pages = {};
12830
+ for (const literal of literals){
12831
+ const rootRel = literal.replace(/^\.?\/+/, '');
12832
+ if (!rootRel || !/\.html?$/i.test(rootRel)) continue;
12833
+ const absPage = __rspack_external_node_path_c5b9b54f.join(projectDir, rootRel);
12834
+ const relToProject = __rspack_external_node_path_c5b9b54f.relative(projectDir, absPage);
12835
+ if (!relToProject || relToProject.startsWith('..')) continue;
12836
+ if (!__rspack_external_node_fs_5ea92f0c.existsSync(absPage)) continue;
12837
+ const key = rootRel.replace(/\.html?$/i, '').replace(/\\/g, '/');
12838
+ pages[key] = absPage;
12839
+ }
12840
+ return pages;
12841
+ }
12623
12842
  function isCriticalJsonFeatureKey(key) {
12624
12843
  return key.startsWith('declarative_net_request') || 'storage.managed_schema' === key;
12625
12844
  }
@@ -12803,6 +13022,7 @@ class plugin_web_extension_WebExtensionPlugin {
12803
13022
  browser: this.browser,
12804
13023
  includeList: {
12805
13024
  ...manifestFieldsData.html,
13025
+ ...discoverDevtoolsPanelPages(manifestPath),
12806
13026
  ...specialFoldersData.pages
12807
13027
  }
12808
13028
  }).apply(compiler);
@@ -1,10 +1,11 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
2
  import { __webpack_require__ } from "./0~rslib-runtime.mjs";
3
- import { prefix } from "./349.mjs";
3
+ import { prefix, isDebug } from "./349.mjs";
4
4
  var stats_handler_namespaceObject = {};
5
5
  __webpack_require__.r(stats_handler_namespaceObject);
6
6
  __webpack_require__.d(stats_handler_namespaceObject, {
7
7
  handleStatsErrors: ()=>handleStatsErrors,
8
+ humanizeCaseMismatchBlocks: ()=>humanizeCaseMismatchBlocks,
8
9
  isEmitTimeWarning: ()=>isEmitTimeWarning,
9
10
  renderStatsBlocks: ()=>renderStatsBlocks,
10
11
  wrapStatsBlocks: ()=>wrapStatsBlocks
@@ -90,6 +91,29 @@ function dropEmitTimeWarningBlocks(raw, excluded) {
90
91
  flush();
91
92
  return kept.join('\n');
92
93
  }
94
+ const CASE_MISMATCH_PATTERN = /\[CaseSensitivePathsPlugin\]\s*`([^`]+)`\s*does not match the corresponding path on disk\s*`?([^`\s]+?)`?\.?\s*$/;
95
+ function humanizeCaseMismatchBlocks(raw, showStack = isDebug()) {
96
+ const lines = String(raw || '').split('\n');
97
+ const out = [];
98
+ let droppingStack = false;
99
+ for (const line of lines){
100
+ const plain = line.replace(ANSI_PATTERN, '');
101
+ const match = CASE_MISMATCH_PATTERN.exec(plain);
102
+ if (match) {
103
+ const reference = match[1];
104
+ const onDisk = match[2];
105
+ out.push(` × \`${reference}\` does not match its casing on disk: \`${onDisk}\`.`, " Case-sensitive filesystems fail this reference. Rename the file or the import so both agree.");
106
+ droppingStack = !showStack;
107
+ continue;
108
+ }
109
+ if (droppingStack) {
110
+ if (plain.trim().startsWith('│')) continue;
111
+ droppingStack = false;
112
+ }
113
+ out.push(line);
114
+ }
115
+ return out.join('\n');
116
+ }
93
117
  function wrapStatsBlocks(raw) {
94
118
  const lines = String(raw || '').split('\n');
95
119
  const wrapped = [];
@@ -125,7 +149,7 @@ function renderStatsBlocks(stats, opts) {
125
149
  if (!raw) return '';
126
150
  const filtered = opts.warnings ? dropEmitTimeWarningBlocks(raw, collectEmitTimeWarningTexts(stats)) : raw;
127
151
  if (!filtered.trim()) return '';
128
- return wrapStatsBlocks(scrubBrand(filtered));
152
+ return wrapStatsBlocks(scrubBrand(humanizeCaseMismatchBlocks(filtered)));
129
153
  }
130
154
  function handleStatsErrors(stats) {
131
155
  try {
package/dist/0~zip.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
- import adm_zip from "adm-zip";
2
+ import { unzipSync } from "fflate";
3
3
  import { unpackagingExtension, failedToDownloadOrExtractZIPFileError, invalidRemoteZip, notAZipArchive, unpackagedSuccessfully, localZipNotFound, downloadingText } from "./101.mjs";
4
4
  import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
5
5
  import * as __rspack_external_node_path_c5b9b54f from "node:path";
@@ -12,8 +12,27 @@ function isZipBuffer(buffer) {
12
12
  }
13
13
  function extractBuffer(zipBuffer, destinationPath) {
14
14
  console.log(unpackagingExtension(destinationPath));
15
- const zip = new adm_zip(zipBuffer);
16
- zip.extractAllTo(destinationPath, true);
15
+ const root = __rspack_external_node_path_c5b9b54f.resolve(destinationPath);
16
+ const entries = unzipSync(new Uint8Array(zipBuffer));
17
+ __rspack_external_node_fs_5ea92f0c.mkdirSync(root, {
18
+ recursive: true
19
+ });
20
+ for (const [name, data] of Object.entries(entries)){
21
+ const normalized = name.replace(/\\/g, '/');
22
+ const target = __rspack_external_node_path_c5b9b54f.resolve(root, normalized);
23
+ const relative = __rspack_external_node_path_c5b9b54f.relative(root, target);
24
+ if (!relative || relative.startsWith('..') || __rspack_external_node_path_c5b9b54f.isAbsolute(relative)) throw new Error(`Refusing to extract zip entry outside the destination: ${name}`);
25
+ if (normalized.endsWith('/')) {
26
+ __rspack_external_node_fs_5ea92f0c.mkdirSync(target, {
27
+ recursive: true
28
+ });
29
+ continue;
30
+ }
31
+ __rspack_external_node_fs_5ea92f0c.mkdirSync(__rspack_external_node_path_c5b9b54f.dirname(target), {
32
+ recursive: true
33
+ });
34
+ __rspack_external_node_fs_5ea92f0c.writeFileSync(target, data);
35
+ }
17
36
  console.log(unpackagedSuccessfully());
18
37
  }
19
38
  function asZipError(error) {
package/dist/101.mjs CHANGED
@@ -8,7 +8,7 @@ import { fetchExtensionFromStore } from "extension-from-store";
8
8
  import node_fs from "node:fs";
9
9
  import node_path from "node:path";
10
10
  import { getSpecialFoldersData } from "browser-extension-manifest-fields";
11
- import { fmt, humanWarn, isDebug, browserRowValue, artifactNoun, prefix as messaging_prefix, card } from "./349.mjs";
11
+ import { humanWarn, browserRowValue, artifactNoun, prefix as messaging_prefix, card, humanLine, fmt, isDebug } from "./349.mjs";
12
12
  import { findNearestDenoConfigSync, validateDenoConfig, PROJECT_MANIFEST_FILENAMES, readProjectDependencies } from "./80.mjs";
13
13
  import { stripBom, parseJsonSafe } from "./23.mjs";
14
14
  import { readyContractPath, browserArtifactsDir, eventsPath as session_paths_eventsPath } from "./494.mjs";
@@ -682,7 +682,7 @@ async function config_loader_isUsingExperimentalConfig(projectPath) {
682
682
  }
683
683
  return false;
684
684
  }
685
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.32","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.1.1","@rspack/dev-server":"2.1.0","@rspack/plugin-preact-refresh":"2.0.1","@rspack/plugin-react-refresh":"2.0.2","@vue/compiler-sfc":"3.5.26","acorn":"^8.16.0","adm-zip":"^0.6.0","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.23","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","prefers-yarn":"2.0.1","react-refresh":"0.18.0","sass-loader":"17.0.0","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.20.1"}}');
685
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.34","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.1.1","@rspack/dev-server":"2.1.0","@rspack/plugin-preact-refresh":"2.0.1","@rspack/plugin-react-refresh":"2.0.2","@vue/compiler-sfc":"3.5.26","acorn":"^8.16.0","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.2.5","fflate":"^0.8.3","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.23","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","prefers-yarn":"2.0.1","react-refresh":"0.18.0","sass-loader":"17.0.0","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.20.1"}}');
686
686
  function asAbsolute(p) {
687
687
  return __rspack_external_node_path_c5b9b54f.isAbsolute(p) ? p : __rspack_external_node_path_c5b9b54f.resolve(p);
688
688
  }
@@ -1418,6 +1418,7 @@ function createPlaywrightMetadataWriter(options) {
1418
1418
  instanceExplicit: options.instanceExplicit
1419
1419
  })) humanWarn(anotherDevSessionActive(options.browser, liveOwner.pid, liveOwner.runId));
1420
1420
  const toManagedRecords = (dirs)=>Array.isArray(dirs) && dirs.length > 0 ? managedExtensionRecords(options.browser, dirs) : void 0;
1421
+ let managedExtensionsExplicit = void 0 !== options.managedExtensionDirs;
1421
1422
  let managedExtensions = toManagedRecords(options.managedExtensionDirs);
1422
1423
  const base = {
1423
1424
  schemaVersion: 2,
@@ -1443,48 +1444,55 @@ function createPlaywrightMetadataWriter(options) {
1443
1444
  function writeReady(status, extra) {
1444
1445
  if (foreignLiveDevSession) return;
1445
1446
  plugin_playwright_ensureDirSync(metadataDir);
1447
+ let prev;
1448
+ try {
1449
+ if (__rspack_external_node_fs_5ea92f0c.existsSync(readyPath)) prev = JSON.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(readyPath, 'utf-8'));
1450
+ } catch {
1451
+ prev = void 0;
1452
+ }
1453
+ const compiledAtExplicit = Boolean(extra && 'compiledAt' in extra);
1454
+ const compiledAt = compiledAtExplicit ? extra?.compiledAt ?? null : 'string' == typeof prev?.compiledAt ? prev.compiledAt : 'ready' === status ? nowISO() : null;
1446
1455
  const payload = {
1447
1456
  ...base,
1448
1457
  status,
1449
1458
  pid: process.pid,
1450
1459
  ts: nowISO(),
1451
- compiledAt: extra?.compiledAt ?? null,
1460
+ compiledAt,
1452
1461
  errors: Array.isArray(extra?.errors) ? extra.errors : []
1453
1462
  };
1463
+ if ('starting' !== status && prev && prev.runId === base.runId && 'string' == typeof prev.startedAt) payload.startedAt = prev.startedAt;
1454
1464
  if (extra?.code) payload.code = extra.code;
1455
1465
  if (extra?.message) payload.message = extra.message;
1456
- if (managedExtensions) payload.managedExtensions = managedExtensions;
1466
+ if (managedExtensionsExplicit) {
1467
+ if (managedExtensions) payload.managedExtensions = managedExtensions;
1468
+ } else if (Array.isArray(prev?.managedExtensions) && prev.managedExtensions.length > 0) payload.managedExtensions = prev.managedExtensions;
1457
1469
  const derivedExtensionId = deriveDistExtensionId(options.browser, options.distPath);
1458
1470
  if (derivedExtensionId) payload.extensionId = derivedExtensionId;
1459
- try {
1460
- if (__rspack_external_node_fs_5ea92f0c.existsSync(readyPath)) {
1461
- const prev = JSON.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(readyPath, 'utf-8'));
1462
- if ('number' == typeof prev.cdpPort) payload.cdpPort = prev.cdpPort;
1463
- if ('number' == typeof prev.rdpPort) payload.rdpPort = prev.rdpPort;
1464
- if (!payload.managedExtensions && Array.isArray(prev.managedExtensions)) payload.managedExtensions = prev.managedExtensions;
1465
- if ('string' == typeof prev.profilePath) payload.profilePath = prev.profilePath;
1466
- if ('number' == typeof prev.browserPid) payload.browserPid = prev.browserPid;
1467
- if ('string' == typeof prev.extensionId && prev.extensionId) payload.extensionId = prev.extensionId;
1468
- if ('string' == typeof prev.browserExitedAt) {
1469
- payload.browserExitedAt = prev.browserExitedAt;
1470
- payload.browserExitCode = prev.browserExitCode ?? null;
1471
- }
1472
- if ('string' == typeof prev.executorAttachedAt) {
1473
- payload.executorAttachedAt = prev.executorAttachedAt;
1474
- payload.runtime = 'attached';
1475
- }
1476
- if ('starting' !== status && 'string' == typeof prev.extensionLoadRefusedAt) {
1477
- const target = payload;
1478
- target.extensionLoadRefusedAt = prev.extensionLoadRefusedAt;
1479
- if ('string' == typeof prev.extensionLoadRefusedReason) target.extensionLoadRefusedReason = prev.extensionLoadRefusedReason;
1480
- if ('ready' === status) {
1481
- payload.status = 'error';
1482
- payload.code = 'extension_load_refused';
1483
- payload.message = String(prev.message || 'the browser refused to load the extension');
1484
- }
1471
+ if (prev) {
1472
+ if ('number' == typeof prev.cdpPort) payload.cdpPort = prev.cdpPort;
1473
+ if ('number' == typeof prev.rdpPort) payload.rdpPort = prev.rdpPort;
1474
+ if ('string' == typeof prev.profilePath) payload.profilePath = prev.profilePath;
1475
+ if ('number' == typeof prev.browserPid) payload.browserPid = prev.browserPid;
1476
+ if ('string' == typeof prev.extensionId && prev.extensionId) payload.extensionId = prev.extensionId;
1477
+ if ('string' == typeof prev.browserExitedAt) {
1478
+ payload.browserExitedAt = prev.browserExitedAt;
1479
+ payload.browserExitCode = prev.browserExitCode ?? null;
1480
+ }
1481
+ if ('string' == typeof prev.executorAttachedAt) {
1482
+ payload.executorAttachedAt = prev.executorAttachedAt;
1483
+ payload.runtime = 'attached';
1484
+ }
1485
+ if ('starting' !== status && 'string' == typeof prev.extensionLoadRefusedAt) {
1486
+ const target = payload;
1487
+ target.extensionLoadRefusedAt = prev.extensionLoadRefusedAt;
1488
+ if ('string' == typeof prev.extensionLoadRefusedReason) target.extensionLoadRefusedReason = prev.extensionLoadRefusedReason;
1489
+ if ('ready' === status) {
1490
+ payload.status = 'error';
1491
+ payload.code = 'extension_load_refused';
1492
+ payload.message = String(prev.message || 'the browser refused to load the extension');
1485
1493
  }
1486
1494
  }
1487
- } catch {}
1495
+ }
1488
1496
  writeJsonAtomic(readyPath, payload);
1489
1497
  }
1490
1498
  function appendEvent(event) {
@@ -1502,6 +1510,7 @@ function createPlaywrightMetadataWriter(options) {
1502
1510
  readyPath,
1503
1511
  eventsPath,
1504
1512
  setManagedExtensionDirs (dirs) {
1513
+ managedExtensionsExplicit = true;
1505
1514
  managedExtensions = toManagedRecords(dirs);
1506
1515
  },
1507
1516
  writeStarting () {
@@ -1510,10 +1519,12 @@ function createPlaywrightMetadataWriter(options) {
1510
1519
  try {
1511
1520
  __rspack_external_node_fs_5ea92f0c.writeFileSync(eventsPath, '', 'utf-8');
1512
1521
  } catch {}
1513
- writeReady('starting');
1522
+ writeReady('starting', {
1523
+ compiledAt: null
1524
+ });
1514
1525
  },
1515
1526
  writeReady (compiledAt) {
1516
- writeReady('ready', {
1527
+ void 0 === compiledAt ? writeReady('ready') : writeReady('ready', {
1517
1528
  compiledAt: compiledAt || nowISO()
1518
1529
  });
1519
1530
  },
@@ -2081,6 +2092,80 @@ function finalizeSpecialFoldersData(data, projectRoot, publicDir) {
2081
2092
  }
2082
2093
  };
2083
2094
  }
2095
+ function getDarkModeDefaults(browser) {
2096
+ if (isChromiumBasedBrowser(String(browser))) return {
2097
+ browserFlags: [
2098
+ '--force-dark-mode',
2099
+ '--enable-features=WebUIDarkMode'
2100
+ ],
2101
+ preferences: {}
2102
+ };
2103
+ if (isGeckoBasedBrowser(String(browser))) return {
2104
+ browserFlags: [],
2105
+ preferences: {
2106
+ 'ui.systemUsesDarkTheme': 1,
2107
+ 'layout.css.prefers-color-scheme.content-override': 2,
2108
+ 'devtools.theme': 'dark'
2109
+ }
2110
+ };
2111
+ return {
2112
+ browserFlags: [],
2113
+ preferences: {}
2114
+ };
2115
+ }
2116
+ function normalizeFlag(flag) {
2117
+ return String(flag ?? '').trim();
2118
+ }
2119
+ function isFlagExcluded(flag, excludeFlags) {
2120
+ return excludeFlags.some((exclude)=>{
2121
+ if (!exclude) return false;
2122
+ if (flag === exclude) return true;
2123
+ return flag.startsWith(`${exclude}=`) || flag.startsWith(`${exclude},`);
2124
+ });
2125
+ }
2126
+ function featureList(flag, switchName) {
2127
+ const prefix = `${switchName}=`;
2128
+ if (!flag.startsWith(prefix)) return [];
2129
+ return flag.slice(prefix.length).split(',').map((part)=>part.trim()).filter(Boolean);
2130
+ }
2131
+ function hasFeature(flags, switchName, feature) {
2132
+ return flags.some((flag)=>featureList(flag, switchName).includes(feature));
2133
+ }
2134
+ function withDarkMode(config) {
2135
+ const defaults = getDarkModeDefaults(config.browser);
2136
+ const excludeFlags = (config.excludeBrowserFlags || []).map(normalizeFlag);
2137
+ const appearanceOptedOut = isFlagExcluded('--force-dark-mode', excludeFlags);
2138
+ const existingFlags = Array.isArray(config.browserFlags) ? config.browserFlags.map(normalizeFlag) : [];
2139
+ const nextFlags = [
2140
+ ...existingFlags
2141
+ ];
2142
+ if (!appearanceOptedOut) {
2143
+ for (const flag of defaults.browserFlags || [])if (!isFlagExcluded(flag, excludeFlags)) {
2144
+ if (!nextFlags.some((existing)=>existing === flag)) {
2145
+ if (flag.startsWith('--enable-features=')) {
2146
+ const feature = flag.slice(18);
2147
+ if (hasFeature(nextFlags, '--disable-features', feature)) continue;
2148
+ const enableIndex = nextFlags.findIndex((existing)=>existing.startsWith('--enable-features='));
2149
+ if (enableIndex >= 0) {
2150
+ if (!hasFeature(nextFlags, '--enable-features', feature)) nextFlags[enableIndex] = `${nextFlags[enableIndex]},${feature}`;
2151
+ continue;
2152
+ }
2153
+ }
2154
+ nextFlags.push(flag);
2155
+ }
2156
+ }
2157
+ }
2158
+ const userPreferences = config.preferences || {};
2159
+ const nextPreferences = {
2160
+ ...userPreferences,
2161
+ ...Object.fromEntries(Object.entries(defaults.preferences || {}).filter(([key])=>!(key in userPreferences) && !appearanceOptedOut))
2162
+ };
2163
+ return {
2164
+ ...config,
2165
+ browserFlags: nextFlags,
2166
+ preferences: nextPreferences
2167
+ };
2168
+ }
2084
2169
  const cjsRequire = createRequire(import.meta.url);
2085
2170
  function messages_getLoggingPrefix(type) {
2086
2171
  return messaging_prefix(type);
@@ -2202,46 +2287,6 @@ function noEntrypointsDetected(port) {
2202
2287
  function spacerLine() {
2203
2288
  return ' ';
2204
2289
  }
2205
- function getDarkModeDefaults(browser) {
2206
- if (isChromiumBasedBrowser(String(browser))) return {
2207
- browserFlags: [
2208
- '--force-dark-mode',
2209
- '--enable-features=WebUIDarkMode'
2210
- ],
2211
- preferences: {}
2212
- };
2213
- if (isGeckoBasedBrowser(String(browser))) return {
2214
- browserFlags: [],
2215
- preferences: {
2216
- 'ui.systemUsesDarkTheme': 1,
2217
- 'layout.css.prefers-color-scheme.content-override': 2,
2218
- 'devtools.theme': 'dark'
2219
- }
2220
- };
2221
- return {
2222
- browserFlags: [],
2223
- preferences: {}
2224
- };
2225
- }
2226
- function withDarkMode(config) {
2227
- const defaults = getDarkModeDefaults(config.browser);
2228
- const existingFlags = Array.isArray(config.browserFlags) ? [
2229
- ...config.browserFlags
2230
- ] : [];
2231
- const nextFlags = [
2232
- ...existingFlags
2233
- ];
2234
- for (const flag of defaults.browserFlags || [])if (!nextFlags.some((f)=>String(f).trim() === flag)) nextFlags.push(flag);
2235
- const nextPreferences = {
2236
- ...config.preferences || {},
2237
- ...Object.fromEntries(Object.entries(defaults.preferences || {}).filter(([k])=>!(k in (config.preferences || {}))))
2238
- };
2239
- return {
2240
- ...config,
2241
- browserFlags: nextFlags,
2242
- preferences: nextPreferences
2243
- };
2244
- }
2245
2290
  function hasNewTabOverride(extensionDir) {
2246
2291
  const manifestPath = __rspack_external_node_path_c5b9b54f.join(extensionDir, 'manifest.json');
2247
2292
  if (!__rspack_external_node_fs_5ea92f0c.existsSync(manifestPath)) return false;
@@ -2354,7 +2399,7 @@ function resolveCompanionExtensionDirs(opts) {
2354
2399
  }
2355
2400
  };
2356
2401
  scanOneLevel(absScan);
2357
- if ('extensions' === __rspack_external_node_path_c5b9b54f.basename(absScan)) for (const ent of entries){
2402
+ for (const ent of entries){
2358
2403
  if (!ent.isDirectory()) continue;
2359
2404
  if (ent.name.startsWith('.')) continue;
2360
2405
  const browserDir = __rspack_external_node_path_c5b9b54f.join(absScan, ent.name);
@@ -2370,6 +2415,14 @@ function resolveCompanionExtensionDirs(opts) {
2370
2415
  }
2371
2416
  return unique;
2372
2417
  }
2418
+ function readRunIdFromReadyFile(readyPath) {
2419
+ try {
2420
+ const parsed = JSON.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(readyPath, 'utf-8'));
2421
+ return 'string' == typeof parsed?.runId ? parsed.runId : void 0;
2422
+ } catch {
2423
+ return;
2424
+ }
2425
+ }
2373
2426
  async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher) {
2374
2427
  const projectStructure = await getProjectStructure(pathOrRemoteUrl);
2375
2428
  const debug = isDebug();
@@ -2389,11 +2442,12 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2389
2442
  manifestPath: projectStructure.manifestPath,
2390
2443
  port: 'number' == typeof previewOptions.port ? previewOptions.port : 'string' == typeof previewOptions.port ? parseInt(previewOptions.port, 10) : null
2391
2444
  });
2392
- metadata.writeStarting();
2445
+ const continuingStartRun = 'start' === metadataCommand && readRunIdFromReadyFile(metadata.readyPath) === getSessionRunId(packageJsonDir, String(browser));
2446
+ if (!continuingStartRun) metadata.writeStarting();
2393
2447
  if (debug) {
2394
- console.log(debugDirs(manifestDir, packageJsonDir));
2395
- console.log(debugBrowser(browser, previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary));
2396
- console.log(debugPreviewOutput(outputPath, distPath));
2448
+ humanLine(debugDirs(manifestDir, packageJsonDir));
2449
+ humanLine(debugBrowser(browser, previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary));
2450
+ humanLine(debugPreviewOutput(outputPath, distPath));
2397
2451
  }
2398
2452
  const manifestAtOutput = __rspack_external_node_path_c5b9b54f.join(outputPath, 'manifest.json');
2399
2453
  if (!__rspack_external_node_fs_5ea92f0c.existsSync(manifestAtOutput)) {
@@ -2404,19 +2458,19 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2404
2458
  const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
2405
2459
  if (previewOptions.noBrowser) {
2406
2460
  const browserLabel = String(browser || 'unknown');
2407
- console.log(spacerLine());
2408
- console.log(browserRunnerDisabled({
2461
+ humanLine(spacerLine());
2462
+ humanLine(browserRunnerDisabled({
2409
2463
  browser: browserLabel,
2410
2464
  manifestPath: projectStructure.manifestPath,
2411
2465
  readyPath: metadata.readyPath,
2412
2466
  distPath: outputPath
2413
2467
  }));
2414
- console.log(spacerLine());
2415
- console.log(runningMessage(browser, true));
2468
+ humanLine(spacerLine());
2469
+ humanLine(runningMessage(browser, true));
2416
2470
  metadata.writeReady();
2417
2471
  return;
2418
2472
  }
2419
- console.log(runningMessage(browser));
2473
+ humanLine(runningMessage(browser));
2420
2474
  const safeBrowserConfig = sanitize(browserConfig);
2421
2475
  const safeCommandConfig = sanitize(commandConfig);
2422
2476
  const safePreviewOptions = sanitize(previewOptions);
@@ -2438,7 +2492,8 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2438
2492
  const darkDefaults = withDarkMode({
2439
2493
  browser,
2440
2494
  browserFlags: merged.browserFlags,
2441
- preferences: merged.preferences
2495
+ preferences: merged.preferences,
2496
+ excludeBrowserFlags: merged.excludeBrowserFlags
2442
2497
  });
2443
2498
  const companionUnpackedExtensionDirs = resolveCompanionExtensionDirs({
2444
2499
  projectRoot: packageJsonDir,
@@ -2476,4 +2531,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2476
2531
  await browserLauncher(resolvedOpts);
2477
2532
  metadata.writeReady();
2478
2533
  }
2479
- export { BUILD_COMMAND_DEFAULTS, CHROMIUM_FAMILY_ALIASES, DEV_COMMAND_DEFAULTS, GECKO_FAMILY_ALIASES, PlaywrightPlugin, START_BUILD_DEFAULTS, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserLaunchFailed, browserRunnerDisabled, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildWarningsDetails, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionLoadRecovered, extensionLoadStillRefused, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, isGeckoBasedBrowser, isWebkitBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, mergeOptionLayers, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, shouldWarnPortConflict, spacerLine, stampReadyDistExtensionId, stampReadyKnownExtensionId, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
2534
+ export { BUILD_COMMAND_DEFAULTS, CHROMIUM_FAMILY_ALIASES, DEV_COMMAND_DEFAULTS, GECKO_FAMILY_ALIASES, PlaywrightPlugin, START_BUILD_DEFAULTS, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserLaunchFailed, browserRunnerDisabled, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildWarningsDetails, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionLoadRecovered, extensionLoadStillRefused, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, isGeckoBasedBrowser, isWebkitBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, mergeOptionLayers, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, shouldWarnPortConflict, spacerLine, stampReadyDistExtensionId, stampReadyKnownExtensionId, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, withDarkMode, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
package/dist/349.mjs CHANGED
@@ -29,6 +29,10 @@ const MACHINE_OUTPUT_VALUES = new Set([
29
29
  function isMachineOutput() {
30
30
  return MACHINE_OUTPUT_VALUES.has(String(process.env.EXTENSION_OUTPUT || '').trim().toLowerCase());
31
31
  }
32
+ function humanLine(...parts) {
33
+ if (isMachineOutput()) return;
34
+ console.log(...parts);
35
+ }
32
36
  function humanWarn(...parts) {
33
37
  if (isMachineOutput()) return;
34
38
  console.warn(...parts);
@@ -267,4 +271,4 @@ const ENVELOPE = {
267
271
  }, extras);
268
272
  }
269
273
  };
270
- export { CODES, ENVELOPE, artifactNoun, browserRowValue, card, claimCardKey, fmt, humanWarn, isDebug, isMachineOutput, prefix };
274
+ export { CODES, ENVELOPE, artifactNoun, browserRowValue, card, claimCardKey, fmt, humanLine, humanWarn, isDebug, isMachineOutput, prefix };
package/dist/839.mjs CHANGED
@@ -5,7 +5,7 @@ import { buildExecEnv, detectPackageManagerFromLockfile } from "prefers-yarn";
5
5
  import "pintor";
6
6
  import { EventEmitter } from "node:events";
7
7
  import { browserRowValue, ENVELOPE, CODES, prefix as messaging_prefix, card, isDebug, claimCardKey, isMachineOutput } from "./349.mjs";
8
- import { package_namespaceObject, buildWarningsDetails, DEV_COMMAND_DEFAULTS, buildFailed, getDirs, stampReadyDistExtensionId, zipArtifactReady, stampReadyKnownExtensionId, projectInstallFallbackToNpm, assertNoManagedDependencyConflicts, debugDirs, browserLaunchFailed, START_BUILD_DEFAULTS, extensionLoadRecovered, extensionLoadStillRefused, writingTypeDefinitionsError, projectInstallScriptsDisabled, authorInstallNotice, getSpecialFoldersDataForProjectRoot, buildAssetsTree, loadCommandConfig, needsInstall, mergeOptionLayers, buildCommandFailed, writingTypeDefinitions, buildComplete, normalizeBrowser, debugBrowser, debugOutputPath, loadCustomConfig, devCommandFailed, getProjectStructure, getDistPath, resolveCompanionExtensionsConfig, buildShareHint, loadBrowserConfig, BUILD_COMMAND_DEFAULTS } from "./101.mjs";
8
+ import { package_namespaceObject, buildWarningsDetails, DEV_COMMAND_DEFAULTS, buildFailed, getDirs, stampReadyDistExtensionId, zipArtifactReady, stampReadyKnownExtensionId, projectInstallFallbackToNpm, assertNoManagedDependencyConflicts, debugDirs, browserLaunchFailed, START_BUILD_DEFAULTS, extensionLoadRecovered, extensionLoadStillRefused, writingTypeDefinitionsError, projectInstallScriptsDisabled, authorInstallNotice, getSpecialFoldersDataForProjectRoot, buildAssetsTree, loadCommandConfig, needsInstall, mergeOptionLayers, buildCommandFailed, writingTypeDefinitions, buildComplete, normalizeBrowser, debugBrowser, debugOutputPath, loadCustomConfig, devCommandFailed, getProjectStructure, getDistPath, resolveCompanionExtensionsConfig, buildShareHint, loadBrowserConfig, BUILD_COMMAND_DEFAULTS, withDarkMode } from "./101.mjs";
9
9
  import { stripBom, parseJsonSafe } from "./23.mjs";
10
10
  import { hasProjectDependency, findNearestProjectManifestDirSync } from "./80.mjs";
11
11
  import { buildSummaryPath, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore } from "./494.mjs";
@@ -890,7 +890,14 @@ let hasShownUserMessage = false;
890
890
  function findNearestPackageJsonDirectory(startPath) {
891
891
  return findNearestProjectManifestDirSync(startPath, 6);
892
892
  }
893
- function hasTypeScriptSourceFiles(projectPath) {
893
+ const NON_SOURCE_DIRS = new Set([
894
+ 'node_modules',
895
+ 'dist',
896
+ 'public'
897
+ ]);
898
+ const MAX_SOURCE_SCAN_DEPTH = 4;
899
+ function hasTypeScriptSourceFiles(projectPath, depth = 0) {
900
+ if (depth > MAX_SOURCE_SCAN_DEPTH) return false;
894
901
  try {
895
902
  const entries = __rspack_external_node_fs_5ea92f0c.readdirSync(projectPath, {
896
903
  withFileTypes: true
@@ -904,14 +911,9 @@ function hasTypeScriptSourceFiles(projectPath) {
904
911
  return true;
905
912
  }
906
913
  if (entry.isDirectory()) {
907
- if (![
908
- 'src',
909
- 'content',
910
- 'sidebar',
911
- 'background'
912
- ].includes(entry.name)) return false;
914
+ if (entry.name.startsWith('.') || NON_SOURCE_DIRS.has(entry.name)) return false;
913
915
  const sub = __rspack_external_node_path_c5b9b54f.join(projectPath, entry.name);
914
- return hasTypeScriptSourceFiles(sub);
916
+ return hasTypeScriptSourceFiles(sub, depth + 1);
915
917
  }
916
918
  return false;
917
919
  });
@@ -930,18 +932,18 @@ function isUsingTypeScript(projectPath) {
930
932
  return hasTypeScriptDependency(projectPath) || hasTypeScriptSourceFiles(projectPath);
931
933
  }
932
934
  function ensureTypeScriptConfig(projectPath) {
933
- if (hasShownUserMessage) return;
934
935
  const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
935
936
  const hasDep = hasTypeScriptDependency(projectPath);
936
937
  const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
937
- if (hasDep || hasTsFiles) if (tsConfigFilePath) {
938
- if (isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
939
- } else if (hasTsFiles) throw new Error('[Extension.js] Missing tsconfig.json next to package.json. Create one to use TypeScript.');
940
- else {
941
- console.log(creatingTSConfig());
942
- writeTsConfig(projectPath);
938
+ if (hasDep || hasTsFiles) {
939
+ if (tsConfigFilePath) {
940
+ if (!hasShownUserMessage && isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
941
+ } else {
942
+ if (!hasShownUserMessage) console.log(creatingTSConfig());
943
+ writeTsConfig(projectPath);
944
+ }
945
+ hasShownUserMessage = true;
943
946
  }
944
- hasShownUserMessage = true;
945
947
  }
946
948
  function defaultTypeScriptConfig(projectPath, _opts) {
947
949
  return {
@@ -978,7 +980,8 @@ function getUserTypeScriptConfigFile(projectPath) {
978
980
  }
979
981
  }
980
982
  function writeTsConfig(projectPath) {
981
- __rspack_external_node_fs_5ea92f0c.writeFileSync(__rspack_external_node_path_c5b9b54f.join(projectPath, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
983
+ const targetDir = findNearestPackageJsonDirectory(projectPath) || projectPath;
984
+ __rspack_external_node_fs_5ea92f0c.writeFileSync(__rspack_external_node_path_c5b9b54f.join(targetDir, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
982
985
  mode: 'development'
983
986
  }), null, 2));
984
987
  }
@@ -1055,8 +1058,9 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
1055
1058
  if (userManifestPath) assertNoManagedDependencyConflicts(userManifestPath, manifestDir);
1056
1059
  const commandKey = buildOptions?.metadataCommand === 'start' ? 'start' : 'build';
1057
1060
  const commandConfig = await loadCommandConfig(packageJsonDir, commandKey);
1061
+ const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
1058
1062
  const specialFoldersData = getSpecialFoldersDataForProjectRoot(packageJsonDir);
1059
- const mergedBuildOptions = mergeOptionLayers('start' === commandKey ? START_BUILD_DEFAULTS : BUILD_COMMAND_DEFAULTS, commandConfig, buildOptions);
1063
+ const mergedBuildOptions = mergeOptionLayers('start' === commandKey ? START_BUILD_DEFAULTS : BUILD_COMMAND_DEFAULTS, browserConfig, commandConfig, buildOptions);
1060
1064
  const silent = Boolean(mergedBuildOptions.silent);
1061
1065
  removeStaleStagingDirs(distPath);
1062
1066
  if (debug) {
@@ -1064,7 +1068,7 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
1064
1068
  console.log(debugBrowser(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
1065
1069
  console.log(debugOutputPath(distPath));
1066
1070
  }
1067
- const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? specialFoldersData.extensions;
1071
+ const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? browserConfig.extensions ?? specialFoldersData.extensions;
1068
1072
  const resolvedExtensionsConfig = await resolveCompanionExtensionsConfig({
1069
1073
  projectRoot: packageJsonDir,
1070
1074
  browser,
@@ -1678,7 +1682,10 @@ async function extensionDev(pathOrRemoteUrl, devOptions) {
1678
1682
  }
1679
1683
  const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
1680
1684
  const commandConfig = await loadCommandConfig(packageJsonDir, 'dev');
1681
- const merged = mergeOptionLayers(DEV_COMMAND_DEFAULTS, browserConfig, commandConfig, devOptions);
1685
+ const merged = withDarkMode({
1686
+ ...mergeOptionLayers(DEV_COMMAND_DEFAULTS, browserConfig, commandConfig, devOptions),
1687
+ browser
1688
+ });
1682
1689
  if (('safari' === browser || 'webkit-based' === browser) && !devOptions.noBrowser && devOptions.safariPackager) {
1683
1690
  const safariPackager = devOptions.safariPackager;
1684
1691
  const safariOverrides = {
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "E_BROWSER_NOT_INSTALLABLE": {
42
42
  "area": "usage",
43
- "summary": "The browser ships with the OS and cannot be installed by the CLI."
43
+ "summary": "The browser is a known target but has no managed download; the CLI cannot fetch it."
44
44
  },
45
45
  "E_PARENT_GONE": {
46
46
  "area": "usage",
@@ -18,6 +18,7 @@ export interface StatsToStringLike {
18
18
  export declare function isEmitTimeWarning(warning: {
19
19
  code?: unknown;
20
20
  } | string | null | undefined): boolean;
21
+ export declare function humanizeCaseMismatchBlocks(raw: string, showStack?: boolean): string;
21
22
  export declare function wrapStatsBlocks(raw: string): string;
22
23
  export declare function renderStatsBlocks(stats: StatsToStringLike, opts: {
23
24
  errors: boolean;
@@ -1,3 +1,3 @@
1
- export type AssetCategory = 'content-script' | 'service-worker' | 'page' | 'ignored';
1
+ export type AssetCategory = 'content-script' | 'service-worker' | 'page' | 'runtime' | 'ignored';
2
2
  export declare function categorizeAsset(rawName: string): AssetCategory;
3
3
  export declare const BUDGET_BYTES: Record<AssetCategory, number>;
@@ -14,6 +14,7 @@ interface PerfBudgetsPluginOptions {
14
14
  * content_scripts/* → 512 KiB (injected on every navigation)
15
15
  * background / SW → 512 KiB (wakes from cold each session)
16
16
  * pages / sidebar / … → 1 MiB (opened on demand)
17
+ * runtime / wasm cores → 1 MiB (hashed payloads at the output root)
17
18
  * images, fonts, etc. → silenced (not a code-splitting concern)
18
19
  *
19
20
  * Numbers are sized to clear realistic framework templates (React/Vue/
@@ -7,6 +7,7 @@ export declare class WasmPlugin {
7
7
  constructor(options: PluginInterface & {
8
8
  mode: DevOptions['mode'];
9
9
  });
10
+ private collectSearchRoots;
10
11
  private resolveAssetPath;
11
12
  private buildAssetAliases;
12
13
  private ensureWasmResolution;
@@ -1,4 +1,6 @@
1
1
  import type { Compilation } from '@rspack/core';
2
2
  import type { FilepathList } from '../../types';
3
3
  export declare const EMITTED_ASSET_REF_PATTERN: RegExp;
4
+ export declare function listEmittedAssetNames(compilation: Compilation): string[];
5
+ export declare function collectReferencedRuntimePayloads(source: string, emittedAssetNames: string[]): string[];
4
6
  export declare function collectContentScriptEntryImports(compilation: Compilation, includeList?: FilepathList): Record<string, string[]>;
@@ -0,0 +1,8 @@
1
+ import type { FilepathList } from '../../types';
2
+ /**
3
+ * Statically discovers HTML pages referenced only through
4
+ * chrome.devtools.panels.create in the devtools page's scripts, and returns
5
+ * them as extra HTML entries keyed by their extension-root-relative path so
6
+ * the emitted dist serves the exact URL Chrome will request.
7
+ */
8
+ export declare function discoverDevtoolsPanelPages(manifestPath: string): FilepathList;
package/package.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "runtime"
44
44
  ],
45
45
  "name": "extension-develop",
46
- "version": "4.0.32",
46
+ "version": "4.0.34",
47
47
  "description": "Develop, build, preview, and package Extension.js projects.",
48
48
  "author": {
49
49
  "name": "Cezar Augusto",
@@ -99,13 +99,13 @@
99
99
  "@rspack/plugin-react-refresh": "2.0.2",
100
100
  "@vue/compiler-sfc": "3.5.26",
101
101
  "acorn": "^8.16.0",
102
- "adm-zip": "^0.6.0",
103
102
  "browser-extension-manifest-fields": "^2.2.9",
104
103
  "case-sensitive-paths-webpack-plugin": "^2.4.0",
105
104
  "content-security-policy-parser": "^0.6.0",
106
105
  "dotenv": "^17.2.3",
107
106
  "es-module-lexer": "^2.1.0",
108
- "extension-from-store": "^0.1.1",
107
+ "extension-from-store": "^0.2.5",
108
+ "fflate": "^0.8.3",
109
109
  "go-git-it": "^5.1.5",
110
110
  "ignore": "^7.0.5",
111
111
  "less": "4.6.7",
@@ -133,7 +133,6 @@
133
133
  "devDependencies": {
134
134
  "@prefresh/webpack": "4.0.6",
135
135
  "@rslib/core": "^0.23.1",
136
- "@types/adm-zip": "^0.5.7",
137
136
  "@types/case-sensitive-paths-webpack-plugin": "^2.1.9",
138
137
  "@types/chrome": "^0.1.33",
139
138
  "@types/cross-spawn": "^6.0.6",