extension-develop 4.0.15 → 4.0.16

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.
Files changed (26) hide show
  1. package/README.md +4 -4
  2. package/dist/0~rspack-config.mjs +36 -16
  3. package/dist/101.mjs +33 -4
  4. package/dist/839.mjs +66 -5
  5. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  6. package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
  7. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  8. package/dist/extension-js-devtools/chrome/pages/welcome.js +3 -3
  9. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  10. package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
  11. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  12. package/dist/extension-js-devtools/chromium/pages/welcome.js +3 -3
  13. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  14. package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
  15. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  16. package/dist/extension-js-devtools/edge/pages/welcome.js +3 -3
  17. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  18. package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
  19. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  20. package/dist/extension-js-devtools/firefox/pages/welcome.js +3 -3
  21. package/dist/lib/manifest-utils.d.ts +2 -0
  22. package/dist/lib/messages.d.ts +3 -0
  23. package/dist/plugin-browsers/index.d.ts +18 -0
  24. package/dist/plugin-web-extension/feature-icons/messages.d.ts +2 -0
  25. package/dist/plugin-web-extension/feature-json/messages.d.ts +1 -0
  26. package/package.json +2 -2
package/README.md CHANGED
@@ -285,14 +285,14 @@ dist/
285
285
 
286
286
  ## Notes and compatibility
287
287
 
288
- - Built on the same Rspack stack as `@/webpack`; user config is loaded when an `extension.config.*` is present.
288
+ - Built on the Rspack stack; user config is loaded when an `extension.config.*` is present.
289
289
  - Only `EXTENSION_PUBLIC_*` variables are injected into client code; avoid secrets in templated `.json`/`.html`.
290
290
 
291
291
  ## Plugins
292
292
 
293
293
  | Name | Group | Summary |
294
294
  | -------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
295
- | plugin-extension | core | - Core builder: emits pages and scripts<br/>- Validates and rewrites `manifest.json`<br/>- Ships icons, JSON, locales, and web resources<br/>- Ensures dev parity between local and shipped output |
295
+ | plugin-web-extension | core | - Core builder: emits pages and scripts<br/>- Validates and rewrites `manifest.json`<br/>- Ships icons, JSON, locales, and web resources<br/>- Ensures dev parity between local and shipped output |
296
296
  | plugin-css | core | - Auto‑wires CSS for HTML and content scripts<br/>- Optional SASS/LESS/PostCSS when configs exist<br/>- Integrates Stylelint when configured |
297
297
  | plugin-js-frameworks | core | - Detects React/Preact/Vue/Svelte and TypeScript<br/>- Configures SWC parsing, loaders/plugins, and safe aliases<br/>- Sets `tsconfig` resolution<br/>- Defers heavy work to `beforeRun` in production |
298
298
  | plugin-static-assets | core | - Emits images, fonts, and misc files to `assets/`<br/>- Inlines small SVGs (≤2KB), emits larger ones<br/>- Content hashing in production; stable names in development<br/>- Respects existing custom SVG rules |
@@ -306,9 +306,9 @@ dist/
306
306
 
307
307
  ## Related files in this folder
308
308
 
309
- - `webpack/webpack-config.ts`: Assembles the plugin stack and shared configuration.
309
+ - `rspack-config.ts`: Assembles the plugin stack and shared configuration.
310
310
  - `dev-server/`: Local development server wiring and reload orchestration.
311
- - `webpack/webpack-types.ts`: Common types for the plugin stack.
311
+ - `types.ts`: Common types for the plugin stack.
312
312
 
313
313
  ## License
314
314
 
@@ -16,7 +16,7 @@ import { isResourceUnderDirs, canonicalizeDir, toResourceKey } from "./93.mjs";
16
16
  import { debugExtensionsToLoad, package_namespaceObject, getDirs, asAbsolute, browserRunnerDisabled, packagingDistributionFiles, PlaywrightPlugin, toPosixPath, resolveCompanionExtensionDirs, debugContextPath, spacerLine, messages_ready, CHROMIUM_FAMILY_ALIASES, treeWithSourceAndDistFiles, treeWithDistFilesbrowser, computeExtensionsToLoad, noCompanionExtensionsResolved, treeWithSourceFiles, bundlerFatalError, bundlerRecompiling, constants_isGeckoBasedBrowser, noEntrypointsDetected, GECKO_FAMILY_ALIASES, packagingSourceFiles, debugBrowser, debugOutputPath, manifestInvalidJson, isChromiumBasedBrowser, getSpecialFoldersDataForCompiler } from "./101.mjs";
17
17
  import { scrubBrand, makeSanitizedConsole } from "./0~branding.mjs";
18
18
  import { stripBom, parseJsonSafe } from "./23.mjs";
19
- import { unixify as paths_unixify, getManifestOverrides, isUsingTypeScript, resolvePackageManager, jsFrameworksIntegrationsEnabled, resolveRootAbsoluteRef, getCurrentManifestContent, buildCanonicalManifest, ensureTypeScriptConfig, resolveDevelopInstallRoot, filterKeysForThisBrowser as manifest_utils_filterKeysForThisBrowser, isUsingCustomLoader, getUserTypeScriptConfigFile, isUsingIntegration as messages_isUsingIntegration, reportToCompilation, normalizeManifestOutputPath, jsFrameworksHmrSummary, ReloadPlugin, jsFrameworksConfigsDetected, collectRootAbsoluteRefs, getManifestContent, resolveDevelopDistFile, hasDependency, setOriginalManifestContent, isFromFilepathList, setCurrentManifestContent } from "./839.mjs";
19
+ import { unixify as paths_unixify, getManifestOverrides, isUsingTypeScript, resolvePackageManager, jsFrameworksIntegrationsEnabled, resolveRootAbsoluteRef, isStaticThemeSource, getCurrentManifestContent, buildCanonicalManifest, ensureTypeScriptConfig, resolveDevelopInstallRoot, filterKeysForThisBrowser as manifest_utils_filterKeysForThisBrowser, isUsingCustomLoader, getUserTypeScriptConfigFile, isUsingIntegration as messages_isUsingIntegration, reportToCompilation, normalizeManifestOutputPath, jsFrameworksHmrSummary, ReloadPlugin, jsFrameworksConfigsDetected, collectRootAbsoluteRefs, getManifestContent, resolveDevelopDistFile, hasDependency, setOriginalManifestContent, isFromFilepathList, setCurrentManifestContent } from "./839.mjs";
20
20
  import { hasProjectDependency, findNearestProjectManifestSync, PROJECT_MANIFEST_FILENAMES, readProjectDependencies } from "./80.mjs";
21
21
  import { cssIntegrationsEnabled, cssConfigsDetected, deadCssUrlRef, missingSassDependency, isUsingIntegration, postCssPluginNotResolved } from "./845.mjs";
22
22
  import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset, getCanonicalContentScriptJsAssetName, isCanonicalContentScriptAsset, EXTENSIONJS_CONTENT_SCRIPT_LAYER } from "./291.mjs";
@@ -5290,12 +5290,20 @@ function iconsMissingFile(manifestField, filePath, opts) {
5290
5290
  const lines = [];
5291
5291
  lines.push(`Check the ${pintor.yellow(manifestField)} field in your ${pintor.yellow('manifest.json')} file.`);
5292
5292
  lines.push("The icon path must point to an existing file that will be packaged with the extension.");
5293
- lines.push("Browsers can reject or crash the extension when required icons are missing. We fail the build early to protect you.");
5293
+ lines.push(opts?.fatal ? "Browsers reject the whole extension when this file is missing. We fail the build early to protect you." : "Browsers can reject or misrender the extension when this file is missing. The build continues.");
5294
5294
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
5295
5295
  lines.push('');
5296
5296
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(filePath)}`);
5297
5297
  return lines.join('\n');
5298
5298
  }
5299
+ function themeImageIsEmpty(manifestField, filePath) {
5300
+ const lines = [];
5301
+ lines.push(`Check the ${pintor.yellow(manifestField)} field in your ${pintor.yellow('manifest.json')} file.`);
5302
+ lines.push("The theme image is empty (0 bytes). Chrome loads the extension but drops the entire theme, so no colors or images apply.");
5303
+ lines.push('');
5304
+ lines.push(`${pintor.red('EMPTY FILE')} ${pintor.underline(filePath)}`);
5305
+ return lines.join('\n');
5306
+ }
5299
5307
  function manifestIconsEntrypointChange(manifestField, pathAfter, pathBefore) {
5300
5308
  const lines = [];
5301
5309
  const fieldLabel = manifestField ? manifestField.replace(/\//g, '.') : 'icons';
@@ -5367,6 +5375,13 @@ class add_to_file_dependencies_AddToFileDependencies {
5367
5375
  });
5368
5376
  }
5369
5377
  }
5378
+ function isEmptyFile(filePath) {
5379
+ try {
5380
+ return 0 === __rspack_external_node_fs_5ea92f0c.statSync(filePath).size;
5381
+ } catch {
5382
+ return false;
5383
+ }
5384
+ }
5370
5385
  class EmitFile {
5371
5386
  manifestPath;
5372
5387
  includeList;
@@ -5431,20 +5446,24 @@ class EmitFile {
5431
5446
  }
5432
5447
  const relToPublic = __rspack_external_node_path_c5b9b54f.relative(publicDir, resolved);
5433
5448
  const isUnderPublic = relToPublic && !relToPublic.startsWith('..') && !__rspack_external_node_path_c5b9b54f.isAbsolute(relToPublic) || entry.startsWith('/') && __rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(projectPath, 'public', entry.slice(1)));
5449
+ const parts = String(feature).split('/');
5450
+ const group = parts[0];
5451
+ const sub = parts[1] || '';
5452
+ const isDefaultIconFamily = ('action' === group || 'browser_action' === group || 'page_action' === group || 'sidebar_action' === group) && 'default_icon' === sub;
5453
+ const isThemeImage = 'theme' === group && 'images' === sub;
5434
5454
  if (!__rspack_external_node_fs_5ea92f0c.existsSync(resolved)) {
5435
5455
  const isPublicRoot = entry.startsWith('/') && !entry.startsWith(projectPath);
5436
- const parts = String(feature).split('/');
5437
- const group = parts[0];
5438
- const sub = parts[1] || '';
5439
5456
  const displayPath = !__rspack_external_node_path_c5b9b54f.isAbsolute(entry) && isPublicRoot ? __rspack_external_node_path_c5b9b54f.join(projectPath, 'public', entry.slice(1)) : __rspack_external_node_path_c5b9b54f.isAbsolute(entry) ? entry : __rspack_external_node_path_c5b9b54f.join(projectPath, entry);
5440
- const isDefaultIconFamily = ('action' === group || 'browser_action' === group || 'page_action' === group || 'sidebar_action' === group) && 'default_icon' === sub;
5441
- const severity = 'icons' === group || isDefaultIconFamily ? 'error' : 'warning';
5457
+ const isFatal = 'icons' === group || isDefaultIconFamily || isThemeImage;
5458
+ const severity = isFatal ? 'error' : 'warning';
5442
5459
  reportToCompilation(compilation, compiler, iconsMissingFile(feature, displayPath, {
5443
- publicRootHint: isPublicRoot
5460
+ publicRootHint: isPublicRoot,
5461
+ fatal: isFatal
5444
5462
  }), severity, 'manifest.json');
5445
5463
  missingCount++;
5446
5464
  continue;
5447
5465
  }
5466
+ if (isThemeImage && isEmptyFile(resolved)) reportToCompilation(compilation, compiler, themeImageIsEmpty(feature, resolved), 'warning', 'manifest.json');
5448
5467
  if (isUnderPublic) {
5449
5468
  try {
5450
5469
  compilation.fileDependencies.add(resolved);
@@ -5455,13 +5474,10 @@ class EmitFile {
5455
5474
  const source = __rspack_external_node_fs_5ea92f0c.readFileSync(resolved);
5456
5475
  const rawSource = new core_sources.RawSource(source);
5457
5476
  const basename = __rspack_external_node_path_c5b9b54f.basename(resolved);
5458
- const parts = String(feature).split('/');
5459
- const group = parts[0];
5460
- const sub = parts[1] || '';
5461
5477
  let outputDir = group;
5462
- if (('action' === group || 'browser_action' === group || 'page_action' === group || 'sidebar_action' === group) && 'default_icon' === sub) outputDir = 'icons';
5478
+ if (isDefaultIconFamily) outputDir = 'icons';
5463
5479
  else if ('browser_action' === group && 'theme_icons' === sub) outputDir = 'browser_action';
5464
- else if ('theme' === group && 'images' === sub) outputDir = 'theme/images';
5480
+ else if (isThemeImage) outputDir = 'theme/images';
5465
5481
  let filename = `${outputDir}/${basename}`;
5466
5482
  if ('icons' === outputDir) {
5467
5483
  const relFromManifest = __rspack_external_node_path_c5b9b54f.relative(manifestDir, resolved).replace(/\\/g, '/');
@@ -5510,7 +5526,7 @@ function jsonMissingFile(manifestField, filePath, opts) {
5510
5526
  const lines = [];
5511
5527
  lines.push(`Check the ${pintor.yellow(manifestField)} field in your ${pintor.yellow('manifest.json')} file.`);
5512
5528
  lines.push("The JSON path must point to an existing file that will be packaged with the extension.");
5513
- lines.push("Browsers can reject or crash the extension when required JSON files (like rulesets or managed schemas) are missing. We fail the build early to protect you.");
5529
+ lines.push(opts?.fatal ? "Browsers can reject or crash the extension when required JSON files (like rulesets or managed schemas) are missing. We fail the build early to protect you." : "Browsers can reject or misread the extension when this file is missing. The build continues.");
5514
5530
  if (opts?.publicRootHint) lines.push(`Paths starting with '/' are resolved from the extension output root (served from ${pintor.yellow('public/')}), not your source directory.`);
5515
5531
  lines.push('');
5516
5532
  lines.push(`${pintor.red('NOT FOUND')} ${pintor.underline(filePath)}`);
@@ -5618,12 +5634,14 @@ function processJsonAssets(compilation, manifestPath, includeList) {
5618
5634
  const isPublicRoot = rawRef.startsWith('/') && !__rspack_external_node_path_c5b9b54f.isAbsolute(rawRef);
5619
5635
  const outputRoot = compilation?.options?.output?.path || '';
5620
5636
  const displayPath = isPublicRoot ? __rspack_external_node_path_c5b9b54f.join(outputRoot, rawRef.slice(1)) : abs;
5637
+ const isFatal = isCriticalJsonFeature(feature);
5621
5638
  const notFound = new WebpackError(jsonMissingFile(feature, displayPath, {
5622
- publicRootHint: isPublicRoot
5639
+ publicRootHint: isPublicRoot,
5640
+ fatal: isFatal
5623
5641
  }));
5624
5642
  notFound.name = 'JSONMissingFile';
5625
5643
  notFound.file = 'manifest.json';
5626
- if (isCriticalJsonFeature(feature)) compilation.errors.push(notFound);
5644
+ if (isFatal) compilation.errors.push(notFound);
5627
5645
  else compilation.warnings.push(notFound);
5628
5646
  missingCount++;
5629
5647
  continue;
@@ -6339,6 +6357,7 @@ class ApplyDevDefaults {
6339
6357
  } catch {}
6340
6358
  return;
6341
6359
  }
6360
+ if (isStaticThemeSource(this.manifestPath, this.browser)) return;
6342
6361
  const canonicalManifest = getManifestContent(compilation, this.manifestPath);
6343
6362
  const contentScriptMatches = Array.isArray(canonicalManifest.content_scripts) ? canonicalManifest.content_scripts.flatMap((cs)=>Array.isArray(cs?.matches) ? cs.matches : []) : [];
6344
6363
  const hostPermissionsPatch = 3 === canonicalManifest.manifest_version && contentScriptMatches.length > 0 ? {
@@ -6985,6 +7004,7 @@ class PatchWAR {
6985
7004
  stage: Compilation.PROCESS_ASSETS_STAGE_REPORT
6986
7005
  }, ()=>{
6987
7006
  if (compilation.errors.length > 0) return;
7007
+ if (isStaticThemeSource(this.manifestPath, this.browser)) return;
6988
7008
  const shared = getSharedFor(compilation);
6989
7009
  generateManifestPatches(compilation, this.manifestPath, shared.entryImports || {}, this.browser);
6990
7010
  });
package/dist/101.mjs CHANGED
@@ -122,6 +122,15 @@ function previewing(browser) {
122
122
  function previewSkippedNoBrowser(browser) {
123
123
  return `${getLoggingPrefix('info')} Skipping browser launch for ${capitalizedBrowserName(browser)} (no-browser).`;
124
124
  }
125
+ function extensionLoadRecovered() {
126
+ return `${getLoggingPrefix('success')} The browser accepted the extension. It is running now.`;
127
+ }
128
+ function extensionLoadStillRefused(reason) {
129
+ return `${getLoggingPrefix('error')} The browser still refuses to load this extension.\n${pintor.gray('REASON')} ${pintor.red(reason)}`;
130
+ }
131
+ function browserLaunchFailed(browser, reason) {
132
+ return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} could not be started, so the extension is NOT running.\n${reason}\nThe dev server keeps watching, but nothing will load until this is fixed.`;
133
+ }
125
134
  function authorInstallNotice(target) {
126
135
  return `${getLoggingPrefix('warn')} Author mode: installing ${target}.`;
127
136
  }
@@ -328,9 +337,10 @@ function printTree(node, prefix = '') {
328
337
  const connector = isLast ? '└─' : '├─';
329
338
  const child = node[key];
330
339
  const childNode = child && 'object' == typeof child ? child : void 0;
331
- const sizeInKB = childNode?.size ? ` (${getFileSize(childNode.size)})` : '';
340
+ const isLeaf = 'number' == typeof childNode?.size;
341
+ const sizeInKB = isLeaf ? ` (${getFileSize(childNode?.size ?? 0)})` : '';
332
342
  output += `${pintor.gray(prefix)}${pintor.gray(connector)} ${key}${pintor.gray(sizeInKB)}\n`;
333
- if (childNode && !childNode.size) output += printTree(childNode, `${prefix}${isLast ? ' ' : pintor.gray('│ ')}`);
343
+ if (childNode && !isLeaf) output += printTree(childNode, `${prefix}${isLast ? ' ' : pintor.gray('│ ')}`);
334
344
  });
335
345
  return output;
336
346
  }
@@ -698,7 +708,7 @@ async function config_loader_isUsingExperimentalConfig(projectPath) {
698
708
  }
699
709
  return false;
700
710
  }
701
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.15","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.10","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"}}');
711
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.16","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.12","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"}}');
702
712
  function asAbsolute(p) {
703
713
  return __rspack_external_node_path_c5b9b54f.isAbsolute(p) ? p : __rspack_external_node_path_c5b9b54f.resolve(p);
704
714
  }
@@ -1925,6 +1935,16 @@ function createPlaywrightMetadataWriter(options) {
1925
1935
  payload.executorAttachedAt = prev.executorAttachedAt;
1926
1936
  payload.runtime = 'attached';
1927
1937
  }
1938
+ if ('starting' !== status && 'string' == typeof prev.extensionLoadRefusedAt) {
1939
+ const target = payload;
1940
+ target.extensionLoadRefusedAt = prev.extensionLoadRefusedAt;
1941
+ if ('string' == typeof prev.extensionLoadRefusedReason) target.extensionLoadRefusedReason = prev.extensionLoadRefusedReason;
1942
+ if ('ready' === status) {
1943
+ payload.status = 'error';
1944
+ payload.code = 'extension_load_refused';
1945
+ payload.message = String(prev.message || 'the browser refused to load the extension');
1946
+ }
1947
+ }
1928
1948
  }
1929
1949
  } catch {}
1930
1950
  writeJsonAtomic(readyPath, payload);
@@ -1983,6 +2003,15 @@ function createPlaywrightMetadataWriter(options) {
1983
2003
  if ('string' == typeof prev.executorAttachedAt) return;
1984
2004
  prev.executorAttachedAt = nowISO();
1985
2005
  prev.runtime = 'attached';
2006
+ if ('string' == typeof prev.extensionLoadRefusedAt) {
2007
+ delete prev.extensionLoadRefusedAt;
2008
+ delete prev.extensionLoadRefusedReason;
2009
+ if ('extension_load_refused' === prev.code) {
2010
+ prev.status = 'ready';
2011
+ delete prev.code;
2012
+ delete prev.message;
2013
+ }
2014
+ }
1986
2015
  prev.ts = nowISO();
1987
2016
  writeJsonAtomic(readyPath, prev);
1988
2017
  } catch {}
@@ -2230,4 +2259,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2230
2259
  await browserLauncher(resolvedOpts);
2231
2260
  metadata.writeReady();
2232
2261
  }
2233
- export { CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, PlaywrightPlugin, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, buildCommandFailed, buildSuccess, buildSuccessWithWarnings, buildWarningsDetails, buildWebpack, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, constants_isGeckoBasedBrowser, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };
2262
+ export { CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, PlaywrightPlugin, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserLaunchFailed, browserRunnerDisabled, buildCommandFailed, buildSuccess, buildSuccessWithWarnings, buildWarningsDetails, buildWebpack, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, constants_isGeckoBasedBrowser, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionLoadRecovered, extensionLoadStillRefused, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };
package/dist/839.mjs CHANGED
@@ -5,7 +5,7 @@ import { buildExecEnv, detectPackageManagerFromLockfile } from "prefers-yarn";
5
5
  import pintor from "pintor";
6
6
  import { EventEmitter } from "node:events";
7
7
  import { Compilation as core_Compilation, WebpackError as core_WebpackError, sources as core_sources } from "@rspack/core";
8
- import { package_namespaceObject, buildWarningsDetails, sanitize, getDirs, projectInstallFallbackToNpm, assertNoManagedDependencyConflicts, debugDirs, buildSuccess, writingTypeDefinitionsError, projectInstallScriptsDisabled, authorInstallNotice, getSpecialFoldersDataForProjectRoot, buildSuccessWithWarnings, loadCommandConfig, needsInstall, buildCommandFailed, writingTypeDefinitions, constants_isGeckoBasedBrowser, buildWebpack, debugBrowser, normalizeBrowser, debugOutputPath, loadCustomConfig, isChromiumBasedBrowser, devCommandFailed, getDistPath, loadBrowserConfig, getProjectStructure, resolveCompanionExtensionsConfig } from "./101.mjs";
8
+ import { package_namespaceObject, buildWarningsDetails, sanitize, getDirs, projectInstallFallbackToNpm, assertNoManagedDependencyConflicts, debugDirs, browserLaunchFailed, buildSuccess, extensionLoadRecovered, writingTypeDefinitionsError, extensionLoadStillRefused, projectInstallScriptsDisabled, authorInstallNotice, getSpecialFoldersDataForProjectRoot, buildSuccessWithWarnings, loadCommandConfig, needsInstall, buildCommandFailed, writingTypeDefinitions, constants_isGeckoBasedBrowser, buildWebpack, debugBrowser, normalizeBrowser, debugOutputPath, loadCustomConfig, devCommandFailed, getProjectStructure, getDistPath, resolveCompanionExtensionsConfig, loadBrowserConfig, isChromiumBasedBrowser } from "./101.mjs";
9
9
  import { stripBom, parseJsonSafe } from "./23.mjs";
10
10
  import { hasProjectDependency, findNearestProjectManifestDirSync } from "./80.mjs";
11
11
  import { buildSummaryPath, ensureSessionArtifactsIgnoreFile } from "./494.mjs";
@@ -2379,6 +2379,41 @@ function filterKeysForThisBrowser(manifest, browser) {
2379
2379
  };
2380
2380
  return resolve(manifest);
2381
2381
  }
2382
+ const THEME_DISQUALIFYING_KEYS = [
2383
+ 'background',
2384
+ "content_scripts",
2385
+ 'action',
2386
+ 'browser_action',
2387
+ 'page_action',
2388
+ 'sidebar_action',
2389
+ 'side_panel',
2390
+ 'options_page',
2391
+ 'options_ui',
2392
+ 'devtools_page',
2393
+ 'chrome_url_overrides',
2394
+ 'sandbox',
2395
+ "user_scripts",
2396
+ 'declarative_net_request',
2397
+ 'web_accessible_resources'
2398
+ ];
2399
+ function isStaticTheme(manifest) {
2400
+ if (!manifest || 'object' != typeof manifest) return false;
2401
+ const theme = manifest.theme;
2402
+ if (!theme || 'object' != typeof theme) return false;
2403
+ return !THEME_DISQUALIFYING_KEYS.some((key)=>{
2404
+ const value = manifest[key];
2405
+ return null != value;
2406
+ });
2407
+ }
2408
+ function isStaticThemeSource(manifestPath, browser) {
2409
+ if (!manifestPath) return false;
2410
+ try {
2411
+ const parsed = parseJsonSafe(__rspack_external_node_fs_5ea92f0c.readFileSync(manifestPath, 'utf-8'));
2412
+ return isStaticTheme(filterKeysForThisBrowser(parsed, browser));
2413
+ } catch {
2414
+ return false;
2415
+ }
2416
+ }
2382
2417
  function isFromFilepathList(filePath, filepathList) {
2383
2418
  return Object.values(filepathList || {}).some((value)=>value === filePath);
2384
2419
  }
@@ -2640,7 +2675,7 @@ function storage(manifest) {
2640
2675
  }
2641
2676
  const theme_getBasename = (filepath)=>__rspack_external_node_path_c5b9b54f.basename(filepath);
2642
2677
  const rewriteThemeImage = (value)=>getFilename(`theme/images/${theme_getBasename(value)}`, value);
2643
- function theme(manifest) {
2678
+ function theme_theme(manifest) {
2644
2679
  return manifest.theme && {
2645
2680
  theme: {
2646
2681
  ...manifest.theme,
@@ -2701,7 +2736,7 @@ function manifestCommon(manifest, manifestPath) {
2701
2736
  ...optionsUi(manifest, manifestPath),
2702
2737
  ...sandbox(manifest),
2703
2738
  ...storage(manifest),
2704
- ...theme(manifest),
2739
+ ...theme_theme(manifest),
2705
2740
  ...userScripts(manifest),
2706
2741
  ...webAccessibleResources(manifest),
2707
2742
  ...contentSecurityPolicy(manifest),
@@ -3068,6 +3103,7 @@ class SetupBackgroundEntry {
3068
3103
  const filteredManifest = filterKeysForThisBrowser(manifest, browser) || manifest;
3069
3104
  const manifestBg = filteredManifest?.background ?? manifest.background;
3070
3105
  const manifestVersion = filteredManifest?.manifest_version ?? manifest.manifest_version;
3106
+ if (isStaticTheme(filteredManifest)) return;
3071
3107
  function hookError(maybeError) {
3072
3108
  compiler.hooks.thisCompilation.tap('run-chromium:setup-background-entry', (compilation)=>{
3073
3109
  reportToCompilation(compilation, compiler, maybeError, 'error');
@@ -4479,6 +4515,7 @@ class BrowsersPlugin {
4479
4515
  controller;
4480
4516
  reloadBroker;
4481
4517
  logSink;
4518
+ lastReportedRefusal;
4482
4519
  constructor(options){
4483
4520
  this.options = options;
4484
4521
  }
@@ -4488,6 +4525,27 @@ class BrowsersPlugin {
4488
4525
  setLogSink(sink) {
4489
4526
  this.logSink = sink;
4490
4527
  }
4528
+ async retryRefusedExtensionLoad() {
4529
+ const controller = this.controller;
4530
+ if (!controller?.retryExtensionLoad || !controller.getExtensionLoadRefusal) return false;
4531
+ if (!controller.getExtensionLoadRefusal()) return false;
4532
+ if (void 0 === this.lastReportedRefusal) this.lastReportedRefusal = controller.getExtensionLoadRefusal();
4533
+ let outcome;
4534
+ try {
4535
+ outcome = await controller.retryExtensionLoad();
4536
+ } catch {
4537
+ return false;
4538
+ }
4539
+ if ('loaded' === outcome.status) {
4540
+ console.log(extensionLoadRecovered());
4541
+ return true;
4542
+ }
4543
+ if ('refused' === outcome.status && outcome.reason && outcome.reason !== this.lastReportedRefusal) {
4544
+ this.lastReportedRefusal = outcome.reason;
4545
+ console.error(extensionLoadStillRefused(outcome.reason));
4546
+ }
4547
+ return false;
4548
+ }
4491
4549
  apply(compiler) {
4492
4550
  const changedSources = createChangedSourcesTracker(compiler);
4493
4551
  compiler.hooks.done.tapPromise(BrowsersPlugin.name, async (stats)=>{
@@ -4530,12 +4588,15 @@ class BrowsersPlugin {
4530
4588
  tabFilter: this.options.browserOptions.logTab
4531
4589
  });
4532
4590
  } catch (error) {
4591
+ const reason = error instanceof Error ? error.message : String(error);
4592
+ console.error(browserLaunchFailed(this.options.browserOptions.browser, reason));
4533
4593
  this.emitter.emit('error', {
4534
4594
  errors: [
4535
- error instanceof Error ? error.message : String(error)
4595
+ reason
4536
4596
  ]
4537
4597
  });
4538
4598
  }
4599
+ else if (await this.retryRefusedExtensionLoad()) ;
4539
4600
  else if (this.reloadBroker) await dispatchReload(reloadInstruction, {
4540
4601
  broker: this.reloadBroker
4541
4602
  });
@@ -4708,4 +4769,4 @@ async function extensionDev(pathOrRemoteUrl, devOptions) {
4708
4769
  process.exit(1);
4709
4770
  }
4710
4771
  }
4711
- export { BuildEmitter, ReloadPlugin, buildCanonicalManifest, buildSourceFeatureIndex, classifyReloadFromSources, collectRootAbsoluteRefs, createChangedSourcesTracker, dispatchReload, ensureTypeScriptConfig, extensionBuild, extensionDev, filterKeysForThisBrowser, getCurrentManifestContent, getManifestContent, getManifestOverrides, getUserTypeScriptConfigFile, hasDependency, isFromFilepathList, isUsingCustomLoader, isUsingIntegration, isUsingTypeScript, jsFrameworksConfigsDetected, jsFrameworksHmrSummary, jsFrameworksIntegrationsEnabled, normalizeManifestOutputPath, readContentScriptCount, reportToCompilation, resolveDevelopDistFile, resolveDevelopInstallRoot, resolvePackageManager, resolveRootAbsoluteRef, setCurrentManifestContent, setOriginalManifestContent, unixify };
4772
+ export { BuildEmitter, ReloadPlugin, buildCanonicalManifest, buildSourceFeatureIndex, classifyReloadFromSources, collectRootAbsoluteRefs, createChangedSourcesTracker, dispatchReload, ensureTypeScriptConfig, extensionBuild, extensionDev, filterKeysForThisBrowser, getCurrentManifestContent, getManifestContent, getManifestOverrides, getUserTypeScriptConfigFile, hasDependency, isFromFilepathList, isStaticThemeSource, isUsingCustomLoader, isUsingIntegration, isUsingTypeScript, jsFrameworksConfigsDetected, jsFrameworksHmrSummary, jsFrameworksIntegrationsEnabled, normalizeManifestOutputPath, readContentScriptCount, reportToCompilation, resolveDevelopDistFile, resolveDevelopInstallRoot, resolvePackageManager, resolveRootAbsoluteRef, setCurrentManifestContent, setOriginalManifestContent, unixify };