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/840~0.mjs CHANGED
@@ -9,14 +9,16 @@ import pintor from "pintor";
9
9
  import { DefinePlugin, WebpackError } from "@rspack/core";
10
10
  import { pathToFileURL } from "node:url";
11
11
  import { EventEmitter } from "node:events";
12
- import { package_namespaceObject, loadCommandConfig, DEV_COMMAND_DEFAULTS, stampReadyDistExtensionId, loadProjectConfigDefaults, mergeOptionLayers, loadConfigResolvedHook, stampReadyKnownExtensionId, assertNoManagedDependencyConflicts, loadDefineTypes, loadCustomConfig, START_BUILD_DEFAULTS, loadBrowserConfig, resolveCompanionExtensionsConfig, BUILD_COMMAND_DEFAULTS, getSpecialFoldersDataForProjectRoot, withDarkMode } from "./832~0.mjs";
12
+ import { browserRowValue, CODES, ENVELOPE, prefix as messaging_prefix, humanLine, card, debugLine, isDebug, claimCardKey, isMachineOutput } from "./852~0.mjs";
13
+ import { package_namespaceObject, DEV_COMMAND_DEFAULTS, stampReadyDistExtensionId, takeCodedWarnings, mergeOptionLayers, shouldWarnPortConflict, stampReadyKnownExtensionId, assertNoManagedDependencyConflicts, recordCodedWarning, falseProfileSource, START_BUILD_DEFAULTS, resolveCompanionExtensionsConfig, BUILD_COMMAND_DEFAULTS, getSpecialFoldersDataForProjectRoot, withDarkMode } from "./832~0.mjs";
13
14
  import { stripBom, parseJsonSafe, isGeckoBasedBrowser } from "./937~0.mjs";
14
- import { browserRowValue, isDebug, prefix as messaging_prefix, claimCardKey, card } from "./852~0.mjs";
15
+ import { buildWarningsDetails, buildFailed, getDirs, listOutputFiles, zipArtifactReady, projectInstallFallbackToNpm, debugDirs, zipArtifactNotCreated, addonLintDependencyAttribution, browserLaunchFailed, collapseHomeDir, addonLintMore, extensionLoadRecovered, writingTypeDefinitionsError, extensionLoadStillRefused, operaBuildUnminified, buildAssetsTree, addonLintFailed, addonLintFailedDebug, safariBuildOutputNotFound, projectInstallScriptsDisabled, addonLintFinding, authorInstallNotice, addonLintSummary, codedError, configResolvedChangeIgnored, projectInstallInWorkspaceRoot, addonLintNotInstalled, writingTypeDefinitions, buildComplete, buildCommandFailed, needsInstall, relativeToDir, displayPath, updatingTypeDefinitions, runtimeChunkKeptInline, debugBrowser, normalizeBrowser, configBrowserOrThrow, debugOutputPath, safariInvalidBundleId, devCommandFailed, buildShareHint, getDistPath, getProjectStructure, debugSplitChunksNarrowed } from "./469~0.mjs";
15
16
  import { hasProjectDependency, findNearestProjectManifestDirSync } from "./731~0.mjs";
16
- import { buildWarningsDetails, stripAnsi, buildFailed, getDirs, zipArtifactReady, projectInstallFallbackToNpm, debugDirs, zipArtifactNotCreated, addonLintDependencyAttribution, browserLaunchFailed, collapseHomeDir, addonLintMore, extensionLoadRecovered, writingTypeDefinitionsError, extensionLoadStillRefused, operaBuildUnminified, buildAssetsTree, addonLintFailed, addonLintFailedDebug, safariBuildOutputNotFound, projectInstallScriptsDisabled, addonLintFinding, authorInstallNotice, addonLintSummary, needsInstall, configResolvedChangeIgnored, projectInstallInWorkspaceRoot, addonLintNotInstalled, writingTypeDefinitions, buildComplete, buildCommandFailed, relativeToDir, displayPath, configBrowserOrThrow, runtimeChunkKeptInline, humanLine, debugBrowser, normalizeBrowser, buildSummaryPath, debugOutputPath, safariInvalidBundleId, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore, devCommandFailed, buildShareHint, getDistPath, getProjectStructure, debugSplitChunksNarrowed } from "./896~0.mjs";
17
+ import { loadCommandConfig, loadDefineTypes, loadBrowserConfig, loadProjectConfigDefaults, loadConfigResolvedHook, loadCustomConfig } from "./846~0.mjs";
17
18
  import { isResourceUnderDirs, canonicalizeDir } from "./712~0.mjs";
19
+ import { buildSummaryPath, ensureSessionArtifactsIgnoreFile, ensureSessionStateInProjectGitignore } from "./771~0.mjs";
20
+ import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset } from "./640~0.mjs";
18
21
  import { publicRootsFor } from "./105~0.mjs";
19
- import { getCanonicalContentScriptEntryName } from "./640~0.mjs";
20
22
  import { rememberSpecialFoldersConfig } from "./471~0.mjs";
21
23
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
22
24
  import { dirname as __rspack_dirname } from "node:path";
@@ -24,6 +26,533 @@ var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(imp
24
26
  import * as __rspack_external_node_fs_1b05aee1 from "node:fs";
25
27
  import * as __rspack_external_node_path_806ed179 from "node:path";
26
28
  import * as __rspack_external_node_fs_promises_3b710708 from "node:fs/promises";
29
+ const NAMED_CODES = {
30
+ WARInvalidMatchPattern: CODES.E_WAR_INVALID,
31
+ WARStringEntryInMv3: CODES.E_WAR_INVALID,
32
+ LocalesLayoutWarning: CODES.E_LOCALES_LAYOUT,
33
+ LocalesFolderWithoutMessages: CODES.E_LOCALES_LAYOUT,
34
+ PerfBudgetWarning: CODES.E_PERF_BUDGET,
35
+ EnvNoMatchingFile: CODES.E_ENV_NO_MATCH,
36
+ JSONMissingFile: CODES.E_ENTRY_NOT_FOUND,
37
+ LocalesPluginMissingFile: CODES.E_ENTRY_NOT_FOUND,
38
+ HtmlEntrypointMissing: CODES.E_ENTRY_NOT_FOUND,
39
+ ScriptsMissingFile: CODES.E_ENTRY_NOT_FOUND,
40
+ HtmlPublicAssetMissing: CODES.E_ASSET_MISSING,
41
+ WARRelativeAssetMissing: CODES.E_ASSET_MISSING,
42
+ MissingCssAssetWarning: CODES.E_ASSET_MISSING,
43
+ RuntimeLoadedFileCompileFailed: CODES.E_SCRIPT_DEP_MISSING,
44
+ UnresolvedBareRequireWarning: CODES.E_SCRIPT_DEP_MISSING,
45
+ RemoteResourceBlocked: CODES.E_REMOTE_RESOURCE_BLOCKED,
46
+ ReservedScriptsFolder: CODES.E_RESERVED_FOLDER,
47
+ CssPreprocessorMissing: CODES.E_CSS_PREPROCESSOR_MISSING,
48
+ CssDeadRef: CODES.E_CSS_DEAD_REF,
49
+ CssParseWarning: CODES.E_CSS_PARSE,
50
+ BackgroundRequired: CODES.E_BACKGROUND_REQUIRED,
51
+ ContentScriptSyntax: CODES.E_CONTENT_SCRIPT_SYNTAX
52
+ };
53
+ const WRAPPER_NAMES = new Set([
54
+ 'Error',
55
+ 'ModuleBuildError',
56
+ 'ModuleError',
57
+ 'ModuleWarning',
58
+ 'ModuleParseError',
59
+ 'ModuleParseWarning',
60
+ 'ModuleNotFoundError'
61
+ ]);
62
+ const STYLESHEET = /\.(?:css|scss|sass|less|styl|pcss)(?:\?.*)?$/i;
63
+ function diagnostic_code_text(value) {
64
+ return 'string' == typeof value ? value : '';
65
+ }
66
+ function diagnosticName(issue) {
67
+ const err = issue ?? {};
68
+ const own = diagnostic_code_text(err.name);
69
+ if (own && !WRAPPER_NAMES.has(own)) return own;
70
+ const inner = diagnostic_code_text(err.error?.name);
71
+ if (inner && !WRAPPER_NAMES.has(inner)) return inner;
72
+ const header = /^([A-Za-z]\w*): /.exec(diagnostic_code_text(err.details))?.[1];
73
+ if (header && !WRAPPER_NAMES.has(header)) return header;
74
+ }
75
+ function isModuleNotFound(err) {
76
+ return 'ModuleNotFoundError' === err.name || /^\s*[×]?\s*Module not found:/.test(diagnostic_code_text(err.message));
77
+ }
78
+ function isSyntaxFailure(err) {
79
+ return 'ModuleBuildError' === err.name && /syntax/i.test(diagnostic_code_text(err.error?.name));
80
+ }
81
+ function diagnostic_code_resource(err) {
82
+ return diagnostic_code_text(err.module?.resource);
83
+ }
84
+ function diagnosticCode(issue, context = {}) {
85
+ const err = issue ?? {};
86
+ const declared = diagnostic_code_text(err.code);
87
+ if (declared && Object.prototype.hasOwnProperty.call(CODES, declared)) return declared;
88
+ const named = diagnosticName(issue);
89
+ if (named && NAMED_CODES[named]) return NAMED_CODES[named];
90
+ if (isModuleNotFound(err)) return CODES.E_MODULE_NOT_FOUND;
91
+ if (isSyntaxFailure(err) && context.contentScripts?.has(diagnostic_code_resource(err))) return CODES.E_CONTENT_SCRIPT_SYNTAX;
92
+ if ('ModuleParseError' === err.name && STYLESHEET.test(diagnostic_code_resource(err))) return CODES.E_CSS_PARSE;
93
+ }
94
+ const ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
95
+ function finite(value) {
96
+ return 'number' == typeof value && Number.isFinite(value) ? value : void 0;
97
+ }
98
+ function plainMessage(raw) {
99
+ return String(raw ?? '').replace(ANSI_PATTERN, '').split('\n').map((line, index)=>0 === index ? line.replace(/^\s*[×⚠]\s*/, '') : line.replace(/^\s*│ ?/, '')).join('\n').trim();
100
+ }
101
+ function fileOf(issue, root) {
102
+ if ('string' == typeof issue.file && issue.file) return issue.file;
103
+ const resource = issue.module?.resource;
104
+ if ('string' != typeof resource || !resource) return;
105
+ if (!root || !__rspack_external_node_path_806ed179.isAbsolute(resource)) return resource;
106
+ for (const base of [
107
+ root,
108
+ realpath(root)
109
+ ]){
110
+ const relative = __rspack_external_node_path_806ed179.relative(base, resource);
111
+ if (relative && !relative.startsWith('..') && !__rspack_external_node_path_806ed179.isAbsolute(relative)) return relative.split(__rspack_external_node_path_806ed179.sep).join('/');
112
+ }
113
+ return resource;
114
+ }
115
+ function realpath(dir) {
116
+ try {
117
+ return __rspack_external_node_fs_1b05aee1.realpathSync.native(dir);
118
+ } catch {
119
+ return dir;
120
+ }
121
+ }
122
+ function toDiagnostic(issue, severity, root, context = {}) {
123
+ const error = issue && 'object' == typeof issue ? issue : {};
124
+ const message = 'string' == typeof issue ? plainMessage(issue) : plainMessage(error.message);
125
+ const code = diagnosticCode(issue, context);
126
+ const file = fileOf(error, root);
127
+ const line = finite(error.loc?.start?.line);
128
+ const column = finite(error.loc?.start?.column);
129
+ const name = 'string' == typeof error.name && 'Error' !== error.name ? error.name : void 0;
130
+ return {
131
+ ...code ? {
132
+ code
133
+ } : {},
134
+ message,
135
+ ...file ? {
136
+ file
137
+ } : {},
138
+ ...void 0 !== line ? {
139
+ line
140
+ } : {},
141
+ ...void 0 !== column ? {
142
+ column
143
+ } : {},
144
+ severity,
145
+ ...name ? {
146
+ name
147
+ } : {}
148
+ };
149
+ }
150
+ function contentScriptResources(compilation) {
151
+ const found = new Set();
152
+ const getChunkModules = compilation?.chunkGraph?.getChunkModules;
153
+ try {
154
+ for (const [name, entry] of compilation?.entrypoints ?? [])if (name.startsWith("content_scripts/") && getChunkModules) {
155
+ for (const chunk of entry.chunks ?? [])for (const module of getChunkModules.call(compilation?.chunkGraph, chunk))if ('string' == typeof module?.resource) found.add(module.resource);
156
+ }
157
+ } catch {}
158
+ return found;
159
+ }
160
+ function compilationDiagnostics(input, root) {
161
+ const compilation = input;
162
+ const base = root ?? compilation?.compiler?.context;
163
+ const context = {
164
+ contentScripts: contentScriptResources(compilation)
165
+ };
166
+ const errors = Array.isArray(compilation?.errors) ? compilation.errors : [];
167
+ const warnings = Array.isArray(compilation?.warnings) ? compilation.warnings : [];
168
+ const all = [
169
+ ...errors.map((issue)=>toDiagnostic(issue, 'error', base, context)),
170
+ ...warnings.map((issue)=>toDiagnostic(issue, 'warning', base, context))
171
+ ];
172
+ return {
173
+ details: all.slice(0, 20),
174
+ truncated: all.length > 20
175
+ };
176
+ }
177
+ function warningCodes(input) {
178
+ const compilation = input;
179
+ const codes = new Map();
180
+ for (const issue of compilation?.warnings ?? []){
181
+ const code = diagnosticCode(issue);
182
+ if (!code) continue;
183
+ const message = issue && 'object' == typeof issue ? String(issue.message ?? '') : String(issue ?? '');
184
+ codes.set(message.replace(ANSI_PATTERN, '').trim(), code);
185
+ }
186
+ return codes;
187
+ }
188
+ const MAX_OUTPUT_CHARS = 2000;
189
+ const lifecycle_stream_ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
190
+ function isLifecycleStreamEnabled() {
191
+ return isMachineOutput();
192
+ }
193
+ function stripAnsi(input) {
194
+ return String(input || '').replace(lifecycle_stream_ANSI_PATTERN, '');
195
+ }
196
+ function readReadyContract(readyPath) {
197
+ if (!readyPath) return null;
198
+ try {
199
+ const parsed = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(readyPath, 'utf-8'));
200
+ return parsed && 'object' == typeof parsed ? parsed : null;
201
+ } catch {
202
+ return null;
203
+ }
204
+ }
205
+ function isProfileLocked(ready) {
206
+ if (!ready) return false;
207
+ const code = String(ready.code ?? '').trim().toLowerCase();
208
+ if ('profile_locked' === code || 'profile-locked' === code) return true;
209
+ if (true === ready.profileLocked) return true;
210
+ const message = String(ready.message ?? '');
211
+ return /profile\s+is\s+locked|singletonlock/i.test(message);
212
+ }
213
+ const USAGE_LAUNCH_CODES = new Set([
214
+ CODES.E_BROWSER_BINARY_INVALID,
215
+ CODES.E_BROWSER_BINARY_REQUIRED,
216
+ CODES.E_FLAG_NOT_SUPPORTED_HERE
217
+ ]);
218
+ function stampedLaunchFailureCode(ready) {
219
+ if ('browser_launch_failed' !== ready.code) return;
220
+ const code = ready.browserLaunchFailedCode;
221
+ return 'string' == typeof code && Object.prototype.hasOwnProperty.call(CODES, code) ? code : void 0;
222
+ }
223
+ function cdpFaultWarnings(ready) {
224
+ const code = ready?.cdpFaultCode;
225
+ if ('string' != typeof code || !Object.prototype.hasOwnProperty.call(CODES, code)) return [];
226
+ const message = 'string' == typeof ready?.cdpFaultMessage && ready.cdpFaultMessage.trim() ? ready.cdpFaultMessage.trim() : 'the CDP wire failed after launch';
227
+ return [
228
+ `${code}: ${message}`
229
+ ];
230
+ }
231
+ function toFiniteNumber(value) {
232
+ if ('number' == typeof value && Number.isFinite(value)) return value;
233
+ if ('string' == typeof value) {
234
+ const parsed = Number.parseInt(value, 10);
235
+ return Number.isFinite(parsed) ? parsed : null;
236
+ }
237
+ return null;
238
+ }
239
+ class LifecycleStream {
240
+ options;
241
+ writeLine;
242
+ successfulCompiles = 0;
243
+ compileAttempts = 0;
244
+ readyEmitted = false;
245
+ readyErrorEmitted = false;
246
+ browserExitEmitted = false;
247
+ interruptEmitted = false;
248
+ terminalEmitted = false;
249
+ startingEmitted = false;
250
+ boundPort = null;
251
+ exitWatcher;
252
+ launchFailureWatcher;
253
+ constructor(options){
254
+ this.options = options;
255
+ this.writeLine = options.write || ((line)=>process.stdout.write(line));
256
+ }
257
+ get enabled() {
258
+ return isLifecycleStreamEnabled();
259
+ }
260
+ emit(frame) {
261
+ if (!this.enabled) return null;
262
+ this.writeLine(`${JSON.stringify(frame)}\n`);
263
+ return frame;
264
+ }
265
+ sessionValue(extra = {}) {
266
+ const ready = readReadyContract(this.options.readyPath);
267
+ const port = toFiniteNumber(ready?.port) ?? this.boundPort;
268
+ return {
269
+ command: this.options.command,
270
+ browser: this.options.browser,
271
+ distPath: this.options.distPath,
272
+ pid: process.pid,
273
+ port,
274
+ ...this.options.readyPath ? {
275
+ readyPath: this.options.readyPath
276
+ } : {},
277
+ ...this.options.eventsPath ? {
278
+ eventsPath: this.options.eventsPath
279
+ } : {},
280
+ ...'string' == typeof ready?.runId ? {
281
+ runId: ready.runId
282
+ } : {},
283
+ ...'string' == typeof ready?.instanceId ? {
284
+ instanceId: ready.instanceId
285
+ } : {},
286
+ ...'string' == typeof ready?.toolchainVersion ? {
287
+ toolchainVersion: ready.toolchainVersion
288
+ } : {},
289
+ ...extra
290
+ };
291
+ }
292
+ starting(args) {
293
+ const requestedPort = toFiniteNumber(args.requestedPort);
294
+ const port = toFiniteNumber(args.port);
295
+ this.boundPort = port;
296
+ const reassigned = null !== port && shouldWarnPortConflict(requestedPort, port);
297
+ this.startingEmitted = true;
298
+ const warnings = reassigned ? [
299
+ `${CODES.E_PORT_IN_USE}: port ${requestedPort} was taken, so the dev server listens on port ${port}`
300
+ ] : [];
301
+ warnings.push(...takeCodedWarnings());
302
+ return this.emit(ENVELOPE.ok(this.options.command, 'starting', this.sessionValue({
303
+ requestedPort,
304
+ port
305
+ }), {
306
+ warnings
307
+ }));
308
+ }
309
+ compiled(args) {
310
+ this.compileAttempts += 1;
311
+ this.successfulCompiles += 1;
312
+ const status = 1 === this.successfulCompiles ? 'compiled' : 'recompiled';
313
+ const assets = toFiniteNumber(args.assets) ?? 0;
314
+ const warnings = 0 === assets && 0 === toFiniteNumber(args.entrypoints) ? [
315
+ `${CODES.E_NO_ENTRYPOINTS}: the compilation produced no entrypoints or assets`
316
+ ] : [];
317
+ return this.emit(ENVELOPE.ok(this.options.command, status, this.sessionValue({
318
+ assets,
319
+ durationMs: toFiniteNumber(args.durationMs) ?? 0
320
+ }), {
321
+ warnings
322
+ }));
323
+ }
324
+ compileFailed(args) {
325
+ this.compileAttempts += 1;
326
+ const isFirst = 1 === this.compileAttempts;
327
+ const code = isFirst ? CODES.E_FIRST_COMPILE : CODES.E_COMPILE;
328
+ const raw = stripAnsi(String(args.output || ''));
329
+ const outputTruncated = raw.length > MAX_OUTPUT_CHARS;
330
+ const output = outputTruncated ? `${raw.slice(0, MAX_OUTPUT_CHARS)}…` : raw;
331
+ const message = args.message || (isFirst ? 'The first compilation failed.' : 'A recompilation failed after a change.');
332
+ const details = Array.isArray(args.diagnostics) && args.diagnostics.length > 0 ? args.diagnostics : void 0;
333
+ const launchWithheld = 0 === this.successfulCompiles && !this.options.noBrowser;
334
+ const frame = ENVELOPE.fail(this.options.command, 'compile-failed', {
335
+ code,
336
+ message,
337
+ ...details ? {
338
+ details
339
+ } : {}
340
+ }, {
341
+ truncated: outputTruncated || true === args.diagnosticsTruncated,
342
+ warnings: launchWithheld ? [
343
+ `${CODES.E_LAUNCH_SKIPPED_COMPILE_ERRORS}: the browser launch is withheld until the compile succeeds`
344
+ ] : []
345
+ });
346
+ frame.value = this.sessionValue({
347
+ output,
348
+ durationMs: toFiniteNumber(args.durationMs) ?? 0
349
+ });
350
+ return this.emit(frame);
351
+ }
352
+ ready(args = {}) {
353
+ if (this.readyEmitted) return null;
354
+ if (null != args.port) this.boundPort = toFiniteNumber(args.port);
355
+ const ready = readReadyContract(this.options.readyPath);
356
+ if (ready && 'error' === ready.status) {
357
+ if (this.readyErrorEmitted) return null;
358
+ this.readyErrorEmitted = true;
359
+ return this.contractError(ready, CODES.E_READY_ERROR_STATUS);
360
+ }
361
+ this.readyEmitted = true;
362
+ return this.emit(ENVELOPE.ok(this.options.command, 'ready', this.sessionValue(), {
363
+ warnings: cdpFaultWarnings(ready)
364
+ }));
365
+ }
366
+ contractError(ready, fallback) {
367
+ const launchCode = stampedLaunchFailureCode(ready);
368
+ const frame = ENVELOPE.fail(this.options.command, launchCode && USAGE_LAUNCH_CODES.has(launchCode) ? 'usage' : 'failed', {
369
+ code: launchCode ?? fallback,
370
+ message: String(ready.message || '') || 'The ready contract reports an error for this session.'
371
+ });
372
+ frame.value = this.sessionValue({
373
+ ...'string' == typeof ready.code ? {
374
+ readyCode: ready.code
375
+ } : {}
376
+ });
377
+ this.terminalEmitted = true;
378
+ return this.emit(frame);
379
+ }
380
+ exited(exitCode) {
381
+ if (!this.startingEmitted || this.terminalEmitted || 0 === exitCode) return null;
382
+ const ready = readReadyContract(this.options.readyPath);
383
+ if (ready && 'error' === ready.status) return this.contractError(ready, 'browser_launch_failed' === ready.code ? CODES.E_BROWSER_LAUNCH : CODES.E_READY_ERROR_STATUS);
384
+ const frame = ENVELOPE.fail(this.options.command, 'failed', {
385
+ code: CODES.E_INTERNAL,
386
+ message: `The dev session ended with exit code ${exitCode}.`
387
+ });
388
+ frame.value = this.sessionValue({
389
+ exitCode
390
+ });
391
+ this.terminalEmitted = true;
392
+ return this.emit(frame);
393
+ }
394
+ emitOnExit() {
395
+ const onExit = (code)=>{
396
+ try {
397
+ this.exited(code);
398
+ } catch {}
399
+ };
400
+ process.once('exit', onExit);
401
+ return ()=>{
402
+ process.removeListener('exit', onExit);
403
+ };
404
+ }
405
+ browserExited(args = {}) {
406
+ if (this.browserExitEmitted) return null;
407
+ this.browserExitEmitted = true;
408
+ const ready = readReadyContract(this.options.readyPath);
409
+ const locked = isProfileLocked(ready);
410
+ const code = locked ? CODES.E_PROFILE_LOCKED : CODES.E_BROWSER_LAUNCH;
411
+ const message = args.message || String(ready?.message || '') || (locked ? 'The browser profile is locked by another session.' : 'The browser exited before the session ended.');
412
+ const frame = ENVELOPE.fail(this.options.command, 'browser-exited', {
413
+ code,
414
+ message
415
+ });
416
+ frame.value = this.sessionValue({
417
+ exitCode: toFiniteNumber(args.exitCode) ?? toFiniteNumber(ready?.browserExitCode),
418
+ ...'string' == typeof ready?.browserExitSignal ? {
419
+ exitSignal: ready.browserExitSignal
420
+ } : {},
421
+ ...'string' == typeof ready?.browserExitedAt ? {
422
+ browserExitedAt: ready.browserExitedAt
423
+ } : {}
424
+ });
425
+ this.terminalEmitted = true;
426
+ return this.emit(frame);
427
+ }
428
+ interrupted(signal) {
429
+ if (this.interruptEmitted) return null;
430
+ this.interruptEmitted = true;
431
+ this.terminalEmitted = true;
432
+ const frame = ENVELOPE.fail(this.options.command, 'stopped', {
433
+ code: CODES.E_INTERRUPTED,
434
+ message: `The ${this.options.command} session was interrupted by ${signal}.`
435
+ });
436
+ frame.value = this.sessionValue({
437
+ signal
438
+ });
439
+ return this.emit(frame);
440
+ }
441
+ failed(message) {
442
+ const frame = ENVELOPE.fail(this.options.command, 'failed', {
443
+ code: CODES.E_DEV_SERVER_START,
444
+ message: stripAnsi(message)
445
+ });
446
+ frame.value = this.sessionValue();
447
+ this.terminalEmitted = true;
448
+ return this.emit(frame);
449
+ }
450
+ watchBrowserExit(intervalMs = 1000, onExit) {
451
+ const stop = ()=>{
452
+ if (this.exitWatcher) clearInterval(this.exitWatcher);
453
+ this.exitWatcher = void 0;
454
+ };
455
+ if (!this.options.readyPath) return stop;
456
+ if (!this.enabled && !onExit) return stop;
457
+ if (this.exitWatcher) return stop;
458
+ this.exitWatcher = setInterval(()=>{
459
+ const ready = readReadyContract(this.options.readyPath);
460
+ if ('string' != typeof ready?.browserExitedAt) return;
461
+ onExit?.(ready);
462
+ this.browserExited();
463
+ stop();
464
+ }, intervalMs);
465
+ this.exitWatcher.unref?.();
466
+ return stop;
467
+ }
468
+ watchBrowserLaunchFailure(intervalMs = 1000, onFailure) {
469
+ const stop = ()=>{
470
+ if (this.launchFailureWatcher) clearInterval(this.launchFailureWatcher);
471
+ this.launchFailureWatcher = void 0;
472
+ };
473
+ if (!this.options.readyPath) return stop;
474
+ if (this.launchFailureWatcher) return stop;
475
+ this.launchFailureWatcher = setInterval(()=>{
476
+ const ready = readReadyContract(this.options.readyPath);
477
+ if ('string' != typeof ready?.browserLaunchFailedAt) return;
478
+ onFailure(ready);
479
+ stop();
480
+ }, intervalMs);
481
+ this.launchFailureWatcher.unref?.();
482
+ return stop;
483
+ }
484
+ }
485
+ function createLifecycleStream(options) {
486
+ return new LifecycleStream(options);
487
+ }
488
+ function assetCount(stats) {
489
+ const compilation = stats?.compilation;
490
+ try {
491
+ const assets = compilation?.getAssets?.();
492
+ if (Array.isArray(assets)) return assets.length;
493
+ } catch {}
494
+ return Object.keys(compilation?.assets || {}).length;
495
+ }
496
+ function entrypointCount(stats) {
497
+ try {
498
+ const entrypoints = stats?.toJson?.({
499
+ all: false,
500
+ entrypoints: true
501
+ })?.entrypoints;
502
+ return entrypoints && 'object' == typeof entrypoints ? Object.keys(entrypoints).length : void 0;
503
+ } catch {
504
+ return;
505
+ }
506
+ }
507
+ function compileDuration(stats) {
508
+ const compilation = stats?.compilation;
509
+ const start = Number(compilation?.startTime || 0);
510
+ const end = Number(compilation?.endTime || 0);
511
+ const duration = end - start;
512
+ return Number.isFinite(duration) && duration > 0 ? duration : 0;
513
+ }
514
+ function errorText(stats) {
515
+ try {
516
+ return String(stats?.toString?.({
517
+ all: false,
518
+ errors: true,
519
+ colors: false
520
+ }) || '');
521
+ } catch {
522
+ return '';
523
+ }
524
+ }
525
+ function attachLifecycleStream(compiler, stream) {
526
+ const hooks = compiler?.hooks;
527
+ hooks?.done?.tap('extension.js:lifecycle-stream', (stats)=>{
528
+ try {
529
+ if (stats?.hasErrors?.()) {
530
+ const { details, truncated } = compilationDiagnostics(stats.compilation);
531
+ stream.compileFailed({
532
+ output: errorText(stats),
533
+ durationMs: compileDuration(stats),
534
+ diagnostics: details,
535
+ diagnosticsTruncated: truncated
536
+ });
537
+ return;
538
+ }
539
+ stream.compiled({
540
+ assets: assetCount(stats),
541
+ durationMs: compileDuration(stats),
542
+ entrypoints: entrypointCount(stats)
543
+ });
544
+ stream.ready();
545
+ } catch {}
546
+ });
547
+ hooks?.failed?.tap('extension.js:lifecycle-stream', (error)=>{
548
+ try {
549
+ stream.compileFailed({
550
+ output: error instanceof Error ? error.stack || error.message : String(error),
551
+ message: error instanceof Error ? error.message : String(error)
552
+ });
553
+ } catch {}
554
+ });
555
+ }
27
556
  const cjsRequire = createRequire(import.meta.url);
28
557
  if (!process.env.EXTENSION_JS_OPTIONAL_DEPS_VERSION) process.env.EXTENSION_JS_OPTIONAL_DEPS_VERSION = package_namespaceObject.rE;
29
558
  function resolveDevelopRootFromDir(dir) {
@@ -90,10 +619,10 @@ function resolveDevelopDistFile(stem) {
90
619
  base
91
620
  ];
92
621
  for (const candidate of candidates)if (__rspack_external_node_fs_1b05aee1.existsSync(candidate)) {
93
- if ('1' === process.env.EXTENSION_DEBUG_DEVELOP_ROOT) console.log(`[extjs:develop-root] ${stem} -> ${candidate} (installRoot=${installRoot || '<none>'})`);
622
+ if ('1' === process.env.EXTENSION_DEBUG_DEVELOP_ROOT) debugLine(`[extjs:develop-root] ${stem} -> ${candidate} (installRoot=${installRoot || '<none>'})`);
94
623
  return candidate;
95
624
  }
96
- if ('1' === process.env.EXTENSION_DEBUG_DEVELOP_ROOT) console.log(`[extjs:develop-root] ${stem} -> ${base} (fallback, installRoot=${installRoot || '<none>'})`);
625
+ if ('1' === process.env.EXTENSION_DEBUG_DEVELOP_ROOT) debugLine(`[extjs:develop-root] ${stem} -> ${base} (fallback, installRoot=${installRoot || '<none>'})`);
97
626
  return base;
98
627
  }
99
628
  const BUNDLED_DEPENDENCY_VERSIONS = {
@@ -258,9 +787,47 @@ const OPTIONAL_DEPENDENCY_CONTRACTS = {
258
787
  };
259
788
  function getOptionalDependencyContract(contractId) {
260
789
  const contract = OPTIONAL_DEPENDENCY_CONTRACTS[contractId];
261
- if (!contract) throw new Error(`Unknown optional dependency contract: ${contractId}`);
790
+ if (!contract) throw codedError(CODES.E_OPTIONAL_DEP_UNKNOWN, `Unknown optional dependency contract: ${contractId}`);
262
791
  return contract;
263
792
  }
793
+ const NPMRC_REGISTRY = /^\s*registry\s*=\s*(.*?)\s*$/;
794
+ const PUBLIC_REGISTRY_HOSTS = [
795
+ 'registry.npmjs.org',
796
+ 'registry.yarnpkg.com'
797
+ ];
798
+ function readEnv(source, name) {
799
+ const key = Object.keys(source).find((candidate)=>candidate.toLowerCase() === name.toLowerCase() && source[candidate]);
800
+ return void 0 === key ? void 0 : source[key];
801
+ }
802
+ function readNpmrcRegistry(projectDir) {
803
+ let registry;
804
+ try {
805
+ for (const line of __rspack_external_node_fs_1b05aee1.readFileSync(__rspack_external_node_path_806ed179.join(projectDir, '.npmrc'), 'utf8').split(/\r?\n/)){
806
+ const match = NPMRC_REGISTRY.exec(line);
807
+ if (match) registry = match[1].replace(/^(['"])(.*)\1$/, '$2');
808
+ }
809
+ } catch {}
810
+ return registry;
811
+ }
812
+ function privateRegistry(value) {
813
+ const raw = String(value || '').trim();
814
+ if (!raw || raw.includes('${')) return;
815
+ try {
816
+ const url = new URL(raw);
817
+ if ('http:' !== url.protocol && 'https:' !== url.protocol) return;
818
+ if (PUBLIC_REGISTRY_HOSTS.includes(url.hostname)) return;
819
+ return url.href.replace(/\/+$/, '');
820
+ } catch {
821
+ return;
822
+ }
823
+ }
824
+ function corepackRegistryEnv(source, projectDir) {
825
+ if (readEnv(source, 'COREPACK_NPM_REGISTRY')) return {};
826
+ const registry = privateRegistry(readEnv(source, 'npm_config_registry') || readNpmrcRegistry(projectDir));
827
+ return registry ? {
828
+ COREPACK_NPM_REGISTRY: registry
829
+ } : {};
830
+ }
264
831
  const package_manager_require = createRequire(import.meta.url);
265
832
  function normalizePackageManager(value) {
266
833
  if (!value) return;
@@ -683,12 +1250,13 @@ function buildSpawnInvocation(command, args) {
683
1250
  }
684
1251
  function spawnInstallCommand(command, args, options) {
685
1252
  const invocation = buildSpawnInvocation(command, args);
686
- const env = buildExecEnv();
1253
+ const env = buildExecEnv() || process.env;
687
1254
  return spawn(invocation.command, invocation.args, {
688
1255
  cwd: options?.cwd,
689
1256
  stdio: options?.stdio ?? 'ignore',
690
1257
  env: {
691
- ...env || process.env,
1258
+ ...env,
1259
+ ...corepackRegistryEnv(env, options?.cwd ?? process.cwd()),
692
1260
  ...options?.env
693
1261
  }
694
1262
  });
@@ -705,7 +1273,7 @@ function execInstallCommand(command, args, options) {
705
1273
  }
706
1274
  function debugSwallowed(step, error) {
707
1275
  if (!isVerboseMode()) return;
708
- console.log(`${messaging_prefix('debug')} optional-deps ${step}: ${String(error?.message || error)}`);
1276
+ debugLine(`${messaging_prefix('debug')} optional-deps ${step}: ${String(error?.message || error)}`);
709
1277
  }
710
1278
  function isVerboseMode() {
711
1279
  return '1' === String(process.env.EXTENSION_VERBOSE || '').trim();
@@ -893,7 +1461,7 @@ async function ensureOptionalPackageResolved(input) {
893
1461
  verifyPackageIds: contract.installPackages
894
1462
  });
895
1463
  const headline = `${input.dependencyId} could not be resolved.` + (missing.length > 0 ? ` Missing or invalid packages: ${missing.join(', ')}.` : '');
896
- throw new Error(formatResolverError({
1464
+ throw codedError(CODES.E_OPTIONAL_DEP_UNRESOLVED, formatResolverError({
897
1465
  integration: input.integration,
898
1466
  dependencyId: input.dependencyId,
899
1467
  headline,
@@ -918,7 +1486,7 @@ function resolveOptionalPackageWithoutInstall(input) {
918
1486
  installDependencies: contract.installPackages,
919
1487
  verifyPackageIds: contract.installPackages
920
1488
  });
921
- throw new Error(formatResolverError({
1489
+ throw codedError(CODES.E_OPTIONAL_DEP_UNRESOLVED, formatResolverError({
922
1490
  integration: input.integration,
923
1491
  dependencyId: input.dependencyId,
924
1492
  headline: `${input.dependencyId} could not be resolved from the project or extension-develop.`,
@@ -974,7 +1542,7 @@ async function ensureOptionalModuleLoaded(input) {
974
1542
  resolvedPath,
975
1543
  loadError: lastLoadError instanceof Error ? lastLoadError.message : String(lastLoadError)
976
1544
  };
977
- throw new Error(formatResolverError({
1545
+ throw codedError(CODES.E_OPTIONAL_DEP_LOAD, formatResolverError({
978
1546
  integration: input.integration,
979
1547
  dependencyId: input.dependencyId,
980
1548
  headline: `${input.dependencyId} could not be loaded after it resolved.`,
@@ -1014,7 +1582,7 @@ function loadOptionalModuleWithoutInstall(input) {
1014
1582
  } catch (directRequireError) {
1015
1583
  lastLoadError = directRequireError;
1016
1584
  }
1017
- if (!didLoad) throw new Error(formatResolverError({
1585
+ if (!didLoad) throw codedError(CODES.E_OPTIONAL_DEP_LOAD, formatResolverError({
1018
1586
  integration: input.integration,
1019
1587
  dependencyId: input.dependencyId,
1020
1588
  headline: `${input.dependencyId} could not be loaded after resolving.`,
@@ -1074,6 +1642,10 @@ const ADDON_LINT_PACKAGE = 'addons-linter';
1074
1642
  const DUPLICATED_BY_BUILD_WARNINGS = new Set([
1075
1643
  'MISSING_DATA_COLLECTION_PERMISSIONS'
1076
1644
  ]);
1645
+ const NOTICES_PRINTED_AS_WARNINGS = new Set([
1646
+ 'PERMISSION_FIREFOX_UNSUPPORTED_BY_MIN_VERSION',
1647
+ 'PERMISSION_FIREFOX_ANDROID_UNSUPPORTED_BY_MIN_VERSION'
1648
+ ]);
1077
1649
  const hintedProjects = new Set();
1078
1650
  function toModule(loaded) {
1079
1651
  const candidate = loaded?.createInstance ? loaded : loaded?.default;
@@ -1107,21 +1679,49 @@ function locationOf(finding) {
1107
1679
  const line = 'number' == typeof finding.line ? `:${finding.line}` : '';
1108
1680
  return `${file}${line}`;
1109
1681
  }
1682
+ function oneLine(text) {
1683
+ return String(text || '').replace(/\s+/g, ' ').trim();
1684
+ }
1685
+ function quotedIn(text) {
1686
+ return Array.from(text.matchAll(/"([^"]+)"/g), (match)=>match[1]);
1687
+ }
1688
+ function textOf(finding) {
1689
+ const message = oneLine(finding.message);
1690
+ const description = oneLine(finding.description);
1691
+ if (!message || !description) return message || description;
1692
+ if (quotedIn(message).length > 0) return message;
1693
+ const isOneSentence = !/[.!?]\s+\S/.test(description.replace(/"[^"]*"/g, '""'));
1694
+ const namesMore = quotedIn(description).some((subject)=>!message.includes(subject));
1695
+ return isOneSentence && namesMore ? description : message;
1696
+ }
1110
1697
  function toLine(level, finding) {
1111
1698
  return {
1112
1699
  level,
1113
1700
  code: String(finding.code || 'UNKNOWN').trim(),
1114
- message: String(finding.message || finding.description || '').replace(/\s+/g, ' ').trim(),
1701
+ message: textOf(finding),
1115
1702
  location: locationOf(finding)
1116
1703
  };
1117
1704
  }
1118
1705
  function collectAddonLintLines(output) {
1119
1706
  const errors = Array.isArray(output?.errors) ? output.errors : [];
1120
1707
  const warnings = Array.isArray(output?.warnings) ? output.warnings : [];
1708
+ const notices = Array.isArray(output?.notices) ? output.notices : [];
1709
+ const seen = new Set();
1121
1710
  return [
1122
1711
  ...errors.map((finding)=>toLine('error', finding)),
1123
- ...warnings.map((finding)=>toLine('warning', finding))
1124
- ].filter((line)=>!DUPLICATED_BY_BUILD_WARNINGS.has(line.code));
1712
+ ...warnings.map((finding)=>toLine('warning', finding)),
1713
+ ...notices.map((finding)=>toLine('warning', finding)).filter((line)=>NOTICES_PRINTED_AS_WARNINGS.has(line.code))
1714
+ ].filter((line)=>!DUPLICATED_BY_BUILD_WARNINGS.has(line.code)).filter((line)=>{
1715
+ const printed = [
1716
+ line.level,
1717
+ line.code,
1718
+ line.message,
1719
+ line.location
1720
+ ].join('\0');
1721
+ if (seen.has(printed)) return false;
1722
+ seen.add(printed);
1723
+ return true;
1724
+ });
1125
1725
  }
1126
1726
  function attributionFor(location, chunkProvenance) {
1127
1727
  if (!chunkProvenance || 0 === chunkProvenance.size) return '';
@@ -1329,12 +1929,14 @@ function promoteStagingDist(stagingPath, distPath) {
1329
1929
  } catch {}
1330
1930
  }
1331
1931
  const MAX_SUMMARY_WARNINGS = 20;
1332
- const ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
1333
- function getBuildSummary(browser, info, outputPath) {
1334
- const assets = info?.assets || [];
1932
+ const build_summary_ANSI_PATTERN = /\u001b\[[0-9;]*m/g;
1933
+ function getBuildSummary(browser, info, outputPath, outputFiles, codes) {
1934
+ const assets = outputFiles?.length ? outputFiles : info?.assets || [];
1335
1935
  const warnings = (info?.warnings || []).slice(0, MAX_SUMMARY_WARNINGS).map((warning)=>{
1336
1936
  const message = warning && 'object' == typeof warning ? String(warning.message ?? '') : String(warning ?? '');
1337
- return message.replace(ANSI_PATTERN, '').trim();
1937
+ const text = message.replace(build_summary_ANSI_PATTERN, '').trim();
1938
+ const code = codes?.get(text);
1939
+ return code ? `${code}: ${text.replace(/^[×⚠]\s*/, '')}` : text;
1338
1940
  }).filter(Boolean);
1339
1941
  return {
1340
1942
  browser,
@@ -1528,10 +2130,12 @@ function restoreFixedKeys(holder, before, { name, isFixed }) {
1528
2130
  }
1529
2131
  class ConfigResolvedPlugin {
1530
2132
  hook;
2133
+ context;
1531
2134
  static name = 'plugin-config-resolved';
1532
2135
  applied = false;
1533
- constructor(hook){
2136
+ constructor(hook, context){
1534
2137
  this.hook = hook;
2138
+ this.context = context;
1535
2139
  }
1536
2140
  apply(compiler) {
1537
2141
  const options = compiler.options;
@@ -1555,7 +2159,7 @@ class ConfigResolvedPlugin {
1555
2159
  before: snapshotFixedKeys(holder, fixed)
1556
2160
  };
1557
2161
  });
1558
- const next = await this.hook(compiler.options);
2162
+ const next = await this.hook(compiler.options, this.context);
1559
2163
  if (next && next !== compiler.options) for (const [key, value] of Object.entries(next))options[key] = value;
1560
2164
  const ignored = [];
1561
2165
  for (const { fixed, holder, before } of holders){
@@ -1576,6 +2180,13 @@ class ConfigResolvedPlugin {
1576
2180
  compiler.hooks.watchRun.tapPromise(ConfigResolvedPlugin.name, run);
1577
2181
  }
1578
2182
  }
2183
+ function projectInstallStdio() {
2184
+ return isMachineOutput() ? [
2185
+ 'inherit',
2186
+ 2,
2187
+ 2
2188
+ ] : 'inherit';
2189
+ }
1579
2190
  async function ensureUserProjectDependencies(packageJsonDir) {
1580
2191
  const member = findPnpmWorkspaceMember(packageJsonDir);
1581
2192
  if (!needsInstall(packageJsonDir, member?.root)) return;
@@ -1594,7 +2205,7 @@ async function ensureUserProjectDependencies(packageJsonDir) {
1594
2205
  try {
1595
2206
  await execInstallCommand(cmd.command, cmd.args, {
1596
2207
  cwd: target.cwd,
1597
- stdio: 'inherit',
2208
+ stdio: projectInstallStdio(),
1598
2209
  env: suppression.env
1599
2210
  });
1600
2211
  } catch (error) {
@@ -1610,7 +2221,7 @@ async function ensureUserProjectDependencies(packageJsonDir) {
1610
2221
  ]);
1611
2222
  await execInstallCommand(npmCmd.command, npmCmd.args, {
1612
2223
  cwd: packageJsonDir,
1613
- stdio: 'inherit',
2224
+ stdio: projectInstallStdio(),
1614
2225
  env: npmSuppression.env
1615
2226
  });
1616
2227
  }
@@ -1760,16 +2371,18 @@ async function generateExtensionTypes(manifestDir, packageJsonDir) {
1760
2371
  try {
1761
2372
  await __rspack_external_node_fs_promises_3b710708.access(extensionEnvFile);
1762
2373
  const existingContent = await __rspack_external_node_fs_promises_3b710708.readFile(extensionEnvFile, 'utf8');
1763
- if (existingContent.includes('develop/dist/types')) await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
2374
+ if (existingContent === fileContent) return;
2375
+ humanLine(updatingTypeDefinitions(extensionEnvFile));
1764
2376
  await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
1765
2377
  } catch (err) {
1766
2378
  const manifestText = await __rspack_external_node_fs_promises_3b710708.readFile(__rspack_external_node_path_806ed179.join(manifestDir, 'manifest.json'), 'utf8');
1767
2379
  const manifest = parseJsonSafe(manifestText);
1768
- console.log(writingTypeDefinitions(manifest));
2380
+ humanLine(writingTypeDefinitions(manifest));
1769
2381
  try {
1770
2382
  await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
1771
2383
  } catch (writeErr) {
1772
- console.log(writingTypeDefinitionsError(writeErr));
2384
+ recordCodedWarning(CODES.E_TYPES_EMIT, `Writing ${extensionEnvFile} failed: ${writeErr instanceof Error ? writeErr.message : String(writeErr)}`);
2385
+ humanLine(writingTypeDefinitionsError(writeErr));
1773
2386
  }
1774
2387
  }
1775
2388
  }
@@ -1882,7 +2495,7 @@ function normalizeSplitChunks(config) {
1882
2495
  }
1883
2496
  function applySplitChunksGuard(config) {
1884
2497
  const { config: next, narrowed } = normalizeSplitChunks(config);
1885
- if (narrowed.length > 0 && isDebug()) console.log(debugSplitChunksNarrowed(narrowed));
2498
+ if (narrowed.length > 0 && isDebug()) debugLine(debugSplitChunksNarrowed(narrowed));
1886
2499
  return keepRuntimeInline(keepUserEntriesWhole(next));
1887
2500
  }
1888
2501
  function keepRuntimeInline(config) {
@@ -2027,7 +2640,7 @@ let userMessageDelivered = false;
2027
2640
  function isUsingReact(projectPath) {
2028
2641
  if (hasDependency(projectPath, 'react')) {
2029
2642
  if (!userMessageDelivered) {
2030
- if (isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('React')}`);
2643
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('React')}`);
2031
2644
  userMessageDelivered = true;
2032
2645
  }
2033
2646
  return true;
@@ -2116,7 +2729,7 @@ let preact_userMessageDelivered = false;
2116
2729
  function isUsingPreact(projectPath) {
2117
2730
  if (hasDependency(projectPath, 'preact')) {
2118
2731
  if (!preact_userMessageDelivered) {
2119
- if (isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('Preact')}`);
2732
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Preact')}`);
2120
2733
  preact_userMessageDelivered = true;
2121
2734
  }
2122
2735
  return true;
@@ -2253,7 +2866,7 @@ let solid_userMessageDelivered = false;
2253
2866
  function isUsingSolid(projectPath) {
2254
2867
  const using = hasDependency(projectPath, 'solid-js');
2255
2868
  if (using && !solid_userMessageDelivered) {
2256
- if (isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('Solid')}`);
2869
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Solid')}`);
2257
2870
  solid_userMessageDelivered = true;
2258
2871
  }
2259
2872
  return using;
@@ -2416,7 +3029,7 @@ async function loadLoaderOptions(projectPath, framework) {
2416
3029
  if (configPath) {
2417
3030
  if (!load_loader_options_userMessageDelivered && isDebug()) {
2418
3031
  const display = __rspack_external_node_path_806ed179.basename(configPath);
2419
- console.log(isUsingCustomLoader(display));
3032
+ debugLine(isUsingCustomLoader(display));
2420
3033
  load_loader_options_userMessageDelivered = true;
2421
3034
  }
2422
3035
  try {
@@ -2434,7 +3047,7 @@ let vue_userMessageDelivered = false;
2434
3047
  function isUsingVue(projectPath) {
2435
3048
  const using = hasDependency(projectPath, 'vue');
2436
3049
  if (using && !vue_userMessageDelivered) {
2437
- if (isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('Vue')}`);
3050
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Vue')}`);
2438
3051
  vue_userMessageDelivered = true;
2439
3052
  }
2440
3053
  return using;
@@ -2643,9 +3256,9 @@ function ensureTypeScriptConfig(projectPath) {
2643
3256
  const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
2644
3257
  if (hasTsFiles || hasDep && tsConfigFilePath) {
2645
3258
  if (tsConfigFilePath) {
2646
- if (!hasShownUserMessage && isDebug()) console.log(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
3259
+ if (!hasShownUserMessage && isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
2647
3260
  } else {
2648
- if (!hasShownUserMessage) console.log(creatingTSConfig());
3261
+ if (!hasShownUserMessage) humanLine(creatingTSConfig());
2649
3262
  writeTsConfig(projectPath);
2650
3263
  }
2651
3264
  hasShownUserMessage = true;
@@ -2747,6 +3360,7 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2747
3360
  const stagingDistPath = stagingDistPathFor(distPath);
2748
3361
  const isAuthor = isDebug();
2749
3362
  try {
3363
+ takeCodedWarnings();
2750
3364
  await ensureDevelopArtifacts();
2751
3365
  if (buildOptions?.install !== false) await ensureUserProjectDependencies(packageJsonDir);
2752
3366
  ensureTypeScriptConfig(manifestDir);
@@ -2772,9 +3386,9 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2772
3386
  const safariIdentity = safariPackager ? resolveSafariIdentity(mergedBuildOptions) : void 0;
2773
3387
  removeStaleStagingDirs(distPath);
2774
3388
  if (debug) {
2775
- console.log(debugDirs(manifestDir, packageJsonDir));
2776
- console.log(debugBrowser(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
2777
- console.log(debugOutputPath(distPath));
3389
+ debugLine(debugDirs(manifestDir, packageJsonDir));
3390
+ debugLine(debugBrowser(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
3391
+ debugLine(debugOutputPath(distPath));
2778
3392
  }
2779
3393
  const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? browserConfig.extensions ?? projectConfig.extensions ?? specialFoldersData.extensions;
2780
3394
  const resolvedExtensionsConfig = await resolveCompanionExtensionsConfig({
@@ -2798,7 +3412,12 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2798
3412
  }
2799
3413
  });
2800
3414
  const allPluginsButBrowserRunners = baseConfig.plugins?.filter((plugin)=>plugin?.constructor.name !== 'plugin-browsers');
2801
- const userExtensionConfig = await loadCustomConfig(packageJsonDir);
3415
+ const hookContext = {
3416
+ browser,
3417
+ mode: resolvedMode,
3418
+ command: buildOptions?.metadataCommand || 'build'
3419
+ };
3420
+ const userExtensionConfig = await loadCustomConfig(packageJsonDir, hookContext);
2802
3421
  const userConfig = userExtensionConfig({
2803
3422
  ...baseConfig,
2804
3423
  plugins: allPluginsButBrowserRunners
@@ -2808,7 +3427,7 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2808
3427
  const configResolved = await loadConfigResolvedHook(packageJsonDir);
2809
3428
  if (configResolved) compilerConfig.plugins = [
2810
3429
  ...compilerConfig.plugins || [],
2811
- new ConfigResolvedPlugin(configResolved)
3430
+ new ConfigResolvedPlugin(configResolved, hookContext)
2812
3431
  ];
2813
3432
  const compileContext = 'string' == typeof compilerConfig.context && compilerConfig.context ? __rspack_external_node_path_806ed179.resolve(compilerConfig.context) : packageJsonDir;
2814
3433
  const mergedOutputPath = 'string' == typeof compilerConfig.output?.path ? __rspack_external_node_path_806ed179.resolve(compileContext, compilerConfig.output.path) : '';
@@ -2841,10 +3460,11 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2841
3460
  removeStagingDir(stagingDistPath);
2842
3461
  return reject(new Error('Build failed: bundler returned invalid stats output (no reliable compilation result).'));
2843
3462
  }
3463
+ const outputFiles = listOutputFiles(useStagingSwap ? stagingDistPath : displayDistPath);
2844
3464
  try {
2845
3465
  printBuildCard(projectStructure.manifestPath, browser, displayDistPath);
2846
3466
  if (!silent) {
2847
- const assetsTree = buildAssetsTree(stats);
3467
+ const assetsTree = buildAssetsTree(stats, outputFiles);
2848
3468
  if (assetsTree) humanLine(assetsTree);
2849
3469
  }
2850
3470
  } catch {}
@@ -2861,7 +3481,12 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2861
3481
  } catch {}
2862
3482
  console.error(buildFailed(errorCount));
2863
3483
  if (!shouldExitOnError) {
2864
- const failure = new Error('Build failed with errors');
3484
+ const { details, truncated } = compilationDiagnostics(stats.compilation, packageJsonDir);
3485
+ const failure = Object.assign(new Error('Build failed with errors'), {
3486
+ code: CODES.E_COMPILE,
3487
+ diagnostics: details,
3488
+ truncated
3489
+ });
2865
3490
  reportedBuildFailures.add(failure);
2866
3491
  return reject(failure);
2867
3492
  }
@@ -2882,7 +3507,16 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2882
3507
  warnings: true,
2883
3508
  errors: true
2884
3509
  });
2885
- summary = getBuildSummary(browser, info, displayDistPath);
3510
+ summary = getBuildSummary(browser, info, displayDistPath, outputFiles, warningCodes(stats.compilation));
3511
+ const codedWarnings = takeCodedWarnings();
3512
+ if (codedWarnings.length > 0) summary = {
3513
+ ...summary,
3514
+ warnings_count: summary.warnings_count + codedWarnings.length,
3515
+ warnings: [
3516
+ ...summary.warnings || [],
3517
+ ...codedWarnings
3518
+ ]
3519
+ };
2886
3520
  const distDisplay = displayPath(displayDistPath);
2887
3521
  const lintLines = [];
2888
3522
  try {
@@ -2995,6 +3629,12 @@ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2995
3629
  process.exit(1);
2996
3630
  }
2997
3631
  }
3632
+ function reloadingExtensionForStaticContentScript(label) {
3633
+ return `${messaging_prefix('info')} Reloading the extension for ${label}: a ${pintor.blue('document_start')} content script is read once when the extension loads, so the pages it matches reload too.`;
3634
+ }
3635
+ function backgroundIsRequiredMessageOnly(backgroundChunkName) {
3636
+ return `Check the ${pintor.blue(backgroundChunkName.replace('/', '.'))} field in your ${pintor.blue('manifest.json')} file.`;
3637
+ }
2998
3638
  function viaBroker(broker, instruction) {
2999
3639
  return broker.broadcastReload({
3000
3640
  type: instruction.type,
@@ -3026,14 +3666,14 @@ async function dispatchReload(instruction, executor) {
3026
3666
  if (instruction.label) console.warn(formatUnappliedReloadLine(instruction.label));
3027
3667
  return;
3028
3668
  }
3029
- if (instruction.label) console.log(formatReloadingLine(instruction.label));
3669
+ if (instruction.label) humanLine(instruction.staticContentScriptEntries?.length ? reloadingExtensionForStaticContentScript(instruction.label) : formatReloadingLine(instruction.label));
3030
3670
  return;
3031
3671
  }
3032
3672
  const warning = executor.broker.undeliveredReloadWarning?.(executor.producerRestartExpected ? {
3033
3673
  producerRestartExpected: true
3034
3674
  } : void 0);
3035
3675
  if (warning) return void console.warn(warning);
3036
- if (executor.producerRestartExpected && instruction.label) console.log(formatQueuedReloadLine(instruction.label));
3676
+ if (executor.producerRestartExpected && instruction.label) humanLine(formatQueuedReloadLine(instruction.label));
3037
3677
  }
3038
3678
  }
3039
3679
  function isForcedFullPath(normalized) {
@@ -3119,6 +3759,483 @@ function createChangedSourcesTracker(compiler) {
3119
3759
  }
3120
3760
  };
3121
3761
  }
3762
+ const DEV_CONTENT_SCRIPT_REGISTRY_ASSET = "content_scripts/dev-registry.json";
3763
+ const DEV_CONTENT_SCRIPT_MARKER_KEY = '__extjsDevContentScripts';
3764
+ const DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY = '__extjsDevCsStub';
3765
+ const DEV_CONTENT_SCRIPT_ID_PREFIX = 'extjs-dev-cs-';
3766
+ const DEV_CONTENT_SCRIPT_STATIC_RELOAD_KEY = '__extjsDevStaticReload';
3767
+ const DEV_CONTENT_SCRIPT_STATIC_BUNDLES_KEY = '__extjsDevStaticBundles';
3768
+ function devContentScriptStubAssetName(index) {
3769
+ return `content_scripts/dev-stub-${index}.js`;
3770
+ }
3771
+ function devContentScriptCssMarkerAssetName(index) {
3772
+ return `content_scripts/dev-css-${index}.js`;
3773
+ }
3774
+ const DEV_CONTENT_SCRIPT_STAND_IN_ASSET = /^content_scripts\/dev-(?:stub|css)-\d+\.js$/;
3775
+ function isDevContentScriptStandInAsset(assetName) {
3776
+ return DEV_CONTENT_SCRIPT_STAND_IN_ASSET.test(assetName);
3777
+ }
3778
+ const HASHED_CONTENT_SCRIPT_ASSET = /^content_scripts\/content-(\d+)(?:\.[a-f0-9]+)?\.js$/i;
3779
+ function contentScriptEntryForAsset(assetName) {
3780
+ const match = HASHED_CONTENT_SCRIPT_ASSET.exec(assetName);
3781
+ if (!match) return;
3782
+ return getCanonicalContentScriptEntryName(Number(match[1]));
3783
+ }
3784
+ function stringList(value) {
3785
+ return Array.isArray(value) ? value.filter((item)=>'string' == typeof item) : [];
3786
+ }
3787
+ function runAtOf(value) {
3788
+ if ('document_start' === value || 'document_end' === value) return value;
3789
+ return 'document_idle';
3790
+ }
3791
+ function canonicalIndexOf(entry) {
3792
+ for (const file of [
3793
+ ...stringList(entry.js),
3794
+ ...stringList(entry.css)
3795
+ ]){
3796
+ const parsed = parseCanonicalContentScriptAsset(file);
3797
+ if (parsed) return parsed.index;
3798
+ }
3799
+ }
3800
+ function planDevContentScripts(manifest) {
3801
+ if (3 !== manifest.manifest_version) return;
3802
+ const groups = manifest.content_scripts;
3803
+ if (!Array.isArray(groups) || 0 === groups.length) return;
3804
+ const entries = [];
3805
+ const stubs = {};
3806
+ const nextGroups = groups.map((group)=>{
3807
+ const index = canonicalIndexOf(group);
3808
+ const matches = stringList(group.matches);
3809
+ const js = stringList(group.js);
3810
+ const css = stringList(group.css);
3811
+ if (void 0 === index || 0 === matches.length) return group;
3812
+ if (0 === js.length && 0 === css.length) return group;
3813
+ const entryName = getCanonicalContentScriptEntryName(index);
3814
+ const excludeMatches = stringList(group.exclude_matches);
3815
+ if ('document_start' === group.run_at && 'MAIN' !== group.world) {
3816
+ entries.push({
3817
+ id: `${DEV_CONTENT_SCRIPT_ID_PREFIX}${index}`,
3818
+ entry: entryName,
3819
+ matches,
3820
+ ...excludeMatches.length > 0 ? {
3821
+ excludeMatches
3822
+ } : {},
3823
+ js,
3824
+ css,
3825
+ runAt: 'document_start',
3826
+ allFrames: true === group.all_frames,
3827
+ world: 'ISOLATED',
3828
+ stubOnly: false,
3829
+ static: true
3830
+ });
3831
+ return group;
3832
+ }
3833
+ const stubOnly = stringList(group.include_globs).length > 0 || stringList(group.exclude_globs).length > 0;
3834
+ const cssMarkerAsset = 0 === js.length ? devContentScriptCssMarkerAssetName(index) : void 0;
3835
+ if (cssMarkerAsset) stubs[cssMarkerAsset] = buildDevContentScriptMarkerPrelude(entryName, cssMarkerAsset);
3836
+ entries.push({
3837
+ id: `${DEV_CONTENT_SCRIPT_ID_PREFIX}${index}`,
3838
+ entry: entryName,
3839
+ matches,
3840
+ ...excludeMatches.length > 0 ? {
3841
+ excludeMatches
3842
+ } : {},
3843
+ js: cssMarkerAsset ? [
3844
+ cssMarkerAsset
3845
+ ] : js,
3846
+ css,
3847
+ runAt: runAtOf(group.run_at),
3848
+ allFrames: true === group.all_frames,
3849
+ world: 'MAIN' === group.world ? 'MAIN' : 'ISOLATED',
3850
+ ...true === group.match_origin_as_fallback ? {
3851
+ matchOriginAsFallback: true
3852
+ } : {},
3853
+ stubOnly
3854
+ });
3855
+ const stubAsset = devContentScriptStubAssetName(index);
3856
+ stubs[stubAsset] = buildDevContentScriptStubSource(entryName);
3857
+ const { css: _css, world: _world, ...rest } = group;
3858
+ return {
3859
+ ...rest,
3860
+ js: [
3861
+ stubAsset
3862
+ ]
3863
+ };
3864
+ });
3865
+ if (0 === entries.length) return;
3866
+ return {
3867
+ manifest: {
3868
+ ...manifest,
3869
+ content_scripts: nextGroups
3870
+ },
3871
+ registry: {
3872
+ version: 1,
3873
+ entries
3874
+ },
3875
+ stubs
3876
+ };
3877
+ }
3878
+ function buildDevContentScriptStubSource(entryName) {
3879
+ return `;(function(){try{var c=globalThis.chrome;if(!c||!c.runtime||!c.runtime.sendMessage)return;c.runtime.sendMessage({${DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY}:{entry:${JSON.stringify(entryName)}}},function(){try{void c.runtime.lastError}catch(e){}})}catch(e){}})();\n`;
3880
+ }
3881
+ function buildDevContentScriptMarkerPrelude(entryName, assetName) {
3882
+ return `;(function(){try{var g=globalThis,k=${JSON.stringify(DEV_CONTENT_SCRIPT_MARKER_KEY)};(g[k]=g[k]||{})[${JSON.stringify(entryName)}]=${JSON.stringify(assetName)}}catch(e){}})();\n`;
3883
+ }
3884
+ const DEV_CONTENT_SCRIPTS_RUNTIME_SOURCE = `;(function () {
3885
+ try {
3886
+ var g = (typeof globalThis !== "undefined" ? globalThis : self);
3887
+ if (!g || g.__extjsDevContentScriptsInstalled) return;
3888
+ var chrome = g.chrome;
3889
+ if (!chrome || !chrome.runtime || !chrome.scripting || !chrome.tabs) return;
3890
+ g.__extjsDevContentScriptsInstalled = true;
3891
+
3892
+ var REGISTRY = ${JSON.stringify(DEV_CONTENT_SCRIPT_REGISTRY_ASSET)};
3893
+ var MARKER = ${JSON.stringify(DEV_CONTENT_SCRIPT_MARKER_KEY)};
3894
+ var STUB = ${JSON.stringify(DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY)};
3895
+ var ID_PREFIX = ${JSON.stringify(DEV_CONTENT_SCRIPT_ID_PREFIX)};
3896
+ var STATIC_RELOAD_KEY = ${JSON.stringify(DEV_CONTENT_SCRIPT_STATIC_RELOAD_KEY)};
3897
+ var STATIC_BUNDLES_KEY = ${JSON.stringify(DEV_CONTENT_SCRIPT_STATIC_BUNDLES_KEY)};
3898
+ // The file a frame runs says nothing about which extension generation
3899
+ // injected it, so every probe also stamps the booting worker's token.
3900
+ var GENERATION_KEY = "generation";
3901
+ var GENERATION = Math.random().toString(36).slice(2) + Date.now().toString(36);
3902
+ var registry = null;
3903
+ var ready = false;
3904
+ var whenReady = [];
3905
+
3906
+ function noop() { try { void chrome.runtime.lastError; } catch (e) {
3907
+ // Ignore
3908
+ } }
3909
+ function isString(v) { return typeof v === "string"; }
3910
+ function injectableUrl(url) { return typeof url === "string" && /^(https?|file|ftp):/i.test(url); }
3911
+ function call(fn) { if (fn) { try { fn(); } catch (e) {
3912
+ // Ignore
3913
+ } } }
3914
+ function onReady(fn) { if (ready) call(fn); else whenReady.push(fn); }
3915
+ function markReady() {
3916
+ ready = true;
3917
+ var fns = whenReady;
3918
+ whenReady = [];
3919
+ for (var i = 0; i < fns.length; i++) call(fns[i]);
3920
+ }
3921
+
3922
+ // The registry is read FROM DISK every time: the bundles it names are
3923
+ // content-hashed and the worker outlives many edits.
3924
+ function load(cb) {
3925
+ try {
3926
+ if (typeof g.fetch !== "function") return cb(null);
3927
+ g.fetch(chrome.runtime.getURL(REGISTRY), {cache: "no-store"})
3928
+ .then(function (r) { return r && r.ok ? r.json() : null; })
3929
+ .then(function (reg) { cb(reg && Array.isArray(reg.entries) ? reg : null); })
3930
+ .catch(function () { cb(null); });
3931
+ } catch (e) { cb(null); }
3932
+ }
3933
+
3934
+ // Every field is sent: updateContentScripts keeps any key left out, so a
3935
+ // dropped exclude_matches, css file or fallback would outlive the edit.
3936
+ function registrationOf(e) {
3937
+ return {
3938
+ id: e.id,
3939
+ matches: e.matches,
3940
+ excludeMatches: Array.isArray(e.excludeMatches) ? e.excludeMatches.filter(isString) : [],
3941
+ js: (e.js || []).filter(isString),
3942
+ css: (e.css || []).filter(isString),
3943
+ runAt: e.runAt === "document_start" || e.runAt === "document_end" ? e.runAt : "document_idle",
3944
+ allFrames: !!e.allFrames,
3945
+ world: e.world === "MAIN" ? "MAIN" : "ISOLATED",
3946
+ matchOriginAsFallback: e.matchOriginAsFallback === true,
3947
+ persistAcrossSessions: false
3948
+ };
3949
+ }
3950
+
3951
+ // Register what the registry names, update what is already registered,
3952
+ // drop dev registrations it no longer names. Idempotent per entry id.
3953
+ function sync(reg, done) {
3954
+ try {
3955
+ if (!chrome.scripting.registerContentScripts || !chrome.scripting.getRegisteredContentScripts) return call(done);
3956
+ var wanted = [];
3957
+ for (var i = 0; i < reg.entries.length; i++) {
3958
+ var e = reg.entries[i] || {};
3959
+ if (e.stubOnly || e.static || !isString(e.id) || !Array.isArray(e.matches) || !e.matches.length) continue;
3960
+ var r = registrationOf(e);
3961
+ if (!r.js.length && !r.css.length) continue;
3962
+ wanted.push(r);
3963
+ }
3964
+ chrome.scripting.getRegisteredContentScripts(function (existing) {
3965
+ noop();
3966
+ var have = {};
3967
+ if (existing) {
3968
+ for (var k = 0; k < existing.length; k++) {
3969
+ if (existing[k] && isString(existing[k].id)) have[existing[k].id] = true;
3970
+ }
3971
+ }
3972
+ var toRegister = [], toUpdate = [], toDrop = [], keep = {};
3973
+ for (var j = 0; j < wanted.length; j++) {
3974
+ keep[wanted[j].id] = true;
3975
+ (have[wanted[j].id] ? toUpdate : toRegister).push(wanted[j]);
3976
+ }
3977
+ for (var id in have) {
3978
+ if (id.indexOf(ID_PREFIX) === 0 && !keep[id]) toDrop.push(id);
3979
+ }
3980
+ var ops = [];
3981
+ if (toDrop.length && chrome.scripting.unregisterContentScripts) ops.push(["unregisterContentScripts", {ids: toDrop}]);
3982
+ if (toUpdate.length && chrome.scripting.updateContentScripts) ops.push(["updateContentScripts", toUpdate]);
3983
+ if (toRegister.length) ops.push(["registerContentScripts", toRegister]);
3984
+ var pending = ops.length;
3985
+ if (!pending) return call(done);
3986
+ var step = function () { pending--; if (pending <= 0) call(done); };
3987
+ for (var o = 0; o < ops.length; o++) {
3988
+ try { chrome.scripting[ops[o][0]](ops[o][1], function () { noop(); step(); }); } catch (e) { step(); }
3989
+ }
3990
+ });
3991
+ } catch (e) { call(done); }
3992
+ }
3993
+
3994
+ // Inject one entry into the frames of a tab whose world does not already
3995
+ // run the current file, or on a heal ran it for a previous extension
3996
+ // generation. Chromium's own injection sets the same marker.
3997
+ function inject(e, target, sameGeneration, done) {
3998
+ var world = e.world === "MAIN" ? "MAIN" : "ISOLATED";
3999
+ var js = (e.js || []).filter(isString), css = (e.css || []).filter(isString);
4000
+ var probe = {target: target, world: world, injectImmediately: true,
4001
+ args: [MARKER, GENERATION_KEY, e.entry, js[0] || "", GENERATION, !!sameGeneration],
4002
+ func: function (key, genKey, entry, file, gen, needGen) {
4003
+ try {
4004
+ var g = globalThis, m = g[key] = g[key] || {}, gens = m[genKey] = m[genKey] || {};
4005
+ var covered = m[entry] === file && (!needGen || gens[entry] === gen);
4006
+ gens[entry] = gen;
4007
+ return covered;
4008
+ } catch (x) { return false; }
4009
+ }};
4010
+ try {
4011
+ chrome.scripting.executeScript(probe, function (results) {
4012
+ noop();
4013
+ var frameIds = [];
4014
+ if (results) {
4015
+ for (var i = 0; i < results.length; i++) {
4016
+ var r = results[i];
4017
+ if (!r || r.result === true) continue;
4018
+ frameIds.push(typeof r.frameId === "number" ? r.frameId : 0);
4019
+ }
4020
+ }
4021
+ if (!frameIds.length) return call(done);
4022
+ var into = {tabId: target.tabId, frameIds: frameIds};
4023
+ if (css.length && chrome.scripting.insertCSS) {
4024
+ try { chrome.scripting.insertCSS({target: into, files: css}, noop); } catch (x) {
4025
+ // Ignore
4026
+ }
4027
+ }
4028
+ if (!js.length) return call(done);
4029
+ try {
4030
+ chrome.scripting.executeScript({target: into, files: js, world: world, injectImmediately: true}, function () { noop(); call(done); });
4031
+ } catch (x) { call(done); }
4032
+ });
4033
+ } catch (x) { call(done); }
4034
+ }
4035
+
4036
+ // The open tabs an entry matches, exclude_matches honored, tabs still
4037
+ // loading skipped when asked: Chromium injects those itself on landing.
4038
+ function tabsFor(e, completeOnly, cb) {
4039
+ var matches = Array.isArray(e.matches) ? e.matches : [];
4040
+ if (!matches.length) return cb([]);
4041
+ var excludes = Array.isArray(e.excludeMatches) ? e.excludeMatches : [];
4042
+ var collect = function (excludedIds) {
4043
+ try {
4044
+ chrome.tabs.query({url: matches}, function (tabs) {
4045
+ noop();
4046
+ var out = [];
4047
+ for (var i = 0; tabs && i < tabs.length; i++) {
4048
+ var t = tabs[i];
4049
+ if (!t || t.id == null || !injectableUrl(t.url) || excludedIds[t.id]) continue;
4050
+ if (completeOnly && t.status === "loading") continue;
4051
+ out.push(t);
4052
+ }
4053
+ cb(out);
4054
+ });
4055
+ } catch (x) { cb([]); }
4056
+ };
4057
+ if (!excludes.length) return collect({});
4058
+ try {
4059
+ chrome.tabs.query({url: excludes}, function (tabs) {
4060
+ noop();
4061
+ var ids = {};
4062
+ for (var i = 0; tabs && i < tabs.length; i++) if (tabs[i] && tabs[i].id != null) ids[tabs[i].id] = true;
4063
+ collect(ids);
4064
+ });
4065
+ } catch (x) { collect({}); }
4066
+ }
4067
+
4068
+ function onStub(msg, sender) {
4069
+ if (!msg || !isString(msg.entry) || !sender || !sender.tab || sender.tab.id == null) return;
4070
+ var tabId = sender.tab.id;
4071
+ var frameId = typeof sender.frameId === "number" ? sender.frameId : 0;
4072
+ onReady(function () {
4073
+ if (!registry) return;
4074
+ for (var i = 0; i < registry.entries.length; i++) {
4075
+ var e = registry.entries[i];
4076
+ if (e && !e.static && e.entry === msg.entry) inject(e, {tabId: tabId, frameIds: [frameId]}, false);
4077
+ }
4078
+ });
4079
+ }
4080
+
4081
+ // After a worker restart the open tabs still run the previous generation,
4082
+ // and Chromium never injects into a tab that finished loading before it.
4083
+ function heal(done) {
4084
+ onReady(function () {
4085
+ if (!registry) return call(done);
4086
+ var pending = 1;
4087
+ var step = function () { pending--; if (pending <= 0) call(done); };
4088
+ for (var i = 0; i < registry.entries.length; i++) {
4089
+ (function (e) {
4090
+ if (!e || e.stubOnly || e.static) return;
4091
+ pending++;
4092
+ tabsFor(e, true, function (tabs) {
4093
+ var left = tabs.length;
4094
+ if (!left) return step();
4095
+ for (var t = 0; t < tabs.length; t++) {
4096
+ inject(e, {tabId: tabs[t].id, allFrames: !!e.allFrames}, true, function () { if (--left === 0) step(); });
4097
+ }
4098
+ });
4099
+ })(registry.entries[i]);
4100
+ }
4101
+ step();
4102
+ });
4103
+ }
4104
+
4105
+ // Reload every tab the given entries match, each once.
4106
+ function reloadTabs(entries, done) {
4107
+ var seen = {};
4108
+ var pending = 1;
4109
+ var step = function () { pending--; if (pending <= 0) call(done); };
4110
+ for (var i = 0; i < entries.length; i++) {
4111
+ pending++;
4112
+ tabsFor(entries[i], false, function (tabs) {
4113
+ for (var t = 0; t < tabs.length; t++) {
4114
+ var id = tabs[t].id;
4115
+ if (seen[id]) continue;
4116
+ seen[id] = true;
4117
+ try { chrome.tabs.reload(id, {}, noop); } catch (x) {
4118
+ // Ignore
4119
+ }
4120
+ }
4121
+ step();
4122
+ });
4123
+ }
4124
+ step();
4125
+ }
4126
+
4127
+ // Only an extension reload ships a static entry's edit. The next generation
4128
+ // reloads the tabs it matches, and the producer's flag heals the rest.
4129
+ function reloadExtensionFor(entries) {
4130
+ var names = [];
4131
+ for (var i = 0; i < entries.length; i++) names.push(entries[i].entry);
4132
+ try {
4133
+ if (chrome.storage && chrome.storage.local) {
4134
+ var flags = {__extjsDevPendingReinject: Date.now()};
4135
+ flags[STATIC_RELOAD_KEY] = {entries: names, at: Date.now()};
4136
+ chrome.storage.local.set(flags, noop);
4137
+ }
4138
+ } catch (e) {
4139
+ // Ignore
4140
+ }
4141
+ setTimeout(function () { try { chrome.runtime.reload(); } catch (e) {
4142
+ // Ignore
4143
+ } }, 150);
4144
+ }
4145
+
4146
+ function staticBundlesOf(e) {
4147
+ return (e.js || []).filter(isString).concat((e.css || []).filter(isString)).join("\\n");
4148
+ }
4149
+
4150
+ // The static entries' hashed bundle names, as recorded by the previous
4151
+ // generation: a service worker reload ships a shared module's edit to a
4152
+ // static entry too, and nothing but the name says its tabs are stale.
4153
+ function healStaticEntries() {
4154
+ try {
4155
+ if (!chrome.storage || !chrome.storage.local) return;
4156
+ chrome.storage.local.get([STATIC_RELOAD_KEY, STATIC_BUNDLES_KEY], function (res) {
4157
+ noop();
4158
+ var flag = res && res[STATIC_RELOAD_KEY];
4159
+ var recorded = res && res[STATIC_BUNDLES_KEY];
4160
+ if (flag) {
4161
+ try { chrome.storage.local.remove(STATIC_RELOAD_KEY, noop); } catch (e) {
4162
+ // Ignore
4163
+ }
4164
+ }
4165
+ var flagged = flag && typeof flag.at === "number" && Date.now() - flag.at <= 30000 && Array.isArray(flag.entries) ? flag.entries : [];
4166
+ var known = recorded && typeof recorded === "object" ? recorded : null;
4167
+ onReady(function () {
4168
+ if (!registry) return;
4169
+ var entries = [];
4170
+ var current = {};
4171
+ for (var i = 0; i < registry.entries.length; i++) {
4172
+ var e = registry.entries[i];
4173
+ if (!e || !e.static || !isString(e.entry)) continue;
4174
+ current[e.entry] = staticBundlesOf(e);
4175
+ var changed = known && isString(known[e.entry]) && known[e.entry] !== current[e.entry];
4176
+ if (changed || flagged.indexOf(e.entry) !== -1) entries.push(e);
4177
+ }
4178
+ try {
4179
+ var record = {};
4180
+ record[STATIC_BUNDLES_KEY] = current;
4181
+ chrome.storage.local.set(record, noop);
4182
+ } catch (e) {
4183
+ // Ignore
4184
+ }
4185
+ if (entries.length) reloadTabs(entries);
4186
+ });
4187
+ });
4188
+ } catch (e) {
4189
+ // Ignore
4190
+ }
4191
+ }
4192
+
4193
+ // A content script edit: re-register at the new files and reload the tabs
4194
+ // the edited entries match, or the extension when a static one is edited.
4195
+ function reload(names, done) {
4196
+ load(function (reg) {
4197
+ if (!reg) return call(function () { done(false); });
4198
+ registry = reg;
4199
+ var wanted = Array.isArray(names) && names.length ? names : null;
4200
+ var edited = [], statics = [];
4201
+ for (var i = 0; i < reg.entries.length; i++) {
4202
+ var e = reg.entries[i];
4203
+ if (!e || (wanted && wanted.indexOf(e.entry) === -1)) continue;
4204
+ (e.static ? statics : edited).push(e);
4205
+ }
4206
+ if (statics.length) {
4207
+ reloadExtensionFor(statics);
4208
+ return call(function () { done(true); });
4209
+ }
4210
+ sync(reg, function () {
4211
+ markReady();
4212
+ reloadTabs(edited, function () { done(true); });
4213
+ });
4214
+ });
4215
+ }
4216
+
4217
+ try {
4218
+ chrome.runtime.onMessage.addListener(function (msg, sender) {
4219
+ if (!msg || !msg[STUB]) return;
4220
+ onStub(msg[STUB], sender);
4221
+ });
4222
+ } catch (e) {
4223
+ // Ignore
4224
+ }
4225
+
4226
+ g.__extjsDevContentScripts = {heal: heal, reload: reload, isReady: function () { return ready; }};
4227
+
4228
+ load(function (reg) {
4229
+ registry = reg;
4230
+ if (!reg) return markReady();
4231
+ sync(reg, markReady);
4232
+ });
4233
+ healStaticEntries();
4234
+ } catch (e) {
4235
+ // Ignore
4236
+ }
4237
+ })();
4238
+ `;
3122
4239
  function formatReloadContextLabel(context, files) {
3123
4240
  if (!files.length) return context;
3124
4241
  const shown = files.slice(0, 2).join(', ');
@@ -3338,14 +4455,14 @@ function classifyReloadFromSources(opts) {
3338
4455
  changedAssets: changedSources,
3339
4456
  label: formatReloadContextLabel('extension', changedSources)
3340
4457
  });
3341
- if (contentChanged.length > 0) return withScripts({
4458
+ if (contentChanged.length > 0) return withScripts(withStaticEntries({
3342
4459
  type: "content-scripts",
3343
4460
  changedContentScriptEntries: [
3344
4461
  ...contentEntries
3345
4462
  ].sort(),
3346
4463
  changedAssets: changedSources,
3347
4464
  label: formatReloadContextLabel("content_script", contentChanged)
3348
- });
4465
+ }, outputPath));
3349
4466
  if (pageChanged.length > 0 && 0 === unknown.length) return withScripts({
3350
4467
  type: 'page',
3351
4468
  changedAssets: changedSources,
@@ -3361,12 +4478,12 @@ function classifyReloadFromSources(opts) {
3361
4478
  if (contentScriptCount > 0) {
3362
4479
  const entries = [];
3363
4480
  for(let i = 0; i < contentScriptCount; i++)entries.push(getCanonicalContentScriptEntryName(i));
3364
- return withScripts({
4481
+ return withScripts(withStaticEntries({
3365
4482
  type: "content-scripts",
3366
4483
  changedContentScriptEntries: entries,
3367
4484
  changedAssets: changedSources,
3368
4485
  label: formatReloadContextLabel("content_script", changedSources)
3369
- });
4486
+ }, outputPath));
3370
4487
  }
3371
4488
  return withScripts({
3372
4489
  type: 'page',
@@ -3374,6 +4491,23 @@ function classifyReloadFromSources(opts) {
3374
4491
  label: formatReloadContextLabel(pageContextFromSources(changedSources), changedSources)
3375
4492
  });
3376
4493
  }
4494
+ function readStaticContentScriptEntries(outputPath) {
4495
+ if (!outputPath) return [];
4496
+ try {
4497
+ const registry = JSON.parse(stripBom(__rspack_external_node_fs_1b05aee1.readFileSync(__rspack_external_node_path_806ed179.join(outputPath, DEV_CONTENT_SCRIPT_REGISTRY_ASSET), 'utf8')));
4498
+ return (registry?.entries || []).filter((entry)=>entry?.static === true && 'string' == typeof entry.entry).map((entry)=>entry.entry);
4499
+ } catch {
4500
+ return [];
4501
+ }
4502
+ }
4503
+ function withStaticEntries(instruction, outputPath) {
4504
+ const changed = new Set(instruction.changedContentScriptEntries || []);
4505
+ const statics = readStaticContentScriptEntries(outputPath).filter((entry)=>changed.has(entry));
4506
+ return statics.length > 0 ? {
4507
+ ...instruction,
4508
+ staticContentScriptEntries: statics
4509
+ } : instruction;
4510
+ }
3377
4511
  function readContentScriptCount(compilation, outputPath) {
3378
4512
  try {
3379
4513
  const asset = compilation.getAsset?.('manifest.json');
@@ -3434,7 +4568,7 @@ class BrowsersPlugin {
3434
4568
  return false;
3435
4569
  }
3436
4570
  if ('loaded' === outcome.status) {
3437
- console.log(extensionLoadRecovered());
4571
+ humanLine(extensionLoadRecovered());
3438
4572
  return true;
3439
4573
  }
3440
4574
  if ('refused' === outcome.status && outcome.reason && outcome.reason !== this.lastReportedRefusal) {
@@ -3668,8 +4802,8 @@ async function extensionDev(pathOrRemoteUrl, devOptions) {
3668
4802
  const browser = normalizeBrowser(devOptions.browser || configBrowser || 'chrome', devOptions.chromiumBinary, devOptions.geckoBinary || devOptions.firefoxBinary, devOptions.safariBinary);
3669
4803
  const geckoBinary = devOptions.geckoBinary || devOptions.firefoxBinary;
3670
4804
  if (debug) {
3671
- console.log(debugDirs(manifestDir, packageJsonDir));
3672
- console.log(debugBrowser(browser, devOptions.chromiumBinary, geckoBinary));
4805
+ debugLine(debugDirs(manifestDir, packageJsonDir));
4806
+ debugLine(debugBrowser(browser, devOptions.chromiumBinary, geckoBinary));
3673
4807
  }
3674
4808
  const projectConfig = await loadProjectConfigDefaults(packageJsonDir);
3675
4809
  const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
@@ -3694,6 +4828,7 @@ async function extensionDev(pathOrRemoteUrl, devOptions) {
3694
4828
  enableDevtools: true,
3695
4829
  noOpen: merged.noOpen,
3696
4830
  profile: merged.profile,
4831
+ profileSource: falseProfileSource(merged.profile, devOptions.profile),
3697
4832
  persistProfile: merged.persistProfile,
3698
4833
  keepProfileChanges: merged.keepProfileChanges,
3699
4834
  copyFromProfile: merged.copyFromProfile,
@@ -3733,4 +4868,4 @@ async function extensionDev(pathOrRemoteUrl, devOptions) {
3733
4868
  process.exit(1);
3734
4869
  }
3735
4870
  }
3736
- export { BuildEmitter, ConfigResolvedPlugin, NOT_RAW_RESOURCE_QUERY, RAW_RESOURCE_QUERY, applySplitChunksGuard, buildSourceFeatureIndex, classifyEntrySurface, classifyReloadFromSources, createChangedSourcesTracker, createNodeModulesExclude, defaultSplitChunks, dispatchReload, ensureOptionalContractPackageResolved, ensureTypeScriptConfig, extensionBuild, extensionDev, getJsxImportSource, getUserTypeScriptConfigFile, hasDependency, isSubPath, isUsingIntegration, isUsingJsxFramework, isUsingReact, isUsingTypeScript, isUsingVue, jsFrameworksConfigsDetected, jsFrameworksHmrSummary, jsFrameworksIntegrationsEnabled, loadLoaderOptions, maybeUsePreact, maybeUseReact, maybeUseSolid, maybeUseVue, mergeLoaderOptions, readContentScriptCount, recordZipArtifact, recordZipFailure, resolveDevelopDistFile, resolveDevelopInstallRoot, resolveReactRefreshEntry, resolveTranspilePackageDirs, svelteCompilerRuntimeMismatch, swcParserForFile };
4871
+ export { BuildEmitter, ConfigResolvedPlugin, DEV_CONTENT_SCRIPTS_RUNTIME_SOURCE, DEV_CONTENT_SCRIPT_REGISTRY_ASSET, NOT_RAW_RESOURCE_QUERY, RAW_RESOURCE_QUERY, applySplitChunksGuard, attachLifecycleStream, backgroundIsRequiredMessageOnly, buildDevContentScriptMarkerPrelude, buildSourceFeatureIndex, classifyEntrySurface, classifyReloadFromSources, contentScriptEntryForAsset, createChangedSourcesTracker, createLifecycleStream, createNodeModulesExclude, defaultSplitChunks, dispatchReload, ensureOptionalContractPackageResolved, ensureTypeScriptConfig, extensionBuild, extensionDev, getJsxImportSource, getUserTypeScriptConfigFile, hasDependency, isDevContentScriptStandInAsset, isUsingIntegration, isUsingJsxFramework, isUsingReact, isUsingTypeScript, isUsingVue, jsFrameworksConfigsDetected, jsFrameworksHmrSummary, jsFrameworksIntegrationsEnabled, loadLoaderOptions, maybeUsePreact, maybeUseReact, maybeUseSolid, maybeUseVue, mergeLoaderOptions, planDevContentScripts, readContentScriptCount, recordZipArtifact, recordZipFailure, resolveDevelopDistFile, resolveDevelopInstallRoot, resolveReactRefreshEntry, resolveTranspilePackageDirs, svelteCompilerRuntimeMismatch, swcParserForFile };