extension-develop 4.1.31 → 4.1.32

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 (88) hide show
  1. package/README.md +2 -0
  2. package/dist/105~0.mjs +1 -1
  3. package/dist/177~0.mjs +87 -19
  4. package/dist/273~0.mjs +13 -3
  5. package/dist/363~0.mjs +1874 -0
  6. package/dist/{896~0.mjs → 469~0.mjs} +116 -586
  7. package/dist/519~0.mjs +21 -8
  8. package/dist/616~0.mjs +1 -1
  9. package/dist/771~0.mjs +103 -0
  10. package/dist/832~0.mjs +229 -463
  11. package/dist/840~0.mjs +1189 -54
  12. package/dist/846~0.mjs +453 -0
  13. package/dist/852~0.mjs +8 -6
  14. package/dist/bridge.mjs +3 -2
  15. package/dist/command-preview.d.ts +1 -0
  16. package/dist/contract/codes.json +39 -29
  17. package/dist/contract/envelope.schema.json +16 -0
  18. package/dist/contract/golden.build.compile.json +20 -3
  19. package/dist/contract/golden.eval.csp-blocks-eval.page.json +15 -0
  20. package/dist/css-parse-guard-loader.mjs +3 -1
  21. package/dist/dead-css-url-loader.mjs +129 -13
  22. package/dist/dev-server/cleanup.d.ts +1 -1
  23. package/dist/dev-server/lifecycle-stream.d.ts +14 -3
  24. package/dist/dev-server/session-start-prune.d.ts +13 -0
  25. package/dist/dev-server~0.mjs +91 -14
  26. package/dist/ensure-hmr-for-scripts.js +4 -8
  27. package/dist/ensure-hmr-for-scripts.mjs +4 -8
  28. package/dist/extension-js-devtools/build-stamp.json +2 -2
  29. package/dist/extension-js-theme/build-stamp.json +2 -2
  30. package/dist/feature-scripts-content-script-wrapper.js +7 -4
  31. package/dist/feature-scripts-content-script-wrapper.mjs +7 -4
  32. package/dist/lib/build-summary.d.ts +4 -1
  33. package/dist/lib/coded-warnings.d.ts +3 -0
  34. package/dist/lib/compilation-diagnostics.d.ts +23 -0
  35. package/dist/lib/config-loader.d.ts +2 -2
  36. package/dist/lib/config-resolved-plugin.d.ts +3 -2
  37. package/dist/lib/corepack-registry.d.ts +3 -0
  38. package/dist/lib/diagnostic-code.d.ts +6 -0
  39. package/dist/lib/merge-options.d.ts +1 -0
  40. package/dist/lib/messages.d.ts +4 -1
  41. package/dist/lib/messaging.d.ts +12 -4
  42. package/dist/lib/output-files.d.ts +11 -0
  43. package/dist/lib/package-manager.d.ts +2 -2
  44. package/dist/module.mjs +2 -1
  45. package/dist/plugin-browsers/index.d.ts +1 -0
  46. package/dist/plugin-compatibility/compatibility-lib/free-browser-references.d.ts +9 -0
  47. package/dist/plugin-css/css-lib/dead-url-refs.d.ts +5 -1
  48. package/dist/plugin-css/css-lib/inline-content-script-css.d.ts +4 -2
  49. package/dist/plugin-css/css-lib/line-rewrite-source-map.d.ts +8 -0
  50. package/dist/plugin-css/dead-css-url-loader.d.ts +0 -2
  51. package/dist/plugin-css/public-css-url-loader.d.ts +8 -3
  52. package/dist/plugin-playwright/index.d.ts +9 -4
  53. package/dist/plugin-reload/classify-reload.d.ts +2 -0
  54. package/dist/plugin-reload/messages.d.ts +1 -0
  55. package/dist/plugin-reload/reload-lib/dev-content-scripts.d.ts +4 -0
  56. package/dist/plugin-reload/steps/prune-unreachable-chunks.d.ts +5 -0
  57. package/dist/plugin-special-folders/messages.d.ts +1 -1
  58. package/dist/plugin-special-folders/prune-removed-public-files.d.ts +7 -0
  59. package/dist/plugin-static-assets/check-namespace-imports.d.ts +4 -0
  60. package/dist/plugin-static-assets/static-assets-lib/asset-output-name.d.ts +8 -0
  61. package/dist/plugin-static-assets/static-assets-lib/messages.d.ts +1 -0
  62. package/dist/plugin-web-extension/feature-html/html-lib/utils.d.ts +2 -1
  63. package/dist/plugin-web-extension/feature-icons/messages.d.ts +1 -4
  64. package/dist/plugin-web-extension/feature-locales/get-locales.d.ts +2 -0
  65. package/dist/plugin-web-extension/feature-locales/messages.d.ts +3 -1
  66. package/dist/plugin-web-extension/feature-locales/validation.d.ts +1 -0
  67. package/dist/plugin-web-extension/feature-manifest/manifest-lib/filter-keys-safari.d.ts +1 -0
  68. package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/content_scripts.d.ts +1 -0
  69. package/dist/plugin-web-extension/feature-manifest/messages.d.ts +1 -0
  70. package/dist/plugin-web-extension/feature-scripts/index.d.ts +2 -0
  71. package/dist/plugin-web-extension/feature-scripts/messages.d.ts +4 -3
  72. package/dist/plugin-web-extension/feature-scripts/scripts-lib/load-time-constants.d.ts +11 -0
  73. package/dist/plugin-web-extension/feature-scripts/steps/trace-runtime-loaded-files.d.ts +4 -0
  74. package/dist/plugin-web-extension/feature-scripts/steps/warn-missing-build-constants.d.ts +24 -0
  75. package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/declared-pages.d.ts +2 -0
  76. package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/resolve-war.d.ts +5 -0
  77. package/dist/plugin-web-extension/index.d.ts +1 -0
  78. package/dist/plugin-web-extension/shared/classic-concat.d.ts +1 -0
  79. package/dist/plugin-web-extension/shared/compilation-issues.d.ts +1 -1
  80. package/dist/preprocessor-passthrough-loader.mjs +3 -1
  81. package/dist/public-css-url-loader.mjs +1 -1
  82. package/dist/rspack-config~0.mjs +4925 -5885
  83. package/dist/stats-handler~0.mjs +12 -4
  84. package/dist/types.d.ts +19 -2
  85. package/dist/zip~0.mjs +20 -2
  86. package/package.json +4 -4
  87. package/dist/300~0.mjs +0 -394
  88. package/dist/747~0.mjs +0 -90
package/dist/832~0.mjs CHANGED
@@ -1,464 +1,179 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
- import { createRequire, register } from "node:module";
3
- import { pathToFileURL } from "node:url";
4
- import dotenv from "dotenv";
2
+ import { createRequire } from "node:module";
3
+ import pintor from "pintor";
5
4
  import { createHash } from "node:crypto";
6
5
  import { fetchExtensionFromStore } from "extension-from-store";
7
6
  import node_fs from "node:fs";
8
7
  import node_path from "node:path";
9
8
  import { getSpecialFoldersData } from "browser-extension-manifest-fields";
10
- import pintor from "pintor";
11
- import { configWrongShape, getDirs, computePreviewOutputPath, asAbsolute, previewingSourceFallback, browserRunnerDisabled, starting, spacerLine, debugDirs, browserArtifactsDir, isUsingExperimentalConfig as messages_isUsingExperimentalConfig, configBrowserOrThrow, devtoolsEngineFor, resolveProjectStructureSync, codedError, previewHasNothingToRun, eventsPath as session_paths_eventsPath, anotherDevSessionActive, displayPath, previewing, debugPreviewOutput, ensureSessionArtifactsIgnoreFile, readyContractPath, debugBrowser, normalizeBrowser, configUnknownKeys, configLoadingError, previewingCustomOutput, getProjectStructure, managedDependencyCopyWarning, getDistPath } from "./896~0.mjs";
12
- import { humanWarn, isDebug, CODES, humanLine, prefix as messaging_prefix, stripChannelPrefix } from "./852~0.mjs";
13
- import { isChromiumBasedBrowser, isEmulatorBrowser, isGeckoBasedBrowser, stripBom, parseJsonSafe, isWebkitBasedBrowser } from "./937~0.mjs";
9
+ import { browserRowValue, humanWarn, CODES, artifactNoun, prefix as messaging_prefix, card, humanLine, debugLine, stripChannelPrefix, isDebug } from "./852~0.mjs";
10
+ import { devtoolsEngineFor, getDirs, computePreviewOutputPath, previewHasNothingToRun, asAbsolute, anotherDevSessionActive, previewingSourceFallback, displayPath, previewing, starting, debugPreviewOutput, normalizeBrowser, debugDirs, debugBrowser, collapseHomeDir, previewingCustomOutput, getDistPath, managedDependencyCopyWarning, getProjectStructure, configBrowserOrThrow } from "./469~0.mjs";
14
11
  import { readProjectDependencies } from "./731~0.mjs";
12
+ import { loadCommandConfig, loadBrowserConfig, loadProjectConfigDefaults, findConfigFile } from "./846~0.mjs";
13
+ import { stripBom, isEmulatorBrowser, isChromiumBasedBrowser, isWebkitBasedBrowser, parseJsonSafe, isGeckoBasedBrowser } from "./937~0.mjs";
14
+ import { eventsPath as session_paths_eventsPath, readyContractPath, ensureSessionArtifactsIgnoreFile, browserArtifactsDir } from "./771~0.mjs";
15
15
  import { isScriptsFolderEntry, rememberedFolders, publicFolderSetting } from "./471~0.mjs";
16
16
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
17
17
  import { dirname as __rspack_dirname } from "node:path";
18
18
  var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
19
19
  import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
20
- import * as __rspack_external_node_os_4f3c9d58 from "node:os";
21
20
  import * as __rspack_external_node_path_806ed179 from "node:path";
22
- import * as __rspack_external_node_vm_ef240610 from "node:vm";
23
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.31","El":{"@babel/core":"7.29.7","@babel/preset-typescript":"7.29.7","@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","babel-loader":"10.1.1","babel-preset-solid":"1.9.15","browser-extension-manifest-fields":"^3.0.2","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^18.0.0","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"}}');
24
- const preloadedEnvKeys = new Set();
25
- function getPreloadedEnvKeys() {
26
- return preloadedEnvKeys;
27
- }
28
- const ENV_PRELOAD_ORDER = [
29
- '.env.defaults',
30
- '.env',
31
- '.env.local',
32
- '.env.development'
33
- ];
34
- function applyEnvFile(filePath, shellOwned) {
35
- const parsed = dotenv.parse(__rspack_external_node_fs_1b05aee1.readFileSync(filePath));
36
- for (const [key, value] of Object.entries(parsed))if (!shellOwned.has(key)) {
37
- process.env[key] = value;
38
- preloadedEnvKeys.add(key);
39
- }
21
+ const pending = [];
22
+ function recordCodedWarning(code, text) {
23
+ const line = `${code}: ${text}`;
24
+ if (!pending.includes(line)) pending.push(line);
40
25
  }
41
- function unwrapDefaultExport(loaded) {
42
- if (loaded && 'object' == typeof loaded && 'default' in loaded) return loaded.default;
43
- return loaded;
26
+ function takeCodedWarnings() {
27
+ return pending.splice(0);
44
28
  }
45
- function loadCommonJsConfigWithStableDirname(absolutePath) {
46
- const code = __rspack_external_node_fs_1b05aee1.readFileSync(absolutePath, 'utf-8');
47
- const dirname = __rspack_external_node_path_806ed179.dirname(absolutePath);
48
- const requireFn = createRequire(absolutePath);
49
- const module = {
50
- exports: {}
51
- };
52
- const exports = module.exports;
53
- const wrapped = `(function (exports, require, module, __filename, __dirname) {\n${code}\n})`;
54
- const fn = new __rspack_external_node_vm_ef240610.Script(wrapped, {
55
- filename: absolutePath
56
- }).runInThisContext();
57
- fn(exports, requireFn, module, absolutePath, dirname);
58
- return unwrapDefaultExport(module.exports);
59
- }
60
- function findNearestWorkspaceRoot(startDir) {
61
- let current = __rspack_external_node_path_806ed179.resolve(startDir);
62
- while(true){
63
- if (__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(current, 'pnpm-workspace.yaml'))) return current;
64
- const parent = __rspack_external_node_path_806ed179.dirname(current);
65
- if (parent === current) return;
66
- current = parent;
67
- }
29
+ const cjsRequire = createRequire(import.meta.url);
30
+ function getLoggingPrefix(type) {
31
+ return messaging_prefix(type);
68
32
  }
69
- function preloadEnvFilesFromDir(envDir) {
70
- let loadedAny = false;
71
- const shellOwned = new Set(Object.keys(process.env).filter((key)=>!preloadedEnvKeys.has(key)));
72
- for (const filename of ENV_PRELOAD_ORDER){
73
- const filePath = __rspack_external_node_path_806ed179.join(envDir, filename);
74
- if (__rspack_external_node_fs_1b05aee1.existsSync(filePath)) try {
75
- applyEnvFile(filePath, shellOwned);
76
- loadedAny = true;
77
- } catch {}
78
- }
79
- return {
80
- loadedAny,
81
- envDir
82
- };
83
- }
84
- const PROJECT_CONFIG_FILENAMES = [
85
- 'extension.config.js',
86
- 'extension.config.mjs',
87
- 'extension.config.cjs'
88
- ];
89
- function configCandidatesIn(dir) {
90
- return PROJECT_CONFIG_FILENAMES.map((name)=>__rspack_external_node_path_806ed179.join(dir, name));
33
+ function messages_ready(mode, browser) {
34
+ const noun = artifactNoun(browser);
35
+ const state = pintor.green(`ready for ${mode}`);
36
+ const watching = 'development' === mode ? ' Watching for file changes.' : '';
37
+ return `${getLoggingPrefix('success')} ${noun} ${state}.${watching}`;
91
38
  }
92
- function findConfigFileIn(dir) {
93
- return configCandidatesIn(dir).find((p)=>__rspack_external_node_fs_1b05aee1.existsSync(p));
94
- }
95
- function resolveManifestDir(projectPath) {
39
+ function readJsonRecord(filePath) {
96
40
  try {
97
- if (!__rspack_external_node_fs_1b05aee1.statSync(projectPath).isDirectory()) return;
41
+ return JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(filePath, 'utf8'));
98
42
  } catch {
99
- return;
100
- }
101
- try {
102
- const structure = resolveProjectStructureSync(projectPath, {
103
- quiet: true
104
- });
105
- return __rspack_external_node_path_806ed179.dirname(structure.manifestPath);
106
- } catch {
107
- return;
43
+ return null;
108
44
  }
109
45
  }
110
- function findConfigFile(projectPath) {
111
- const atRoot = findConfigFileIn(projectPath);
112
- if (atRoot) return atRoot;
113
- const manifestDir = resolveManifestDir(projectPath);
114
- if (!manifestDir || __rspack_external_node_path_806ed179.resolve(manifestDir) === __rspack_external_node_path_806ed179.resolve(projectPath)) return;
115
- return findConfigFileIn(manifestDir);
46
+ function capitalizeToken(value) {
47
+ if ('chromium-emulator' === value) return 'Emulated Chromium';
48
+ return value.split('-').filter(Boolean).map((token)=>token.charAt(0).toUpperCase() + token.slice(1)).join('-');
116
49
  }
117
- function projectConfigCandidatePaths(projectPath) {
118
- const dirs = [
119
- projectPath
120
- ];
121
- const manifestDir = resolveManifestDir(projectPath);
122
- if (manifestDir && __rspack_external_node_path_806ed179.resolve(manifestDir) !== __rspack_external_node_path_806ed179.resolve(projectPath)) dirs.push(manifestDir);
123
- return dirs.flatMap((dir)=>configCandidatesIn(dir));
124
- }
125
- function preloadEnvFiles(projectDir) {
126
- const local = preloadEnvFilesFromDir(projectDir);
127
- if (local.loadedAny) return local;
128
- const workspaceRoot = findNearestWorkspaceRoot(projectDir);
129
- if (workspaceRoot && workspaceRoot !== projectDir) return preloadEnvFilesFromDir(workspaceRoot);
130
- return local;
131
- }
132
- const IMPORT_META_ENV_GLOBAL = '__EXTENSION_IMPORT_META_ENV__';
133
- const IMPORT_META_ENV_HOOK = `
134
- import {readFileSync} from 'node:fs'
135
- import {fileURLToPath} from 'node:url'
136
-
137
- const CONFIG_FILE = /(^|\\/)extension\\.config\\.(js|mjs)$/
138
-
139
- export async function load(url, context, nextLoad) {
140
- if (!url.startsWith('file:') || !CONFIG_FILE.test(new URL(url).pathname)) {
141
- return nextLoad(url, context)
142
- }
143
-
144
- let text
145
-
146
- try {
147
- text = readFileSync(fileURLToPath(url), 'utf8')
148
- } catch {
149
- return nextLoad(url, context)
150
- }
151
-
152
- if (!text.includes('import.meta.env')) return nextLoad(url, context)
153
-
154
- // import.meta is module syntax, so the format is settled here. Left to
155
- // Node, a package.json without "type" means a reparse and a warning per run.
156
- const loaded = await nextLoad(url, {...context, format: 'module'})
157
- const source =
158
- typeof loaded.source === 'string'
159
- ? loaded.source
160
- : Buffer.from(loaded.source).toString('utf8')
161
-
162
- return {
163
- ...loaded,
164
- source: source.replaceAll(
165
- 'import.meta.env',
166
- 'globalThis.${IMPORT_META_ENV_GLOBAL}'
167
- )
168
- }
169
- }
170
- `;
171
- let importMetaEnvHookRegistered = false;
172
- function prepareImportMetaEnv(absolutePath) {
173
- let source = '';
174
- try {
175
- source = __rspack_external_node_fs_1b05aee1.readFileSync(absolutePath, 'utf-8');
176
- } catch {
177
- return;
178
- }
179
- if (!source.includes('import.meta.env')) return;
180
- globalThis[IMPORT_META_ENV_GLOBAL] = Object.freeze({
181
- ...process.env
50
+ function getExtensionVersion() {
51
+ return process.env.EXTENSION_DEVELOP_VERSION || process.env.EXTENSION_CLI_VERSION || (()=>{
52
+ try {
53
+ return cjsRequire('../package.json').version;
54
+ } catch {
55
+ return 'unknown';
56
+ }
57
+ })();
58
+ }
59
+ function browserRunnerDisabled(args) {
60
+ const manifest = readJsonRecord(args.manifestPath);
61
+ const ready = readJsonRecord(args.readyPath);
62
+ const browserLabel = capitalizeToken(String(args.browser || 'unknown'));
63
+ const runId = String(ready?.runId || '').trim();
64
+ const pid = Number.isInteger(ready?.pid) ? String(ready?.pid) : '';
65
+ const runLabel = runId ? `${runId}${pid ? ` · PID ${pid}` : ''}` : pid ? `PID ${pid}` : '';
66
+ const extensionName = String(manifest?.name || 'Extension');
67
+ const extensionVersion = String(manifest?.version || '').trim();
68
+ const extensionLabel = extensionVersion ? `${extensionName} ${extensionVersion}` : extensionName;
69
+ const extensionJsVersion = getExtensionVersion();
70
+ const updateSuffix = process.env.EXTENSION_CLI_UPDATE_SUFFIX || '';
71
+ if (updateSuffix) delete process.env.EXTENSION_CLI_UPDATE_SUFFIX;
72
+ return card({
73
+ version: extensionJsVersion,
74
+ suffix: updateSuffix,
75
+ rows: [
76
+ {
77
+ label: 'Browser',
78
+ value: browserRowValue(String(args.browser || 'unknown'), `${browserLabel} (no-browser mode)`)
79
+ },
80
+ {
81
+ label: 'Extension',
82
+ value: extensionLabel
83
+ },
84
+ {
85
+ label: 'Run ID',
86
+ value: runLabel
87
+ },
88
+ {
89
+ label: 'Output',
90
+ value: collapseHomeDir(String(args.distPath || '').trim())
91
+ }
92
+ ]
182
93
  });
183
- if (importMetaEnvHookRegistered) return;
184
- try {
185
- register(`data:text/javascript,${encodeURIComponent(IMPORT_META_ENV_HOOK)}`);
186
- importMetaEnvHookRegistered = true;
187
- } catch {}
188
94
  }
189
- class ConfigShapeError extends Error {
190
- code = CODES.E_CONFIG_LOAD;
95
+ function shouldWarnPortConflict(requested, actual) {
96
+ const requestedPort = Number(requested);
97
+ return Number.isFinite(requestedPort) && 0 !== requestedPort && requestedPort !== actual;
191
98
  }
192
- function configLoadError(configPath, cause) {
193
- return Object.assign(codedError(CODES.E_CONFIG_LOAD, configLoadingError(configPath, cause)), {
194
- cause
195
- });
99
+ function emulatorViewerUrl(url) {
100
+ return `${getLoggingPrefix('info')} Emulated Chromium runs in a web page. Open this address to load your extension:\n${pintor.underline(url)}`;
196
101
  }
197
- function isConfigLoadError(error) {
198
- return error?.code === CODES.E_CONFIG_LOAD;
199
- }
200
- const loadedConfigCache = new Map();
201
- const reportedConfigPaths = new Set();
202
- function reportConfigLoadingErrorOnce(configPath, error) {
203
- if (isConfigLoadError(error)) return;
204
- const key = __rspack_external_node_path_806ed179.resolve(configPath);
205
- if (reportedConfigPaths.has(key)) return;
206
- reportedConfigPaths.add(key);
207
- console.error(configLoadingError(configPath, error));
208
- }
209
- const CONFIG_TOP_LEVEL_KEYS = [
210
- 'browser',
211
- 'commands',
212
- 'config',
213
- 'configResolved',
214
- 'define',
215
- 'extensions',
216
- 'folders',
217
- 'perfBudgets',
218
- 'transpilePackages'
219
- ];
220
- function assertConfigShape(configPath, value) {
221
- if (void 0 === value) return;
222
- if ('object' != typeof value || null === value || Array.isArray(value)) throw new ConfigShapeError(configWrongShape(configPath, value));
223
- const unknown = Object.keys(value).filter((key)=>!CONFIG_TOP_LEVEL_KEYS.includes(key));
224
- if (unknown.length > 0) console.error(configUnknownKeys(configPath, unknown, CONFIG_TOP_LEVEL_KEYS));
225
- }
226
- async function loadConfigFile(configPath) {
227
- const absolutePath = __rspack_external_node_path_806ed179.resolve(configPath);
228
- const cached = loadedConfigCache.get(absolutePath);
229
- if (cached) return cached;
230
- const loading = loadConfigFileUncached(absolutePath).then((value)=>{
231
- assertConfigShape(absolutePath, value);
232
- return value;
233
- });
234
- loadedConfigCache.set(absolutePath, loading);
235
- try {
236
- return await loading;
237
- } catch (error) {
238
- loadedConfigCache.delete(absolutePath);
239
- throw error;
240
- }
102
+ function portInUse(requestedPort, newPort) {
103
+ return `${getLoggingPrefix('warn')} Port ${requestedPort} is in use.\nThe dev server listens on port ${newPort} instead.`;
241
104
  }
242
- async function loadConfigFileUncached(absolutePath) {
243
- const projectDir = __rspack_external_node_path_806ed179.dirname(absolutePath);
244
- preloadEnvFiles(projectDir);
245
- try {
246
- if (absolutePath.endsWith('.cjs')) {
247
- const requireFn = createRequire(import.meta.url);
248
- const required = requireFn(absolutePath);
249
- return unwrapDefaultExport(required);
250
- }
251
- prepareImportMetaEnv(absolutePath);
252
- const module = await import(pathToFileURL(absolutePath).href);
253
- return unwrapDefaultExport(module);
254
- } catch (err) {
255
- const error = err;
256
- try {
257
- if (!absolutePath.endsWith('.mjs')) {
258
- const requireFn = createRequire(import.meta.url);
259
- let required;
260
- try {
261
- required = requireFn(absolutePath);
262
- } catch (requireErr) {
263
- const message = String(error?.message || '') + ' ' + String(requireErr?.message || '');
264
- const looksLikeCommonJsInEsm = message.includes('require is not defined in ES module scope') || message.includes('Cannot use import statement outside a module') || message.includes('ERR_REQUIRE_ESM');
265
- if (looksLikeCommonJsInEsm) try {
266
- required = loadCommonJsConfigWithStableDirname(absolutePath);
267
- } catch {
268
- const tmpDir = __rspack_external_node_fs_1b05aee1.mkdtempSync(__rspack_external_node_path_806ed179.join(__rspack_external_node_os_4f3c9d58.tmpdir(), 'extension-config-'));
269
- try {
270
- const tmpCjsPath = __rspack_external_node_path_806ed179.join(tmpDir, __rspack_external_node_path_806ed179.basename(absolutePath, __rspack_external_node_path_806ed179.extname(absolutePath)) + '.cjs');
271
- __rspack_external_node_fs_1b05aee1.copyFileSync(absolutePath, tmpCjsPath);
272
- required = requireFn(tmpCjsPath);
273
- } finally{
274
- try {
275
- __rspack_external_node_fs_1b05aee1.rmSync(tmpDir, {
276
- recursive: true,
277
- force: true
278
- });
279
- } catch {}
280
- }
281
- }
282
- else throw requireErr;
283
- }
284
- return unwrapDefaultExport(required);
285
- }
286
- } catch {}
287
- try {
288
- const content = __rspack_external_node_fs_1b05aee1.readFileSync(absolutePath, 'utf-8');
289
- return JSON.parse(content);
290
- } catch {
291
- throw configLoadError(absolutePath, error);
292
- }
293
- }
105
+ function devServerHostRefused(host) {
106
+ const name = host || 'an empty Host header';
107
+ return `${getLoggingPrefix('warn')} The dev server refused a request for the host ${pintor.yellow(name)}.\nAllow it with ${pintor.blue(`--allowed-hosts ${host || '<host>'}`)} or ${pintor.blue('commands.dev.allowedHosts')} in extension.config.js. Both take more than one host, comma-separated on the flag.`;
294
108
  }
295
- async function loadCustomConfig(projectPath) {
296
- const configPath = findConfigFile(projectPath);
297
- if (configPath) {
298
- if (await isUsingExperimentalConfig(projectPath)) try {
299
- const userConfig = await loadConfigFile(configPath);
300
- if (userConfig && 'function' == typeof userConfig.config) return userConfig.config;
301
- if (userConfig?.config && 'object' == typeof userConfig.config) {
302
- const partial = userConfig.config;
303
- return (config)=>{
304
- const requireFn = createRequire(import.meta.url);
305
- const { merge } = requireFn('webpack-merge');
306
- return merge(config, partial);
307
- };
308
- }
309
- } catch (err) {
310
- const error = err;
311
- reportConfigLoadingErrorOnce(configPath, error);
312
- throw err;
313
- }
314
- }
315
- return (config)=>config;
316
- }
317
- async function loadConfigResolvedHook(projectPath) {
318
- const configPath = findConfigFile(projectPath);
319
- if (!configPath) return;
320
- if (!await isUsingExperimentalConfig(projectPath)) return;
321
- const userConfig = await loadConfigFile(configPath);
322
- return 'function' == typeof userConfig?.configResolved ? userConfig.configResolved : void 0;
323
- }
324
- function typeOfDefineValue(value) {
325
- if (null === value) return 'null';
326
- if (Array.isArray(value)) return 'unknown[]';
327
- switch(typeof value){
328
- case 'string':
329
- return 'string';
330
- case 'number':
331
- return 'number';
332
- case 'boolean':
333
- return 'boolean';
334
- case 'object':
335
- return 'Record<string, unknown>';
336
- default:
337
- return 'unknown';
338
- }
109
+ function controlBridgeUnavailable(reason) {
110
+ return `${getLoggingPrefix('error')} Extension.js couldn't open the control port.\n${pintor.red(reason)}\nSaves will compile but nothing reloads in the browser. Restart the dev session, and if you passed --host make sure it is an address this machine can listen on.`;
339
111
  }
340
- function collectDefineTypes(into, define) {
341
- if (!define || 'object' != typeof define) return;
342
- for (const [key, value] of Object.entries(define)){
343
- const types = into.get(key) || new Set();
344
- types.add(typeOfDefineValue(value));
345
- into.set(key, types);
346
- }
112
+ function extensionJsRunnerError(error) {
113
+ return `${getLoggingPrefix('error')} Extension.js couldn't start the runner.\n${pintor.red(String(error))}`;
347
114
  }
348
- async function loadDefineTypes(projectPath) {
349
- const configPath = findConfigFile(projectPath);
350
- if (!configPath) return {};
351
- if (!await isUsingExperimentalConfig(projectPath)) return {};
352
- let userConfig;
353
- try {
354
- userConfig = await loadConfigFile(configPath);
355
- } catch {
356
- return {};
357
- }
358
- const found = new Map();
359
- collectDefineTypes(found, userConfig?.define);
360
- for (const scope of [
361
- userConfig?.browser,
362
- userConfig?.commands
363
- ])if (scope && 'object' == typeof scope) for (const entry of Object.values(scope))collectDefineTypes(found, entry?.define);
364
- const types = {};
365
- for (const [key, set] of found)types[key] = [
366
- ...set
367
- ].sort().join(' | ');
368
- return types;
369
- }
370
- async function loadProjectConfigDefaults(projectPath) {
371
- const configPath = findConfigFile(projectPath);
372
- if (configPath) {
373
- if (await isUsingExperimentalConfig(projectPath)) try {
374
- const userConfig = await loadConfigFile(configPath);
375
- return {
376
- ...userConfig?.extensions ? {
377
- extensions: userConfig.extensions
378
- } : {},
379
- ...Array.isArray(userConfig?.transpilePackages) ? {
380
- transpilePackages: userConfig.transpilePackages
381
- } : {},
382
- ...userConfig?.perfBudgets && 'object' == typeof userConfig.perfBudgets ? {
383
- perfBudgets: userConfig.perfBudgets
384
- } : {},
385
- ...userConfig?.define && 'object' == typeof userConfig.define ? {
386
- define: userConfig.define
387
- } : {},
388
- ...userConfig?.folders && 'object' == typeof userConfig.folders ? {
389
- folders: userConfig.folders
390
- } : {}
391
- };
392
- } catch (err) {
393
- const error = err;
394
- reportConfigLoadingErrorOnce(configPath, error);
395
- throw err;
396
- }
397
- }
398
- return {};
115
+ function autoExitModeEnabled(ms) {
116
+ return `${getLoggingPrefix('info')} Auto-exit is enabled.\nThe process exits after ${ms} ms of idle time.`;
399
117
  }
400
- async function loadCommandConfig(projectPath, command) {
401
- const configPath = findConfigFile(projectPath);
402
- if (configPath) {
403
- if (await isUsingExperimentalConfig(projectPath)) try {
404
- const userConfig = await loadConfigFile(configPath);
405
- return userConfig?.commands?.[command] || {};
406
- } catch (err) {
407
- const error = err;
408
- reportConfigLoadingErrorOnce(configPath, error);
409
- throw err;
410
- }
411
- }
412
- return {};
118
+ function autoExitTriggered(ms) {
119
+ return `${getLoggingPrefix('info')} Auto-exit triggered after ${ms} ms.\nThe process cleans up and exits now.`;
413
120
  }
414
- async function loadBrowserConfig(projectPath, browser = 'chrome') {
415
- const configPath = findConfigFile(projectPath);
416
- if (configPath) {
417
- if (await isUsingExperimentalConfig(projectPath)) try {
418
- const userConfig = await loadConfigFile(configPath);
419
- if (userConfig?.browser) {
420
- const browsers = userConfig.browser;
421
- const browserName = String(browser);
422
- if ('chromium-based' === browser) {
423
- if (browsers['chromium-based']) return browsers['chromium-based'];
424
- if (browsers.chromium) return browsers.chromium;
425
- } else if ('gecko-based' === browser) {
426
- if (browsers['gecko-based']) return browsers['gecko-based'];
427
- if (browsers.firefox) return browsers.firefox;
428
- } else if (isWebkitBasedBrowser(browserName)) {
429
- const direct = browsers[browserName];
430
- if (direct) return direct;
431
- if ('safari' !== browserName) {
432
- if (browsers['webkit-based']) return browsers['webkit-based'];
433
- if (browsers.safari) return browsers.safari;
434
- }
435
- } else {
436
- const direct = browsers[browserName];
437
- if (direct) return direct;
438
- }
439
- }
440
- } catch (err) {
441
- const error = err;
442
- reportConfigLoadingErrorOnce(configPath, error);
443
- throw err;
444
- }
445
- }
446
- return {
447
- browser: browser || 'chrome'
448
- };
121
+ function autoExitForceKill(ms) {
122
+ return `${getLoggingPrefix('warn')} The process didn't exit within ${ms} ms, so it exits forcibly now.`;
449
123
  }
450
- let userMessageDelivered = false;
451
- async function isUsingExperimentalConfig(projectPath) {
452
- const configPath = findConfigFile(projectPath);
453
- if (configPath) {
454
- if (!userMessageDelivered) {
455
- if (isDebug()) console.log(messages_isUsingExperimentalConfig('extension.config.js'));
456
- userMessageDelivered = true;
457
- }
458
- return true;
459
- }
460
- return false;
124
+ function devServerStartTimeout(ms) {
125
+ return [
126
+ `${getLoggingPrefix('warn')} The dev server didn't start within ${ms} ms.`,
127
+ "The bundler may have hit an error before emitting the first build.",
128
+ `If nothing else prints, set ${pintor.blue('EXTENSION_VERBOSE=1')} to see more logs.`
129
+ ].join('\n');
130
+ }
131
+ function manifestGoneDuringSession(manifestPath, projectDirGone) {
132
+ const what = projectDirGone ? 'The project directory disappeared during the session.' : 'The manifest.json file disappeared during the session.';
133
+ const where = projectDirGone ? __rspack_external_node_path_806ed179.dirname(manifestPath) : manifestPath;
134
+ return `${getLoggingPrefix('error')} ${what}\n${pintor.gray('NOT FOUND')} ${pintor.underline(collapseHomeDir(where))}\nThe last good build stays loaded. Restore it to keep working, or stop and run ${pintor.blue('extension dev')} again with the right path.`;
135
+ }
136
+ function bundlerFatalError(error) {
137
+ const text = error instanceof Error ? error.stack || error.message : String(error);
138
+ return `${getLoggingPrefix('error')} The build failed to start.\n${pintor.red(text)}`;
139
+ }
140
+ function devServerRestarting(request) {
141
+ const what = 'icons' === request.reason ? 'a manifest icon' : 'html' === request.reason ? 'an HTML entrypoint' : 'json' === request.reason ? 'a manifest JSON entry' : 'env' === request.reason ? 'an environment file' : "a manifest script entry";
142
+ const lines = [
143
+ `${getLoggingPrefix('info')} Restarting the dev server to pick up ${what} change…`
144
+ ];
145
+ if (request.pathChanged) lines.push(`${pintor.gray('CHANGED')} ${pintor.underline(displayPath(request.pathChanged))}`);
146
+ if (request.pathBefore) lines.push(`${pintor.gray('BEFORE')} ${pintor.underline(displayPath(request.pathBefore))}`);
147
+ if (request.pathAfter) lines.push(`${pintor.gray('AFTER')} ${pintor.underline(displayPath(request.pathAfter))}`);
148
+ return lines.join('\n');
149
+ }
150
+ function bundlerRecompiling() {
151
+ return `${getLoggingPrefix('info')} Recompiling due to file changes…`;
152
+ }
153
+ function noEntrypointsDetected(port) {
154
+ return [
155
+ `${getLoggingPrefix('warn')} The first compilation produced no entrypoints or assets.`,
156
+ `The dev server is running on 127.0.0.1:${port}, but nothing is being built.`,
157
+ "Possible causes:",
158
+ "- Empty or missing entry configuration.",
159
+ "- Extension plugins are disabled, so entries aren't derived from the manifest.",
160
+ "- All sources are ignored or excluded.",
161
+ `Set ${pintor.blue('EXTENSION_VERBOSE=1')} to see verbose logs, or review your extension config.`
162
+ ].join('\n');
163
+ }
164
+ function spacerLine() {
165
+ return ' ';
166
+ }
167
+ function runnerCleanupError(error) {
168
+ return `${messaging_prefix('error')} The dev server could not shut down cleanly: ${String(error?.message || error)}`;
169
+ }
170
+ function runnerUncaughtException(error) {
171
+ return `${messaging_prefix('error')} Uncaught exception in the dev server: ${String(error?.message || error)}`;
461
172
  }
173
+ function runnerUnhandledRejection(reason) {
174
+ return `${messaging_prefix('error')} Unhandled rejection in the dev server: ${String(reason?.message || reason)}`;
175
+ }
176
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.1.32","El":{"@babel/core":"7.29.7","@babel/preset-typescript":"7.29.7","@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.43","acorn":"^8.16.0","babel-loader":"10.1.1","babel-preset-solid":"1.9.15","browser-extension-manifest-fields":"^3.0.2","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^18.0.0","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":"11.0.0","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.43","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"}}');
462
177
  function sanitize(obj) {
463
178
  return Object.fromEntries(Object.entries(obj || {}).filter(([, value])=>void 0 !== value));
464
179
  }
@@ -550,6 +265,13 @@ function mergeOptionLayers(defaults, ...layers) {
550
265
  for (const layer of layers)result = mergeLayer(result, layer || {});
551
266
  return result;
552
267
  }
268
+ function isFalseProfile(value) {
269
+ return false === value || 'string' == typeof value && 'false' === value.trim().toLowerCase();
270
+ }
271
+ function falseProfileSource(merged, fromCommandLine) {
272
+ if (!isFalseProfile(merged)) return;
273
+ return isFalseProfile(fromCommandLine) ? 'flag' : 'config';
274
+ }
553
275
  function isReferencedAsModuleSpecifier(configSource, dep) {
554
276
  const escaped = dep.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
555
277
  const specifierRe = new RegExp(`['"\`]${escaped}(?:/[^'"\`]*)?['"\`]`);
@@ -571,6 +293,7 @@ function assertNoManagedDependencyConflicts(userManifestPath, projectPath) {
571
293
  return;
572
294
  }
573
295
  if (0 === duplicates.length) return;
296
+ recordCodedWarning(CODES.E_MANAGED_DEP_CONFLICT, `${__rspack_external_node_path_806ed179.basename(configPath)} loads its own copy of ${duplicates.map((name)=>`${name} (Extension.js ships ${shipped[name]})`).join(', ')}.`);
574
297
  warnOnce(managedDependencyCopyWarning(duplicates.map((name)=>({
575
298
  name,
576
299
  shipped: shipped[name]
@@ -714,6 +437,7 @@ function getSessionRunId(packageJsonDir, browser) {
714
437
  return getRunIdForSession(getPlaywrightMetadataDir(packageJsonDir, browser));
715
438
  }
716
439
  const writerEpochByMetadataDir = new Map();
440
+ const devOverDevWarnedByMetadataDir = new Set();
717
441
  function deriveDistExtensionId(browser, distPath) {
718
442
  try {
719
443
  if (isWebkitBasedBrowser(browser) || isEmulatorBrowser(browser)) return;
@@ -787,6 +511,7 @@ function detectLiveDevSessionOwner(readyPath, isAlive = (pid)=>{
787
511
  if (!isAlive(prev.pid)) return null;
788
512
  return {
789
513
  pid: prev.pid,
514
+ port: 'number' == typeof prev.port ? prev.port : null,
790
515
  runId: 'string' == typeof prev.runId ? prev.runId : '',
791
516
  instanceId: 'string' == typeof prev.instanceId ? prev.instanceId : void 0,
792
517
  instanceExplicit: true === prev.instanceExplicit
@@ -795,10 +520,6 @@ function detectLiveDevSessionOwner(readyPath, isAlive = (pid)=>{
795
520
  return null;
796
521
  }
797
522
  }
798
- function shouldWarnDevOverDev(owner, my) {
799
- if (owner.instanceExplicit && my.instanceExplicit && owner.instanceId && my.instanceId && owner.instanceId !== my.instanceId) return false;
800
- return true;
801
- }
802
523
  function getPlaywrightMetadataDir(packageJsonDir, browser) {
803
524
  return asAbsolute(browserArtifactsDir(packageJsonDir, browser));
804
525
  }
@@ -817,10 +538,10 @@ function createPlaywrightMetadataWriter(options) {
817
538
  const liveOwner = detectLiveDevSessionOwner(readyPath);
818
539
  const foreignLiveDevSession = 'dev' !== options.command && liveOwner ? liveOwner : null;
819
540
  if (foreignLiveDevSession) console.warn(`[extension] a live dev session (pid ${foreignLiveDevSession.pid}) owns ${readyPath}; this ${options.command} run will not rewrite the session's ready.json/events.ndjson. The output dir is shared, so the dev browser may pick up freshly ${options.command}-built files. Stop the dev session first for a clean ${options.command} receipt.`);
820
- if ('dev' === options.command && liveOwner && shouldWarnDevOverDev(liveOwner, {
821
- instanceId: options.instanceId,
822
- instanceExplicit: options.instanceExplicit
823
- })) humanWarn(anotherDevSessionActive(options.browser, liveOwner.pid, liveOwner.runId));
541
+ if ('dev' === options.command && liveOwner && !devOverDevWarnedByMetadataDir.has(metadataDir)) {
542
+ devOverDevWarnedByMetadataDir.add(metadataDir);
543
+ humanWarn(anotherDevSessionActive(options.browser, liveOwner.pid, liveOwner.runId));
544
+ }
824
545
  const toManagedRecords = (dirs)=>Array.isArray(dirs) && dirs.length > 0 && !isEmulatorBrowser(options.browser) ? managedExtensionRecords(options.browser, dirs) : void 0;
825
546
  let managedExtensionsExplicit = void 0 !== options.managedExtensionDirs;
826
547
  let managedExtensions = toManagedRecords(options.managedExtensionDirs);
@@ -891,6 +612,13 @@ function createPlaywrightMetadataWriter(options) {
891
612
  if (prev && sameRun) {
892
613
  if ('number' == typeof prev.cdpPort) payload.cdpPort = prev.cdpPort;
893
614
  if ('number' == typeof prev.rdpPort) payload.rdpPort = prev.rdpPort;
615
+ if ('string' == typeof prev.cdpFaultCode) {
616
+ payload.cdpFaultCode = prev.cdpFaultCode;
617
+ if ('string' == typeof prev.cdpFaultMessage) payload.cdpFaultMessage = prev.cdpFaultMessage;
618
+ }
619
+ if ('number' == typeof prev.webdriverPort) payload.webdriverPort = prev.webdriverPort;
620
+ if ('string' == typeof prev.webdriverSessionId) payload.webdriverSessionId = prev.webdriverSessionId;
621
+ if ('string' == typeof prev.webdriverUnavailableReason) payload.webdriverUnavailableReason = prev.webdriverUnavailableReason;
894
622
  if ('string' == typeof prev.profilePath) payload.profilePath = prev.profilePath;
895
623
  if ('number' == typeof prev.browserPid) payload.browserPid = prev.browserPid;
896
624
  if ('number' == typeof prev.launcherPid) payload.launcherPid = prev.launcherPid;
@@ -980,6 +708,11 @@ function createPlaywrightMetadataWriter(options) {
980
708
  compiledAt: null
981
709
  });
982
710
  },
711
+ writeCompiled (compiledAt) {
712
+ writeReady('starting', {
713
+ compiledAt
714
+ });
715
+ },
983
716
  writeReady (compiledAt) {
984
717
  void 0 === compiledAt ? writeReady('ready') : writeReady('ready', {
985
718
  compiledAt: compiledAt || nowISO()
@@ -1049,9 +782,11 @@ class PlaywrightPlugin {
1049
782
  writer;
1050
783
  command;
1051
784
  browser;
785
+ launchFollows;
1052
786
  constructor(options){
1053
787
  this.browser = String(options.browser || 'chromium');
1054
788
  this.command = options.command || ('development' === options.mode ? 'dev' : 'start');
789
+ this.launchFollows = true === options.launchFollows;
1055
790
  this.writer = createPlaywrightMetadataWriter({
1056
791
  packageJsonDir: options.packageJsonDir,
1057
792
  browser: this.browser,
@@ -1112,7 +847,8 @@ class PlaywrightPlugin {
1112
847
  durationMs: Number.isFinite(durationMs) ? durationMs : void 0,
1113
848
  errorCount: 0
1114
849
  });
1115
- this.writer.writeReady(nowISO());
850
+ if (this.launchFollows) this.writer.writeCompiled(nowISO());
851
+ else this.writer.writeReady(nowISO());
1116
852
  });
1117
853
  compiler.hooks.failed.tap(PlaywrightPlugin.name, (error)=>{
1118
854
  this.writer.appendEvent({
@@ -1301,7 +1037,7 @@ async function runExtensionFromStore(url, outDir) {
1301
1037
  outDir,
1302
1038
  extract: true,
1303
1039
  logger: isAuthor ? {
1304
- onInfo: (message)=>console.log(message),
1040
+ onInfo: (message)=>debugLine(message),
1305
1041
  onWarn: (message)=>console.warn(message),
1306
1042
  onError: (message, error)=>console.error(message, error)
1307
1043
  } : void 0
@@ -1391,9 +1127,10 @@ function specialFoldersSetupSummary(hasPublic, copyEnabled, ignoredCount) {
1391
1127
  function specialFolderChangeDetected(action, folder, relativePath) {
1392
1128
  return `${messaging_prefix('debug')} folders change=${action} scope=${folder} path=${relativePath}`;
1393
1129
  }
1394
- function unreferencedScriptDropped(relativePaths) {
1130
+ function packageScriptLeftOut(relativePaths) {
1131
+ const one = 1 === relativePaths.length;
1395
1132
  const list = relativePaths.map((entry)=>` ${pintor.yellow(entry)}`).join('\n');
1396
- return `${messaging_prefix('warn')} Dropped ${relativePaths.length} unreferenced ${1 === relativePaths.length ? 'entry' : 'entries'} from ${pintor.yellow("scripts/")}:\n${list}\nNothing in this project mentions ${1 === relativePaths.length ? 'that path' : 'those paths'}, so ${1 === relativePaths.length ? 'it was' : 'they were'} treated as dead code. Reference the path where you inject it (for example in the ${pintor.yellow("chrome.scripting.executeScript")} call) to keep ${1 === relativePaths.length ? 'it' : 'them'} in the build.`;
1133
+ return `${messaging_prefix('debug')} Left ${relativePaths.length} ${one ? 'entry' : 'entries'} in ${pintor.yellow("scripts/")} out of the build, a package.json script runs ${one ? 'it' : 'them'} and nothing in the extension names ${one ? 'it' : 'them'}:\n${list}`;
1397
1134
  }
1398
1135
  function publicFileCollidesWithEntry(publicPath, emittedPath) {
1399
1136
  return `${pintor.yellow(publicPath)} would be written to ${pintor.yellow(emittedPath)}, which this extension already generates from its manifest, so two different files claim one output path. Rename the file under ${pintor.yellow('public/')}, or move it to a subfolder that no generated page uses.`;
@@ -1482,7 +1219,28 @@ function importsNodeOnly(specifier) {
1482
1219
  const bare = specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
1483
1220
  return NODE_BUILTINS.has(specifier) || NODE_BUILTINS.has(bare) || NODE_BUILD_TOOLS.has(bare);
1484
1221
  }
1485
- function isNodeToolingScript(absPath) {
1222
+ const SIBLING_EXTS = [
1223
+ '',
1224
+ '.js',
1225
+ '.mjs',
1226
+ '.cjs',
1227
+ '.ts',
1228
+ '.mts',
1229
+ '.cts'
1230
+ ];
1231
+ function resolveSibling(fromFile, specifier) {
1232
+ const base = node_path.resolve(node_path.dirname(fromFile), specifier);
1233
+ for (const ext of SIBLING_EXTS){
1234
+ const candidate = `${base}${ext}`;
1235
+ try {
1236
+ if (node_fs.statSync(candidate).isFile()) return candidate;
1237
+ } catch {}
1238
+ }
1239
+ return null;
1240
+ }
1241
+ function isNodeToolingScript(absPath, seen = new Set()) {
1242
+ if (seen.has(absPath)) return false;
1243
+ seen.add(absPath);
1486
1244
  let source;
1487
1245
  try {
1488
1246
  source = node_fs.readFileSync(absPath, 'utf8');
@@ -1492,7 +1250,13 @@ function isNodeToolingScript(absPath) {
1492
1250
  if (/^#!.*\bnode\b/.test(source)) return true;
1493
1251
  const specifierRe = /(?:require\s*\(\s*|(?:import|export)\b[^'"()]*?\bfrom\s*|import\s*)['"]([^'"]+)['"]/g;
1494
1252
  let match;
1495
- while(null !== (match = specifierRe.exec(source)))if (importsNodeOnly(match[1])) return true;
1253
+ while(null !== (match = specifierRe.exec(source))){
1254
+ const specifier = match[1];
1255
+ if (importsNodeOnly(specifier)) return true;
1256
+ if (!specifier.startsWith('.')) continue;
1257
+ const sibling = resolveSibling(absPath, specifier);
1258
+ if (sibling && isNodeToolingScript(sibling, seen)) return true;
1259
+ }
1496
1260
  return false;
1497
1261
  }
1498
1262
  function filterNodeToolingScripts(list) {
@@ -1594,7 +1358,6 @@ function referenceSpellings(relativePath) {
1594
1358
  `${relativePath.slice(0, -ext.length)}.js`
1595
1359
  ];
1596
1360
  }
1597
- const warnedDroppedScripts = new Set();
1598
1361
  function packageScriptsText(projectRoot) {
1599
1362
  try {
1600
1363
  const raw = node_fs.readFileSync(node_path.join(projectRoot, 'package.json'), 'utf8');
@@ -1604,15 +1367,22 @@ function packageScriptsText(projectRoot) {
1604
1367
  return '';
1605
1368
  }
1606
1369
  }
1607
- function filterUnreferencedScripts(list, projectRoot) {
1370
+ const reportedDroppedScripts = new Set();
1371
+ function filterPackageToolingScripts(list, projectRoot) {
1608
1372
  const entries = Object.entries(list || {});
1609
1373
  if (0 === entries.length) return list || {};
1374
+ const tooling = packageScriptsText(projectRoot);
1375
+ if ('' === tooling) return list || {};
1376
+ const relativeTo = (abs)=>node_path.relative(projectRoot, abs).split(node_path.sep).join('/');
1377
+ const runByPackageScript = (entry)=>node_path.isAbsolute(entry) && tooling.includes(relativeTo(entry));
1378
+ const candidates = entries.flatMap(([, value])=>(Array.isArray(value) ? value : value ? [
1379
+ value
1380
+ ] : []).map(String));
1381
+ if (!candidates.some(runByPackageScript)) return list || {};
1610
1382
  const corpus = collectReferenceCorpus(projectRoot);
1611
1383
  if ('' === corpus) return list || {};
1612
- const isReferenced = (entry, key)=>{
1613
- const abs = String(entry);
1614
- if (!node_path.isAbsolute(abs)) return true;
1615
- const rel = node_path.relative(projectRoot, abs).split(node_path.sep).join('/');
1384
+ const isReferenced = (abs, key)=>{
1385
+ const rel = relativeTo(abs);
1616
1386
  const spellings = new Set([
1617
1387
  ...referenceSpellings(rel),
1618
1388
  `${key}${node_path.extname(rel)}`,
@@ -1628,23 +1398,18 @@ function filterUnreferencedScripts(list, projectRoot) {
1628
1398
  const paths = Array.isArray(value) ? value : value ? [
1629
1399
  value
1630
1400
  ] : [];
1631
- const kept = paths.filter((entry)=>isReferenced(String(entry), key));
1632
- for (const entry of paths){
1633
- if (kept.includes(entry)) continue;
1401
+ const kept = paths.filter((entry)=>{
1634
1402
  const abs = String(entry);
1635
- dropped.push(node_path.isAbsolute(abs) ? node_path.relative(projectRoot, abs).split(node_path.sep).join('/') : abs);
1636
- }
1403
+ return !runByPackageScript(abs) || isReferenced(abs, key);
1404
+ });
1405
+ for (const entry of paths)if (!kept.includes(entry)) dropped.push(relativeTo(String(entry)));
1637
1406
  if (0 !== kept.length) next[key] = Array.isArray(value) ? kept : kept[0];
1638
1407
  }
1639
- const tooling = packageScriptsText(projectRoot);
1640
- const quiet = dropped.filter((rel)=>tooling.includes(rel));
1641
- const loud = dropped.filter((rel)=>!tooling.includes(rel));
1642
- if (quiet.length > 0 && isDebug()) console.log(unreferencedScriptDropped(quiet));
1643
- if (loud.length > 0) {
1644
- const signature = loud.slice().sort().join('|');
1645
- if (!warnedDroppedScripts.has(signature)) {
1646
- warnedDroppedScripts.add(signature);
1647
- humanWarn(unreferencedScriptDropped(loud));
1408
+ if (dropped.length > 0 && isDebug()) {
1409
+ const signature = dropped.slice().sort().join('|');
1410
+ if (!reportedDroppedScripts.has(signature)) {
1411
+ reportedDroppedScripts.add(signature);
1412
+ debugLine(packageScriptLeftOut(dropped));
1648
1413
  }
1649
1414
  }
1650
1415
  return next;
@@ -1716,7 +1481,7 @@ function finalizeSpecialFoldersData(data, projectRoot, publicDir) {
1716
1481
  return {
1717
1482
  ...data,
1718
1483
  pages: filterPublicEntrypoints(data.pages, projectRoot, publicDir),
1719
- scripts: filterPublicEntrypoints(filterUnreferencedScripts(filterNodeToolingScripts(data.scripts), projectRoot), projectRoot, publicDir),
1484
+ scripts: filterPublicEntrypoints(filterPackageToolingScripts(filterNodeToolingScripts(data.scripts), projectRoot), projectRoot, publicDir),
1720
1485
  extensions: {
1721
1486
  dir: './extensions'
1722
1487
  }
@@ -2073,6 +1838,7 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2073
1838
  extensionsToLoad: unpackedExtensionDirsToLoad,
2074
1839
  noOpen: merged.noOpen,
2075
1840
  profile: merged.profile,
1841
+ profileSource: falseProfileSource(merged.profile, safePreviewOptions.profile),
2076
1842
  persistProfile: merged.persistProfile,
2077
1843
  preferences: darkDefaults.preferences,
2078
1844
  browserFlags: darkDefaults.browserFlags,
@@ -2101,4 +1867,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2101
1867
  warnings
2102
1868
  };
2103
1869
  }
2104
- export { BUILD_COMMAND_DEFAULTS, DEV_COMMAND_DEFAULTS, PlaywrightPlugin, START_BUILD_DEFAULTS, assertNoManagedDependencyConflicts, computeExtensionsToLoad, createPlaywrightMetadataWriter, extensionPreview, getPreloadedEnvKeys, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, loadBrowserConfig, loadCommandConfig, loadConfigResolvedHook, loadCustomConfig, loadDefineTypes, loadProjectConfigDefaults, mergeOptionLayers, package_namespaceObject, projectConfigCandidatePaths, publicFileCollidesWithEntry, publicFolderOffRef, publicFolderShadowed, publicMustBeAtProjectRoot, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, serverRestartRequiredFromSpecialFolderMessageOnly, specialFolderChangeDetected, specialFoldersSetupSummary, stampReadyDistExtensionId, stampReadyKnownExtensionId, withDarkMode };
1870
+ export { BUILD_COMMAND_DEFAULTS, DEV_COMMAND_DEFAULTS, PlaywrightPlugin, START_BUILD_DEFAULTS, assertNoManagedDependencyConflicts, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserRunnerDisabled, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, controlBridgeUnavailable, createPlaywrightMetadataWriter, detectLiveDevSessionOwner, devServerHostRefused, devServerRestarting, devServerStartTimeout, emulatorViewerUrl, extensionJsRunnerError, extensionPreview, falseProfileSource, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, manifestGoneDuringSession, mergeOptionLayers, messages_ready, noEntrypointsDetected, package_namespaceObject, portInUse, publicFileCollidesWithEntry, publicFolderOffRef, publicFolderShadowed, publicMustBeAtProjectRoot, recordCodedWarning, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, runnerCleanupError, runnerUncaughtException, runnerUnhandledRejection, sanitize, serverRestartRequiredFromSpecialFolderMessageOnly, shouldWarnPortConflict, spacerLine, specialFolderChangeDetected, specialFoldersSetupSummary, stampReadyDistExtensionId, stampReadyKnownExtensionId, takeCodedWarnings, withDarkMode };