extension-develop 4.1.25 → 4.1.26

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.
@@ -1,6 +1,56 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
- import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
3
2
  import * as __rspack_external_node_path_806ed179 from "node:path";
3
+ import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
4
+ __rspack_external_node_path_806ed179.join(process.cwd(), 'node_modules/extension-develop/dist/certs');
5
+ const CHROMIUM_BASED_BROWSERS = [
6
+ 'chrome',
7
+ 'edge',
8
+ 'brave',
9
+ 'opera',
10
+ 'vivaldi',
11
+ 'yandex'
12
+ ];
13
+ const GECKO_BASED_BROWSERS = [
14
+ 'firefox',
15
+ 'waterfox',
16
+ 'librewolf',
17
+ 'zen',
18
+ 'floorp'
19
+ ];
20
+ const WEBKIT_BASED_BROWSERS = [
21
+ 'safari'
22
+ ];
23
+ const CHROMIUM_FAMILY_ALIASES = [
24
+ 'chromium',
25
+ 'chrome',
26
+ 'edge',
27
+ 'chromium-based'
28
+ ];
29
+ const GECKO_FAMILY_ALIASES = [
30
+ 'firefox',
31
+ 'gecko-based'
32
+ ];
33
+ const EMULATOR_BROWSER = 'chromium-emulator';
34
+ function isEmulatorLaneEnabled(env = process.env) {
35
+ const value = String(env.EXTENSION_EXPERIMENTAL_EMULATOR || '').trim().toLowerCase();
36
+ return '1' === value || 'true' === value;
37
+ }
38
+ function isEmulatorBrowser(browser) {
39
+ return browser === EMULATOR_BROWSER;
40
+ }
41
+ [
42
+ ...CHROMIUM_BASED_BROWSERS,
43
+ ...GECKO_BASED_BROWSERS
44
+ ];
45
+ function isChromiumBasedBrowser(browser) {
46
+ return CHROMIUM_BASED_BROWSERS.includes(browser) || String(browser).includes('chromium');
47
+ }
48
+ function isGeckoBasedBrowser(browser) {
49
+ return GECKO_BASED_BROWSERS.includes(browser) || String(browser).includes('gecko') || String(browser).includes('firefox');
50
+ }
51
+ function isWebkitBasedBrowser(browser) {
52
+ return WEBKIT_BASED_BROWSERS.includes(browser) || String(browser).includes('webkit');
53
+ }
4
54
  function stripBom(text) {
5
55
  const raw = 'string' == typeof text ? text : String(text || '');
6
56
  return raw && 0xfeff === raw.charCodeAt(0) ? raw.slice(1) : raw;
@@ -208,4 +258,4 @@ function validateDenoConfig(denoConfigPath) {
208
258
  return false;
209
259
  }
210
260
  }
211
- export { PROJECT_MANIFEST_FILENAMES, findNearestDenoConfigSync, findNearestProjectManifestDirSync, findNearestProjectManifestSync, hasProjectDependency, parseJsonSafe, readProjectDependencies, stripBom, validateDenoConfig };
261
+ export { CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, PROJECT_MANIFEST_FILENAMES, findNearestDenoConfigSync, findNearestProjectManifestDirSync, findNearestProjectManifestSync, hasProjectDependency, isChromiumBasedBrowser, isEmulatorBrowser, isEmulatorLaneEnabled, isGeckoBasedBrowser, isWebkitBasedBrowser, parseJsonSafe, readProjectDependencies, stripBom, validateDenoConfig };
package/dist/672~0.mjs CHANGED
@@ -1,7 +1,6 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
2
  import pintor from "pintor";
3
- import { isChromiumBasedBrowser, isGeckoBasedBrowser } from "./331~0.mjs";
4
- import { parseJsonSafe } from "./731~0.mjs";
3
+ import { isChromiumBasedBrowser, parseJsonSafe, isGeckoBasedBrowser } from "./474~0.mjs";
5
4
  import { prefix as messaging_prefix } from "./852~0.mjs";
6
5
  import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
7
6
  const CHROMIUM_VENDOR_PREFIXES = [
package/dist/832~0.mjs CHANGED
@@ -9,9 +9,8 @@ import node_path from "node:path";
9
9
  import { getSpecialFoldersData } from "browser-extension-manifest-fields";
10
10
  import pintor from "pintor";
11
11
  import { devtoolsEngineFor, managedDependencyConflict, resolveProjectStructureSync, getDirs, computePreviewOutputPath, eventsPath as session_paths_eventsPath, anotherDevSessionActive, previewingSourceFallback, asAbsolute, displayPath, previewing, starting, debugPreviewOutput, ensureSessionArtifactsIgnoreFile, debugDirs, debugBrowser, readyContractPath, configLoadingError, normalizeBrowser, collapseHomeDir, previewingCustomOutput, browserArtifactsDir, getProjectStructure, isUsingExperimentalConfig as messages_isUsingExperimentalConfig, getDistPath, configBrowserOrThrow } from "./950~0.mjs";
12
- import { isChromiumBasedBrowser, isWebkitBasedBrowser, isGeckoBasedBrowser } from "./331~0.mjs";
12
+ import { isChromiumBasedBrowser, isEmulatorBrowser, isGeckoBasedBrowser, readProjectDependencies, stripBom, parseJsonSafe, isWebkitBasedBrowser } from "./474~0.mjs";
13
13
  import { humanWarn, isDebug, browserRowValue, artifactNoun, prefix as messaging_prefix, card, humanLine } from "./852~0.mjs";
14
- import { stripBom, parseJsonSafe, readProjectDependencies } from "./731~0.mjs";
15
14
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
16
15
  import { dirname as __rspack_dirname } from "node:path";
17
16
  var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
@@ -19,7 +18,7 @@ import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
19
18
  import * as __rspack_external_node_os_4f3c9d58 from "node:os";
20
19
  import * as __rspack_external_node_path_806ed179 from "node:path";
21
20
  import * as __rspack_external_node_vm_ef240610 from "node:vm";
22
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.25","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"2.2.3","@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":"^3.0.1","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","es-module-lexer":"^3.0.2","extension-from-store":"^0.2.5","fflate":"^0.8.3","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.9.1","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"}}');
21
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.26","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"2.2.3","@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":"^3.0.1","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","es-module-lexer":"^3.0.2","extension-from-store":"^0.2.5","fflate":"^0.8.3","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.9.1","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"}}');
23
22
  const preloadedEnvKeys = new Set();
24
23
  function getPreloadedEnvKeys() {
25
24
  return preloadedEnvKeys;
@@ -435,15 +434,29 @@ function idFromHash(hash) {
435
434
  for (const char of hex)id += String.fromCharCode('a'.charCodeAt(0) + parseInt(char, 16));
436
435
  return id;
437
436
  }
437
+ function registeredDirectoryPath(dir, platform) {
438
+ const absolute = __rspack_external_node_path_806ed179.resolve(dir);
439
+ if ('win32' === platform) return absolute;
440
+ try {
441
+ return __rspack_external_node_fs_1b05aee1.realpathSync.native(absolute);
442
+ } catch {
443
+ return absolute;
444
+ }
445
+ }
446
+ function upperCaseDriveLetter(windowsPath) {
447
+ return /^[a-z]:/.test(windowsPath) ? windowsPath[0].toUpperCase() + windowsPath.slice(1) : windowsPath;
448
+ }
438
449
  function chromiumExtensionIdFromKey(manifestKey) {
439
450
  const decoded = Buffer.from(manifestKey, 'base64');
440
451
  return idFromHash(createHash('sha256').update(decoded).digest());
441
452
  }
442
- function chromiumExtensionIdFromPath(extensionDir) {
443
- const absolute = __rspack_external_node_path_806ed179.resolve(extensionDir);
444
- const bytes = 'win32' === process.platform ? Buffer.from(absolute.replace(/[A-Z]/g, (char)=>char.toLowerCase()), 'utf16le') : Buffer.from(absolute, 'utf8');
453
+ function chromiumExtensionIdFromRegisteredPath(registeredPath, platform = process.platform) {
454
+ const bytes = 'win32' === platform ? Buffer.from(upperCaseDriveLetter(registeredPath.replace(/\//g, '\\')), 'utf16le') : Buffer.from(registeredPath, 'utf8');
445
455
  return idFromHash(createHash('sha256').update(bytes).digest());
446
456
  }
457
+ function chromiumExtensionIdFromPath(extensionDir) {
458
+ return chromiumExtensionIdFromRegisteredPath(registeredDirectoryPath(extensionDir, process.platform), process.platform);
459
+ }
447
460
  function readManifest(extensionDir) {
448
461
  try {
449
462
  const raw = __rspack_external_node_fs_1b05aee1.readFileSync(__rspack_external_node_path_806ed179.join(extensionDir, 'manifest.json'), 'utf-8');
@@ -512,7 +525,7 @@ function getSessionRunId(packageJsonDir, browser) {
512
525
  }
513
526
  function deriveDistExtensionId(browser, distPath) {
514
527
  try {
515
- if (isWebkitBasedBrowser(browser)) return;
528
+ if (isWebkitBasedBrowser(browser) || isEmulatorBrowser(browser)) return;
516
529
  if (!__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(distPath, 'manifest.json'))) return;
517
530
  const id = isGeckoBasedBrowser(browser) ? geckoExtensionId(distPath) : chromiumExtensionId(distPath);
518
531
  return id || void 0;
@@ -616,7 +629,7 @@ function createPlaywrightMetadataWriter(options) {
616
629
  instanceId: options.instanceId,
617
630
  instanceExplicit: options.instanceExplicit
618
631
  })) humanWarn(anotherDevSessionActive(options.browser, liveOwner.pid, liveOwner.runId));
619
- const toManagedRecords = (dirs)=>Array.isArray(dirs) && dirs.length > 0 ? managedExtensionRecords(options.browser, dirs) : void 0;
632
+ const toManagedRecords = (dirs)=>Array.isArray(dirs) && dirs.length > 0 && !isEmulatorBrowser(options.browser) ? managedExtensionRecords(options.browser, dirs) : void 0;
620
633
  let managedExtensionsExplicit = void 0 !== options.managedExtensionDirs;
621
634
  let managedExtensions = toManagedRecords(options.managedExtensionDirs);
622
635
  const base = {
@@ -638,7 +651,11 @@ function createPlaywrightMetadataWriter(options) {
638
651
  controlPath: options.controlPath,
639
652
  logsPath: options.logsPath,
640
653
  toolchainVersion: package_namespaceObject.rE,
641
- ...readManifestProvenance(options.manifestPath)
654
+ ...readManifestProvenance(options.manifestPath),
655
+ ...isEmulatorBrowser(options.browser) ? {
656
+ engine: 'emulator',
657
+ browserPid: null
658
+ } : {}
642
659
  };
643
660
  function writeReady(status, extra) {
644
661
  if (foreignLiveDevSession) return;
@@ -1498,6 +1515,7 @@ function readJsonRecord(filePath) {
1498
1515
  }
1499
1516
  }
1500
1517
  function capitalizeToken(value) {
1518
+ if ('chromium-emulator' === value) return 'Emulated Chromium';
1501
1519
  return value.split('-').filter(Boolean).map((token)=>token.charAt(0).toUpperCase() + token.slice(1)).join('-');
1502
1520
  }
1503
1521
  function getExtensionVersion() {
@@ -1549,6 +1567,9 @@ function shouldWarnPortConflict(requested, actual) {
1549
1567
  const requestedPort = Number(requested);
1550
1568
  return Number.isFinite(requestedPort) && 0 !== requestedPort && requestedPort !== actual;
1551
1569
  }
1570
+ function emulatorViewerUrl(url) {
1571
+ return `${getLoggingPrefix('info')} Emulated Chromium runs in a web page. Open this address to load your extension:\n${pintor.underline(url)}`;
1572
+ }
1552
1573
  function portInUse(requestedPort, newPort) {
1553
1574
  return `${getLoggingPrefix('warn')} Port ${requestedPort} is in use.\nThe dev server listens on port ${newPort} instead.`;
1554
1575
  }
@@ -1864,4 +1885,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
1864
1885
  metadata.writeShutdown(`the ${metadataCommand} session ended`);
1865
1886
  });
1866
1887
  }
1867
- export { BUILD_COMMAND_DEFAULTS, DEV_COMMAND_DEFAULTS, PlaywrightPlugin, START_BUILD_DEFAULTS, assertNoManagedDependencyConflicts, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, createPlaywrightMetadataWriter, devServerRestarting, devServerStartTimeout, extensionJsRunnerError, extensionPreview, getPreloadedEnvKeys, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, loadBrowserConfig, loadCommandConfig, loadCustomConfig, loadProjectConfigDefaults, mergeOptionLayers, messages_ready, noEntrypointsDetected, package_namespaceObject, portInUse, publicFolderShadowed, publicMustBeAtProjectRoot, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, runnerCleanupError, runnerUncaughtException, runnerUnhandledRejection, sanitize, serverRestartRequiredFromSpecialFolderMessageOnly, shouldWarnPortConflict, spacerLine, specialFolderChangeDetected, specialFoldersSetupSummary, stampReadyDistExtensionId, stampReadyKnownExtensionId, withDarkMode };
1888
+ export { BUILD_COMMAND_DEFAULTS, DEV_COMMAND_DEFAULTS, PlaywrightPlugin, START_BUILD_DEFAULTS, assertNoManagedDependencyConflicts, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, createPlaywrightMetadataWriter, devServerRestarting, devServerStartTimeout, emulatorViewerUrl, extensionJsRunnerError, extensionPreview, getPreloadedEnvKeys, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, loadBrowserConfig, loadCommandConfig, loadCustomConfig, loadProjectConfigDefaults, mergeOptionLayers, messages_ready, noEntrypointsDetected, package_namespaceObject, portInUse, publicFolderShadowed, publicMustBeAtProjectRoot, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, runnerCleanupError, runnerUncaughtException, runnerUnhandledRejection, sanitize, serverRestartRequiredFromSpecialFolderMessageOnly, shouldWarnPortConflict, spacerLine, specialFolderChangeDetected, specialFoldersSetupSummary, stampReadyDistExtensionId, stampReadyKnownExtensionId, withDarkMode };
package/dist/840~0.mjs CHANGED
@@ -9,9 +9,8 @@ import { pathToFileURL } from "node:url";
9
9
  import { EventEmitter } from "node:events";
10
10
  import { humanWarn, browserRowValue, CODES, ENVELOPE, prefix as messaging_prefix, card, isDebug, claimCardKey, isMachineOutput } from "./852~0.mjs";
11
11
  import { package_namespaceObject, loadCommandConfig, DEV_COMMAND_DEFAULTS, stampReadyDistExtensionId, loadProjectConfigDefaults, mergeOptionLayers, stampReadyKnownExtensionId, assertNoManagedDependencyConflicts, loadCustomConfig, START_BUILD_DEFAULTS, loadBrowserConfig, resolveCompanionExtensionsConfig, BUILD_COMMAND_DEFAULTS, getSpecialFoldersDataForProjectRoot, withDarkMode } from "./832~0.mjs";
12
- import { stripBom, hasProjectDependency, parseJsonSafe, findNearestProjectManifestDirSync } from "./731~0.mjs";
13
- import { isGeckoBasedBrowser } from "./331~0.mjs";
14
- import { buildWarningsDetails, buildFailed, getDirs, zipArtifactReady, projectInstallFallbackToNpm, debugDirs, addonLintDependencyAttribution, browserLaunchFailed, collapseHomeDir, addonLintMore, extensionLoadRecovered, writingTypeDefinitionsError, extensionLoadStillRefused, relativeToDir, projectInstallScriptsDisabled, authorInstallNotice, addonLintFailed, buildAssetsTree, addonLintSummary, addonLintFinding, configBrowserOrThrow, buildSummaryPath, needsInstall, projectInstallInWorkspaceRoot, buildCommandFailed, addonLintNotInstalled, writingTypeDefinitions, buildComplete, ensureSessionStateInProjectGitignore, displayPath, ensureSessionArtifactsIgnoreFile, debugBrowser, normalizeBrowser, debugOutputPath, devCommandFailed, buildShareHint, getDistPath, getProjectStructure, debugSplitChunksNarrowed } from "./950~0.mjs";
12
+ import { stripBom, hasProjectDependency, isGeckoBasedBrowser, parseJsonSafe, findNearestProjectManifestDirSync } from "./474~0.mjs";
13
+ import { buildWarningsDetails, buildFailed, getDirs, zipArtifactReady, projectInstallFallbackToNpm, debugDirs, addonLintDependencyAttribution, browserLaunchFailed, collapseHomeDir, addonLintMore, extensionLoadStillRefused, extensionLoadRecovered, writingTypeDefinitionsError, operaBuildUnminified, projectInstallScriptsDisabled, authorInstallNotice, addonLintFailed, buildAssetsTree, addonLintSummary, addonLintFinding, relativeToDir, configBrowserOrThrow, needsInstall, projectInstallInWorkspaceRoot, buildCommandFailed, addonLintNotInstalled, writingTypeDefinitions, buildComplete, buildSummaryPath, displayPath, ensureSessionStateInProjectGitignore, ensureSessionArtifactsIgnoreFile, debugBrowser, normalizeBrowser, debugOutputPath, devCommandFailed, buildShareHint, getDistPath, getProjectStructure, debugSplitChunksNarrowed } from "./950~0.mjs";
15
14
  import { publicRootsFor } from "./105~0.mjs";
16
15
  import { getCanonicalContentScriptEntryName } from "./640~0.mjs";
17
16
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
@@ -2425,6 +2424,7 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2425
2424
  extensions: resolvedExtensionsConfig,
2426
2425
  browser,
2427
2426
  mode: resolvedMode,
2427
+ minify: mergedBuildOptions.minify ?? 'opera' !== browser,
2428
2428
  metadataCommand: buildOptions?.metadataCommand || 'build',
2429
2429
  output: {
2430
2430
  clean: false,
@@ -2553,6 +2553,7 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2553
2553
  if (warningDetails) humanLine(warningDetails);
2554
2554
  }
2555
2555
  for (const line of lintLines)humanLine(line);
2556
+ if ('production' === resolvedMode && 'opera' === browser && void 0 === mergedBuildOptions.minify) humanLine(operaBuildUnminified());
2556
2557
  humanLine(buildComplete(browser, distDisplay, summary.total_bytes, resolvedMode));
2557
2558
  for (const artifact of getZipArtifacts(stats.compilation)){
2558
2559
  const artifactPath = useStagingSwap && artifact.path.startsWith(stagingDistPath) ? distPath + artifact.path.slice(stagingDistPath.length) : artifact.path;
@@ -2993,6 +2994,7 @@ class BrowsersPlugin {
2993
2994
  controller;
2994
2995
  reloadBroker;
2995
2996
  logSink;
2997
+ emulatorViewerUrl;
2996
2998
  lastReportedRefusal;
2997
2999
  constructor(options){
2998
3000
  this.options = options;
@@ -3003,6 +3005,9 @@ class BrowsersPlugin {
3003
3005
  setLogSink(sink) {
3004
3006
  this.logSink = sink;
3005
3007
  }
3008
+ setEmulatorViewerUrl(url) {
3009
+ this.emulatorViewerUrl = url;
3010
+ }
3006
3011
  async retryRefusedExtensionLoad() {
3007
3012
  const controller = this.controller;
3008
3013
  if (!controller?.retryExtensionLoad || !controller.getExtensionLoadRefusal) return false;
@@ -3053,7 +3058,10 @@ class BrowsersPlugin {
3053
3058
  outputPath,
3054
3059
  contextDir,
3055
3060
  extensionsToLoad: this.extensionsToLoad,
3056
- logSink: this.logSink
3061
+ logSink: this.logSink,
3062
+ ...this.emulatorViewerUrl ? {
3063
+ emulatorViewerUrl: this.emulatorViewerUrl
3064
+ } : {}
3057
3065
  });
3058
3066
  const logLevel = this.options.browserOptions.logLevel || 'off';
3059
3067
  if ('off' !== logLevel && this.controller) await this.controller.enableUnifiedLogging({
package/dist/852~0.mjs CHANGED
@@ -105,6 +105,8 @@ const GECKO_BROWSERS = new Set([
105
105
  'firefox-based',
106
106
  'gecko-based',
107
107
  'librewolf',
108
+ 'zen',
109
+ 'floorp',
108
110
  'waterfox'
109
111
  ]);
110
112
  function artifactNoun(browser) {
package/dist/950~0.mjs CHANGED
@@ -2,7 +2,7 @@ import { createRequire as __extjsCreateRequire } from "node:module"; const requi
2
2
  import pintor from "pintor";
3
3
  import { spawnSync } from "node:child_process";
4
4
  import { fmt, isDebug, artifactNoun, prefix as messaging_prefix, hasChannelPrefix } from "./852~0.mjs";
5
- import { findNearestDenoConfigSync, validateDenoConfig, PROJECT_MANIFEST_FILENAMES, parseJsonSafe, readProjectDependencies } from "./731~0.mjs";
5
+ import { findNearestDenoConfigSync, isEmulatorLaneEnabled, validateDenoConfig, isEmulatorBrowser, PROJECT_MANIFEST_FILENAMES, parseJsonSafe, readProjectDependencies } from "./474~0.mjs";
6
6
  import * as __rspack_external_node_path_806ed179 from "node:path";
7
7
  import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
8
8
  import * as __rspack_external_node_os_4f3c9d58 from "node:os";
@@ -91,6 +91,9 @@ function buildComplete(browser, distDisplayPath, totalBytes, mode) {
91
91
  const size = 'number' == typeof totalBytes && totalBytes > 0 ? ` (${getHumanSize(totalBytes)})` : '';
92
92
  return `${getLoggingPrefix('success')} ${noun} ${builtFor} ${pintor.underline(distDisplayPath)}${size}.`;
93
93
  }
94
+ function operaBuildUnminified() {
95
+ return `${getLoggingPrefix('info')} Opera Add-ons reviews readable source, so this build does not minify first-party code. Pass ${pintor.blue('--minify')} to minify it anyway.`;
96
+ }
94
97
  function platformDocsUrl() {
95
98
  return String(process.env.EXTENSION_DEV_DOCS_URL || '').trim().replace(/\/+$/, '');
96
99
  }
@@ -810,13 +813,17 @@ const KNOWN_BROWSER_NAMES = new Set([
810
813
  'firefox',
811
814
  'waterfox',
812
815
  'librewolf',
816
+ 'zen',
817
+ 'floorp',
813
818
  'gecko-based',
814
819
  'firefox-based',
815
820
  'safari',
816
821
  'webkit-based'
817
822
  ]);
818
823
  function isKnownBrowserName(name) {
819
- return 'string' == typeof name && KNOWN_BROWSER_NAMES.has(name);
824
+ if ('string' != typeof name) return false;
825
+ if (isEmulatorBrowser(name)) return isEmulatorLaneEnabled();
826
+ return KNOWN_BROWSER_NAMES.has(name);
820
827
  }
821
828
  function configBrowserOrThrow(configBrowser, command) {
822
829
  if (null == configBrowser) return;
@@ -862,6 +869,10 @@ function normalizeBrowser(browser, chromiumBinary, geckoBinary, safariBinary) {
862
869
  return 'waterfox';
863
870
  case 'librewolf':
864
871
  return 'librewolf';
872
+ case 'zen':
873
+ return 'zen';
874
+ case 'floorp':
875
+ return 'floorp';
865
876
  case 'gecko-based':
866
877
  case 'firefox-based':
867
878
  return 'gecko-based';
@@ -869,6 +880,9 @@ function normalizeBrowser(browser, chromiumBinary, geckoBinary, safariBinary) {
869
880
  return 'safari';
870
881
  case 'webkit-based':
871
882
  return 'webkit-based';
883
+ case 'chromium-emulator':
884
+ if (isEmulatorLaneEnabled()) return 'chromium-emulator';
885
+ return 'chrome';
872
886
  default:
873
887
  return 'chrome';
874
888
  }
@@ -895,6 +909,7 @@ function devtoolsEngineFor(browser) {
895
909
  return 'edge';
896
910
  case 'chromium':
897
911
  case 'chromium-based':
912
+ case 'chromium-emulator':
898
913
  case 'brave':
899
914
  case 'opera':
900
915
  case 'vivaldi':
@@ -904,6 +919,8 @@ function devtoolsEngineFor(browser) {
904
919
  case 'gecko-based':
905
920
  case 'waterfox':
906
921
  case 'librewolf':
922
+ case 'zen':
923
+ case 'floorp':
907
924
  return 'firefox';
908
925
  case 'safari':
909
926
  case 'webkit-based':
@@ -996,4 +1013,4 @@ function actionsPath(projectPath, browser) {
996
1013
  function buildSummaryPath(projectPath, browser) {
997
1014
  return __rspack_external_node_path_806ed179.join(browserArtifactsDir(projectPath, browser), 'build-summary.json');
998
1015
  }
999
- export { actionsPath, addonLintDependencyAttribution, addonLintFailed, addonLintFinding, addonLintMore, addonLintNotInstalled, addonLintSummary, anotherDevSessionActive, asAbsolute, authorInstallNotice, browserArtifactsDir, browserDistDir, browserLaunchFailed, browserProfileRootDir, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildSummaryPath, buildWarningsDetails, collapseHomeDir, computePreviewOutputPath, configBrowserOrThrow, configLoadingError, controlPortFilePath, controlTokenPath, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, debugPreviewOutput, debugSplitChunksNarrowed, devCommandFailed, devtoolsEngineFor, displayPath, downloadingText, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore, eventsPath, extensionLoadRecovered, extensionLoadStillRefused, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, invalidRemoteZip, isUsingExperimentalConfig, legacyControlPortFilePath, legacyControlTokenPath, localZipNotFound, logsPath, managedDependencyConflict, manifestInvalidJson, needsInstall, noCompanionExtensionsResolved, normalizeBrowser, notAZipArchive, packagingDistributionFiles, packagingSourceFiles, previewing, previewingCustomOutput, previewingSourceFallback, projectInstallFallbackToNpm, projectInstallInWorkspaceRoot, projectInstallScriptsDisabled, readyContractPath, relativeToDir, resolveProjectStructureSync, sessionArtifactsRootDir, sessionStateDir, starting, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
1016
+ export { actionsPath, addonLintDependencyAttribution, addonLintFailed, addonLintFinding, addonLintMore, addonLintNotInstalled, addonLintSummary, anotherDevSessionActive, asAbsolute, authorInstallNotice, browserArtifactsDir, browserDistDir, browserLaunchFailed, browserProfileRootDir, buildAssetsTree, buildCommandFailed, buildComplete, buildFailed, buildShareHint, buildSummaryPath, buildWarningsDetails, collapseHomeDir, computePreviewOutputPath, configBrowserOrThrow, configLoadingError, controlPortFilePath, controlTokenPath, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, debugPreviewOutput, debugSplitChunksNarrowed, devCommandFailed, devtoolsEngineFor, displayPath, downloadingText, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore, eventsPath, extensionLoadRecovered, extensionLoadStillRefused, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, invalidRemoteZip, isUsingExperimentalConfig, legacyControlPortFilePath, legacyControlTokenPath, localZipNotFound, logsPath, managedDependencyConflict, manifestInvalidJson, needsInstall, noCompanionExtensionsResolved, normalizeBrowser, notAZipArchive, operaBuildUnminified, packagingDistributionFiles, packagingSourceFiles, previewing, previewingCustomOutput, previewingSourceFallback, projectInstallFallbackToNpm, projectInstallInWorkspaceRoot, projectInstallScriptsDisabled, readyContractPath, relativeToDir, resolveProjectStructureSync, sessionArtifactsRootDir, sessionStateDir, starting, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
package/dist/bridge.mjs CHANGED
@@ -27,6 +27,7 @@ function readReadyContract(projectPath, browser = 'chrome') {
27
27
  schema: 'number' == typeof c.schema ? c.schema : void 0,
28
28
  logsPath: c.logsPath,
29
29
  status: c.status,
30
+ engine: 'string' == typeof c.engine ? c.engine : void 0,
30
31
  pid: 'number' == typeof c.pid ? c.pid : void 0,
31
32
  cdpPort: 'number' == typeof c.cdpPort ? c.cdpPort : void 0,
32
33
  browserExitedAt: 'string' == typeof c.browserExitedAt ? c.browserExitedAt : void 0,
@@ -1,16 +1,18 @@
1
1
  import { type ActionsSink } from './actions-file.js';
2
- import { type AnyFrame, type CommandFrame, type DevReloadKind, type IncomingLogEvent, type ServerFrame } from './contracts.js';
2
+ import { type AnyFrame, type BridgeEngine, type CommandFrame, type DevReloadKind, type IncomingLogEvent, type ServerFrame } from './contracts.js';
3
3
  import type { LogsFileWriter } from './logs-file.js';
4
4
  import { LogRingBuffer } from './ring-buffer.js';
5
5
  export interface BridgeConnection {
6
6
  readonly id: string;
7
+ readonly origin?: string;
7
8
  send(frame: ServerFrame | CommandFrame): void;
8
9
  close(code?: number, reason?: string): void;
9
10
  }
10
11
  export interface BridgeBrokerOptions {
11
12
  instanceId: string;
12
13
  runId: string;
13
- engine?: 'chromium' | 'firefox' | 'webkit';
14
+ engine?: BridgeEngine;
15
+ viewerOrigin?: string | null;
14
16
  ring?: LogRingBuffer;
15
17
  file?: LogsFileWriter;
16
18
  allowControl?: boolean;
@@ -31,6 +33,8 @@ export declare class BridgeBroker {
31
33
  private readonly instanceId;
32
34
  private readonly runId;
33
35
  private readonly engine?;
36
+ private readonly viewerOrigin;
37
+ private viewerEverConnected;
34
38
  private readonly ring;
35
39
  private readonly file?;
36
40
  private readonly roles;
@@ -57,6 +61,7 @@ export declare class BridgeBroker {
57
61
  get consumerCount(): number;
58
62
  get producerCount(): number;
59
63
  get controllerCount(): number;
64
+ get viewerCount(): number;
60
65
  get pendingCount(): number;
61
66
  onFrame(conn: BridgeConnection, frame: AnyFrame): void;
62
67
  onClose(conn: BridgeConnection): void;
@@ -83,5 +88,6 @@ export declare class BridgeBroker {
83
88
  private firstExecutor;
84
89
  private audit;
85
90
  private fanOut;
91
+ private isReloadReceiver;
86
92
  private countRole;
87
93
  }
@@ -10,6 +10,7 @@ export interface ReadyContractInfo {
10
10
  schema?: number;
11
11
  logsPath?: string;
12
12
  status?: string;
13
+ engine?: string;
13
14
  /** Dev-server pid; absent in pre-4.1 contracts. */
14
15
  pid?: number;
15
16
  /** Browser CDP port, stamped post-launch, may lag `status: 'ready'`. */
@@ -33,7 +33,8 @@ export interface LogEvent {
33
33
  export type IncomingLogEvent = Omit<LogEvent, 'seq'> & {
34
34
  seq?: number;
35
35
  };
36
- export type BridgeRole = 'producer' | 'consumer' | 'controller';
36
+ export type BridgeRole = 'producer' | 'consumer' | 'controller' | 'viewer';
37
+ export type BridgeEngine = 'chromium' | 'firefox' | 'webkit' | 'emulator';
37
38
  export interface BridgeTarget {
38
39
  context: 'background' | 'popup' | 'options' | 'sidebar' | 'devtools' | 'content' | 'page';
39
40
  url?: string;
@@ -68,7 +69,7 @@ export interface ReadyFrame {
68
69
  type: 'ready';
69
70
  runId: string;
70
71
  bufferedFrom?: number;
71
- engine?: 'chromium' | 'firefox' | 'webkit';
72
+ engine?: BridgeEngine;
72
73
  capabilities?: {
73
74
  eval?: boolean;
74
75
  storage?: boolean;
@@ -9,6 +9,8 @@ export interface StartControlServerOptions {
9
9
  host?: string;
10
10
  port?: number;
11
11
  path?: string;
12
+ viewerOrigin?: string | null;
12
13
  }
13
14
  export declare function isWebOrigin(origin: string | undefined): boolean;
15
+ export declare function isAdmittedOrigin(origin: string | undefined, viewerOrigin?: string | null): boolean;
14
16
  export declare function startControlServer(options: StartControlServerOptions): Promise<ControlServer>;
@@ -0,0 +1,16 @@
1
+ import type { ReadStream } from 'node:fs';
2
+ import type { IncomingMessage, ServerResponse } from 'node:http';
3
+ export interface OutputFileSystemLike {
4
+ readFileSync?: (filePath: string) => Buffer;
5
+ }
6
+ export interface ActiveCompilerRef {
7
+ outputPath(): string | undefined;
8
+ outputFileSystem(): OutputFileSystemLike | undefined;
9
+ }
10
+ type ResponseData = Buffer | ReadStream;
11
+ interface ModifiedResponseData {
12
+ data: ResponseData;
13
+ byteLength: number;
14
+ }
15
+ export declare function createResponseDataRepair(ref: ActiveCompilerRef): (req: IncomingMessage, res: ServerResponse, data: ResponseData, byteLength: number) => ModifiedResponseData;
16
+ export {};
@@ -0,0 +1,56 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ export declare const EMULATOR_FILES_PATH = "/__extjs-emulator/files.json";
3
+ export declare const EMULATOR_FILES_VERSION: 1;
4
+ export declare const EMULATOR_WIRE_VERSION = "1";
5
+ export declare const DEFAULT_EMULATOR_ORIGIN = "https://browsers.extension.land";
6
+ export interface EmulatorFileEntry {
7
+ path: string;
8
+ size: number;
9
+ sha256: string;
10
+ }
11
+ export interface EmulatorFileIndex {
12
+ version: typeof EMULATOR_FILES_VERSION;
13
+ instanceId: string;
14
+ root: '/';
15
+ livereload?: {
16
+ path: string;
17
+ };
18
+ files: EmulatorFileEntry[];
19
+ }
20
+ export declare function normalizeWebOrigin(value: unknown): string | null;
21
+ export declare function resolveEmulatorOrigin(env?: NodeJS.ProcessEnv): string;
22
+ export declare function isSameWebOrigin(candidate: unknown, expected: string | null | undefined): boolean;
23
+ export declare function buildEmulatorViewerUrl(options: {
24
+ origin: string;
25
+ host: string;
26
+ port: number;
27
+ controlPort: number | null;
28
+ controlPath: string;
29
+ instanceId: string;
30
+ }): string;
31
+ export interface EmulatorAssetLike {
32
+ name: string;
33
+ source: {
34
+ buffer(): Buffer;
35
+ };
36
+ info?: {
37
+ hotModuleReplacement?: boolean;
38
+ related?: Record<string, string | string[] | undefined>;
39
+ };
40
+ }
41
+ export declare function buildEmulatorFileIndex(assets: Iterable<EmulatorAssetLike>, instanceId: string): EmulatorFileIndex;
42
+ export declare function resolveLivereloadPath(webSocketServer: unknown): string | null;
43
+ export interface EmulatorFileIndexHolder {
44
+ publish(assets: Iterable<EmulatorAssetLike>): EmulatorFileIndex;
45
+ reset(): void;
46
+ setLivereloadPath(socketPath: string | null): void;
47
+ current(): Promise<EmulatorFileIndex>;
48
+ }
49
+ export declare function createEmulatorFileIndexHolder(instanceId: string): EmulatorFileIndexHolder;
50
+ export declare function attachEmulatorFileIndex(compiler: unknown, holder: EmulatorFileIndexHolder): void;
51
+ export declare function createEmulatorFilesMiddlewareEntry(holder: EmulatorFileIndexHolder, devServer: unknown): {
52
+ name: string;
53
+ path: string;
54
+ middleware: (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => Promise<void>;
55
+ };
56
+ export declare function createEmulatorFilesMiddleware(holder: EmulatorFileIndexHolder): (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => Promise<void>;
@@ -6,6 +6,7 @@ export declare function browserRunnerDisabled(args: {
6
6
  distPath?: string;
7
7
  }): string;
8
8
  export declare function shouldWarnPortConflict(requested: unknown, actual: number): boolean;
9
+ export declare function emulatorViewerUrl(url: string): string;
9
10
  export declare function portInUse(requestedPort: number, newPort: number): string;
10
11
  export declare function extensionJsRunnerError(error: unknown): string;
11
12
  export declare function autoExitModeEnabled(ms: number): string;