extension-develop 4.1.12 → 4.1.14

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 (111) hide show
  1. package/dist/0~dev-server.mjs +147 -81
  2. package/dist/0~rspack-config.mjs +1098 -694
  3. package/dist/0~zip.mjs +1 -1
  4. package/dist/101.mjs +190 -900
  5. package/dist/129.mjs +89 -0
  6. package/dist/278.mjs +52 -0
  7. package/dist/292.mjs +61 -0
  8. package/dist/372.mjs +87 -0
  9. package/dist/518.mjs +434 -0
  10. package/dist/77.mjs +933 -0
  11. package/dist/80.mjs +6 -4
  12. package/dist/839.mjs +176 -39
  13. package/dist/845.mjs +10 -1
  14. package/dist/887.mjs +1 -1
  15. package/dist/bridge-entry.d.ts +2 -1
  16. package/dist/bridge.mjs +56 -7
  17. package/dist/css-parse-guard-loader.mjs +3 -0
  18. package/dist/dead-css-url-loader.mjs +51 -24
  19. package/dist/dev-server/cleanup.d.ts +2 -1
  20. package/dist/dev-server/control-bridge/broker.d.ts +1 -0
  21. package/dist/dev-server/control-bridge/contracts.d.ts +2 -0
  22. package/dist/dev-server/control-bridge/logs-query.d.ts +12 -1
  23. package/dist/dev-server/control-bridge/producer-runtime.d.ts +1 -1
  24. package/dist/dev-server/messages.d.ts +8 -0
  25. package/dist/dev-server/session-restart.d.ts +29 -0
  26. package/dist/ensure-hmr-for-scripts.js +37 -20
  27. package/dist/ensure-hmr-for-scripts.mjs +37 -20
  28. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  29. package/dist/extension-js-devtools/chrome/scripts/logger-client.js +1 -1
  30. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  31. package/dist/extension-js-devtools/chromium/scripts/logger-client.js +1 -1
  32. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  33. package/dist/extension-js-devtools/edge/scripts/logger-client.js +1 -1
  34. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  35. package/dist/extension-js-devtools/firefox/scripts/logger-client.js +1 -1
  36. package/dist/feature-scripts-classic-concat-loader.js +58 -5
  37. package/dist/feature-scripts-classic-concat-loader.mjs +58 -5
  38. package/dist/feature-scripts-content-script-wrapper.js +14 -17
  39. package/dist/feature-scripts-content-script-wrapper.mjs +14 -17
  40. package/dist/feature-scripts-native-geturl-import-loader.mjs +10 -3
  41. package/dist/lib/asset-source-maps.d.ts +7 -0
  42. package/dist/lib/config-loader.d.ts +7 -34
  43. package/dist/lib/loader-source-maps.d.ts +17 -0
  44. package/dist/lib/messages.d.ts +1 -0
  45. package/dist/lib/msg-placeholders.d.ts +2 -0
  46. package/dist/lib/paths.d.ts +2 -0
  47. package/dist/lib/project.d.ts +3 -0
  48. package/dist/lib/session-project-root.d.ts +1 -0
  49. package/dist/minimum-script-file.js +41 -1
  50. package/dist/minimum-script-file.mjs +41 -1
  51. package/dist/module.d.ts +1 -1
  52. package/dist/module.mjs +1 -1
  53. package/dist/plugin-css/css-lib/dead-url-refs.d.ts +5 -0
  54. package/dist/plugin-css/css-lib/inline-content-script-css.d.ts +32 -0
  55. package/dist/plugin-css/css-lib/messages.d.ts +3 -0
  56. package/dist/plugin-css/css-lib/verbatim-css.d.ts +9 -0
  57. package/dist/plugin-css/css-parse-guard-loader.d.ts +3 -0
  58. package/dist/plugin-css/css-tools/postcss.d.ts +1 -0
  59. package/dist/plugin-css/dead-css-url-loader.d.ts +8 -4
  60. package/dist/plugin-css/index.d.ts +1 -0
  61. package/dist/plugin-js-frameworks/js-frameworks-lib/jsx-transform.d.ts +10 -0
  62. package/dist/plugin-js-frameworks/js-tools/solid-jsx-runtime.d.ts +8 -0
  63. package/dist/plugin-js-frameworks/js-tools/solid.d.ts +3 -0
  64. package/dist/plugin-js-frameworks/swc-targets.d.ts +3 -0
  65. package/dist/plugin-reload/classify-reload.d.ts +6 -0
  66. package/dist/plugin-reload/index.d.ts +2 -1
  67. package/dist/plugin-reload/reload-dispatch.d.ts +1 -0
  68. package/dist/plugin-special-folders/folder-extensions/resolve-dirs.d.ts +1 -0
  69. package/dist/plugin-special-folders/folder-extensions/utils.d.ts +3 -0
  70. package/dist/plugin-special-folders/messages.d.ts +2 -0
  71. package/dist/plugin-special-folders/resolve-public-folder.d.ts +13 -0
  72. package/dist/plugin-web-extension/feature-html/html-lib/assets.d.ts +1 -1
  73. package/dist/plugin-web-extension/feature-html/html-lib/base-href.d.ts +11 -0
  74. package/dist/plugin-web-extension/feature-html/html-lib/patch-html.d.ts +2 -2
  75. package/dist/plugin-web-extension/feature-html/html-lib/utils.d.ts +13 -0
  76. package/dist/plugin-web-extension/feature-html/index.d.ts +1 -0
  77. package/dist/plugin-web-extension/feature-html/steps/ensure-hmr-for-scripts.d.ts +1 -1
  78. package/dist/plugin-web-extension/feature-icons/extract-action-theme-icons.d.ts +2 -0
  79. package/dist/plugin-web-extension/feature-icons/omnibox-fields.d.ts +2 -0
  80. package/dist/plugin-web-extension/feature-icons/theme-image-fields.d.ts +2 -0
  81. package/dist/plugin-web-extension/feature-json/json-validation.d.ts +1 -0
  82. package/dist/plugin-web-extension/feature-manifest/index.d.ts +1 -0
  83. package/dist/plugin-web-extension/feature-manifest/manifest-lib/manifest.d.ts +1 -1
  84. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/index.d.ts +1 -1
  85. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/sandbox.d.ts +1 -1
  86. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/storage.d.ts +1 -1
  87. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/theme.d.ts +1 -1
  88. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/index.d.ts +1 -1
  89. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/mv2/chrome_settings_overrides.d.ts +1 -1
  90. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/mv2/index.d.ts +1 -1
  91. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/mv2/theme_experiment.d.ts +1 -1
  92. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/mv3/action.d.ts +2 -1
  93. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/mv3/declarative_net_request.d.ts +1 -1
  94. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/mv3/index.d.ts +1 -1
  95. package/dist/plugin-web-extension/feature-manifest/messages.d.ts +2 -0
  96. package/dist/plugin-web-extension/feature-manifest/normalize-manifest-path.d.ts +4 -0
  97. package/dist/plugin-web-extension/feature-manifest/steps/apply-dev-defaults-lib/patch-csp.d.ts +1 -1
  98. package/dist/plugin-web-extension/feature-manifest/steps/apply-dev-defaults.d.ts +1 -0
  99. package/dist/plugin-web-extension/feature-scripts/steps/native-geturl-import-loader.d.ts +7 -2
  100. package/dist/plugin-web-extension/feature-web-resources/collect-entry-imports.d.ts +1 -0
  101. package/dist/plugin-web-extension/index.d.ts +1 -0
  102. package/dist/plugin-web-extension/shared/html-surfaces.d.ts +19 -0
  103. package/dist/plugin-web-extension/shared/manifest-fields-change-detector.d.ts +1 -0
  104. package/dist/plugin-web-extension/shared/manifest-fields.d.ts +18 -0
  105. package/dist/plugin-web-extension/shared/manifest-path-assets.d.ts +4 -0
  106. package/dist/plugin-web-extension/shared/paths.d.ts +1 -0
  107. package/dist/solid-jsx-runtime.mjs +15 -0
  108. package/dist/types.d.ts +20 -7
  109. package/package.json +1 -1
  110. package/dist/494.mjs +0 -89
  111. package/dist/86.mjs +0 -36
package/dist/101.mjs CHANGED
@@ -2,16 +2,16 @@ import { createRequire as __extjsCreateRequire } from "node:module"; const requi
2
2
  import { createRequire } from "node:module";
3
3
  import { pathToFileURL } from "node:url";
4
4
  import dotenv from "dotenv";
5
- import pintor from "pintor";
6
5
  import { createHash } from "node:crypto";
7
6
  import { fetchExtensionFromStore } from "extension-from-store";
8
7
  import node_fs from "node:fs";
9
8
  import node_path from "node:path";
10
9
  import { getSpecialFoldersData } from "browser-extension-manifest-fields";
11
- import { humanWarn, browserRowValue, artifactNoun, prefix as messaging_prefix, card, humanLine, fmt, isDebug } from "./349.mjs";
12
- import { findNearestDenoConfigSync, validateDenoConfig, PROJECT_MANIFEST_FILENAMES, readProjectDependencies } from "./80.mjs";
10
+ import pintor from "pintor";
11
+ import { devtoolsEngineFor, managedDependencyConflict, resolveProjectStructureSync, getDirs, computePreviewOutputPath, eventsPath as session_paths_eventsPath, anotherDevSessionActive, previewingSourceFallback, asAbsolute, previewing, starting, debugPreviewOutput, ensureSessionArtifactsIgnoreFile, debugDirs, debugBrowser, readyContractPath, configLoadingError, normalizeBrowser, previewingCustomOutput, browserArtifactsDir, getProjectStructure, isUsingExperimentalConfig as messages_isUsingExperimentalConfig, getDistPath, configBrowserOrThrow } from "./77.mjs";
12
+ import { humanWarn, isDebug, browserRowValue, artifactNoun, prefix as messaging_prefix, card, humanLine } from "./349.mjs";
13
+ import { readProjectDependencies } from "./80.mjs";
13
14
  import { stripBom, parseJsonSafe } from "./23.mjs";
14
- import { readyContractPath, browserArtifactsDir, eventsPath as session_paths_eventsPath } from "./494.mjs";
15
15
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
16
16
  import { dirname as __rspack_dirname } from "node:path";
17
17
  var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
@@ -59,382 +59,22 @@ function isGeckoBasedBrowser(browser) {
59
59
  function isWebkitBasedBrowser(browser) {
60
60
  return WEBKIT_BASED_BROWSERS.includes(browser) || String(browser).includes('webkit');
61
61
  }
62
- function getLoggingPrefix(type) {
63
- return messaging_prefix(type);
64
- }
65
- function isPathLike(input) {
66
- return input.includes('/') || input.includes('\\') || __rspack_external_node_path_c5b9b54f.isAbsolute(input);
67
- }
68
- function resolvedWorkspaceManifest(projectPath, manifestPath) {
69
- const manifestDir = __rspack_external_node_path_c5b9b54f.dirname(manifestPath);
70
- const packageDir = 'src' === __rspack_external_node_path_c5b9b54f.basename(manifestDir) ? __rspack_external_node_path_c5b9b54f.dirname(manifestDir) : manifestDir;
71
- const display = __rspack_external_node_path_c5b9b54f.relative(projectPath, packageDir) || packageDir;
72
- return `${getLoggingPrefix('info')} ${pintor.gray('Workspace root detected.')}\n${pintor.gray('PACKAGE')} ${pintor.underline(display)}`;
73
- }
74
- function remoteFetchTimedOut(target, ms) {
75
- return `${getLoggingPrefix('error')} Timed out after ${Math.round(ms / 1000)} s fetching the remote file.\n${pintor.gray('URL')} ${pintor.underline(target)}\nCheck your network, or set ${pintor.blue('EXTENSION_FETCH_TIMEOUT_MS')} to allow more time.`;
76
- }
77
- function manifestInvalidJson(manifestPath, error) {
78
- const detail = error instanceof Error ? error.message : String(error);
79
- return `${getLoggingPrefix('error')} Couldn't parse manifest.json as JSON.\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\n${pintor.gray('REASON')} ${pintor.red(detail)}\nFix the syntax error, then run the command again.`;
80
- }
81
- function notAnExtensionManifestError(manifestPath) {
82
- return `${getLoggingPrefix('error')} manifest.json isn't a browser extension manifest.\nIt has no ${pintor.blue('manifest_version')} field, so it looks like a PWA web-app manifest.\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\nPoint Extension.js at the directory that contains your extension manifest.`;
83
- }
84
- function manifestNotFoundError(manifestPath, candidates = []) {
85
- const base = `${getLoggingPrefix('error')} Manifest file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(manifestPath)}\nEnsure the path to your extension exists, then try again.`;
86
- if (!candidates.length) return base;
87
- const projectRoot = __rspack_external_node_path_c5b9b54f.dirname(manifestPath);
88
- const hint = 1 === candidates.length ? "Did you mean to point at this workspace package?" : "Did you mean to point at one of these workspace packages?";
89
- const suggestions = candidates.map((candidate)=>{
90
- const dir = 'manifest.json' === __rspack_external_node_path_c5b9b54f.basename(candidate) ? __rspack_external_node_path_c5b9b54f.dirname(candidate) : candidate;
91
- const normalized = 'src' === __rspack_external_node_path_c5b9b54f.basename(dir) ? __rspack_external_node_path_c5b9b54f.dirname(dir) : dir;
92
- const display = __rspack_external_node_path_c5b9b54f.isAbsolute(normalized) ? __rspack_external_node_path_c5b9b54f.relative(projectRoot, normalized) || normalized : normalized;
93
- return ` extension dev ${display}`;
94
- }).join('\n');
95
- return `${base}\n\n${pintor.gray(hint)}\n${pintor.blue(suggestions)}`;
96
- }
97
- function previewingSourceFallback(browser, distDir) {
98
- return `${getLoggingPrefix('warn')} No production build found at ${distDir}, previewing the source manifest directory instead.\nRun \`extension build --browser ${String(browser)}\` first to preview the built output.`;
99
- }
100
- function previewing(browser, noBrowser) {
101
- const suffix = noBrowser ? ' (no-browser mode)' : '';
102
- return `${getLoggingPrefix('info')} Previewing on ${capitalizedBrowserName(browser)}${suffix}.`;
103
- }
104
- function starting(browser, noBrowser) {
105
- const suffix = noBrowser ? ' (no-browser mode)' : '';
106
- return `${getLoggingPrefix('info')} Starting on ${capitalizedBrowserName(browser)}${suffix}.`;
107
- }
108
- function extensionLoadRecovered() {
109
- return `${getLoggingPrefix('success')} The browser accepted the extension.\nIt's running now.`;
110
- }
111
- function extensionLoadStillRefused(reason) {
112
- return `${getLoggingPrefix('error')} The browser still refuses to load this extension.\n${pintor.gray('REASON')} ${pintor.red(reason)}`;
113
- }
114
- function browserLaunchFailed(browser, reason) {
115
- return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} couldn't start, so the extension isn't running.\n${reason}\nThe dev server keeps watching, but nothing will load until this is fixed.`;
116
- }
117
- function authorInstallNotice(target) {
118
- return `${messaging_prefix('debug')} install target=${target}`;
119
- }
120
- function projectInstallFallbackToNpm(pmName) {
121
- return `${getLoggingPrefix('warn')} Dependency install with ${pmName} failed.\nExtension.js retries once with npm so the build can continue.`;
122
- }
123
- function projectInstallScriptsDisabled(pmName) {
124
- return `${getLoggingPrefix('info')} Installing the project dependencies with ${pmName}…\nLifecycle scripts are disabled for safety.\nSet ${pintor.blue('EXTENSION_ALLOW_INSTALL_SCRIPTS=true')} to run them.`;
125
- }
126
- function anotherDevSessionActive(browser, pid, runId) {
127
- const run = runId ? `, run ${runId}` : '';
128
- return `${getLoggingPrefix('warn')} Another dev session is already writing dist/${browser} (PID ${pid}${run}).\nBoth sessions rebuild the same output, so the last compile wins.\nStop the other session, or pass ${fmt.code('--instance-id')} to run them side by side.`;
129
- }
130
- function buildAssetsTree(stats) {
131
- const statsJson = stats?.toJson?.({
132
- all: false,
133
- assets: true
134
- });
135
- const assets = statsJson?.assets || [];
136
- return getAssetsTree(assets);
137
- }
138
- function buildComplete(browser, distDisplayPath, totalBytes) {
139
- const noun = artifactNoun(String(browser));
140
- const size = 'number' == typeof totalBytes && totalBytes > 0 ? ` (${getHumanSize(totalBytes)})` : '';
141
- return `${getLoggingPrefix('success')} ${noun} built for production in ${pintor.underline(distDisplayPath)}${size}.`;
142
- }
143
- function platformDocsUrl() {
144
- return String(process.env.EXTENSION_DEV_DOCS_URL || '').trim().replace(/\/+$/, '');
145
- }
146
- function buildShareHint() {
147
- const docs = platformDocsUrl();
148
- if (!docs) return '';
149
- return `${getLoggingPrefix('info')} Send this build to someone for review: ` + pintor.underline(`${docs}/share/unpublished-build-for-review?utm_source=cli-build`);
150
- }
151
- function buildFailed(errorCount) {
152
- const count = Math.max(1, Math.floor(errorCount || 1));
153
- const noun = 1 === count ? 'error' : 'errors';
154
- return `${getLoggingPrefix('error')} Build failed with ${count} ${noun}.`;
155
- }
156
- function stripModuleWarningWrapper(message) {
157
- return message.replace(/^Module (?:Warning|Error) \(from [^)]*\):\s*/, '');
158
- }
159
- function getWarningMessage(warning) {
160
- if (!warning) return '';
161
- if ('string' == typeof warning) return stripModuleWarningWrapper(warning.trim());
162
- const candidates = [
163
- warning.message,
164
- warning.details,
165
- warning.reason,
166
- warning.description
167
- ];
168
- for (const candidate of candidates)if ('string' == typeof candidate && candidate.trim()) return stripModuleWarningWrapper(candidate.trim());
169
- return '';
170
- }
171
- function getWarningSource(warning) {
172
- if (!warning || 'string' == typeof warning) return 'bundler';
173
- const candidates = [
174
- warning.name,
175
- warning.moduleName,
176
- warning.moduleIdentifier,
177
- warning.originName,
178
- warning.pluginName
179
- ];
180
- for (const candidate of candidates)if ('string' == typeof candidate && candidate.trim()) return candidate.trim();
181
- return 'bundler';
182
- }
183
- function getWarningArtifact(warning) {
184
- if (!warning || 'string' == typeof warning) return '';
185
- const candidates = [
186
- warning.file,
187
- warning.chunkName,
188
- warning.moduleName
189
- ];
190
- for (const candidate of candidates)if ('string' == typeof candidate && candidate.trim()) return candidate.trim();
191
- return '';
192
- }
193
- function classifyWarning(message, source) {
194
- const haystack = `${message} ${source}`.toLowerCase();
195
- if (haystack.includes('performance') || haystack.includes('asset size') || haystack.includes('entrypoint size') || haystack.includes('exceeds the recommended size') || haystack.includes('hints')) return 'Performance';
196
- if (haystack.includes('deprecat') || haystack.includes('[dep_') || haystack.includes('legacy')) return 'Deprecation';
197
- if (haystack.includes('invalid') || haystack.includes('unknown option') || haystack.includes('configuration') || haystack.includes('schema')) return 'Configuration';
198
- if (haystack.includes('manifest') || haystack.includes('browser') || haystack.includes('target')) return 'Compatibility';
199
- if (haystack.includes('runtime') || haystack.includes('will fail') || haystack.includes('cannot resolve') || haystack.includes('service_worker')) return 'Runtime-risk';
200
- return 'Warning';
201
- }
202
- function suggestedHintForWarning(category) {
203
- if ('Performance' === category) return 'Inspect the largest startup bundles and split optional code paths.';
204
- if ('Deprecation' === category) return 'Move to the supported API or plugin path before the next update.';
205
- if ('Configuration' === category) return 'Review extension and bundler config keys, then remove or rename invalid options.';
206
- if ('Compatibility' === category) return 'Verify browser target and manifest compatibility for this build.';
207
- if ('Runtime-risk' === category) return 'Address this before release. It may fail or degrade at runtime.';
208
- return 'Re-run with EXTENSION_VERBOSE=1 to inspect full warning details.';
209
- }
210
- function buildWarningsDetails(warnings) {
211
- if (!Array.isArray(warnings) || 0 === warnings.length) return '';
212
- const blocks = [];
213
- warnings.forEach((warning, index)=>{
214
- const message = getWarningMessage(warning);
215
- const source = getWarningSource(warning);
216
- const artifact = getWarningArtifact(warning);
217
- const category = classifyWarning(message, source);
218
- const hint = suggestedHintForWarning(category);
219
- if (!message) return void blocks.push(`${getLoggingPrefix('warn')} Warning ${index + 1}: details were suppressed by tool output.\n${formatWarningLabelLine('Source', pintor.gray(source))}\n${formatWarningLabelLine('Hint', 'Re-run with EXTENSION_VERBOSE=1 to inspect full warning messages.')}`);
220
- const performanceWarning = parsePerformanceWarning(warning, source, artifact);
221
- if (performanceWarning) return void blocks.push(performanceWarning);
222
- const oneLine = message.replace(/\s+/g, ' ').trim();
223
- const artifactSuffix = artifact ? ` ${pintor.gray(`(${artifact})`)}` : '';
224
- blocks.push(`${getLoggingPrefix('warn')} ${category}: ${oneLine}${artifactSuffix}\n${formatWarningLabelLine('Source', pintor.gray(source))}\n${formatWarningLabelLine('Hint', hint)}`);
225
- });
226
- return blocks.join('\n\n');
227
- }
228
- function fetchingProjectPath(owner, project) {
229
- return fmt.block('Fetching project', [
230
- [
231
- 'URL',
232
- fmt.val(`https://github.com/${owner}/${project}`)
233
- ]
234
- ]);
235
- }
236
- function downloadingProjectPath(projectName) {
237
- const formatted = isPathLike(projectName) ? pintor.underline(projectName) : projectName;
238
- return `${getLoggingPrefix('info')} Downloading ${formatted}…`;
239
- }
240
- function creatingProjectPath(projectPath) {
241
- return `${getLoggingPrefix('info')} Creating a new browser extension…\n${pintor.gray('PATH')} ${pintor.underline(projectPath)}`;
242
- }
243
- function downloadedProjectFolderNotFound(cwd, candidates) {
244
- return `${getLoggingPrefix('error')} Downloaded project folder not found.\n${pintor.gray('PATH')} ${pintor.underline(cwd)}\n${pintor.gray('NOT FOUND')} ${pintor.underline(candidates.join(', '))}`;
245
- }
246
- function packagingSourceFiles(zipPath) {
247
- return `${messaging_prefix('debug')} zip pack=source gitignore=excluded path=${zipPath}`;
248
- }
249
- function zipArtifactReady(zipPath, sizeInBytes) {
250
- return `${getLoggingPrefix('success')} Packaged ${pintor.underline(zipPath)} (${getHumanSize(sizeInBytes)}).`;
251
- }
252
- function packagingDistributionFiles(zipPath) {
253
- return `${messaging_prefix('debug')} zip pack=dist path=${zipPath}`;
254
- }
255
- function treeWithSourceAndDistFiles(browser, name, sourceZip, destZip) {
256
- return `${messaging_prefix('debug')} zip name=${name} browser=${String(browser)} source=${sourceZip} dist=${destZip}`;
257
- }
258
- function treeWithDistFilesBrowser(name, ext, browser, zipPath) {
259
- return `${messaging_prefix('debug')} zip name=${name}.${ext} browser=${String(browser)} dist=${zipPath}`;
260
- }
261
- function treeWithSourceFiles(name, ext, browser, zipPath) {
262
- return `${messaging_prefix('debug')} zip name=${name}-source.${ext} browser=${String(browser)} source=${zipPath}`;
263
- }
264
- function writingTypeDefinitions(manifest) {
265
- return `${getLoggingPrefix('info')} Writing the type definitions for ${manifest.name || 'the extension'}…`;
266
- }
267
- function writingTypeDefinitionsError(error) {
268
- return `${getLoggingPrefix('error')} Couldn't write the extension type definitions.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck the file permissions, then try again.`;
269
- }
270
- function downloadingText(url) {
271
- return fmt.block('Downloading extension', [
272
- [
273
- 'URL',
274
- fmt.val(url)
275
- ]
276
- ]);
277
- }
278
- function unpackagingExtension(zipFilePath) {
279
- return `${getLoggingPrefix('info')} Unpackaging the browser extension…\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
280
- }
281
- function unpackagedSuccessfully() {
282
- return `${getLoggingPrefix('success')} Extension unpackaged.`;
283
- }
284
- function failedToDownloadOrExtractZIPFileError(error) {
285
- return `${getLoggingPrefix('error')} Couldn't download or extract the ZIP file.\n${pintor.gray('REASON')} ${pintor.red(String(error))}\nCheck the URL and your network, then try again.`;
286
- }
287
- function invalidRemoteZip(url, contentType) {
288
- return `${getLoggingPrefix('error')} The remote URL doesn't point to a ZIP archive.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('GOT')} ${pintor.underline(contentType || 'unknown')}\nUse a direct-download URL, or download the file and pass the local path.`;
289
- }
290
- function notAZipArchive(source, contentType) {
291
- return `${getLoggingPrefix('error')} The downloaded content isn't a ZIP archive.\n${pintor.gray('SOURCE')} ${pintor.underline(source)}\n` + (contentType ? `${pintor.gray('GOT')} ${pintor.underline(contentType)}\n` : '') + `The URL likely requires authentication and returned an HTML login page instead of the file.\n` + `This happens with Slack, Google Drive, and Dropbox file pages.\n` + "Download the ZIP in the browser and pass the local path, or use a direct-download URL.";
292
- }
293
- function localZipNotFound(zipFilePath) {
294
- return `${getLoggingPrefix('error')} ZIP file not found.\n${pintor.gray('NOT FOUND')} ${pintor.underline(zipFilePath)}\nCheck the path, then try again.`;
295
- }
296
- function capitalizedBrowserName(browser) {
297
- const b = String(browser || '');
298
- const cap = b.charAt(0).toUpperCase() + b.slice(1);
299
- return pintor.yellow(`${cap}`);
300
- }
301
- function getFileSize(fileSizeInBytes) {
302
- return `${(fileSizeInBytes / 1024).toFixed(2)}KB`;
303
- }
304
- function getHumanSize(sizeInBytes) {
305
- const bytes = Math.max(0, sizeInBytes || 0);
306
- if (bytes < 1024) return `${bytes} B`;
307
- if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
308
- return `${(bytes / 1048576).toFixed(1)} MB`;
309
- }
310
- function printTree(node, prefix = '') {
311
- let output = '';
312
- Object.keys(node).forEach((key, index, array)=>{
313
- const isLast = index === array.length - 1;
314
- const connector = isLast ? '└─' : '├─';
315
- const child = node[key];
316
- const childNode = child && 'object' == typeof child ? child : void 0;
317
- const isLeaf = 'number' == typeof childNode?.size;
318
- const sizeInKB = isLeaf ? ` (${getFileSize(childNode?.size ?? 0)})` : '';
319
- output += `${pintor.gray(prefix)}${pintor.gray(connector)} ${key}${pintor.gray(sizeInKB)}\n`;
320
- if (childNode && !isLeaf) output += printTree(childNode, `${prefix}${isLast ? ' ' : pintor.gray('│ ')}`);
321
- });
322
- return output;
323
- }
324
- function getAssetsTree(assets) {
325
- const assetTree = {};
326
- assets?.forEach((asset)=>{
327
- if ('string' != typeof asset?.name) return;
328
- const paths = asset.name.split('/');
329
- let currentLevel = assetTree;
330
- paths.forEach((part, index)=>{
331
- if (!currentLevel[part]) currentLevel[part] = {};
332
- if (index === paths.length - 1) currentLevel[part] = {
333
- size: asset.size
334
- };
335
- else currentLevel = currentLevel[part];
336
- });
337
- });
338
- if (0 === Object.keys(assetTree).length) return '';
339
- return `.\n${printTree(assetTree)}`;
340
- }
341
- function formatWarningLabelLine(label, value) {
342
- return `${pintor.gray('│')} ${pintor.gray(`${label}:`)} ${value}`;
343
- }
344
- function parsePerformanceWarning(warning, source, _artifact) {
345
- const normalized = getWarningBody(warning).replace(/\r/g, '');
346
- const lower = normalized.toLowerCase();
347
- const threshold = normalized.match(/\(([\d.]+\s(?:KiB|MiB|GiB|KB|MB|GB))\)/)?.[1] || '';
348
- if (lower.includes('asset size limit')) return formatPerformanceWarningBlock({
349
- title: 'asset size limit exceeded',
350
- threshold,
351
- impact: 'Large emitted files can increase package size and slow extension startup.',
352
- source,
353
- hint: 'Inspect the largest startup bundles and split optional code paths.'
354
- });
355
- if (lower.includes('entrypoint size limit')) return formatPerformanceWarningBlock({
356
- title: 'entrypoint size limit exceeded',
357
- threshold,
358
- impact: 'Startup entrypoints are heavier than recommended.',
359
- source,
360
- hint: 'Keep startup entrypoints thin and defer non-critical code.'
361
- });
362
- }
363
- function formatPerformanceWarningBlock(options) {
364
- const lines = [
365
- `${getLoggingPrefix('warn')} Performance: ${options.title}`
366
- ];
367
- if (options.threshold) lines.push(formatWarningLabelLine('Threshold', options.threshold));
368
- lines.push(formatWarningLabelLine('Impact', options.impact));
369
- lines.push(pintor.gray('│'));
370
- lines.push(formatWarningLabelLine('Source', pintor.gray(options.source)));
371
- lines.push(formatWarningLabelLine('Hint', options.hint));
372
- return lines.join('\n');
373
- }
374
- function getWarningBody(warning) {
375
- if (!warning) return '';
376
- if ('string' == typeof warning) return warning;
377
- return [
378
- warning.message,
379
- warning.details,
380
- warning.reason,
381
- warning.description
382
- ].filter((value)=>'string' == typeof value && value.trim().length > 0).join('\n');
383
- }
384
- function isUsingExperimentalConfig(integration) {
385
- return `${messaging_prefix('debug')} config using=${String(integration)}`;
386
- }
387
- function debugDirs(manifestDir, packageJsonDir) {
388
- return `${messaging_prefix('debug')} dirs manifest=${manifestDir} pkg=${packageJsonDir}`;
389
- }
390
- function debugBrowser(browser, chromiumBinary, geckoBinary) {
391
- return `${messaging_prefix('debug')} browser target=${String(browser)} chromiumBinary=${String(chromiumBinary || 'auto')} geckoBinary=${String(geckoBinary || 'auto')}`;
392
- }
393
- function debugOutputPath(pathValue) {
394
- return `${messaging_prefix('debug')} output path=${pathValue}`;
395
- }
396
- function debugPreviewOutput(outputPath, distPath) {
397
- return `${messaging_prefix('debug')} preview output=${outputPath} dist=${distPath}`;
398
- }
399
- function debugContextPath(packageJsonDir) {
400
- return `${messaging_prefix('debug')} context path=${packageJsonDir}`;
401
- }
402
- function debugExtensionsToLoad(extensions) {
403
- return `${messaging_prefix('debug')} extensions count=${extensions.length} paths=${extensions.join(',')}`;
404
- }
405
- function noCompanionExtensionsResolved() {
406
- return `${getLoggingPrefix('warn')} No companion extensions resolved from the ${pintor.blue('extensions')} config.\nPoint each entry at an unpacked extension directory that contains a manifest.json, for example ./extensions/<name>/manifest.json.`;
407
- }
408
- function configLoadingError(configPath, error) {
409
- return `${getLoggingPrefix('error')} Couldn't load ${pintor.blue('extension.config.js')}.\n${fmt.label('PATH')} ${fmt.val(configPath)}\n${pintor.red(fmt.truncate(error, 1200))}\nFix the config file, then run the command again.`;
410
- }
411
- function buildCommandFailed(error) {
412
- const message = (()=>{
413
- if (error instanceof Error && error.message) return error.message;
414
- return String(error || 'Unknown error');
415
- })();
416
- if (message.includes(getLoggingPrefix('error'))) return message;
417
- return `${getLoggingPrefix('error')} ${pintor.red(fmt.truncate(message, 1200))}`;
418
- }
419
- function devCommandFailed(error) {
420
- const message = (()=>{
421
- if (error instanceof Error && error.message) return error.message;
422
- return String(error || 'Unknown error');
423
- })();
424
- return `${getLoggingPrefix('error')} Dev mode failed.\n${pintor.red(fmt.truncate(message, 1200))}`;
425
- }
426
- function managedDependencyConflict(duplicates, userPackageJsonPath) {
427
- const list = duplicates.map((d)=>`- ${pintor.yellow(d)}`).join('\n');
428
- return `${getLoggingPrefix('error')} Your project declares dependencies that Extension.js already manages, so the build was aborted.\n${pintor.red('Duplicate declarations can cause version conflicts and break the build.')}\n\n${pintor.gray('Remove these from your package.json:')}\n${list}\n\n${pintor.gray('PATH')} ${pintor.underline(userPackageJsonPath)}\nIf you need a different version, open an issue so we can consider bundling it safely.`;
429
- }
430
62
  const preloadedEnvKeys = new Set();
431
63
  function getPreloadedEnvKeys() {
432
64
  return preloadedEnvKeys;
433
65
  }
434
- function recordPreloadedKeys(filePath) {
435
- try {
436
- for (const key of Object.keys(dotenv.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(filePath))))if (!(key in process.env)) preloadedEnvKeys.add(key);
437
- } catch {}
66
+ const ENV_PRELOAD_ORDER = [
67
+ '.env.defaults',
68
+ '.env',
69
+ '.env.local',
70
+ '.env.development'
71
+ ];
72
+ function applyEnvFile(filePath, shellOwned) {
73
+ const parsed = dotenv.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(filePath));
74
+ for (const [key, value] of Object.entries(parsed))if (!shellOwned.has(key)) {
75
+ process.env[key] = value;
76
+ preloadedEnvKeys.add(key);
77
+ }
438
78
  }
439
79
  function loadCommonJsConfigWithStableDirname(absolutePath) {
440
80
  const code = __rspack_external_node_fs_5ea92f0c.readFileSync(absolutePath, 'utf-8');
@@ -460,51 +100,51 @@ function findNearestWorkspaceRoot(startDir) {
460
100
  current = parent;
461
101
  }
462
102
  }
463
- function preloadEnvFilesFromDir(envDir, options) {
103
+ function preloadEnvFilesFromDir(envDir) {
464
104
  let loadedAny = false;
465
- try {
466
- const defaultsPath = __rspack_external_node_path_c5b9b54f.join(envDir, '.env.defaults');
467
- if (__rspack_external_node_fs_5ea92f0c.existsSync(defaultsPath)) {
468
- recordPreloadedKeys(defaultsPath);
469
- dotenv.config({
470
- path: defaultsPath,
471
- override: Boolean(options?.override),
472
- quiet: true
473
- });
105
+ const shellOwned = new Set(Object.keys(process.env).filter((key)=>!preloadedEnvKeys.has(key)));
106
+ for (const filename of ENV_PRELOAD_ORDER){
107
+ const filePath = __rspack_external_node_path_c5b9b54f.join(envDir, filename);
108
+ if (__rspack_external_node_fs_5ea92f0c.existsSync(filePath)) try {
109
+ applyEnvFile(filePath, shellOwned);
474
110
  loadedAny = true;
475
- }
476
- const envCandidates = [
477
- '.env.development',
478
- '.env.local',
479
- '.env'
480
- ];
481
- for (const filename of envCandidates){
482
- const filePath = __rspack_external_node_path_c5b9b54f.join(envDir, filename);
483
- if (__rspack_external_node_fs_5ea92f0c.existsSync(filePath)) {
484
- recordPreloadedKeys(filePath);
485
- dotenv.config({
486
- path: filePath,
487
- override: Boolean(options?.override),
488
- quiet: true
489
- });
490
- loadedAny = true;
491
- break;
492
- }
493
- }
494
- } catch {}
111
+ } catch {}
112
+ }
495
113
  return {
496
114
  loadedAny,
497
115
  envDir
498
116
  };
499
117
  }
500
- function findConfigFile(projectPath) {
118
+ function findConfigFileIn(dir) {
501
119
  const candidates = [
502
- __rspack_external_node_path_c5b9b54f.join(projectPath, 'extension.config.js'),
503
- __rspack_external_node_path_c5b9b54f.join(projectPath, 'extension.config.mjs'),
504
- __rspack_external_node_path_c5b9b54f.join(projectPath, 'extension.config.cjs')
120
+ __rspack_external_node_path_c5b9b54f.join(dir, 'extension.config.js'),
121
+ __rspack_external_node_path_c5b9b54f.join(dir, 'extension.config.mjs'),
122
+ __rspack_external_node_path_c5b9b54f.join(dir, 'extension.config.cjs')
505
123
  ];
506
124
  return candidates.find((p)=>__rspack_external_node_fs_5ea92f0c.existsSync(p));
507
125
  }
126
+ function resolveManifestDir(projectPath) {
127
+ try {
128
+ if (!__rspack_external_node_fs_5ea92f0c.statSync(projectPath).isDirectory()) return;
129
+ } catch {
130
+ return;
131
+ }
132
+ try {
133
+ const structure = resolveProjectStructureSync(projectPath, {
134
+ quiet: true
135
+ });
136
+ return __rspack_external_node_path_c5b9b54f.dirname(structure.manifestPath);
137
+ } catch {
138
+ return;
139
+ }
140
+ }
141
+ function findConfigFile(projectPath) {
142
+ const atRoot = findConfigFileIn(projectPath);
143
+ if (atRoot) return atRoot;
144
+ const manifestDir = resolveManifestDir(projectPath);
145
+ if (!manifestDir || __rspack_external_node_path_c5b9b54f.resolve(manifestDir) === __rspack_external_node_path_c5b9b54f.resolve(projectPath)) return;
146
+ return findConfigFileIn(manifestDir);
147
+ }
508
148
  function preloadEnvFiles(projectDir) {
509
149
  const local = preloadEnvFilesFromDir(projectDir);
510
150
  if (local.loadedAny) return local;
@@ -607,7 +247,7 @@ async function loadConfigFileUncached(absolutePath) {
607
247
  async function loadCustomConfig(projectPath) {
608
248
  const configPath = findConfigFile(projectPath);
609
249
  if (configPath) {
610
- if (await config_loader_isUsingExperimentalConfig(projectPath)) try {
250
+ if (await isUsingExperimentalConfig(projectPath)) try {
611
251
  const userConfig = await loadConfigFile(configPath);
612
252
  if (userConfig && 'function' == typeof userConfig.config) return userConfig.config;
613
253
  if (userConfig?.config && 'object' == typeof userConfig.config) {
@@ -626,27 +266,21 @@ async function loadCustomConfig(projectPath) {
626
266
  }
627
267
  return (config)=>config;
628
268
  }
629
- async function loadCommandConfig(projectPath, command) {
269
+ async function loadProjectConfigDefaults(projectPath) {
630
270
  const configPath = findConfigFile(projectPath);
631
271
  if (configPath) {
632
- if (await config_loader_isUsingExperimentalConfig(projectPath)) try {
272
+ if (await isUsingExperimentalConfig(projectPath)) try {
633
273
  const userConfig = await loadConfigFile(configPath);
634
- const configExtras = userConfig;
635
- const baseExtensions = configExtras && configExtras.extensions ? {
636
- extensions: configExtras.extensions
637
- } : {};
638
- const baseTranspilePackages = configExtras && Array.isArray(configExtras.transpilePackages) ? {
639
- transpilePackages: configExtras.transpilePackages
640
- } : {};
641
- const basePerfBudgets = configExtras && configExtras.perfBudgets && 'object' == typeof configExtras.perfBudgets ? {
642
- perfBudgets: configExtras.perfBudgets
643
- } : {};
644
- const perCommand = userConfig?.commands?.[command] ? userConfig.commands[command] : {};
645
274
  return {
646
- ...baseExtensions,
647
- ...baseTranspilePackages,
648
- ...basePerfBudgets,
649
- ...perCommand
275
+ ...userConfig?.extensions ? {
276
+ extensions: userConfig.extensions
277
+ } : {},
278
+ ...Array.isArray(userConfig?.transpilePackages) ? {
279
+ transpilePackages: userConfig.transpilePackages
280
+ } : {},
281
+ ...userConfig?.perfBudgets && 'object' == typeof userConfig.perfBudgets ? {
282
+ perfBudgets: userConfig.perfBudgets
283
+ } : {}
650
284
  };
651
285
  } catch (err) {
652
286
  const error = err;
@@ -656,10 +290,24 @@ async function loadCommandConfig(projectPath, command) {
656
290
  }
657
291
  return {};
658
292
  }
293
+ async function loadCommandConfig(projectPath, command) {
294
+ const configPath = findConfigFile(projectPath);
295
+ if (configPath) {
296
+ if (await isUsingExperimentalConfig(projectPath)) try {
297
+ const userConfig = await loadConfigFile(configPath);
298
+ return userConfig?.commands?.[command] || {};
299
+ } catch (err) {
300
+ const error = err;
301
+ console.error(configLoadingError(configPath, error));
302
+ throw err;
303
+ }
304
+ }
305
+ return {};
306
+ }
659
307
  async function loadBrowserConfig(projectPath, browser = 'chrome') {
660
308
  const configPath = findConfigFile(projectPath);
661
309
  if (configPath) {
662
- if (await config_loader_isUsingExperimentalConfig(projectPath)) try {
310
+ if (await isUsingExperimentalConfig(projectPath)) try {
663
311
  const userConfig = await loadConfigFile(configPath);
664
312
  if (userConfig?.browser) {
665
313
  const browsers = userConfig.browser;
@@ -693,142 +341,18 @@ async function loadBrowserConfig(projectPath, browser = 'chrome') {
693
341
  };
694
342
  }
695
343
  let userMessageDelivered = false;
696
- async function config_loader_isUsingExperimentalConfig(projectPath) {
344
+ async function isUsingExperimentalConfig(projectPath) {
697
345
  const configPath = findConfigFile(projectPath);
698
346
  if (configPath) {
699
347
  if (!userMessageDelivered) {
700
- if (isDebug()) console.log(isUsingExperimentalConfig('extension.config.js'));
348
+ if (isDebug()) console.log(messages_isUsingExperimentalConfig('extension.config.js'));
701
349
  userMessageDelivered = true;
702
350
  }
703
351
  return true;
704
352
  }
705
353
  return false;
706
354
  }
707
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.12","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.3.1","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"}}');
708
- function asAbsolute(p) {
709
- return __rspack_external_node_path_c5b9b54f.isAbsolute(p) ? p : __rspack_external_node_path_c5b9b54f.resolve(p);
710
- }
711
- function toPosixPath(p) {
712
- return p.split(__rspack_external_node_path_c5b9b54f.sep).join('/');
713
- }
714
- function getDirs(struct) {
715
- const manifestDir = asAbsolute(__rspack_external_node_path_c5b9b54f.dirname(struct.manifestPath));
716
- const projectManifestPath = struct.packageJsonPath || struct.denoJsonPath;
717
- const packageJsonDir = asAbsolute(projectManifestPath ? __rspack_external_node_path_c5b9b54f.dirname(projectManifestPath) : manifestDir);
718
- return {
719
- manifestDir,
720
- packageJsonDir
721
- };
722
- }
723
- function getNodeModulesDir(packageJsonDir) {
724
- return asAbsolute(__rspack_external_node_path_c5b9b54f.join(packageJsonDir, 'node_modules'));
725
- }
726
- function needsInstall(packageJsonDir) {
727
- const nm = getNodeModulesDir(packageJsonDir);
728
- const hasManifest = PROJECT_MANIFEST_FILENAMES.some((filename)=>__rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(packageJsonDir, filename)));
729
- if (!hasManifest) return false;
730
- try {
731
- const deps = Object.keys(readProjectDependencies(packageJsonDir));
732
- if (0 === deps.length) return false;
733
- if (!__rspack_external_node_fs_5ea92f0c.existsSync(nm)) return true;
734
- if (__rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(nm, '.pnpm'))) return false;
735
- if (__rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(nm, '.modules.yaml'))) return false;
736
- if (__rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(nm, '.deno'))) return false;
737
- const hasInstalledDep = deps.some((dep)=>__rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(nm, dep)));
738
- return !hasInstalledDep;
739
- } catch {
740
- return true;
741
- }
742
- }
743
- function normalizeBrowser(browser, chromiumBinary, geckoBinary, safariBinary) {
744
- const requested = String(browser || '');
745
- if (chromiumBinary) {
746
- if (!requested || 'chromium-based' === requested) return 'chromium-based';
747
- if ('chromium' === requested) return 'chromium';
748
- if ('edge' === requested) return 'edge';
749
- if ('chrome' === requested) return 'chrome';
750
- }
751
- if (geckoBinary) {
752
- if (!requested || 'gecko-based' === requested || 'firefox-based' === requested) return 'gecko-based';
753
- if ('firefox' === requested) return 'firefox';
754
- }
755
- if (safariBinary) {
756
- if (!requested || 'webkit-based' === requested) return 'webkit-based';
757
- if ('safari' === requested) return 'safari';
758
- }
759
- switch(requested){
760
- case 'chrome':
761
- return 'chrome';
762
- case 'edge':
763
- return 'edge';
764
- case 'chromium':
765
- return 'chromium';
766
- case 'brave':
767
- return 'brave';
768
- case 'opera':
769
- return 'opera';
770
- case 'vivaldi':
771
- return 'vivaldi';
772
- case 'yandex':
773
- return 'yandex';
774
- case 'chromium-based':
775
- return 'chromium-based';
776
- case 'firefox':
777
- return 'firefox';
778
- case 'waterfox':
779
- return 'waterfox';
780
- case 'librewolf':
781
- return 'librewolf';
782
- case 'gecko-based':
783
- case 'firefox-based':
784
- return 'gecko-based';
785
- case 'safari':
786
- return 'safari';
787
- case 'webkit-based':
788
- return 'webkit-based';
789
- default:
790
- return 'chrome';
791
- }
792
- }
793
- function getDistPath(packageJsonDir, browser) {
794
- return asAbsolute(__rspack_external_node_path_c5b9b54f.join(packageJsonDir, 'dist', browser));
795
- }
796
- function computePreviewOutputPath(struct, browser, explicitOutputPath) {
797
- const { manifestDir, packageJsonDir } = getDirs(struct);
798
- if (explicitOutputPath) return asAbsolute(explicitOutputPath);
799
- if (struct.packageJsonPath || struct.denoJsonPath) {
800
- const distDir = getDistPath(packageJsonDir, browser);
801
- try {
802
- if (__rspack_external_node_fs_5ea92f0c.existsSync(__rspack_external_node_path_c5b9b54f.join(distDir, 'manifest.json'))) return distDir;
803
- } catch {}
804
- }
805
- return manifestDir;
806
- }
807
- function devtoolsEngineFor(browser) {
808
- switch(browser){
809
- case 'chrome':
810
- return 'chrome';
811
- case 'edge':
812
- return 'edge';
813
- case 'chromium':
814
- case 'chromium-based':
815
- case 'brave':
816
- case 'opera':
817
- case 'vivaldi':
818
- case 'yandex':
819
- return 'chromium';
820
- case 'firefox':
821
- case 'gecko-based':
822
- case 'waterfox':
823
- case 'librewolf':
824
- return 'firefox';
825
- case 'safari':
826
- case 'webkit-based':
827
- return 'safari';
828
- default:
829
- return 'chrome';
830
- }
831
- }
355
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.14","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.3.1","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"}}');
832
356
  function sanitize(obj) {
833
357
  return Object.fromEntries(Object.entries(obj || {}).filter(([, value])=>void 0 !== value));
834
358
  }
@@ -917,315 +441,6 @@ function mergeOptionLayers(defaults, ...layers) {
917
441
  for (const layer of layers)result = mergeLayer(result, layer || {});
918
442
  return result;
919
443
  }
920
- async function findUpLocal(filename, options) {
921
- const root = __rspack_external_node_path_c5b9b54f.parse(options.cwd).root;
922
- let currentDir = options.cwd;
923
- while(true){
924
- const candidate = __rspack_external_node_path_c5b9b54f.join(currentDir, filename);
925
- try {
926
- const stat = await __rspack_external_node_fs_5ea92f0c.promises.stat(candidate);
927
- if (stat.isFile()) return candidate;
928
- } catch {}
929
- if (currentDir === root) return;
930
- currentDir = __rspack_external_node_path_c5b9b54f.dirname(currentDir);
931
- }
932
- }
933
- async function findNearestPackageJson(manifestPath) {
934
- try {
935
- const manifestDir = __rspack_external_node_path_c5b9b54f.dirname(manifestPath);
936
- const packageJsonPath = await findUpLocal('package.json', {
937
- cwd: manifestDir
938
- });
939
- return packageJsonPath || null;
940
- } catch (error) {
941
- console.warn('Failed to find package.json:', error);
942
- return null;
943
- }
944
- }
945
- function validatePackageJson(packageJsonPath) {
946
- try {
947
- if (!__rspack_external_node_fs_5ea92f0c.existsSync(packageJsonPath)) return false;
948
- const content = __rspack_external_node_fs_5ea92f0c.readFileSync(packageJsonPath, 'utf-8');
949
- JSON.parse(content);
950
- return true;
951
- } catch (error) {
952
- console.warn('Invalid package.json at:', packageJsonPath, error);
953
- return false;
954
- }
955
- }
956
- const isUrl = (url)=>{
957
- try {
958
- new URL(url);
959
- return true;
960
- } catch (e) {
961
- return false;
962
- }
963
- };
964
- const REMOTE_FETCH_TIMEOUT_MS = (()=>{
965
- const raw = parseInt(String(process.env.EXTENSION_FETCH_TIMEOUT_MS || ''), 10);
966
- return Number.isFinite(raw) && raw > 0 ? raw : 60000;
967
- })();
968
- function withTimeout(task, ms, label) {
969
- let timer;
970
- const timeout = new Promise((_, reject)=>{
971
- timer = setTimeout(()=>reject(new Error(remoteFetchTimedOut(label, ms))), ms);
972
- });
973
- return Promise.race([
974
- task,
975
- timeout
976
- ]).finally(()=>{
977
- if (timer) clearTimeout(timer);
978
- });
979
- }
980
- async function importUrlSourceFromGithub(pathOrRemoteUrl, text) {
981
- const cwd = process.cwd();
982
- const url = new URL(pathOrRemoteUrl);
983
- const segments = url.pathname.split('/').filter(Boolean);
984
- const repoName = segments.length >= 2 ? segments[1] : segments[segments.length - 1];
985
- const treeIndex = segments.indexOf('tree');
986
- const expectedName = -1 !== treeIndex && segments.length > treeIndex + 2 ? segments[segments.length - 1] : repoName;
987
- const expectedPath = __rspack_external_node_path_c5b9b54f.resolve(cwd, expectedName);
988
- if (__rspack_external_node_fs_5ea92f0c.existsSync(expectedPath)) try {
989
- const entries = __rspack_external_node_fs_5ea92f0c.readdirSync(expectedPath);
990
- if (0 === entries.length) __rspack_external_node_fs_5ea92f0c.rmSync(expectedPath, {
991
- recursive: true,
992
- force: true
993
- });
994
- else {
995
- const hasManifest = (dir)=>{
996
- const stack = [
997
- dir
998
- ];
999
- while(stack.length){
1000
- const current = stack.pop();
1001
- const items = __rspack_external_node_fs_5ea92f0c.readdirSync(current, {
1002
- withFileTypes: true
1003
- });
1004
- for (const it of items){
1005
- if (it.isFile() && 'manifest.json' === it.name) return true;
1006
- if (it.isDirectory() && 'node_modules' !== it.name && 'dist' !== it.name && !it.name.startsWith('.')) stack.push(__rspack_external_node_path_c5b9b54f.join(current, it.name));
1007
- }
1008
- }
1009
- return false;
1010
- };
1011
- if (hasManifest(expectedPath)) return expectedPath;
1012
- __rspack_external_node_fs_5ea92f0c.rmSync(expectedPath, {
1013
- recursive: true,
1014
- force: true
1015
- });
1016
- }
1017
- } catch {}
1018
- async function tryGitClone() {
1019
- const { default: goGitIt } = await import("go-git-it");
1020
- await withTimeout(goGitIt(pathOrRemoteUrl, cwd, text), REMOTE_FETCH_TIMEOUT_MS, pathOrRemoteUrl);
1021
- }
1022
- async function tryZipFallback() {
1023
- const branch = -1 !== treeIndex && segments.length > treeIndex + 1 ? segments[treeIndex + 1] : 'main';
1024
- const owner = segments[0];
1025
- const repo = segments[1];
1026
- const subdir = -1 !== treeIndex && segments.length > treeIndex + 2 ? segments.slice(treeIndex + 2).join('/') : '';
1027
- const zipUrl = `https://codeload.github.com/${owner}/${repo}/zip/refs/heads/${branch}`;
1028
- const extractedPath = await importUrlSourceFromZip(zipUrl);
1029
- const extractedDirs = __rspack_external_node_fs_5ea92f0c.readdirSync(extractedPath, {
1030
- withFileTypes: true
1031
- }).filter((d)=>d.isDirectory()).map((d)=>d.name);
1032
- const repoRootDir = extractedDirs.find((d)=>d.startsWith(`${repo}-${branch}`));
1033
- const repoRoot = repoRootDir ? __rspack_external_node_path_c5b9b54f.join(extractedPath, repoRootDir) : extractedPath;
1034
- return subdir ? __rspack_external_node_path_c5b9b54f.join(repoRoot, subdir) : repoRoot;
1035
- }
1036
- try {
1037
- await tryGitClone();
1038
- } catch {
1039
- return await tryZipFallback();
1040
- }
1041
- const candidates = [];
1042
- if (-1 !== treeIndex && segments.length > treeIndex + 2) candidates.push(segments[segments.length - 1]);
1043
- candidates.push(repoName);
1044
- for (const name of candidates){
1045
- const p = __rspack_external_node_path_c5b9b54f.resolve(cwd, name);
1046
- if (__rspack_external_node_fs_5ea92f0c.existsSync(p)) return p;
1047
- }
1048
- const dirs = __rspack_external_node_fs_5ea92f0c.readdirSync(cwd, {
1049
- withFileTypes: true
1050
- }).filter((d)=>d.isDirectory()).map((d)=>d.name);
1051
- for (const dir of dirs){
1052
- const manifestPath = __rspack_external_node_path_c5b9b54f.join(cwd, dir, 'manifest.json');
1053
- if (__rspack_external_node_fs_5ea92f0c.existsSync(manifestPath)) return __rspack_external_node_path_c5b9b54f.join(cwd, dir);
1054
- }
1055
- try {
1056
- const dirs = __rspack_external_node_fs_5ea92f0c.readdirSync(cwd, {
1057
- withFileTypes: true
1058
- }).filter((d)=>d.isDirectory()).map((d)=>d.name);
1059
- const ghRoot = dirs.find((d)=>/-main$|-master$/.test(d));
1060
- if (ghRoot) return __rspack_external_node_path_c5b9b54f.join(cwd, ghRoot);
1061
- } catch {}
1062
- throw new Error(downloadedProjectFolderNotFound(cwd, candidates));
1063
- }
1064
- async function importUrlSourceFromZip(pathOrRemoteUrl) {
1065
- const cwd = process.cwd();
1066
- const { downloadAndExtractZip } = await import("./0~zip.mjs");
1067
- const extractedPath = await withTimeout(downloadAndExtractZip(pathOrRemoteUrl, cwd), REMOTE_FETCH_TIMEOUT_MS, pathOrRemoteUrl);
1068
- return extractedPath;
1069
- }
1070
- async function importLocalSourceFromZip(zipFilePath) {
1071
- const cwd = process.cwd();
1072
- const { extractLocalZip } = await import("./0~zip.mjs");
1073
- return await extractLocalZip(zipFilePath, cwd);
1074
- }
1075
- async function getProjectPath(pathOrRemoteUrl) {
1076
- if (!pathOrRemoteUrl) return process.cwd();
1077
- if (isUrl(pathOrRemoteUrl)) {
1078
- const url = new URL(pathOrRemoteUrl);
1079
- if (url.protocol.startsWith('http')) {
1080
- const pathname = url.pathname.toLowerCase();
1081
- if (pathname.endsWith('.zip')) return await importUrlSourceFromZip(pathOrRemoteUrl);
1082
- if ('https://github.com' !== url.origin) {
1083
- const urlSource = await importUrlSourceFromZip(pathOrRemoteUrl);
1084
- return urlSource;
1085
- }
1086
- const urlData = url.pathname.split('/');
1087
- const owner = urlData.slice(1, 3)[0];
1088
- const project = urlData.slice(1, 3)[1];
1089
- console.log(fetchingProjectPath(owner, project));
1090
- const projectName = __rspack_external_node_path_c5b9b54f.basename(url.pathname);
1091
- const urlSource = await importUrlSourceFromGithub(pathOrRemoteUrl, downloadingProjectPath(projectName));
1092
- console.log(creatingProjectPath(url.pathname));
1093
- return urlSource;
1094
- }
1095
- }
1096
- const resolvedPath = __rspack_external_node_path_c5b9b54f.resolve(process.cwd(), pathOrRemoteUrl);
1097
- if ('.zip' === __rspack_external_node_path_c5b9b54f.extname(resolvedPath).toLowerCase() && __rspack_external_node_fs_5ea92f0c.existsSync(resolvedPath) && __rspack_external_node_fs_5ea92f0c.statSync(resolvedPath).isFile()) return await importLocalSourceFromZip(resolvedPath);
1098
- return resolvedPath;
1099
- }
1100
- function collectManifestCandidates(rootDir, maxDepth) {
1101
- const SKIP_DIRS = new Set([
1102
- 'node_modules',
1103
- 'dist',
1104
- 'build',
1105
- 'out',
1106
- '.git',
1107
- '.turbo',
1108
- '.next',
1109
- 'coverage',
1110
- '.cache',
1111
- '.vercel'
1112
- ]);
1113
- const results = [];
1114
- const walk = (dir, depth)=>{
1115
- if (depth > maxDepth || results.length >= 10) return;
1116
- let entries;
1117
- try {
1118
- entries = __rspack_external_node_fs_5ea92f0c.readdirSync(dir, {
1119
- withFileTypes: true
1120
- });
1121
- } catch {
1122
- return;
1123
- }
1124
- for (const entry of entries){
1125
- if (entry.isFile() && 'manifest.json' === entry.name) {
1126
- results.push(__rspack_external_node_path_c5b9b54f.join(dir, entry.name));
1127
- continue;
1128
- }
1129
- if (entry.isDirectory() && !entry.name.startsWith('.') && !SKIP_DIRS.has(entry.name)) walk(__rspack_external_node_path_c5b9b54f.join(dir, entry.name), depth + 1);
1130
- }
1131
- };
1132
- walk(rootDir, 0);
1133
- return results;
1134
- }
1135
- async function getProjectStructure(pathOrRemoteUrl) {
1136
- const projectPath = await getProjectPath(pathOrRemoteUrl);
1137
- const isUnderDir = (baseDir, candidatePath)=>{
1138
- const rel = __rspack_external_node_path_c5b9b54f.relative(baseDir, candidatePath);
1139
- return Boolean(rel && !rel.startsWith('..') && !__rspack_external_node_path_c5b9b54f.isAbsolute(rel));
1140
- };
1141
- const packageJsonPathFromProject = await findNearestPackageJson(__rspack_external_node_path_c5b9b54f.join(projectPath, 'manifest.json'));
1142
- const denoJsonPathFromProject = findNearestDenoConfigSync(__rspack_external_node_path_c5b9b54f.join(projectPath, 'manifest.json'));
1143
- const packageJsonDirFromProject = packageJsonPathFromProject ? __rspack_external_node_path_c5b9b54f.dirname(packageJsonPathFromProject) : denoJsonPathFromProject ? __rspack_external_node_path_c5b9b54f.dirname(denoJsonPathFromProject) : void 0;
1144
- const rootManifestPath = __rspack_external_node_path_c5b9b54f.join(projectPath, 'manifest.json');
1145
- const srcManifestPath = __rspack_external_node_path_c5b9b54f.join(projectPath, 'src', 'manifest.json');
1146
- let manifestPath = __rspack_external_node_fs_5ea92f0c.existsSync(srcManifestPath) ? srcManifestPath : rootManifestPath;
1147
- if (!__rspack_external_node_fs_5ea92f0c.existsSync(manifestPath)) if (packageJsonDirFromProject) {
1148
- const absoluteCandidates = collectManifestCandidates(projectPath, 3);
1149
- const relativeCandidates = absoluteCandidates.map((candidate)=>__rspack_external_node_path_c5b9b54f.relative(projectPath, candidate) || candidate);
1150
- if (1 === absoluteCandidates.length) {
1151
- manifestPath = absoluteCandidates[0];
1152
- console.log(resolvedWorkspaceManifest(projectPath, manifestPath));
1153
- } else throw new Error(manifestNotFoundError(manifestPath, relativeCandidates));
1154
- } else {
1155
- const MAX_DEPTH = 5;
1156
- const findManifest = (dir, depth)=>{
1157
- if (depth > MAX_DEPTH) return null;
1158
- let files;
1159
- try {
1160
- files = __rspack_external_node_fs_5ea92f0c.readdirSync(dir, {
1161
- withFileTypes: true
1162
- });
1163
- } catch {
1164
- return null;
1165
- }
1166
- for (const file of files){
1167
- if (file.isFile() && 'manifest.json' === file.name) return __rspack_external_node_path_c5b9b54f.join(dir, file.name);
1168
- if (file.isDirectory() && !file.name.startsWith('.') && 'node_modules' !== file.name && 'dist' !== file.name && 'public' !== file.name) {
1169
- const found = findManifest(__rspack_external_node_path_c5b9b54f.join(dir, file.name), depth + 1);
1170
- if (found) return found;
1171
- }
1172
- }
1173
- return null;
1174
- };
1175
- const foundManifest = findManifest(projectPath, 0);
1176
- if (foundManifest) manifestPath = foundManifest;
1177
- else throw new Error(manifestNotFoundError(manifestPath));
1178
- }
1179
- const readManifestObject = (candidatePath)=>{
1180
- try {
1181
- const parsed = parseJsonSafe(__rspack_external_node_fs_5ea92f0c.readFileSync(candidatePath));
1182
- if (null === parsed || 'object' != typeof parsed || Array.isArray(parsed)) return;
1183
- return parsed;
1184
- } catch {
1185
- return;
1186
- }
1187
- };
1188
- const isPwaManifest = (candidatePath)=>{
1189
- const parsed = readManifestObject(candidatePath);
1190
- if (!parsed || null != parsed.manifest_version) return false;
1191
- return Array.isArray(parsed.icons) || 'string' == typeof parsed.start_url || 'string' == typeof parsed.display || null != parsed.related_applications || null != parsed.prefer_related_applications;
1192
- };
1193
- if (__rspack_external_node_fs_5ea92f0c.existsSync(manifestPath) && isPwaManifest(manifestPath)) {
1194
- const alternatives = collectManifestCandidates(projectPath, 3).filter((candidate)=>__rspack_external_node_path_c5b9b54f.resolve(candidate) !== __rspack_external_node_path_c5b9b54f.resolve(manifestPath) && readManifestObject(candidate)?.manifest_version != null);
1195
- if (1 === alternatives.length) {
1196
- manifestPath = alternatives[0];
1197
- console.log(resolvedWorkspaceManifest(projectPath, manifestPath));
1198
- } else throw new Error(notAnExtensionManifestError(manifestPath));
1199
- }
1200
- const packageJsonPath = await findNearestPackageJson(manifestPath);
1201
- const packageJsonDir = packageJsonPath ? __rspack_external_node_path_c5b9b54f.dirname(packageJsonPath) : void 0;
1202
- const nearestDenoJsonPath = findNearestDenoConfigSync(manifestPath);
1203
- const denoJsonPath = nearestDenoJsonPath && validateDenoConfig(nearestDenoJsonPath) ? nearestDenoJsonPath : void 0;
1204
- const projectRootDir = packageJsonDir ?? (denoJsonPath ? __rspack_external_node_path_c5b9b54f.dirname(denoJsonPath) : void 0);
1205
- if (projectRootDir) {
1206
- const publicRoot = __rspack_external_node_path_c5b9b54f.join(projectRootDir, 'public');
1207
- if (isUnderDir(publicRoot, manifestPath)) {
1208
- const fallbackSrc = __rspack_external_node_path_c5b9b54f.join(projectRootDir, 'src', 'manifest.json');
1209
- const fallbackRoot = __rspack_external_node_path_c5b9b54f.join(projectRootDir, 'manifest.json');
1210
- if (__rspack_external_node_fs_5ea92f0c.existsSync(fallbackSrc)) manifestPath = fallbackSrc;
1211
- else if (__rspack_external_node_fs_5ea92f0c.existsSync(fallbackRoot)) manifestPath = fallbackRoot;
1212
- else throw new Error(manifestNotFoundError(fallbackRoot));
1213
- }
1214
- }
1215
- if (!packageJsonPath || !validatePackageJson(packageJsonPath)) return {
1216
- manifestPath,
1217
- ...denoJsonPath ? {
1218
- denoJsonPath
1219
- } : {}
1220
- };
1221
- return {
1222
- manifestPath,
1223
- packageJsonPath,
1224
- ...denoJsonPath ? {
1225
- denoJsonPath
1226
- } : {}
1227
- };
1228
- }
1229
444
  function isReferencedAsModuleSpecifier(configSource, dep) {
1230
445
  const escaped = dep.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1231
446
  const specifierRe = new RegExp(`['"\`]${escaped}(?:/[^'"\`]*)?['"\`]`);
@@ -1374,7 +589,7 @@ function readManifestProvenance(manifestPath) {
1374
589
  return {};
1375
590
  }
1376
591
  }
1377
- function plugin_playwright_ensureDirSync(dirPath) {
592
+ function ensureDirSync(dirPath) {
1378
593
  try {
1379
594
  __rspack_external_node_fs_5ea92f0c.mkdirSync(dirPath, {
1380
595
  recursive: true
@@ -1465,7 +680,7 @@ function createPlaywrightMetadataWriter(options) {
1465
680
  };
1466
681
  function writeReady(status, extra) {
1467
682
  if (foreignLiveDevSession) return;
1468
- plugin_playwright_ensureDirSync(metadataDir);
683
+ ensureDirSync(metadataDir);
1469
684
  let prev;
1470
685
  try {
1471
686
  if (__rspack_external_node_fs_5ea92f0c.existsSync(readyPath)) prev = JSON.parse(__rspack_external_node_fs_5ea92f0c.readFileSync(readyPath, 'utf-8'));
@@ -1522,7 +737,7 @@ function createPlaywrightMetadataWriter(options) {
1522
737
  }
1523
738
  function appendEvent(event) {
1524
739
  if (foreignLiveDevSession) return;
1525
- plugin_playwright_ensureDirSync(metadataDir);
740
+ ensureDirSync(metadataDir);
1526
741
  try {
1527
742
  __rspack_external_node_fs_5ea92f0c.appendFileSync(eventsPath, `${JSON.stringify({
1528
743
  ...event,
@@ -1540,7 +755,7 @@ function createPlaywrightMetadataWriter(options) {
1540
755
  },
1541
756
  writeStarting () {
1542
757
  if (foreignLiveDevSession) return;
1543
- plugin_playwright_ensureDirSync(metadataDir);
758
+ ensureDirSync(metadataDir);
1544
759
  try {
1545
760
  __rspack_external_node_fs_5ea92f0c.writeFileSync(eventsPath, '', 'utf-8');
1546
761
  } catch {}
@@ -1720,7 +935,23 @@ function normalizeCompanionConfig(config) {
1720
935
  paths: explicitPaths
1721
936
  };
1722
937
  }
1723
- function resolve_config_isPathLike(value) {
938
+ const BROWSER_COMPANION_FOLDERS = new Set([
939
+ 'chrome',
940
+ 'edge',
941
+ 'firefox'
942
+ ]);
943
+ function isBrowserNamedCompanionFolder(name) {
944
+ return BROWSER_COMPANION_FOLDERS.has(name.toLowerCase());
945
+ }
946
+ function companionFolderForBrowser(browser) {
947
+ if (browser && isGeckoBasedBrowser(String(browser))) return 'firefox';
948
+ if ('edge' === browser) return 'edge';
949
+ return 'chrome';
950
+ }
951
+ function companionFolderMatchesBrowser(name, browser) {
952
+ return name.toLowerCase() === companionFolderForBrowser(browser);
953
+ }
954
+ function isPathLike(value) {
1724
955
  if (__rspack_external_node_path_c5b9b54f.isAbsolute(value)) return true;
1725
956
  if (value.startsWith('./') || value.startsWith('../')) return true;
1726
957
  return value.includes('/') || value.includes('\\');
@@ -1735,27 +966,46 @@ function getBrowserFolder(browser) {
1735
966
  return 'chrome';
1736
967
  }
1737
968
  function parseChromeWebStoreId(url) {
1738
- if ('chromewebstore.google.com' !== url.hostname) return null;
969
+ const host = stripWww(url.hostname);
970
+ const legacy = 'chrome.google.com' === host && /^\/webstore(?:\/|$)/i.test(url.pathname);
971
+ if ('chromewebstore.google.com' !== host && !legacy) return null;
1739
972
  const match = url.pathname.match(/\/([a-z]{32})(?:\/|$)/i);
1740
973
  return match ? match[1] : null;
1741
974
  }
1742
975
  function parseEdgeAddonsId(url) {
1743
- if ('microsoftedge.microsoft.com' !== url.hostname) return null;
976
+ if ('microsoftedge.microsoft.com' !== stripWww(url.hostname)) return null;
1744
977
  const match = url.pathname.match(/\/([a-z]{32})(?:\/|$)/i);
1745
978
  return match ? match[1] : null;
1746
979
  }
1747
980
  function parseAmoSlug(url) {
1748
- if ('addons.mozilla.org' !== url.hostname) return null;
981
+ if ('addons.mozilla.org' !== stripWww(url.hostname)) return null;
1749
982
  const match = url.pathname.match(/\/addon\/([^/]+)(?:\/|$)/i);
1750
983
  return match ? match[1] : null;
1751
984
  }
1752
- function parseStoreUrl(raw) {
1753
- let url;
985
+ const STORE_HOSTS = new Set([
986
+ 'chromewebstore.google.com',
987
+ 'chrome.google.com',
988
+ 'microsoftedge.microsoft.com',
989
+ 'addons.mozilla.org'
990
+ ]);
991
+ function stripWww(hostname) {
992
+ return hostname.toLowerCase().replace(/^www\./, '');
993
+ }
994
+ function toWebUrl(raw) {
1754
995
  try {
1755
- url = new URL(raw);
996
+ const url = new URL(raw);
997
+ if ('http:' === url.protocol || 'https:' === url.protocol) return url;
998
+ return null;
999
+ } catch {}
1000
+ const match = raw.match(/^([a-z0-9.-]+)(?:[/?#].*)?$/i);
1001
+ if (!match || !STORE_HOSTS.has(stripWww(match[1]))) return null;
1002
+ try {
1003
+ return new URL(`https://${raw}`);
1756
1004
  } catch {
1757
1005
  return null;
1758
1006
  }
1007
+ }
1008
+ function parseStoreUrl(url) {
1759
1009
  const chromeId = parseChromeWebStoreId(url);
1760
1010
  if (chromeId) return {
1761
1011
  browser: 'chrome',
@@ -1845,19 +1095,26 @@ async function resolveCompanionExtensionsConfig(opts) {
1845
1095
  const resolvedPaths = [];
1846
1096
  const localPaths = [];
1847
1097
  for (const entry of normalized.paths){
1848
- const parsedStore = parseStoreUrl(entry);
1849
- if (parsedStore) {
1098
+ const url = toWebUrl(entry);
1099
+ if (url) {
1100
+ const parsedStore = parseStoreUrl(url);
1101
+ if (!parsedStore) throw new Error(`Companion extension link is not a store link this resolver recognises: ${entry}\nSupported links: https://chromewebstore.google.com/detail/<name>/<id>, https://microsoftedge.microsoft.com/addons/detail/<name>/<id>, https://addons.mozilla.org/<locale>/firefox/addon/<slug>`);
1850
1102
  if (parsedStore.browser !== runtimeBrowser) continue;
1851
1103
  const resolvedPath = await resolveStoreExtensionToPath({
1852
1104
  projectRoot,
1853
- storeUrl: entry,
1105
+ storeUrl: url.href,
1854
1106
  browser: parsedStore.browser,
1855
1107
  id: parsedStore.id
1856
1108
  });
1857
1109
  resolvedPaths.push(resolvedPath);
1858
1110
  continue;
1859
1111
  }
1860
- if (resolve_config_isPathLike(entry)) localPaths.push(entry);
1112
+ if (isPathLike(entry)) {
1113
+ localPaths.push(entry);
1114
+ continue;
1115
+ }
1116
+ if (/^[a-p]{32}$/i.test(entry)) throw new Error(`Companion extension entry looks like a store id, not a store link: ${entry}\nUse the full store link so the browser it belongs to is known, for example https://chromewebstore.google.com/detail/<name>/${entry}`);
1117
+ throw new Error(`Companion extension entry is neither a store link nor a folder path: ${entry}\nGive a store link or a path under ./extensions`);
1861
1118
  }
1862
1119
  if (localPaths.length > 0) {
1863
1120
  const absLocalPaths = ensurePathsUnderExtensions(projectRoot, localPaths);
@@ -1876,6 +1133,15 @@ async function resolveCompanionExtensionsConfig(opts) {
1876
1133
  function serverRestartRequiredFromSpecialFolderMessageOnly(addingOrRemoving, folder, typeOfAsset) {
1877
1134
  return `${messaging_prefix('warn')} ${addingOrRemoving} ${pintor.yellow(typeOfAsset)} in ${pintor.underline(`${folder}/`)} changes the extension entrypoints.\nRestart the dev server to apply the change.`;
1878
1135
  }
1136
+ function displayPath(absolutePath) {
1137
+ return absolutePath.replace(/\\/g, '/');
1138
+ }
1139
+ function publicMustBeAtProjectRoot(foundAt, expectedAt) {
1140
+ return `The public folder sits in the legacy next-to-manifest location.\nGOT ${displayPath(foundAt)}\nEXPECTED ${displayPath(expectedAt)}\nStatic files ship from the extension root, so public/ is canonically placed at the project root.\nThe build uses it either way.\nMove the folder to the project root to silence this warning.`;
1141
+ }
1142
+ function publicFolderShadowed(usedAt, ignoredAt) {
1143
+ return `Two public folders were found and only one is copied into the build.\nUSING ${displayPath(usedAt)}\nIGNORED ${displayPath(ignoredAt)}\npublic/ is canonically placed at the project root, and that copy wins.\nFiles that exist only in the ignored folder do not ship.\nMove or merge the ignored folder to silence this warning.`;
1144
+ }
1879
1145
  function specialFoldersSetupSummary(hasPublic, copyEnabled, ignoredCount) {
1880
1146
  return `${messaging_prefix('debug')} folders setup public=${String(hasPublic)} copy=${String(copyEnabled)} ignored=${String(ignoredCount)}`;
1881
1147
  }
@@ -2238,14 +1504,14 @@ function withDarkMode(config) {
2238
1504
  };
2239
1505
  }
2240
1506
  const cjsRequire = createRequire(import.meta.url);
2241
- function messages_getLoggingPrefix(type) {
1507
+ function getLoggingPrefix(type) {
2242
1508
  return messaging_prefix(type);
2243
1509
  }
2244
1510
  function messages_ready(mode, browser) {
2245
1511
  const noun = artifactNoun(browser);
2246
1512
  const state = pintor.green(`ready for ${mode}`);
2247
1513
  const watching = 'development' === mode ? ' Watching for file changes.' : '';
2248
- return `${messages_getLoggingPrefix('success')} ${noun} ${state}.${watching}`;
1514
+ return `${getLoggingPrefix('success')} ${noun} ${state}.${watching}`;
2249
1515
  }
2250
1516
  function readJsonRecord(filePath) {
2251
1517
  try {
@@ -2316,37 +1582,46 @@ function shouldWarnPortConflict(requested, actual) {
2316
1582
  return Number.isFinite(requestedPort) && 0 !== requestedPort && requestedPort !== actual;
2317
1583
  }
2318
1584
  function portInUse(requestedPort, newPort) {
2319
- return `${messages_getLoggingPrefix('warn')} Port ${requestedPort} is in use.\nThe dev server listens on port ${newPort} instead.`;
1585
+ return `${getLoggingPrefix('warn')} Port ${requestedPort} is in use.\nThe dev server listens on port ${newPort} instead.`;
2320
1586
  }
2321
1587
  function extensionJsRunnerError(error) {
2322
- return `${messages_getLoggingPrefix('error')} Extension.js couldn't start the runner.\n${pintor.red(String(error))}`;
1588
+ return `${getLoggingPrefix('error')} Extension.js couldn't start the runner.\n${pintor.red(String(error))}`;
2323
1589
  }
2324
1590
  function autoExitModeEnabled(ms) {
2325
- return `${messages_getLoggingPrefix('info')} Auto-exit is enabled.\nThe process exits after ${ms} ms of idle time.`;
1591
+ return `${getLoggingPrefix('info')} Auto-exit is enabled.\nThe process exits after ${ms} ms of idle time.`;
2326
1592
  }
2327
1593
  function autoExitTriggered(ms) {
2328
- return `${messages_getLoggingPrefix('info')} Auto-exit triggered after ${ms} ms.\nThe process cleans up and exits now.`;
1594
+ return `${getLoggingPrefix('info')} Auto-exit triggered after ${ms} ms.\nThe process cleans up and exits now.`;
2329
1595
  }
2330
1596
  function autoExitForceKill(ms) {
2331
- return `${messages_getLoggingPrefix('warn')} The process didn't exit within ${ms} ms, so it exits forcibly now.`;
1597
+ return `${getLoggingPrefix('warn')} The process didn't exit within ${ms} ms, so it exits forcibly now.`;
2332
1598
  }
2333
1599
  function devServerStartTimeout(ms) {
2334
1600
  return [
2335
- `${messages_getLoggingPrefix('warn')} The dev server didn't start within ${ms} ms.`,
1601
+ `${getLoggingPrefix('warn')} The dev server didn't start within ${ms} ms.`,
2336
1602
  "The bundler may have hit an error before emitting the first build.",
2337
1603
  `If nothing else prints, set ${pintor.blue('EXTENSION_VERBOSE=1')} to see more logs.`
2338
1604
  ].join('\n');
2339
1605
  }
2340
1606
  function bundlerFatalError(error) {
2341
1607
  const text = error instanceof Error ? error.stack || error.message : String(error);
2342
- return `${messages_getLoggingPrefix('error')} The build failed to start.\n${pintor.red(text)}`;
1608
+ return `${getLoggingPrefix('error')} The build failed to start.\n${pintor.red(text)}`;
1609
+ }
1610
+ function devServerRestarting(request) {
1611
+ const what = 'icons' === request.reason ? 'a manifest icon' : 'html' === request.reason ? 'an HTML entrypoint' : 'json' === request.reason ? 'a manifest JSON entry' : "a manifest script entry";
1612
+ const lines = [
1613
+ `${getLoggingPrefix('info')} Restarting the dev server to pick up ${what} change…`
1614
+ ];
1615
+ if (request.pathBefore) lines.push(`${pintor.gray('BEFORE')} ${pintor.underline(request.pathBefore)}`);
1616
+ if (request.pathAfter) lines.push(`${pintor.gray('AFTER')} ${pintor.underline(request.pathAfter)}`);
1617
+ return lines.join('\n');
2343
1618
  }
2344
1619
  function bundlerRecompiling() {
2345
- return `${messages_getLoggingPrefix('info')} Recompiling due to file changes…`;
1620
+ return `${getLoggingPrefix('info')} Recompiling due to file changes…`;
2346
1621
  }
2347
1622
  function noEntrypointsDetected(port) {
2348
1623
  return [
2349
- `${messages_getLoggingPrefix('warn')} The first compilation produced no entrypoints or assets.`,
1624
+ `${getLoggingPrefix('warn')} The first compilation produced no entrypoints or assets.`,
2350
1625
  `The dev server is running on 127.0.0.1:${port}, but nothing is being built.`,
2351
1626
  "Possible causes:",
2352
1627
  "- Empty or missing entry configuration.",
@@ -2358,6 +1633,15 @@ function noEntrypointsDetected(port) {
2358
1633
  function spacerLine() {
2359
1634
  return ' ';
2360
1635
  }
1636
+ function runnerCleanupError(error) {
1637
+ return `${messaging_prefix('error')} The dev server could not shut down cleanly: ${String(error?.message || error)}`;
1638
+ }
1639
+ function runnerUncaughtException(error) {
1640
+ return `${messaging_prefix('error')} Uncaught exception in the dev server: ${String(error?.message || error)}`;
1641
+ }
1642
+ function runnerUnhandledRejection(reason) {
1643
+ return `${messaging_prefix('error')} Unhandled rejection in the dev server: ${String(reason?.message || reason)}`;
1644
+ }
2361
1645
  function hasNewTabOverride(extensionDir) {
2362
1646
  const manifestPath = __rspack_external_node_path_c5b9b54f.join(extensionDir, 'manifest.json');
2363
1647
  if (!__rspack_external_node_fs_5ea92f0c.existsSync(manifestPath)) return false;
@@ -2433,7 +1717,7 @@ function computeExtensionsToLoad(baseDir, mode, browser, userExtensionOutputPath
2433
1717
  return dedupeByResolvedPath(list);
2434
1718
  }
2435
1719
  function resolveCompanionExtensionDirs(opts) {
2436
- const { projectRoot, config } = opts;
1720
+ const { projectRoot, config, browser } = opts;
2437
1721
  const normalized = normalizeCompanionConfig(config);
2438
1722
  const explicitPaths = normalized.paths;
2439
1723
  const scanDir = normalized.dir;
@@ -2473,6 +1757,7 @@ function resolveCompanionExtensionDirs(opts) {
2473
1757
  for (const ent of entries){
2474
1758
  if (!ent.isDirectory()) continue;
2475
1759
  if (ent.name.startsWith('.')) continue;
1760
+ if (browser && isBrowserNamedCompanionFolder(ent.name) && !companionFolderMatchesBrowser(ent.name, browser)) continue;
2476
1761
  const browserDir = __rspack_external_node_path_c5b9b54f.join(absScan, ent.name);
2477
1762
  scanOneLevel(browserDir);
2478
1763
  }
@@ -2500,16 +1785,17 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2500
1785
  const { manifestDir, packageJsonDir } = getDirs(projectStructure);
2501
1786
  const userManifestPath = projectStructure.packageJsonPath || projectStructure.denoJsonPath;
2502
1787
  if (userManifestPath) assertNoManagedDependencyConflicts(userManifestPath, packageJsonDir);
2503
- const browser = normalizeBrowser(previewOptions.browser || 'chrome', previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary);
1788
+ const metadataCommand = 'start' === previewOptions.metadataCommand ? 'start' : 'preview';
1789
+ const configBrowser = previewOptions.browser ? void 0 : configBrowserOrThrow((await loadCommandConfig(packageJsonDir, metadataCommand)).browser, metadataCommand);
1790
+ const browser = normalizeBrowser(previewOptions.browser || configBrowser || 'chrome', previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary);
2504
1791
  const outputPath = computePreviewOutputPath(projectStructure, browser, previewOptions.outputPath);
2505
1792
  const distPath = getDistPath(packageJsonDir, browser);
2506
- const metadataCommand = 'start' === previewOptions.metadataCommand ? 'start' : 'preview';
2507
1793
  const runningMessage = 'start' === metadataCommand ? starting : previewing;
2508
1794
  const metadata = createPlaywrightMetadataWriter({
2509
1795
  packageJsonDir,
2510
1796
  browser: String(browser),
2511
1797
  command: metadataCommand,
2512
- distPath,
1798
+ distPath: outputPath,
2513
1799
  manifestPath: projectStructure.manifestPath,
2514
1800
  port: 'number' == typeof previewOptions.port ? previewOptions.port : 'string' == typeof previewOptions.port ? parseInt(previewOptions.port, 10) : null
2515
1801
  });
@@ -2520,11 +1806,13 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2520
1806
  humanLine(debugBrowser(browser, previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary));
2521
1807
  humanLine(debugPreviewOutput(outputPath, distPath));
2522
1808
  }
1809
+ ensureSessionArtifactsIgnoreFile(packageJsonDir);
2523
1810
  const manifestAtOutput = __rspack_external_node_path_c5b9b54f.join(outputPath, 'manifest.json');
2524
1811
  if (!__rspack_external_node_fs_5ea92f0c.existsSync(manifestAtOutput)) {
2525
1812
  metadata.writeError('preview_manifest_missing', `Expected manifest at ${manifestAtOutput}`);
2526
1813
  throw new Error(`Preview is run-only and does not compile.\nExpected an unpacked extension at:\n ${manifestAtOutput}\n\nRun \`extension build\` or \`extension dev\` first, or pass --output-path to an existing unpacked extension directory.`);
2527
1814
  }
1815
+ const projectConfig = await loadProjectConfigDefaults(packageJsonDir);
2528
1816
  const commandConfig = await loadCommandConfig(packageJsonDir, metadataCommand);
2529
1817
  const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
2530
1818
  if (previewOptions.noBrowser) {
@@ -2542,12 +1830,13 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2542
1830
  return;
2543
1831
  }
2544
1832
  humanLine(runningMessage(browser));
2545
- if (!previewOptions.outputPath && __rspack_external_node_path_c5b9b54f.resolve(outputPath) !== __rspack_external_node_path_c5b9b54f.resolve(distPath)) humanLine(previewingSourceFallback(browser, distPath));
1833
+ if (__rspack_external_node_path_c5b9b54f.resolve(outputPath) !== __rspack_external_node_path_c5b9b54f.resolve(distPath)) humanLine(previewOptions.outputPath ? previewingCustomOutput(browser, outputPath, distPath) : previewingSourceFallback(browser, distPath));
1834
+ const safeProjectConfig = sanitize(projectConfig);
2546
1835
  const safeBrowserConfig = sanitize(browserConfig);
2547
1836
  const safeCommandConfig = sanitize(commandConfig);
2548
1837
  const safePreviewOptions = sanitize(previewOptions);
2549
1838
  const specialFoldersData = getSpecialFoldersDataForProjectRoot(packageJsonDir);
2550
- const mergedExtensionsConfig = safePreviewOptions.extensions ?? safeCommandConfig.extensions ?? safeBrowserConfig.extensions ?? specialFoldersData.extensions;
1839
+ const mergedExtensionsConfig = safePreviewOptions.extensions ?? safeCommandConfig.extensions ?? safeBrowserConfig.extensions ?? safeProjectConfig.extensions ?? specialFoldersData.extensions;
2551
1840
  const resolvedExtensionsConfig = await resolveCompanionExtensionsConfig({
2552
1841
  projectRoot: packageJsonDir,
2553
1842
  browser,
@@ -2556,7 +1845,7 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2556
1845
  const mergedGeckoBinary = safePreviewOptions.geckoBinary || safePreviewOptions.firefoxBinary || safeCommandConfig.geckoBinary || safeCommandConfig.firefoxBinary || safeBrowserConfig.geckoBinary || safeBrowserConfig.firefoxBinary;
2557
1846
  const mergedChromiumBinary = safePreviewOptions.chromiumBinary || safeCommandConfig.chromiumBinary || safeBrowserConfig.chromiumBinary;
2558
1847
  const merged = {
2559
- ...mergeOptionLayers(SERVE_COMMAND_DEFAULTS, safeBrowserConfig, safeCommandConfig, safePreviewOptions),
1848
+ ...mergeOptionLayers(SERVE_COMMAND_DEFAULTS, safeProjectConfig, safeBrowserConfig, safeCommandConfig, safePreviewOptions),
2560
1849
  extensions: resolvedExtensionsConfig,
2561
1850
  chromiumBinary: mergedChromiumBinary,
2562
1851
  geckoBinary: mergedGeckoBinary
@@ -2569,7 +1858,8 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2569
1858
  });
2570
1859
  const companionUnpackedExtensionDirs = resolveCompanionExtensionDirs({
2571
1860
  projectRoot: packageJsonDir,
2572
- config: merged.extensions
1861
+ config: merged.extensions,
1862
+ browser
2573
1863
  });
2574
1864
  const unpackedExtensionDirsToLoad = computeExtensionsToLoad(__rspack_external_node_path_c5b9b54f.resolve(__rspack_import_meta_dirname__, '..'), 'production', browser, outputPath, companionUnpackedExtensionDirs, projectStructure.manifestPath);
2575
1865
  metadata.setManagedExtensionDirs(unpackedExtensionDirsToLoad.filter((dir)=>__rspack_external_node_path_c5b9b54f.resolve(dir) !== __rspack_external_node_path_c5b9b54f.resolve(outputPath)));
@@ -2603,4 +1893,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2603
1893
  await browserLauncher(resolvedOpts);
2604
1894
  metadata.writeReady();
2605
1895
  }
2606
- 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, getPreloadedEnvKeys, 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, serverRestartRequiredFromSpecialFolderMessageOnly, shouldWarnPortConflict, spacerLine, specialFolderChangeDetected, specialFoldersSetupSummary, stampReadyDistExtensionId, stampReadyKnownExtensionId, toPosixPath, treeWithDistFilesBrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, withDarkMode, writingTypeDefinitions, writingTypeDefinitionsError, zipArtifactReady };
1896
+ export { BUILD_COMMAND_DEFAULTS, CHROMIUM_FAMILY_ALIASES, DEV_COMMAND_DEFAULTS, GECKO_FAMILY_ALIASES, PlaywrightPlugin, START_BUILD_DEFAULTS, assertNoManagedDependencyConflicts, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, createPlaywrightMetadataWriter, devServerRestarting, devServerStartTimeout, extensionJsRunnerError, extensionPreview, getPreloadedEnvKeys, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, isChromiumBasedBrowser, isGeckoBasedBrowser, isWebkitBasedBrowser, 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 };