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.
- package/README.md +2 -0
- package/dist/105~0.mjs +1 -1
- package/dist/177~0.mjs +87 -19
- package/dist/273~0.mjs +13 -3
- package/dist/363~0.mjs +1874 -0
- package/dist/{896~0.mjs → 469~0.mjs} +116 -586
- package/dist/519~0.mjs +21 -8
- package/dist/616~0.mjs +1 -1
- package/dist/771~0.mjs +103 -0
- package/dist/832~0.mjs +229 -463
- package/dist/840~0.mjs +1189 -54
- package/dist/846~0.mjs +453 -0
- package/dist/852~0.mjs +8 -6
- package/dist/bridge.mjs +3 -2
- package/dist/command-preview.d.ts +1 -0
- package/dist/contract/codes.json +39 -29
- package/dist/contract/envelope.schema.json +16 -0
- package/dist/contract/golden.build.compile.json +20 -3
- package/dist/contract/golden.eval.csp-blocks-eval.page.json +15 -0
- package/dist/css-parse-guard-loader.mjs +3 -1
- package/dist/dead-css-url-loader.mjs +129 -13
- package/dist/dev-server/cleanup.d.ts +1 -1
- package/dist/dev-server/lifecycle-stream.d.ts +14 -3
- package/dist/dev-server/session-start-prune.d.ts +13 -0
- package/dist/dev-server~0.mjs +91 -14
- package/dist/ensure-hmr-for-scripts.js +4 -8
- package/dist/ensure-hmr-for-scripts.mjs +4 -8
- package/dist/extension-js-devtools/build-stamp.json +2 -2
- package/dist/extension-js-theme/build-stamp.json +2 -2
- package/dist/feature-scripts-content-script-wrapper.js +7 -4
- package/dist/feature-scripts-content-script-wrapper.mjs +7 -4
- package/dist/lib/build-summary.d.ts +4 -1
- package/dist/lib/coded-warnings.d.ts +3 -0
- package/dist/lib/compilation-diagnostics.d.ts +23 -0
- package/dist/lib/config-loader.d.ts +2 -2
- package/dist/lib/config-resolved-plugin.d.ts +3 -2
- package/dist/lib/corepack-registry.d.ts +3 -0
- package/dist/lib/diagnostic-code.d.ts +6 -0
- package/dist/lib/merge-options.d.ts +1 -0
- package/dist/lib/messages.d.ts +4 -1
- package/dist/lib/messaging.d.ts +12 -4
- package/dist/lib/output-files.d.ts +11 -0
- package/dist/lib/package-manager.d.ts +2 -2
- package/dist/module.mjs +2 -1
- package/dist/plugin-browsers/index.d.ts +1 -0
- package/dist/plugin-compatibility/compatibility-lib/free-browser-references.d.ts +9 -0
- package/dist/plugin-css/css-lib/dead-url-refs.d.ts +5 -1
- package/dist/plugin-css/css-lib/inline-content-script-css.d.ts +4 -2
- package/dist/plugin-css/css-lib/line-rewrite-source-map.d.ts +8 -0
- package/dist/plugin-css/dead-css-url-loader.d.ts +0 -2
- package/dist/plugin-css/public-css-url-loader.d.ts +8 -3
- package/dist/plugin-playwright/index.d.ts +9 -4
- package/dist/plugin-reload/classify-reload.d.ts +2 -0
- package/dist/plugin-reload/messages.d.ts +1 -0
- package/dist/plugin-reload/reload-lib/dev-content-scripts.d.ts +4 -0
- package/dist/plugin-reload/steps/prune-unreachable-chunks.d.ts +5 -0
- package/dist/plugin-special-folders/messages.d.ts +1 -1
- package/dist/plugin-special-folders/prune-removed-public-files.d.ts +7 -0
- package/dist/plugin-static-assets/check-namespace-imports.d.ts +4 -0
- package/dist/plugin-static-assets/static-assets-lib/asset-output-name.d.ts +8 -0
- package/dist/plugin-static-assets/static-assets-lib/messages.d.ts +1 -0
- package/dist/plugin-web-extension/feature-html/html-lib/utils.d.ts +2 -1
- package/dist/plugin-web-extension/feature-icons/messages.d.ts +1 -4
- package/dist/plugin-web-extension/feature-locales/get-locales.d.ts +2 -0
- package/dist/plugin-web-extension/feature-locales/messages.d.ts +3 -1
- package/dist/plugin-web-extension/feature-locales/validation.d.ts +1 -0
- package/dist/plugin-web-extension/feature-manifest/manifest-lib/filter-keys-safari.d.ts +1 -0
- package/dist/plugin-web-extension/feature-manifest/manifest-overrides/common/content_scripts.d.ts +1 -0
- package/dist/plugin-web-extension/feature-manifest/messages.d.ts +1 -0
- package/dist/plugin-web-extension/feature-scripts/index.d.ts +2 -0
- package/dist/plugin-web-extension/feature-scripts/messages.d.ts +4 -3
- package/dist/plugin-web-extension/feature-scripts/scripts-lib/load-time-constants.d.ts +11 -0
- package/dist/plugin-web-extension/feature-scripts/steps/trace-runtime-loaded-files.d.ts +4 -0
- package/dist/plugin-web-extension/feature-scripts/steps/warn-missing-build-constants.d.ts +24 -0
- package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/declared-pages.d.ts +2 -0
- package/dist/plugin-web-extension/feature-web-resources/web-resources-lib/resolve-war.d.ts +5 -0
- package/dist/plugin-web-extension/index.d.ts +1 -0
- package/dist/plugin-web-extension/shared/classic-concat.d.ts +1 -0
- package/dist/plugin-web-extension/shared/compilation-issues.d.ts +1 -1
- package/dist/preprocessor-passthrough-loader.mjs +3 -1
- package/dist/public-css-url-loader.mjs +1 -1
- package/dist/rspack-config~0.mjs +4925 -5885
- package/dist/stats-handler~0.mjs +12 -4
- package/dist/types.d.ts +19 -2
- package/dist/zip~0.mjs +20 -2
- package/package.json +4 -4
- package/dist/300~0.mjs +0 -394
- 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 {
|
|
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 {
|
|
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 {
|
|
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)
|
|
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)
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
|
|
2380
|
+
humanLine(writingTypeDefinitions(manifest));
|
|
1769
2381
|
try {
|
|
1770
2382
|
await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
|
|
1771
2383
|
} catch (writeErr) {
|
|
1772
|
-
|
|
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())
|
|
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())
|
|
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())
|
|
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())
|
|
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
|
-
|
|
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())
|
|
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())
|
|
3259
|
+
if (!hasShownUserMessage && isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
|
|
2647
3260
|
} else {
|
|
2648
|
-
if (!hasShownUserMessage)
|
|
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
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
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
|
|
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
|
|
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)
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
3672
|
-
|
|
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,
|
|
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 };
|