@addfox/core 0.1.1-beta.2

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.
@@ -0,0 +1,1729 @@
1
+ "use strict";
2
+ const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
3
+ return "u" < typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
4
+ }();
5
+ var __webpack_require__ = {};
6
+ (()=>{
7
+ __webpack_require__.d = (exports1, definition)=>{
8
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
9
+ enumerable: true,
10
+ get: definition[key]
11
+ });
12
+ };
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
16
+ })();
17
+ (()=>{
18
+ __webpack_require__.r = (exports1)=>{
19
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
20
+ value: 'Module'
21
+ });
22
+ Object.defineProperty(exports1, '__esModule', {
23
+ value: true
24
+ });
25
+ };
26
+ })();
27
+ var __webpack_exports__ = {};
28
+ __webpack_require__.r(__webpack_exports__);
29
+ __webpack_require__.d(__webpack_exports__, {
30
+ getScriptOnlyEntryNames: ()=>getScriptOnlyEntryNames,
31
+ resolveManifestChromium: ()=>resolveManifestChromium,
32
+ RSTEST_CONFIG_FILES: ()=>RSTEST_CONFIG_FILES,
33
+ MANIFEST_FILE_NAMES: ()=>MANIFEST_FILE_NAMES,
34
+ BROWSER_OUTPUT_PREFIX: ()=>BROWSER_OUTPUT_PREFIX,
35
+ getScriptInjectIfMatches: ()=>getScriptInjectIfMatches,
36
+ DEFAULT_ENV_PREFIXES: ()=>DEFAULT_ENV_PREFIXES,
37
+ getManifestRecordForTarget: ()=>getManifestRecordForTarget,
38
+ resolveManifestForTarget: ()=>resolveManifestForTarget,
39
+ toReloadManagerEntries: ()=>toReloadManagerEntries,
40
+ DEFAULT_BROWSER: ()=>DEFAULT_BROWSER,
41
+ ManifestLoader: ()=>ManifestLoader,
42
+ MANIFEST_ENTRY_KEYS: ()=>MANIFEST_ENTRY_KEYS,
43
+ getAllEntryNames: ()=>getAllEntryNames,
44
+ DEFAULT_OUT_DIR: ()=>DEFAULT_OUT_DIR,
45
+ SCRIPT_ONLY_ENTRY_NAMES: ()=>SCRIPT_ONLY_ENTRY_NAMES,
46
+ clearConfigCache: ()=>clearConfigCache,
47
+ extractEntriesFromManifest: ()=>extractEntriesFromManifest,
48
+ resolveAddfoxConfig: ()=>resolveAddfoxConfig,
49
+ resolveManifestInput: ()=>resolveManifestInput,
50
+ MANIFEST_ENTRY_PATHS: ()=>MANIFEST_ENTRY_PATHS,
51
+ MANIFEST_DIR: ()=>MANIFEST_DIR,
52
+ getResolvedConfigFilePath: ()=>getResolvedConfigFilePath,
53
+ buildForBrowser: ()=>buildForBrowser,
54
+ loadConfigFile: ()=>loadConfigFile,
55
+ parseAddfoxEntryFromHtml: ()=>parseAddfoxEntryFromHtml,
56
+ SUPPORTED_BROWSERS: ()=>SUPPORTED_BROWSERS,
57
+ CLI_COMMANDS: ()=>CLI_COMMANDS,
58
+ RELOAD_MANAGER_ENTRY_NAMES: ()=>RELOAD_MANAGER_ENTRY_NAMES,
59
+ HMR_WS_PORT: ()=>23333,
60
+ SCRIPT_EXTS: ()=>SCRIPT_EXTS,
61
+ getAddfoxVersion: ()=>getAddfoxVersion,
62
+ getHtmlEntryNames: ()=>getHtmlEntryNames,
63
+ isScriptSrcRelative: ()=>isScriptSrcRelative,
64
+ ADDFOX_OUTPUT_ROOT: ()=>ADDFOX_OUTPUT_ROOT,
65
+ DEFAULT_APP_DIR: ()=>"app",
66
+ RESERVED_ENTRY_NAMES: ()=>RESERVED_ENTRY_NAMES,
67
+ detectFrontendFramework: ()=>detectFrontendFramework,
68
+ HTML_ENTRY_NAMES: ()=>HTML_ENTRY_NAMES,
69
+ getResolvedRstestConfigFilePath: ()=>getResolvedRstestConfigFilePath,
70
+ discoverEntries: ()=>discoverEntries,
71
+ Pipeline: ()=>Pipeline,
72
+ resolveEntries: ()=>resolveEntries,
73
+ resolveManifestFirefox: ()=>resolveManifestFirefox,
74
+ CONFIG_FILES: ()=>CONFIG_FILES,
75
+ defineConfig: ()=>defineConfig,
76
+ SUPPORTED_LAUNCH_TARGETS: ()=>SUPPORTED_LAUNCH_TARGETS,
77
+ getBrowserOutputDir: ()=>getBrowserOutputDir,
78
+ resolveScriptFromHtmlStrict: ()=>resolveScriptFromHtmlStrict
79
+ });
80
+ function defineConfig(config) {
81
+ return config;
82
+ }
83
+ const external_module_namespaceObject = require("module");
84
+ const external_path_namespaceObject = require("path");
85
+ const external_fs_namespaceObject = require("fs");
86
+ const CONFIG_FILES = [
87
+ "addfox.config.ts",
88
+ "addfox.config.js",
89
+ "addfox.config.mjs"
90
+ ];
91
+ const SCRIPT_EXTS = [
92
+ ".js",
93
+ ".jsx",
94
+ ".ts",
95
+ ".tsx"
96
+ ];
97
+ const RESERVED_ENTRY_NAMES = [
98
+ "popup",
99
+ "options",
100
+ "sidepanel",
101
+ "offscreen",
102
+ "sandbox",
103
+ "newtab",
104
+ "bookmarks",
105
+ "history",
106
+ "background",
107
+ "devtools",
108
+ "content"
109
+ ];
110
+ const HTML_ENTRY_NAMES = [
111
+ "popup",
112
+ "options",
113
+ "sidepanel",
114
+ "devtools",
115
+ "offscreen",
116
+ "sandbox",
117
+ "newtab",
118
+ "bookmarks",
119
+ "history"
120
+ ];
121
+ const SCRIPT_ONLY_ENTRY_NAMES = [
122
+ "background",
123
+ "content"
124
+ ];
125
+ const RELOAD_MANAGER_ENTRY_NAMES = new Set(SCRIPT_ONLY_ENTRY_NAMES);
126
+ const ADDFOX_OUTPUT_ROOT = ".addfox";
127
+ const DEFAULT_OUT_DIR = "extension";
128
+ const DEFAULT_ENV_PREFIXES = [
129
+ "ADDFOX_PUBLIC_"
130
+ ];
131
+ const DEFAULT_BROWSER = "chromium";
132
+ const SUPPORTED_BROWSERS = [
133
+ "chromium",
134
+ "firefox"
135
+ ];
136
+ const BROWSER_OUTPUT_PREFIX = "extension";
137
+ function getBrowserOutputDir(browser) {
138
+ return `${BROWSER_OUTPUT_PREFIX}-${browser}`;
139
+ }
140
+ const SUPPORTED_LAUNCH_TARGETS = [
141
+ "chrome",
142
+ "chromium",
143
+ "edge",
144
+ "brave",
145
+ "vivaldi",
146
+ "opera",
147
+ "santa",
148
+ "arc",
149
+ "yandex",
150
+ "browseros",
151
+ "custom",
152
+ "firefox"
153
+ ];
154
+ const CLI_COMMANDS = [
155
+ "dev",
156
+ "build",
157
+ "test"
158
+ ];
159
+ const RSTEST_CONFIG_FILES = [
160
+ "rstest.config.cts",
161
+ "rstest.config.mts",
162
+ "rstest.config.cjs",
163
+ "rstest.config.js",
164
+ "rstest.config.ts",
165
+ "rstest.config.mjs"
166
+ ];
167
+ const MANIFEST_DIR = "manifest";
168
+ const MANIFEST_FILE_NAMES = {
169
+ base: "manifest.json",
170
+ chromium: "manifest.chromium.json",
171
+ firefox: "manifest.firefox.json"
172
+ };
173
+ const MANIFEST_ENTRY_PATHS = {
174
+ background: "background/index.js",
175
+ content: "content/index.js",
176
+ popup: "popup/index.html",
177
+ options: "options/index.html",
178
+ sidepanel: "sidepanel/index.html",
179
+ devtools: "devtools/index.html",
180
+ offscreen: "offscreen/index.html",
181
+ sandbox: "sandbox/index.html",
182
+ newtab: "newtab/index.html",
183
+ bookmarks: "bookmarks/index.html",
184
+ history: "history/index.html"
185
+ };
186
+ const MANIFEST_ENTRY_KEYS = Object.keys(MANIFEST_ENTRY_PATHS);
187
+ const common_namespaceObject = require("@addfox/common");
188
+ function isScriptSrcRelative(src) {
189
+ const t = src.trim();
190
+ if (t.startsWith("/") || t.startsWith("\\")) return false;
191
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(t)) return false;
192
+ return true;
193
+ }
194
+ const ENTRY_SCRIPT_REGEX = /<script\b[^>]*data-addfox-entry[^>]*>[\s\S]*?<\/script>/gi;
195
+ const HEAD_CLOSE_REGEX = /<\/head\s*>/i;
196
+ const SCRIPT_WITH_SRC_REGEX = /<script\b[^>]*\ssrc\s*=\s*["']([^"']+)["'][^>]*>[\s\S]*?<\/script>/gi;
197
+ function findFirstScriptWithRelativeSrc(html) {
198
+ const reg = new RegExp(SCRIPT_WITH_SRC_REGEX.source, "gi");
199
+ let match;
200
+ while(null !== (match = reg.exec(html))){
201
+ const src = match[1];
202
+ if (!isScriptSrcRelative(src)) continue;
203
+ return {
204
+ src,
205
+ fullTag: match[0],
206
+ tagStartIndex: match.index
207
+ };
208
+ }
209
+ }
210
+ function parseAddfoxEntryFromHtml(htmlPath) {
211
+ const raw = (0, external_fs_namespaceObject.readFileSync)(htmlPath, "utf-8");
212
+ const reg = new RegExp(ENTRY_SCRIPT_REGEX.source, "gi");
213
+ const match = reg.exec(raw);
214
+ if (match) {
215
+ const tag = match[0];
216
+ const tagStartIndex = match.index;
217
+ const srcMatch = tag.match(/src\s*=\s*["']([^"']+)["']/i);
218
+ if (srcMatch?.[1] && isScriptSrcRelative(srcMatch[1])) {
219
+ const src = srcMatch[1];
220
+ const headCloseMatch = raw.match(HEAD_CLOSE_REGEX);
221
+ const headCloseIndex = headCloseMatch?.index ?? -1;
222
+ const inject = headCloseIndex >= 0 && tagStartIndex < headCloseIndex ? "head" : "body";
223
+ const strippedHtml = raw.replace(ENTRY_SCRIPT_REGEX, "").trimEnd();
224
+ return {
225
+ src,
226
+ inject,
227
+ strippedHtml
228
+ };
229
+ }
230
+ }
231
+ const fallback = findFirstScriptWithRelativeSrc(raw);
232
+ if (!fallback) return;
233
+ const headCloseMatch = raw.match(HEAD_CLOSE_REGEX);
234
+ const headCloseIndex = headCloseMatch?.index ?? -1;
235
+ const inject = headCloseIndex >= 0 && fallback.tagStartIndex < headCloseIndex ? "head" : "body";
236
+ const strippedHtml = raw.replace(fallback.fullTag, "").trimEnd();
237
+ return {
238
+ src: fallback.src,
239
+ inject,
240
+ strippedHtml
241
+ };
242
+ }
243
+ function getScriptInjectIfMatches(htmlPath, scriptPath) {
244
+ try {
245
+ const parsed = parseAddfoxEntryFromHtml(htmlPath);
246
+ if (!parsed) return;
247
+ const resolvedFromHtml = (0, external_path_namespaceObject.resolve)((0, external_path_namespaceObject.dirname)(htmlPath), parsed.src);
248
+ return resolvedFromHtml === scriptPath ? parsed.inject : void 0;
249
+ } catch {
250
+ return;
251
+ }
252
+ }
253
+ function resolveScriptFromHtmlStrict(htmlPath) {
254
+ const parsed = parseAddfoxEntryFromHtml(htmlPath);
255
+ if (!parsed) throw new Error("data-addfox-entry script must have a src attribute (relative path)");
256
+ if (!isScriptSrcRelative(parsed.src)) throw new Error(`data-addfox-entry src must be relative, got: ${JSON.stringify(parsed.src)}`);
257
+ const scriptPath = (0, external_path_namespaceObject.resolve)((0, external_path_namespaceObject.dirname)(htmlPath), parsed.src);
258
+ if (!(0, external_fs_namespaceObject.existsSync)(scriptPath)) throw new Error(`Entry script not found: ${scriptPath}`);
259
+ return {
260
+ scriptPath,
261
+ inject: parsed.inject
262
+ };
263
+ }
264
+ function readDirContents(dir) {
265
+ try {
266
+ const entries = (0, external_fs_namespaceObject.readdirSync)(dir, {
267
+ withFileTypes: true
268
+ });
269
+ return {
270
+ files: new Set(entries.filter((e)=>e.isFile()).map((e)=>e.name)),
271
+ dirs: new Set(entries.filter((e)=>e.isDirectory()).map((e)=>e.name))
272
+ };
273
+ } catch {
274
+ return null;
275
+ }
276
+ }
277
+ function findScriptInDir(dir, scriptExts) {
278
+ const contents = readDirContents(dir);
279
+ if (!contents) return;
280
+ for (const ext of scriptExts)if (contents.files.has(`index${ext}`)) return (0, external_path_namespaceObject.resolve)(dir, `index${ext}`);
281
+ }
282
+ function findScriptInDirFromContents(dirPath, contents, scriptExts) {
283
+ if (!contents) return findScriptInDir(dirPath, scriptExts);
284
+ for (const ext of scriptExts)if (contents.files.has(`index${ext}`)) return (0, external_path_namespaceObject.resolve)(dirPath, `index${ext}`);
285
+ }
286
+ function findNamedScript(baseDir, name, scriptExts, baseContents) {
287
+ if (baseContents) {
288
+ for (const ext of scriptExts)if (baseContents.files.has(`${name}${ext}`)) return (0, external_path_namespaceObject.resolve)(baseDir, `${name}${ext}`);
289
+ return;
290
+ }
291
+ for (const ext of scriptExts){
292
+ const p = (0, external_path_namespaceObject.resolve)(baseDir, `${name}${ext}`);
293
+ if ((0, external_fs_namespaceObject.existsSync)(p)) return p;
294
+ }
295
+ }
296
+ function findNamedHtml(baseDir, name, baseContents) {
297
+ if (baseContents) return baseContents.files.has(`${name}.html`) ? (0, external_path_namespaceObject.resolve)(baseDir, `${name}.html`) : void 0;
298
+ const p = (0, external_path_namespaceObject.resolve)(baseDir, `${name}.html`);
299
+ return (0, external_fs_namespaceObject.existsSync)(p) ? p : void 0;
300
+ }
301
+ function isValidScriptExt(pathStr, scriptExts) {
302
+ const lower = pathStr.trim().toLowerCase();
303
+ return scriptExts.some((ext)=>lower.endsWith(ext));
304
+ }
305
+ function resolveScriptFromHtmlWithInjectStrict(htmlPath, scriptExts) {
306
+ const resolved = resolveScriptFromHtmlStrict(htmlPath);
307
+ if (!isValidScriptExt(resolved.scriptPath, scriptExts)) throw new common_namespaceObject.AddfoxError({
308
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.ENTRY_SCRIPT_FROM_HTML,
309
+ message: "Invalid data-addfox-entry script in HTML",
310
+ details: `HTML: ${htmlPath}. Resolved path is not a supported script: ${resolved.scriptPath}`,
311
+ hint: "data-addfox-entry script must have a relative src and the file must exist"
312
+ });
313
+ return resolved;
314
+ }
315
+ function tryResolveEntryFromHtml(htmlPath, scriptExts) {
316
+ try {
317
+ const parsed = parseAddfoxEntryFromHtml(htmlPath);
318
+ if (!parsed) return;
319
+ return resolveScriptFromHtmlWithInjectStrict(htmlPath, scriptExts);
320
+ } catch (e) {
321
+ throw new common_namespaceObject.AddfoxError({
322
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.ENTRY_SCRIPT_FROM_HTML,
323
+ message: "Invalid data-addfox-entry script in HTML",
324
+ details: `HTML: ${htmlPath}. ${e instanceof Error ? e.message : String(e)}`,
325
+ hint: "data-addfox-entry script must have a relative src and the file must exist"
326
+ });
327
+ }
328
+ }
329
+ function buildHtmlEntryInfo(name, htmlPath, conventionalScriptPath, scriptExts) {
330
+ const fromHtml = tryResolveEntryFromHtml(htmlPath, scriptExts);
331
+ if (fromHtml) return {
332
+ name,
333
+ scriptPath: fromHtml.scriptPath,
334
+ htmlPath,
335
+ html: true,
336
+ scriptInject: fromHtml.inject,
337
+ outputFollowsScriptPath: true
338
+ };
339
+ if (!conventionalScriptPath) return null;
340
+ return {
341
+ name,
342
+ scriptPath: conventionalScriptPath,
343
+ htmlPath,
344
+ html: true,
345
+ scriptInject: getScriptInjectIfMatches(htmlPath, conventionalScriptPath)
346
+ };
347
+ }
348
+ function discoverScriptOnlyEntry(baseDir, name, contents, options) {
349
+ const singleScript = findNamedScript(baseDir, name, options.scriptExts, contents);
350
+ if (singleScript) return {
351
+ name,
352
+ scriptPath: singleScript,
353
+ html: false
354
+ };
355
+ if (!contents?.dirs.has(name)) return null;
356
+ const scriptPath = findScriptInDir((0, external_path_namespaceObject.resolve)(baseDir, name), options.scriptExts);
357
+ return scriptPath ? {
358
+ name,
359
+ scriptPath,
360
+ html: false
361
+ } : null;
362
+ }
363
+ function discoverHtmlEntryFromFlat(baseDir, name, contents, options) {
364
+ const singleScript = findNamedScript(baseDir, name, options.scriptExts, contents);
365
+ const singleHtml = findNamedHtml(baseDir, name, contents);
366
+ if (singleScript && singleHtml) return buildHtmlEntryInfo(name, singleHtml, singleScript, options.scriptExts);
367
+ if (singleHtml) {
368
+ const conventional = findNamedScript(baseDir, name, options.scriptExts, contents);
369
+ return buildHtmlEntryInfo(name, singleHtml, conventional, options.scriptExts);
370
+ }
371
+ return null;
372
+ }
373
+ function discoverHtmlEntryFromDir(baseDir, name, contents, options) {
374
+ if (!contents?.dirs.has(name)) return null;
375
+ const dirPath = (0, external_path_namespaceObject.resolve)(baseDir, name);
376
+ const subContents = readDirContents(dirPath);
377
+ const htmlPath = subContents?.files.has("index.html") ? (0, external_path_namespaceObject.resolve)(dirPath, "index.html") : void 0;
378
+ const scriptPath = findScriptInDirFromContents(dirPath, subContents, options.scriptExts);
379
+ if (scriptPath && htmlPath) return buildHtmlEntryInfo(name, htmlPath, scriptPath, options.scriptExts);
380
+ if (scriptPath) return {
381
+ name,
382
+ scriptPath,
383
+ htmlPath,
384
+ html: true,
385
+ scriptInject: htmlPath ? getScriptInjectIfMatches(htmlPath, scriptPath) : void 0
386
+ };
387
+ if (!htmlPath) return null;
388
+ return buildHtmlEntryInfo(name, htmlPath, void 0, options.scriptExts);
389
+ }
390
+ function discoverHtmlEntry(baseDir, name, contents, options) {
391
+ return discoverHtmlEntryFromFlat(baseDir, name, contents, options) ?? discoverHtmlEntryFromDir(baseDir, name, contents, options);
392
+ }
393
+ function discoverEntriesInternal(baseDir, options) {
394
+ const contents = readDirContents(baseDir);
395
+ const entries = [];
396
+ for (const name of options.scriptOnlyNames){
397
+ const entry = discoverScriptOnlyEntry(baseDir, name, contents, options);
398
+ if (entry) entries.push(entry);
399
+ }
400
+ for (const name of options.htmlEntryNames){
401
+ const entry = discoverHtmlEntry(baseDir, name, contents, options);
402
+ if (entry) entries.push(entry);
403
+ }
404
+ return entries;
405
+ }
406
+ function createOptions(options = {}) {
407
+ return {
408
+ scriptExts: options.scriptExts ?? SCRIPT_EXTS,
409
+ scriptOnlyNames: options.scriptOnlyNames ?? SCRIPT_ONLY_ENTRY_NAMES,
410
+ htmlEntryNames: options.htmlEntryNames ?? HTML_ENTRY_NAMES
411
+ };
412
+ }
413
+ function discoverEntries(baseDir, options) {
414
+ return discoverEntriesInternal(baseDir, createOptions(options));
415
+ }
416
+ function getHtmlEntryNames(options) {
417
+ return [
418
+ ...options?.htmlEntryNames ?? HTML_ENTRY_NAMES
419
+ ];
420
+ }
421
+ function getScriptOnlyEntryNames(options) {
422
+ return [
423
+ ...options?.scriptOnlyNames ?? SCRIPT_ONLY_ENTRY_NAMES
424
+ ];
425
+ }
426
+ function getAllEntryNames(options) {
427
+ return [
428
+ ...getHtmlEntryNames(options),
429
+ ...getScriptOnlyEntryNames(options)
430
+ ];
431
+ }
432
+ function isSourceFilePath(path) {
433
+ const lower = path.trim().toLowerCase();
434
+ return /\.(ts|tsx|js|jsx)$/.test(lower) && !lower.includes("/dist/") && !lower.includes("\\dist\\");
435
+ }
436
+ function inferEntryNameFromPath(path) {
437
+ const cleanPath = path.replace(/^\.\/|^\//, "");
438
+ const firstSegment = cleanPath.split(/[\/\\]/)[0];
439
+ if (MANIFEST_ENTRY_KEYS.includes(firstSegment)) return firstSegment;
440
+ return null;
441
+ }
442
+ function extractServiceWorker(manifest, browser) {
443
+ const bg = manifest.background;
444
+ if (!bg) return null;
445
+ const serviceWorker = bg.service_worker;
446
+ if ("string" == typeof serviceWorker && isSourceFilePath(serviceWorker)) {
447
+ const entryName = inferEntryNameFromPath(serviceWorker) ?? "background";
448
+ return {
449
+ name: entryName,
450
+ value: serviceWorker.replace(/^\.\//, ""),
451
+ manifestPath: "background.service_worker"
452
+ };
453
+ }
454
+ const scripts = bg.scripts;
455
+ if (Array.isArray(scripts) && scripts.length > 0) {
456
+ const firstScript = scripts[0];
457
+ if ("string" == typeof firstScript && isSourceFilePath(firstScript)) {
458
+ const entryName = inferEntryNameFromPath(firstScript) ?? "background";
459
+ return {
460
+ name: entryName,
461
+ value: firstScript.replace(/^\.\//, ""),
462
+ manifestPath: "background.scripts[0]"
463
+ };
464
+ }
465
+ }
466
+ const page = bg.page;
467
+ if ("string" == typeof page && isSourceFilePath(page)) {
468
+ const entryName = inferEntryNameFromPath(page) ?? "background";
469
+ return {
470
+ name: entryName,
471
+ value: page.replace(/^\.\//, ""),
472
+ manifestPath: "background.page"
473
+ };
474
+ }
475
+ return null;
476
+ }
477
+ function extractPopup(manifest, browser) {
478
+ const mv = 2 === manifest.manifest_version ? 2 : 3;
479
+ let popupPath;
480
+ let manifestPath;
481
+ if (3 === mv) {
482
+ const action = manifest.action;
483
+ const defaultPopup = action?.default_popup;
484
+ if ("string" == typeof defaultPopup) {
485
+ popupPath = defaultPopup;
486
+ manifestPath = "action.default_popup";
487
+ }
488
+ } else {
489
+ const browserAction = manifest.browser_action;
490
+ const defaultPopup = browserAction?.default_popup;
491
+ if ("string" == typeof defaultPopup) {
492
+ popupPath = defaultPopup;
493
+ manifestPath = "browser_action.default_popup";
494
+ }
495
+ }
496
+ if (popupPath && isSourceFilePath(popupPath)) {
497
+ const entryName = inferEntryNameFromPath(popupPath) ?? "popup";
498
+ return {
499
+ name: entryName,
500
+ value: popupPath.replace(/^\.\//, ""),
501
+ manifestPath: manifestPath
502
+ };
503
+ }
504
+ return null;
505
+ }
506
+ function extractOptions(manifest) {
507
+ const mv = 2 === manifest.manifest_version ? 2 : 3;
508
+ let optionsPath;
509
+ let manifestPath;
510
+ if (3 === mv) {
511
+ const optionsUi = manifest.options_ui;
512
+ const page = optionsUi?.page;
513
+ if ("string" == typeof page) {
514
+ optionsPath = page;
515
+ manifestPath = "options_ui.page";
516
+ }
517
+ } else {
518
+ const optionsPage = manifest.options_page;
519
+ if ("string" == typeof optionsPage) {
520
+ optionsPath = optionsPage;
521
+ manifestPath = "options_page";
522
+ }
523
+ }
524
+ if (optionsPath && isSourceFilePath(optionsPath)) {
525
+ const entryName = inferEntryNameFromPath(optionsPath) ?? "options";
526
+ return {
527
+ name: entryName,
528
+ value: optionsPath.replace(/^\.\//, ""),
529
+ manifestPath: manifestPath
530
+ };
531
+ }
532
+ return null;
533
+ }
534
+ function extractDevtools(manifest) {
535
+ const devtoolsPage = manifest.devtools_page;
536
+ if ("string" == typeof devtoolsPage && isSourceFilePath(devtoolsPage)) {
537
+ const entryName = inferEntryNameFromPath(devtoolsPage) ?? "devtools";
538
+ return {
539
+ name: entryName,
540
+ value: devtoolsPage.replace(/^\.\//, ""),
541
+ manifestPath: "devtools_page"
542
+ };
543
+ }
544
+ return null;
545
+ }
546
+ function extractSidepanel(manifest) {
547
+ const sidePanel = manifest.side_panel;
548
+ const defaultPath = sidePanel?.default_path;
549
+ if ("string" == typeof defaultPath && isSourceFilePath(defaultPath)) {
550
+ const entryName = inferEntryNameFromPath(defaultPath) ?? "sidepanel";
551
+ return {
552
+ name: entryName,
553
+ value: defaultPath.replace(/^\.\//, ""),
554
+ manifestPath: "side_panel.default_path"
555
+ };
556
+ }
557
+ return null;
558
+ }
559
+ function extractSandbox(manifest) {
560
+ const sandbox = manifest.sandbox;
561
+ const pages = sandbox?.pages;
562
+ if (Array.isArray(pages) && pages.length > 0) {
563
+ const firstPage = pages[0];
564
+ if ("string" == typeof firstPage && isSourceFilePath(firstPage)) {
565
+ const entryName = inferEntryNameFromPath(firstPage) ?? "sandbox";
566
+ return {
567
+ name: entryName,
568
+ value: firstPage.replace(/^\.\//, ""),
569
+ manifestPath: "sandbox.pages[0]"
570
+ };
571
+ }
572
+ }
573
+ return null;
574
+ }
575
+ function extractOverrides(manifest) {
576
+ const entries = [];
577
+ const overrides = manifest.chrome_url_overrides;
578
+ if (!overrides) return entries;
579
+ const overrideKeys = [
580
+ "newtab",
581
+ "bookmarks",
582
+ "history"
583
+ ];
584
+ for (const key of overrideKeys){
585
+ const path = overrides[key];
586
+ if ("string" == typeof path && isSourceFilePath(path)) {
587
+ const entryName = inferEntryNameFromPath(path) ?? key;
588
+ entries.push({
589
+ name: entryName,
590
+ value: path.replace(/^\.\//, ""),
591
+ manifestPath: `chrome_url_overrides.${key}`
592
+ });
593
+ }
594
+ }
595
+ return entries;
596
+ }
597
+ function extractContentScripts(manifest) {
598
+ const contentScripts = manifest.content_scripts;
599
+ if (!Array.isArray(contentScripts) || 0 === contentScripts.length) return null;
600
+ for(let i = 0; i < contentScripts.length; i++){
601
+ const cs = contentScripts[i];
602
+ const js = cs.js;
603
+ if (Array.isArray(js) && js.length > 0) for(let j = 0; j < js.length; j++){
604
+ const path = js[j];
605
+ if ("string" == typeof path && isSourceFilePath(path)) {
606
+ const entryName = inferEntryNameFromPath(path) ?? "content";
607
+ return {
608
+ name: entryName,
609
+ value: path.replace(/^\.\//, ""),
610
+ manifestPath: `content_scripts[${i}].js[${j}]`
611
+ };
612
+ }
613
+ }
614
+ }
615
+ return null;
616
+ }
617
+ function extractEntriesFromManifest(manifest, browser) {
618
+ const entries = {};
619
+ const replacementMap = new Map();
620
+ const extractors = [
621
+ ()=>extractServiceWorker(manifest, browser),
622
+ ()=>extractPopup(manifest, browser),
623
+ ()=>extractOptions(manifest),
624
+ ()=>extractDevtools(manifest),
625
+ ()=>extractSidepanel(manifest),
626
+ ()=>extractSandbox(manifest),
627
+ ()=>extractContentScripts(manifest),
628
+ ()=>extractOverrides(manifest)
629
+ ];
630
+ for (const extractor of extractors){
631
+ const result = extractor();
632
+ if (result) if (Array.isArray(result)) for (const entry of result){
633
+ entries[entry.name] = entry.value;
634
+ replacementMap.set(entry.manifestPath, entry.name);
635
+ }
636
+ else {
637
+ entries[result.name] = result.value;
638
+ replacementMap.set(result.manifestPath, result.name);
639
+ }
640
+ }
641
+ return {
642
+ entries,
643
+ replacementMap
644
+ };
645
+ }
646
+ const HTML_ENTRY_SET = new Set(HTML_ENTRY_NAMES);
647
+ function isHtmlPath(pathStr) {
648
+ return pathStr.trim().toLowerCase().endsWith(".html");
649
+ }
650
+ function isScriptPath(pathStr) {
651
+ const lower = pathStr.trim().toLowerCase();
652
+ return SCRIPT_EXTS.some((ext)=>lower.endsWith(ext));
653
+ }
654
+ function resolver_findScriptInDir(dir) {
655
+ for (const ext of SCRIPT_EXTS){
656
+ const p = (0, external_path_namespaceObject.resolve)(dir, `index${ext}`);
657
+ if ((0, external_fs_namespaceObject.existsSync)(p)) return p;
658
+ }
659
+ }
660
+ function findScriptForHtmlDir(dir, htmlFilename) {
661
+ const stem = (0, external_path_namespaceObject.basename)(htmlFilename, ".html");
662
+ for (const ext of SCRIPT_EXTS){
663
+ const p = (0, external_path_namespaceObject.resolve)(dir, `${stem}${ext}`);
664
+ if ((0, external_fs_namespaceObject.existsSync)(p)) return p;
665
+ }
666
+ return resolver_findScriptInDir(dir);
667
+ }
668
+ function isEntryConfigObject(value) {
669
+ return "object" == typeof value && null !== value && "src" in value;
670
+ }
671
+ function resolveHtmlPath(baseDir, htmlValue) {
672
+ if (!htmlValue) return;
673
+ const resolved = (0, external_path_namespaceObject.resolve)(baseDir, htmlValue);
674
+ if (!isHtmlPath(resolved)) return;
675
+ return (0, external_fs_namespaceObject.existsSync)(resolved) ? resolved : void 0;
676
+ }
677
+ function resolveHtmlFlag(entryName, htmlValue, hasTemplate) {
678
+ if (false === htmlValue) return false;
679
+ if (true === htmlValue) return true;
680
+ if ("string" == typeof htmlValue) return hasTemplate;
681
+ return isHtmlEntryName(entryName);
682
+ }
683
+ function isHtmlEntryName(entryName) {
684
+ return HTML_ENTRY_SET.has(entryName);
685
+ }
686
+ function enrichEntryWithScriptInject(entry) {
687
+ if (!entry.htmlPath || !entry.scriptPath) return entry;
688
+ const scriptInject = getScriptInjectIfMatches(entry.htmlPath, entry.scriptPath);
689
+ return scriptInject ? {
690
+ ...entry,
691
+ scriptInject
692
+ } : entry;
693
+ }
694
+ function inferHtmlPathForReservedName(entryName, scriptPath) {
695
+ if (!HTML_ENTRY_SET.has(entryName)) return;
696
+ const dir = (0, external_path_namespaceObject.dirname)(scriptPath);
697
+ const htmlPath = (0, external_path_namespaceObject.resolve)(dir, "index.html");
698
+ return (0, external_fs_namespaceObject.existsSync)(htmlPath) ? htmlPath : void 0;
699
+ }
700
+ function resolveEntryFromObject(baseDir, name, value) {
701
+ const scriptPath = (0, external_path_namespaceObject.resolve)(baseDir, value.src);
702
+ if (!(0, external_fs_namespaceObject.existsSync)(scriptPath) || !isScriptPath(scriptPath)) return null;
703
+ const htmlPath = resolveHtmlPath(baseDir, "string" == typeof value.html ? value.html : void 0);
704
+ if ("string" == typeof value.html && !htmlPath) return null;
705
+ const inferredHtml = htmlPath ?? inferHtmlPathForReservedName(name, scriptPath);
706
+ const html = resolveHtmlFlag(name, value.html, Boolean(htmlPath));
707
+ return enrichEntryWithScriptInject({
708
+ name,
709
+ scriptPath,
710
+ htmlPath: inferredHtml,
711
+ html
712
+ });
713
+ }
714
+ function resolveEntryFromHtml(baseDir, name, pathStr) {
715
+ const htmlPath = (0, external_path_namespaceObject.resolve)(baseDir, pathStr);
716
+ const dir = (0, external_path_namespaceObject.dirname)(htmlPath);
717
+ let parsed;
718
+ try {
719
+ parsed = parseAddfoxEntryFromHtml(htmlPath);
720
+ } catch {
721
+ parsed = void 0;
722
+ }
723
+ let scriptPath;
724
+ if (parsed) try {
725
+ scriptPath = resolveScriptFromHtmlStrict(htmlPath).scriptPath;
726
+ } catch (e) {
727
+ throw new common_namespaceObject.AddfoxError({
728
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.ENTRY_SCRIPT_FROM_HTML,
729
+ message: "Invalid data-addfox-entry script in HTML",
730
+ details: `HTML: ${htmlPath}. ${e instanceof Error ? e.message : String(e)}`,
731
+ hint: "data-addfox-entry script must have a relative src and the file must exist"
732
+ });
733
+ }
734
+ else scriptPath = findScriptForHtmlDir(dir, (0, external_path_namespaceObject.basename)(htmlPath));
735
+ if (!scriptPath) return null;
736
+ return enrichEntryWithScriptInject({
737
+ name,
738
+ scriptPath,
739
+ htmlPath,
740
+ html: true,
741
+ outputFollowsScriptPath: Boolean(parsed)
742
+ });
743
+ }
744
+ function resolveEntryFromScript(baseDir, name, pathStr) {
745
+ const scriptPath = (0, external_path_namespaceObject.resolve)(baseDir, pathStr);
746
+ if (!(0, external_fs_namespaceObject.existsSync)(scriptPath)) return null;
747
+ const htmlPath = inferHtmlPathForReservedName(name, scriptPath);
748
+ const html = isHtmlEntryName(name);
749
+ return enrichEntryWithScriptInject({
750
+ name,
751
+ scriptPath,
752
+ htmlPath,
753
+ html
754
+ });
755
+ }
756
+ function resolveSingleEntry(baseDir, name, value) {
757
+ if (isEntryConfigObject(value)) return resolveEntryFromObject(baseDir, name, value);
758
+ const resolved = (0, external_path_namespaceObject.resolve)(baseDir, value);
759
+ if (!(0, external_fs_namespaceObject.existsSync)(resolved)) return null;
760
+ if (isHtmlPath(value)) return resolveEntryFromHtml(baseDir, name, value);
761
+ if (isScriptPath(value)) return resolveEntryFromScript(baseDir, name, value);
762
+ return null;
763
+ }
764
+ function resolveEntries(config, _root, baseDir, manifest, options) {
765
+ const browser = options?.browser ?? "chromium";
766
+ const defaultEntries = discoverEntries(baseDir, options?.entryDiscovererOptions);
767
+ const entryMap = new Map(defaultEntries.map((e)=>[
768
+ e.name,
769
+ e
770
+ ]));
771
+ let manifestReplacementMap;
772
+ const entryConfig = config.entry;
773
+ const hasExplicitEntryConfig = entryConfig && Object.keys(entryConfig).length > 0;
774
+ if (manifest && !hasExplicitEntryConfig) {
775
+ const manifestResult = extractEntriesFromManifest(manifest, browser);
776
+ manifestReplacementMap = manifestResult.replacementMap;
777
+ for (const [name, pathStr] of Object.entries(manifestResult.entries)){
778
+ const resolved = resolveSingleEntry(baseDir, name, pathStr);
779
+ if (resolved) entryMap.set(name, resolved);
780
+ }
781
+ }
782
+ if (hasExplicitEntryConfig) for (const [name, pathStr] of Object.entries(entryConfig)){
783
+ const resolved = resolveSingleEntry(baseDir, name, pathStr);
784
+ if (resolved) entryMap.set(name, resolved);
785
+ else entryMap.delete(name);
786
+ }
787
+ return {
788
+ entries: Array.from(entryMap.values()),
789
+ manifestReplacementMap
790
+ };
791
+ }
792
+ class ManifestLoader {
793
+ readManifestJson(filePath) {
794
+ if (!(0, external_fs_namespaceObject.existsSync)(filePath)) return null;
795
+ try {
796
+ const raw = (0, external_fs_namespaceObject.readFileSync)(filePath, "utf-8");
797
+ const data = JSON.parse(raw);
798
+ return "object" == typeof data && null !== data ? data : null;
799
+ } catch {
800
+ return null;
801
+ }
802
+ }
803
+ isManifestPathConfig(m) {
804
+ if (!m || "object" != typeof m) return false;
805
+ const c = m;
806
+ return ("string" == typeof c.chromium || "string" == typeof c.firefox) && !("manifest_version" in c) && !("name" in c && "version" in c);
807
+ }
808
+ isChromiumFirefoxObject(m) {
809
+ return isChromiumFirefoxObjectValue(m);
810
+ }
811
+ deepMerge(base, override) {
812
+ const out = {
813
+ ...base
814
+ };
815
+ for (const key of Object.keys(override)){
816
+ const b = base[key];
817
+ const o = override[key];
818
+ if (null === o || "object" != typeof o || Array.isArray(o) || null === b || "object" != typeof b || Array.isArray(b)) out[key] = o;
819
+ else out[key] = this.deepMerge(b, o);
820
+ }
821
+ return out;
822
+ }
823
+ loadFromDir(dir) {
824
+ const basePath = (0, external_path_namespaceObject.resolve)(dir, MANIFEST_FILE_NAMES.base);
825
+ const chromPath = (0, external_path_namespaceObject.resolve)(dir, MANIFEST_FILE_NAMES.chromium);
826
+ const firefoxPath = (0, external_path_namespaceObject.resolve)(dir, MANIFEST_FILE_NAMES.firefox);
827
+ return {
828
+ base: this.readManifestJson(basePath),
829
+ chromium: this.readManifestJson(chromPath),
830
+ firefox: this.readManifestJson(firefoxPath)
831
+ };
832
+ }
833
+ hasAnyManifest(files) {
834
+ return null !== files.base || null !== files.chromium || null !== files.firefox;
835
+ }
836
+ buildConfigFromFiles(files) {
837
+ const base = files.base ?? files.chromium ?? files.firefox ?? null;
838
+ if (!base) return null;
839
+ const chromium = files.chromium ? this.deepMerge(base, files.chromium) : base;
840
+ const firefox = files.firefox ? this.deepMerge(base, files.firefox) : base;
841
+ return {
842
+ chromium,
843
+ firefox
844
+ };
845
+ }
846
+ resolve(input, root, appDir) {
847
+ if (null == input) {
848
+ const manifestSubdir = (0, external_path_namespaceObject.resolve)(appDir, MANIFEST_DIR);
849
+ const baseInApp = (0, external_path_namespaceObject.resolve)(appDir, MANIFEST_FILE_NAMES.base);
850
+ const baseInSub = (0, external_path_namespaceObject.resolve)(manifestSubdir, MANIFEST_FILE_NAMES.base);
851
+ const dir = (0, external_fs_namespaceObject.existsSync)(baseInApp) ? appDir : (0, external_fs_namespaceObject.existsSync)(baseInSub) ? manifestSubdir : null;
852
+ if (null !== dir) {
853
+ const files = this.loadFromDir(dir);
854
+ if (this.hasAnyManifest(files)) return validateAndReturn(this.buildConfigFromFiles(files));
855
+ }
856
+ return null;
857
+ }
858
+ if (this.isManifestPathConfig(input)) {
859
+ const result = {};
860
+ if (input.chromium) {
861
+ const obj = this.readManifestJson((0, external_path_namespaceObject.resolve)(appDir, input.chromium));
862
+ if (obj) result.chromium = obj;
863
+ }
864
+ if (input.firefox) {
865
+ const obj = this.readManifestJson((0, external_path_namespaceObject.resolve)(appDir, input.firefox));
866
+ if (obj) result.firefox = obj;
867
+ }
868
+ const chrom = result.chromium ?? result.firefox;
869
+ const ff = result.firefox ?? result.chromium;
870
+ if (!chrom && !ff) return null;
871
+ return validateAndReturn({
872
+ chromium: chrom ?? {},
873
+ firefox: ff ?? {}
874
+ });
875
+ }
876
+ this.isChromiumFirefoxObject(input);
877
+ return validateAndReturn(input);
878
+ }
879
+ }
880
+ const defaultLoader = new ManifestLoader();
881
+ function resolveManifestInput(input, root, appDir) {
882
+ return defaultLoader.resolve(input, root, appDir);
883
+ }
884
+ function validateAndReturn(config) {
885
+ if (!config) return null;
886
+ validateManifestSchema(config);
887
+ return config;
888
+ }
889
+ function validateManifestSchema(config) {
890
+ if (isChromiumFirefoxObjectValue(config)) {
891
+ if (config.chromium) validateManifestRecord(config.chromium, "chromium");
892
+ if (config.firefox) validateManifestRecord(config.firefox, "firefox");
893
+ return;
894
+ }
895
+ validateManifestRecord(config);
896
+ }
897
+ function isChromiumFirefoxObjectValue(m) {
898
+ return "object" == typeof m && null !== m && ("chromium" in m || "firefox" in m);
899
+ }
900
+ function validateManifestRecord(manifest, target) {
901
+ const mv = getManifestVersion(manifest);
902
+ if (null == mv) throw new Error("manifest_version must be 2 or 3");
903
+ const errors = 2 === mv ? validateMv2(manifest) : validateMv3(manifest, target);
904
+ if (errors.length > 0) throw new Error(errors.join("; "));
905
+ }
906
+ function getManifestVersion(manifest) {
907
+ const mv = manifest.manifest_version;
908
+ if (2 === mv || 3 === mv) return mv;
909
+ return null;
910
+ }
911
+ function validateMv2(manifest) {
912
+ const errors = [];
913
+ if (null != manifest.action) errors.push('MV2 does not support "action"; use "browser_action" or "page_action"');
914
+ if (null != manifest.host_permissions) errors.push('MV2 does not support "host_permissions"; use "permissions"');
915
+ errors.push(...validateBackgroundMv2(manifest.background));
916
+ errors.push(...validatePermissionsList(manifest.permissions, "permissions"));
917
+ return errors;
918
+ }
919
+ function validateMv3(manifest, target) {
920
+ const errors = [];
921
+ if (null != manifest.browser_action || null != manifest.page_action) errors.push('MV3 does not support "browser_action" or "page_action"; use "action"');
922
+ const bgErrors = "firefox" === target ? validateBackgroundMv3Firefox(manifest.background) : validateBackgroundMv3Chrome(manifest.background);
923
+ errors.push(...bgErrors);
924
+ errors.push(...validatePermissionsList(manifest.permissions, "permissions"));
925
+ errors.push(...validatePermissionsList(manifest.host_permissions, "host_permissions"));
926
+ errors.push(...validateAction(manifest.action));
927
+ return errors;
928
+ }
929
+ function validateBackgroundMv2(background) {
930
+ const errors = [];
931
+ if (!background) return errors;
932
+ if ("object" != typeof background) {
933
+ errors.push('MV2 "background" must be an object');
934
+ return errors;
935
+ }
936
+ const bg = background;
937
+ if (null != bg.service_worker) errors.push('MV2 "background.service_worker" is not allowed');
938
+ if (null != bg.scripts && !isStringArray(bg.scripts)) errors.push('MV2 "background.scripts" must be string[]');
939
+ if (null != bg.page && "string" != typeof bg.page) errors.push('MV2 "background.page" must be a string');
940
+ return errors;
941
+ }
942
+ function validateBackgroundMv3Chrome(background) {
943
+ const errors = [];
944
+ if (!background) return errors;
945
+ if ("object" != typeof background) {
946
+ errors.push('MV3 (Chrome) "background" must be an object');
947
+ return errors;
948
+ }
949
+ const bg = background;
950
+ if (null != bg.scripts) errors.push('MV3 (Chrome) "background.scripts" is not allowed; use "service_worker"');
951
+ if (null != bg.page) errors.push('MV3 (Chrome) "background.page" is not allowed; use "service_worker"');
952
+ if (null != bg.service_worker && "string" != typeof bg.service_worker) errors.push('MV3 (Chrome) "background.service_worker" must be a string');
953
+ return errors;
954
+ }
955
+ function validateBackgroundMv3Firefox(background) {
956
+ const errors = [];
957
+ if (!background) return errors;
958
+ if ("object" != typeof background) {
959
+ errors.push('MV3 (Firefox) "background" must be an object');
960
+ return errors;
961
+ }
962
+ const bg = background;
963
+ const hasScripts = null != bg.scripts;
964
+ const hasPage = null != bg.page;
965
+ const hasServiceWorker = null != bg.service_worker;
966
+ if (!hasScripts && !hasPage && !hasServiceWorker) return errors;
967
+ if (hasScripts && !isStringArray(bg.scripts)) errors.push('MV3 (Firefox) "background.scripts" must be string[]');
968
+ if (hasPage && "string" != typeof bg.page) errors.push('MV3 (Firefox) "background.page" must be a string');
969
+ if (hasServiceWorker && "string" != typeof bg.service_worker) errors.push('MV3 (Firefox) "background.service_worker" must be a string when present');
970
+ if (hasPage && hasScripts) errors.push('MV3 (Firefox) "background" cannot have both "page" and "scripts"');
971
+ return errors;
972
+ }
973
+ function validateAction(action) {
974
+ if (null == action) return [];
975
+ if ("object" != typeof action) return [
976
+ '"action" must be an object'
977
+ ];
978
+ const act = action;
979
+ if (null != act.default_popup && "string" != typeof act.default_popup) return [
980
+ '"action.default_popup" must be a string'
981
+ ];
982
+ return [];
983
+ }
984
+ function validatePermissionsList(value, key) {
985
+ if (null == value) return [];
986
+ return isStringArray(value) ? [] : [
987
+ `"${key}" must be string[]`
988
+ ];
989
+ }
990
+ function isStringArray(value) {
991
+ return Array.isArray(value) && value.every((item)=>"string" == typeof item);
992
+ }
993
+ const loader_require = (0, external_module_namespaceObject.createRequire)(__filename);
994
+ function loadWithJiti(root, configPath) {
995
+ const isConfigRestart = "1" === process.env.ADDFOX_CONFIG_RESTART;
996
+ const jitiOptions = {
997
+ esmResolve: true
998
+ };
999
+ if (isConfigRestart) {
1000
+ jitiOptions.moduleCache = false;
1001
+ jitiOptions.requireCache = false;
1002
+ }
1003
+ const jitiFn = loader_require("jiti")(root, jitiOptions);
1004
+ return jitiFn(configPath);
1005
+ }
1006
+ function loadNativeJs(configPath) {
1007
+ const mod = loader_require(configPath);
1008
+ return mod?.default ?? mod;
1009
+ }
1010
+ function unwrapConfig(mod) {
1011
+ if (null == mod) return {};
1012
+ if ("object" == typeof mod && "default" in mod && void 0 !== mod.default) return mod.default ?? {};
1013
+ return mod ?? {};
1014
+ }
1015
+ function loadConfigModule(root, configPath, file) {
1016
+ const isNativeJs = file.endsWith(".js") || file.endsWith(".mjs");
1017
+ if (isNativeJs) try {
1018
+ return unwrapConfig(loadNativeJs(configPath));
1019
+ } catch {}
1020
+ return unwrapConfig(loadWithJiti(root, configPath));
1021
+ }
1022
+ function findConfigFile(root, configFiles) {
1023
+ for (const file of configFiles){
1024
+ const p = (0, external_path_namespaceObject.resolve)(root, file);
1025
+ if ((0, external_fs_namespaceObject.existsSync)(p)) return p;
1026
+ }
1027
+ return null;
1028
+ }
1029
+ function loadConfigAtPath(root, configPath, file) {
1030
+ try {
1031
+ return loadConfigModule(root, configPath, file);
1032
+ } catch (e) {
1033
+ const message = e instanceof Error ? e.message : String(e);
1034
+ throw new common_namespaceObject.AddfoxError({
1035
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.CONFIG_LOAD_FAILED,
1036
+ message: "Failed to load config file",
1037
+ details: `File: ${configPath}, error: ${message}`,
1038
+ hint: "Check addfox.config syntax and dependencies",
1039
+ cause: e instanceof Error ? e : void 0
1040
+ });
1041
+ }
1042
+ }
1043
+ function loadConfigFile(root, configFiles = CONFIG_FILES) {
1044
+ for (const file of configFiles){
1045
+ const p = (0, external_path_namespaceObject.resolve)(root, file);
1046
+ if ((0, external_fs_namespaceObject.existsSync)(p)) return loadConfigAtPath(root, p, file);
1047
+ }
1048
+ return null;
1049
+ }
1050
+ function getResolvedConfigFilePath(root, configFiles = CONFIG_FILES) {
1051
+ return findConfigFile(root, configFiles);
1052
+ }
1053
+ function resolveAppDir(root, userConfig) {
1054
+ return (0, external_path_namespaceObject.resolve)(root, userConfig.appDir ?? "app");
1055
+ }
1056
+ function validateAppDir(appDir, entryDisabled) {
1057
+ if (entryDisabled) return;
1058
+ if (!(0, external_fs_namespaceObject.existsSync)(appDir) || !(0, external_fs_namespaceObject.statSync)(appDir).isDirectory()) throw new common_namespaceObject.AddfoxError({
1059
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.APP_DIR_MISSING,
1060
+ message: "App directory not found",
1061
+ details: `Missing appDir: ${appDir}`,
1062
+ hint: "Create the directory or set appDir to an existing folder (default is app/)"
1063
+ });
1064
+ }
1065
+ function createResolvedConfig(userConfig, root, appDir, manifest) {
1066
+ return {
1067
+ ...userConfig,
1068
+ manifest,
1069
+ appDir,
1070
+ outDir: userConfig.outDir ?? DEFAULT_OUT_DIR,
1071
+ envPrefix: userConfig.envPrefix ?? [
1072
+ ...DEFAULT_ENV_PREFIXES
1073
+ ],
1074
+ outputRoot: ADDFOX_OUTPUT_ROOT,
1075
+ root
1076
+ };
1077
+ }
1078
+ function discoverAndResolveEntries(userConfig, root, appDir, manifest, entryDiscovererOptions, entryResolverOptions) {
1079
+ const baseEntries = discoverEntries(appDir, entryDiscovererOptions);
1080
+ const result = resolveEntries(userConfig, root, appDir, manifest ?? void 0, entryResolverOptions);
1081
+ return {
1082
+ baseEntries,
1083
+ entries: result.entries
1084
+ };
1085
+ }
1086
+ function resolveAddfoxConfig(root, options = {}) {
1087
+ const t0 = performance.now();
1088
+ const userConfig = loadConfigFile(root, options.configFiles);
1089
+ if (!userConfig) throw new common_namespaceObject.AddfoxError({
1090
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.CONFIG_NOT_FOUND,
1091
+ message: "Addfox config file not found",
1092
+ details: `No addfox.config.ts, addfox.config.js or addfox.config.mjs found under ${root}`,
1093
+ hint: "Run the command from project root or create addfox.config.ts / addfox.config.js"
1094
+ });
1095
+ const appDir = resolveAppDir(root, userConfig);
1096
+ const entryDisabled = false === userConfig.entry;
1097
+ validateAppDir(appDir, entryDisabled);
1098
+ const manifest = resolveManifestInput(userConfig.manifest, root, appDir);
1099
+ if (!manifest) throw new common_namespaceObject.AddfoxError({
1100
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.MANIFEST_MISSING,
1101
+ message: "Manifest config or file not found",
1102
+ details: "Configure manifest in addfox.config, or place manifest.json / manifest.chromium.json / manifest.firefox.json under appDir or appDir/manifest",
1103
+ hint: "Option 1: manifest: { name, version, ... } in addfox.config; Option 2: manifest.json under appDir or appDir/manifest; Option 3: manifest: { chromium: 'path/to/manifest.json' } (path relative to appDir)"
1104
+ });
1105
+ const config = createResolvedConfig(userConfig, root, appDir, manifest);
1106
+ const manifestForEntry = "object" == typeof manifest && null !== manifest ? manifest.chromium ?? manifest.firefox ?? manifest : null;
1107
+ const { baseEntries, entries } = entryDisabled ? {
1108
+ baseEntries: [],
1109
+ entries: []
1110
+ } : discoverAndResolveEntries(userConfig, root, appDir, manifestForEntry, options.entryDiscovererOptions, options.entryResolverOptions);
1111
+ if (!entryDisabled && 0 === entries.length) throw new common_namespaceObject.AddfoxError({
1112
+ code: common_namespaceObject.ADDFOX_ERROR_CODES.NO_ENTRIES,
1113
+ message: "No entries discovered",
1114
+ details: `No background, content, popup, options or sidepanel entry found under ${appDir}`,
1115
+ hint: "At least one such directory with index.ts / index.js etc. is required"
1116
+ });
1117
+ (0, common_namespaceObject.logDoneTimed)("Parse config", Math.round(performance.now() - t0));
1118
+ (0, common_namespaceObject.logEntriesTable)(entries, {
1119
+ root
1120
+ });
1121
+ return {
1122
+ config,
1123
+ baseEntries,
1124
+ entries
1125
+ };
1126
+ }
1127
+ function clearConfigCache(configFilePath) {
1128
+ try {
1129
+ delete loader_require.cache[configFilePath];
1130
+ } catch {}
1131
+ for (const key of Object.keys(loader_require.cache)){
1132
+ const mod = loader_require.cache[key];
1133
+ if (mod?.filename === configFilePath) try {
1134
+ delete loader_require.cache[key];
1135
+ } catch {}
1136
+ }
1137
+ }
1138
+ function getResolvedRstestConfigFilePath(root) {
1139
+ for (const file of RSTEST_CONFIG_FILES){
1140
+ const p = (0, external_path_namespaceObject.resolve)(root, file);
1141
+ if ((0, external_fs_namespaceObject.existsSync)(p)) return p;
1142
+ }
1143
+ return null;
1144
+ }
1145
+ class Pipeline {
1146
+ hooks;
1147
+ constructor(hooks){
1148
+ this.hooks = hooks;
1149
+ }
1150
+ async execute(root, argv) {
1151
+ let context = {
1152
+ root,
1153
+ argv
1154
+ };
1155
+ try {
1156
+ await this.runStage('init', context);
1157
+ await this.runStage('options', context);
1158
+ await this.runStage('parse', context);
1159
+ await this.runStage('load', context);
1160
+ await this.runStage('resolve', context);
1161
+ await this.runStage('prepare', context);
1162
+ await this.runStage('build', context);
1163
+ } catch (error) {
1164
+ await this.runStage('complete', context);
1165
+ throw error;
1166
+ }
1167
+ await this.runStage('complete', context);
1168
+ return context;
1169
+ }
1170
+ async runStage(stage, payload) {
1171
+ await this.hooks.execute(stage, 'before', payload);
1172
+ await this.hooks.execute(stage, 'after', payload);
1173
+ }
1174
+ }
1175
+ const ADDFOX_PLACEHOLDER_REGEX = /\[addfox\.([a-z]+)\]/g;
1176
+ const CONTENT_PLACEHOLDER = "[addfox.content]";
1177
+ const CONTENT_PLACEHOLDER_LEGACY = "[addfox.content]";
1178
+ const SCRIPT_KEYS_SET = new Set(SCRIPT_ONLY_ENTRY_NAMES);
1179
+ function builder_isSourceFilePath(path) {
1180
+ const lower = path.trim().toLowerCase();
1181
+ return /\.(ts|tsx|js|jsx)$/.test(lower);
1182
+ }
1183
+ function isChromiumFirefoxManifest(m) {
1184
+ return "object" == typeof m && null !== m && ("chromium" in m || "firefox" in m);
1185
+ }
1186
+ function isEntryFieldEmpty(value) {
1187
+ if (null == value) return true;
1188
+ if ("string" == typeof value) return "" === value.trim();
1189
+ if (Array.isArray(value)) return 0 === value.length;
1190
+ return false;
1191
+ }
1192
+ function hasNonEmptyStringArray(value) {
1193
+ return Array.isArray(value) && value.length > 0;
1194
+ }
1195
+ function isManifestRecord(value) {
1196
+ return null !== value && "object" == typeof value && !Array.isArray(value);
1197
+ }
1198
+ function getManifestRecordForTarget(config, target) {
1199
+ return pickManifestForTarget(config, target).manifest;
1200
+ }
1201
+ function pickManifestForTarget(config, target) {
1202
+ if (!isChromiumFirefoxManifest(config)) return {
1203
+ manifest: config
1204
+ };
1205
+ const hasChromium = null != config.chromium && "object" == typeof config.chromium;
1206
+ const hasFirefox = null != config.firefox && "object" == typeof config.firefox;
1207
+ if (hasChromium && hasFirefox) {
1208
+ const match = config[target];
1209
+ if (null != match && "object" == typeof match) return {
1210
+ manifest: match
1211
+ };
1212
+ const fallback = "firefox" === target ? config.chromium : config.firefox;
1213
+ return {
1214
+ manifest: fallback,
1215
+ warnMessage: `Build target is ${target} but manifest.${target} is missing; using ${"firefox" === target ? "chromium" : "firefox"} manifest.`
1216
+ };
1217
+ }
1218
+ if (hasChromium) return {
1219
+ manifest: config.chromium,
1220
+ warnMessage: "firefox" === target ? "Build target is firefox but manifest only has chromium; using chromium manifest." : void 0
1221
+ };
1222
+ if (hasFirefox) return {
1223
+ manifest: config.firefox,
1224
+ warnMessage: "chromium" === target ? "Build target is chromium but manifest only has firefox; using firefox manifest." : void 0
1225
+ };
1226
+ return {
1227
+ manifest: config.chromium ?? config.firefox ?? {},
1228
+ warnMessage: "Manifest has no chromium or firefox object; using fallback."
1229
+ };
1230
+ }
1231
+ function buildScriptOutputPath(entry) {
1232
+ const scriptStem = (0, external_path_namespaceObject.basename)(entry.scriptPath, (0, external_path_namespaceObject.extname)(entry.scriptPath));
1233
+ return scriptStem === entry.name ? `${entry.name}.js` : `${entry.name}/index.js`;
1234
+ }
1235
+ function buildHtmlOutputPath(entry, fallback) {
1236
+ if (!entry.htmlPath) return fallback;
1237
+ const htmlFile = (0, external_path_namespaceObject.basename)(entry.htmlPath).toLowerCase();
1238
+ return htmlFile === `${entry.name}.html` ? `${entry.name}.html` : fallback;
1239
+ }
1240
+ function buildPlaceholderMap(entries) {
1241
+ const map = {};
1242
+ for (const key of MANIFEST_ENTRY_KEYS){
1243
+ const entry = entries.find((e)=>e.name === key);
1244
+ if (entry) map[key] = SCRIPT_KEYS_SET.has(key) ? buildScriptOutputPath(entry) : buildHtmlOutputPath(entry, MANIFEST_ENTRY_PATHS[key]);
1245
+ }
1246
+ return map;
1247
+ }
1248
+ function buildSourceToOutputMap(entries) {
1249
+ const map = new Map();
1250
+ const placeholderMap = buildPlaceholderMap(entries);
1251
+ for (const key of MANIFEST_ENTRY_KEYS){
1252
+ const entry = entries.find((e)=>e.name === key);
1253
+ if (!entry) continue;
1254
+ const sourcePath = entry.scriptPath;
1255
+ const outputPath = placeholderMap[key];
1256
+ if (sourcePath && outputPath) {
1257
+ map.set(sourcePath, outputPath);
1258
+ const basename = sourcePath.split(/[\\/]/).pop();
1259
+ if (basename) {
1260
+ map.set(basename, outputPath);
1261
+ map.set(`./${basename}`, outputPath);
1262
+ }
1263
+ const entryDir = key;
1264
+ const entryIndexPath = `${entryDir}/${basename}`;
1265
+ map.set(entryIndexPath, outputPath);
1266
+ map.set(`./${entryIndexPath}`, outputPath);
1267
+ }
1268
+ }
1269
+ return map;
1270
+ }
1271
+ function shouldUseServiceWorker(mv, browser) {
1272
+ return 3 === mv && "chromium" === browser;
1273
+ }
1274
+ function isChromiumOnlyAutofillKey(key) {
1275
+ return "sidepanel" === key || "newtab" === key || "bookmarks" === key || "history" === key;
1276
+ }
1277
+ const fillers = {
1278
+ background: (mv, browser)=>(out, path)=>{
1279
+ const bg = out.background ?? {};
1280
+ if (shouldUseServiceWorker(mv, browser)) {
1281
+ if (isEntryFieldEmpty(bg.service_worker)) out.background = {
1282
+ ...bg,
1283
+ service_worker: path
1284
+ };
1285
+ } else {
1286
+ const scripts = bg.scripts;
1287
+ if (!Array.isArray(scripts) || 0 === scripts.length) out.background = {
1288
+ ...bg,
1289
+ scripts: [
1290
+ path
1291
+ ]
1292
+ };
1293
+ }
1294
+ },
1295
+ popup: (mv)=>(out, path)=>{
1296
+ if (3 === mv) {
1297
+ const action = out.action ?? {};
1298
+ if (isEntryFieldEmpty(action.default_popup)) out.action = {
1299
+ ...action,
1300
+ default_popup: path
1301
+ };
1302
+ } else {
1303
+ const ba = out.browser_action ?? {};
1304
+ if (isEntryFieldEmpty(ba.default_popup)) out.browser_action = {
1305
+ ...ba,
1306
+ default_popup: path
1307
+ };
1308
+ }
1309
+ },
1310
+ options: (mv)=>(out, path)=>{
1311
+ if (3 === mv) {
1312
+ const opt = out.options_ui ?? {};
1313
+ if (isEntryFieldEmpty(opt.page)) out.options_ui = {
1314
+ ...opt,
1315
+ page: path
1316
+ };
1317
+ } else if (isEntryFieldEmpty(out.options_page)) out.options_page = path;
1318
+ },
1319
+ devtools: ()=>(out, path)=>{
1320
+ if (isEntryFieldEmpty(out.devtools_page)) out.devtools_page = path;
1321
+ },
1322
+ sandbox: ()=>(out, path)=>{
1323
+ const sandbox = out.sandbox;
1324
+ if (null === sandbox || "object" != typeof sandbox || Array.isArray(sandbox)) {
1325
+ out.sandbox = {
1326
+ pages: [
1327
+ path
1328
+ ]
1329
+ };
1330
+ return;
1331
+ }
1332
+ const pages = sandbox.pages;
1333
+ if (!Array.isArray(pages) || 0 === pages.length) out.sandbox = {
1334
+ ...sandbox,
1335
+ pages: [
1336
+ path
1337
+ ]
1338
+ };
1339
+ },
1340
+ content: ()=>(out, path)=>{
1341
+ const cs = out.content_scripts;
1342
+ if (!Array.isArray(cs) || 0 === cs.length) out.content_scripts = [
1343
+ {
1344
+ matches: [
1345
+ "<all_urls>"
1346
+ ],
1347
+ js: [
1348
+ path
1349
+ ],
1350
+ run_at: "document_idle"
1351
+ }
1352
+ ];
1353
+ },
1354
+ newtab: ()=>(out, path)=>{
1355
+ const overrides = out.chrome_url_overrides ?? {};
1356
+ if (isEntryFieldEmpty(overrides.newtab)) out.chrome_url_overrides = {
1357
+ ...overrides,
1358
+ newtab: path
1359
+ };
1360
+ },
1361
+ bookmarks: ()=>(out, path)=>{
1362
+ const overrides = out.chrome_url_overrides ?? {};
1363
+ if (isEntryFieldEmpty(overrides.bookmarks)) out.chrome_url_overrides = {
1364
+ ...overrides,
1365
+ bookmarks: path
1366
+ };
1367
+ ensurePermission(out, "bookmarks");
1368
+ },
1369
+ history: ()=>(out, path)=>{
1370
+ const overrides = out.chrome_url_overrides ?? {};
1371
+ if (isEntryFieldEmpty(overrides.history)) out.chrome_url_overrides = {
1372
+ ...overrides,
1373
+ history: path
1374
+ };
1375
+ ensurePermission(out, "history");
1376
+ },
1377
+ sidepanel: ()=>(out, path)=>{
1378
+ const sp = out.side_panel ?? {};
1379
+ if (isEntryFieldEmpty(sp.default_path)) out.side_panel = {
1380
+ ...sp,
1381
+ default_path: path
1382
+ };
1383
+ }
1384
+ };
1385
+ function ensurePermission(out, permission) {
1386
+ const current = out.permissions;
1387
+ if (!Array.isArray(current)) {
1388
+ out.permissions = [
1389
+ permission
1390
+ ];
1391
+ return;
1392
+ }
1393
+ if (!current.includes(permission)) out.permissions = [
1394
+ ...current,
1395
+ permission
1396
+ ];
1397
+ }
1398
+ function buildAutoFillers(mv, browser) {
1399
+ const result = {};
1400
+ for (const [key, factory] of Object.entries(fillers))if ("sidepanel" !== key || 3 === mv) {
1401
+ if (!("firefox" === browser && isChromiumOnlyAutofillKey(key))) result[key] = factory(mv, browser);
1402
+ }
1403
+ return result;
1404
+ }
1405
+ function needsSidePanelPermission(out, placeholderMap, browser) {
1406
+ if ("chromium" !== browser) return false;
1407
+ if (null != placeholderMap.sidepanel) return true;
1408
+ const sp = out.side_panel;
1409
+ if (null == sp || "object" != typeof sp || Array.isArray(sp)) return false;
1410
+ const path = sp.default_path;
1411
+ return "string" == typeof path && "" !== path.trim();
1412
+ }
1413
+ function autoFillEntryFields(manifest, placeholderMap, browser) {
1414
+ const mv = 2 === manifest.manifest_version ? 2 : 3;
1415
+ const out = {
1416
+ ...manifest
1417
+ };
1418
+ const autoFillers = buildAutoFillers(mv, browser);
1419
+ for (const [key, path] of Object.entries(placeholderMap))autoFillers[key]?.(out, path);
1420
+ if (3 === mv && needsSidePanelPermission(out, placeholderMap, browser)) ensurePermission(out, "sidePanel");
1421
+ return out;
1422
+ }
1423
+ function replacePlaceholderInString(str, placeholderMap) {
1424
+ return str.replace(ADDFOX_PLACEHOLDER_REGEX, (_, key)=>key in placeholderMap ? placeholderMap[key] : `[addfox.${key}]`);
1425
+ }
1426
+ function replacePlaceholdersInValue(value, placeholderMap) {
1427
+ if ("string" == typeof value) return replacePlaceholderInString(value, placeholderMap);
1428
+ if (Array.isArray(value)) return value.map((item)=>replacePlaceholdersInValue(item, placeholderMap));
1429
+ if (null !== value && "object" == typeof value) {
1430
+ const out = {};
1431
+ for (const [k, v] of Object.entries(value))out[k] = replacePlaceholdersInValue(v, placeholderMap);
1432
+ return out;
1433
+ }
1434
+ return value;
1435
+ }
1436
+ function replaceSourcePathsWithOutput(value, sourceToOutputMap) {
1437
+ if ("string" == typeof value) {
1438
+ if (builder_isSourceFilePath(value)) {
1439
+ const outputPath = sourceToOutputMap.get(value);
1440
+ if (outputPath) return outputPath;
1441
+ const basename = value.split(/[\\/]/).pop();
1442
+ if (basename) {
1443
+ const fromBasename = sourceToOutputMap.get(basename);
1444
+ if (fromBasename) return fromBasename;
1445
+ const fromDotSlash = sourceToOutputMap.get(`./${basename}`);
1446
+ if (fromDotSlash) return fromDotSlash;
1447
+ }
1448
+ }
1449
+ return value;
1450
+ }
1451
+ if (Array.isArray(value)) return value.map((item)=>replaceSourcePathsWithOutput(item, sourceToOutputMap));
1452
+ if (null !== value && "object" == typeof value) {
1453
+ const out = {};
1454
+ for (const [k, v] of Object.entries(value))out[k] = replaceSourcePathsWithOutput(v, sourceToOutputMap);
1455
+ return out;
1456
+ }
1457
+ return value;
1458
+ }
1459
+ function resolveContentScriptsPlaceholders(manifest, placeholderMap, contentScriptOutput) {
1460
+ const contentScripts = manifest.content_scripts;
1461
+ if (!Array.isArray(contentScripts)) return manifest;
1462
+ const defaultContentJs = placeholderMap.content ? [
1463
+ placeholderMap.content
1464
+ ] : [];
1465
+ const shouldAutoFillCss = contentScriptOutput?.autoFillCssInManifest !== false;
1466
+ const resolved = contentScripts.map((item)=>{
1467
+ if (null === item || "object" != typeof item || Array.isArray(item)) return item;
1468
+ const obj = item;
1469
+ const out = {
1470
+ ...obj
1471
+ };
1472
+ if (Array.isArray(obj.js)) {
1473
+ const jsReplacement = contentScriptOutput?.js ?? defaultContentJs;
1474
+ out.js = obj.js.flatMap((el)=>el === CONTENT_PLACEHOLDER || el === CONTENT_PLACEHOLDER_LEGACY ? jsReplacement : [
1475
+ el
1476
+ ]);
1477
+ }
1478
+ if (Array.isArray(obj.css)) {
1479
+ const cssReplacement = contentScriptOutput?.css ?? [];
1480
+ const resolvedCss = obj.css.flatMap((el)=>el === CONTENT_PLACEHOLDER || el === CONTENT_PLACEHOLDER_LEGACY ? cssReplacement : [
1481
+ el
1482
+ ]);
1483
+ if (resolvedCss.length > 0) out.css = resolvedCss;
1484
+ else delete out.css;
1485
+ }
1486
+ const hadJs = hasNonEmptyStringArray(out.js);
1487
+ const hadCss = hasNonEmptyStringArray(out.css);
1488
+ if (!hadJs && !hadCss && placeholderMap.content) out.js = contentScriptOutput?.js ?? defaultContentJs;
1489
+ const hasJs = hasNonEmptyStringArray(out.js);
1490
+ const isContentItem = hasJs && null != placeholderMap.content && out.js.includes(placeholderMap.content);
1491
+ if (shouldAutoFillCss && isContentItem && contentScriptOutput?.css?.length && !hasNonEmptyStringArray(out.css)) out.css = contentScriptOutput.css;
1492
+ return out;
1493
+ });
1494
+ return {
1495
+ ...manifest,
1496
+ content_scripts: resolved
1497
+ };
1498
+ }
1499
+ function replaceContentScriptSourcePaths(manifest, sourceToOutputMap) {
1500
+ const contentScripts = manifest.content_scripts;
1501
+ if (!Array.isArray(contentScripts)) return manifest;
1502
+ const resolved = contentScripts.map((item)=>{
1503
+ if (null === item || "object" != typeof item || Array.isArray(item)) return item;
1504
+ const obj = item;
1505
+ const out = {
1506
+ ...obj
1507
+ };
1508
+ if (Array.isArray(obj.js)) out.js = obj.js.map((path)=>{
1509
+ if ("string" == typeof path && builder_isSourceFilePath(path)) {
1510
+ const outputPath = sourceToOutputMap.get(path);
1511
+ if (outputPath) return outputPath;
1512
+ const basename = path.split(/[\\/]/).pop();
1513
+ if (basename) {
1514
+ const fromBasename = sourceToOutputMap.get(basename);
1515
+ if (fromBasename) return fromBasename;
1516
+ }
1517
+ }
1518
+ return path;
1519
+ });
1520
+ return out;
1521
+ });
1522
+ return {
1523
+ ...manifest,
1524
+ content_scripts: resolved
1525
+ };
1526
+ }
1527
+ function buildManifest(manifest, entries, browser, contentScriptOutput) {
1528
+ const placeholderMap = buildPlaceholderMap(entries);
1529
+ const sourceToOutputMap = buildSourceToOutputMap(entries);
1530
+ const pipeline = [
1531
+ (m)=>autoFillEntryFields(m, placeholderMap, browser),
1532
+ (m)=>resolveContentScriptsPlaceholders(m, placeholderMap, contentScriptOutput),
1533
+ (m)=>replaceSourcePathsWithOutput(m, sourceToOutputMap),
1534
+ (m)=>replaceContentScriptSourcePaths(m, sourceToOutputMap),
1535
+ (m)=>replacePlaceholdersInValue(m, placeholderMap)
1536
+ ];
1537
+ const result = pipeline.reduce((acc, fn)=>fn(acc), {
1538
+ ...manifest
1539
+ });
1540
+ return isManifestRecord(result) ? result : manifest;
1541
+ }
1542
+ function buildForBrowser(config, entries, browser, onWarn, contentScriptOutput) {
1543
+ const { manifest, warnMessage } = pickManifestForTarget(config, browser);
1544
+ if (warnMessage) onWarn?.(warnMessage);
1545
+ return buildManifest(manifest, entries, browser, contentScriptOutput);
1546
+ }
1547
+ function resolveManifestChromium(config, entries) {
1548
+ return buildForBrowser(config, entries, "chromium");
1549
+ }
1550
+ function resolveManifestFirefox(config, entries) {
1551
+ return buildForBrowser(config, entries, "firefox");
1552
+ }
1553
+ function resolveManifestForTarget(config, entries, target, onWarn, contentScriptOutput) {
1554
+ return buildForBrowser(config, entries, target, onWarn, contentScriptOutput);
1555
+ }
1556
+ function toReloadManagerEntries(entries, root) {
1557
+ return entries.filter((e)=>RELOAD_MANAGER_ENTRY_NAMES.has(e.name)).map((e)=>({
1558
+ name: e.name,
1559
+ path: (0, external_path_namespaceObject.resolve)(root, e.scriptPath)
1560
+ }));
1561
+ }
1562
+ const external_node_module_namespaceObject = require("node:module");
1563
+ const external_node_fs_namespaceObject = require("node:fs");
1564
+ const external_node_path_namespaceObject = require("node:path");
1565
+ const external_node_url_namespaceObject = require("node:url");
1566
+ const version_require = (0, external_node_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
1567
+ function findPackageJson() {
1568
+ const __dirname = (0, external_node_path_namespaceObject.dirname)((0, external_node_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__));
1569
+ const distPath = (0, external_node_path_namespaceObject.resolve)(__dirname, "../../package.json");
1570
+ if ((0, external_node_fs_namespaceObject.existsSync)(distPath)) return version_require(distPath);
1571
+ const srcPath = (0, external_node_path_namespaceObject.resolve)(__dirname, "../package.json");
1572
+ if ((0, external_node_fs_namespaceObject.existsSync)(srcPath)) return version_require(srcPath);
1573
+ return {};
1574
+ }
1575
+ const version_pkg = findPackageJson();
1576
+ function getAddfoxVersion() {
1577
+ return version_pkg?.version ?? "0.0.0";
1578
+ }
1579
+ const FRAMEWORK_KEYS = [
1580
+ {
1581
+ pkg: "solid-js",
1582
+ name: "Solid"
1583
+ },
1584
+ {
1585
+ pkg: "svelte",
1586
+ name: "Svelte"
1587
+ },
1588
+ {
1589
+ pkg: "vue",
1590
+ name: "Vue"
1591
+ },
1592
+ {
1593
+ pkg: "preact",
1594
+ name: "Preact"
1595
+ },
1596
+ {
1597
+ pkg: "react",
1598
+ name: "React"
1599
+ }
1600
+ ];
1601
+ function readPackageJson(root) {
1602
+ const path = (0, external_node_path_namespaceObject.join)(root, "package.json");
1603
+ if (!(0, external_node_fs_namespaceObject.existsSync)(path)) return null;
1604
+ try {
1605
+ const raw = (0, external_node_fs_namespaceObject.readFileSync)(path, "utf-8");
1606
+ return JSON.parse(raw);
1607
+ } catch {
1608
+ return null;
1609
+ }
1610
+ }
1611
+ function hasDep(pkg, key) {
1612
+ const deps = pkg.dependencies;
1613
+ const devDeps = pkg.devDependencies;
1614
+ if (deps && "string" == typeof deps[key]) return true;
1615
+ if (devDeps && "string" == typeof devDeps[key]) return true;
1616
+ return false;
1617
+ }
1618
+ function detectFrontendFramework(root) {
1619
+ if (!root || "string" != typeof root) return "Vanilla";
1620
+ const pkg = readPackageJson(root);
1621
+ if (!pkg) return "Vanilla";
1622
+ for (const { pkg: key, name } of FRAMEWORK_KEYS)if (hasDep(pkg, key)) return name;
1623
+ return "Vanilla";
1624
+ }
1625
+ exports.ADDFOX_OUTPUT_ROOT = __webpack_exports__.ADDFOX_OUTPUT_ROOT;
1626
+ exports.BROWSER_OUTPUT_PREFIX = __webpack_exports__.BROWSER_OUTPUT_PREFIX;
1627
+ exports.CLI_COMMANDS = __webpack_exports__.CLI_COMMANDS;
1628
+ exports.CONFIG_FILES = __webpack_exports__.CONFIG_FILES;
1629
+ exports.DEFAULT_APP_DIR = __webpack_exports__.DEFAULT_APP_DIR;
1630
+ exports.DEFAULT_BROWSER = __webpack_exports__.DEFAULT_BROWSER;
1631
+ exports.DEFAULT_ENV_PREFIXES = __webpack_exports__.DEFAULT_ENV_PREFIXES;
1632
+ exports.DEFAULT_OUT_DIR = __webpack_exports__.DEFAULT_OUT_DIR;
1633
+ exports.HMR_WS_PORT = __webpack_exports__.HMR_WS_PORT;
1634
+ exports.HTML_ENTRY_NAMES = __webpack_exports__.HTML_ENTRY_NAMES;
1635
+ exports.MANIFEST_DIR = __webpack_exports__.MANIFEST_DIR;
1636
+ exports.MANIFEST_ENTRY_KEYS = __webpack_exports__.MANIFEST_ENTRY_KEYS;
1637
+ exports.MANIFEST_ENTRY_PATHS = __webpack_exports__.MANIFEST_ENTRY_PATHS;
1638
+ exports.MANIFEST_FILE_NAMES = __webpack_exports__.MANIFEST_FILE_NAMES;
1639
+ exports.ManifestLoader = __webpack_exports__.ManifestLoader;
1640
+ exports.Pipeline = __webpack_exports__.Pipeline;
1641
+ exports.RELOAD_MANAGER_ENTRY_NAMES = __webpack_exports__.RELOAD_MANAGER_ENTRY_NAMES;
1642
+ exports.RESERVED_ENTRY_NAMES = __webpack_exports__.RESERVED_ENTRY_NAMES;
1643
+ exports.RSTEST_CONFIG_FILES = __webpack_exports__.RSTEST_CONFIG_FILES;
1644
+ exports.SCRIPT_EXTS = __webpack_exports__.SCRIPT_EXTS;
1645
+ exports.SCRIPT_ONLY_ENTRY_NAMES = __webpack_exports__.SCRIPT_ONLY_ENTRY_NAMES;
1646
+ exports.SUPPORTED_BROWSERS = __webpack_exports__.SUPPORTED_BROWSERS;
1647
+ exports.SUPPORTED_LAUNCH_TARGETS = __webpack_exports__.SUPPORTED_LAUNCH_TARGETS;
1648
+ exports.buildForBrowser = __webpack_exports__.buildForBrowser;
1649
+ exports.clearConfigCache = __webpack_exports__.clearConfigCache;
1650
+ exports.defineConfig = __webpack_exports__.defineConfig;
1651
+ exports.detectFrontendFramework = __webpack_exports__.detectFrontendFramework;
1652
+ exports.discoverEntries = __webpack_exports__.discoverEntries;
1653
+ exports.extractEntriesFromManifest = __webpack_exports__.extractEntriesFromManifest;
1654
+ exports.getAddfoxVersion = __webpack_exports__.getAddfoxVersion;
1655
+ exports.getAllEntryNames = __webpack_exports__.getAllEntryNames;
1656
+ exports.getBrowserOutputDir = __webpack_exports__.getBrowserOutputDir;
1657
+ exports.getHtmlEntryNames = __webpack_exports__.getHtmlEntryNames;
1658
+ exports.getManifestRecordForTarget = __webpack_exports__.getManifestRecordForTarget;
1659
+ exports.getResolvedConfigFilePath = __webpack_exports__.getResolvedConfigFilePath;
1660
+ exports.getResolvedRstestConfigFilePath = __webpack_exports__.getResolvedRstestConfigFilePath;
1661
+ exports.getScriptInjectIfMatches = __webpack_exports__.getScriptInjectIfMatches;
1662
+ exports.getScriptOnlyEntryNames = __webpack_exports__.getScriptOnlyEntryNames;
1663
+ exports.isScriptSrcRelative = __webpack_exports__.isScriptSrcRelative;
1664
+ exports.loadConfigFile = __webpack_exports__.loadConfigFile;
1665
+ exports.parseAddfoxEntryFromHtml = __webpack_exports__.parseAddfoxEntryFromHtml;
1666
+ exports.resolveAddfoxConfig = __webpack_exports__.resolveAddfoxConfig;
1667
+ exports.resolveEntries = __webpack_exports__.resolveEntries;
1668
+ exports.resolveManifestChromium = __webpack_exports__.resolveManifestChromium;
1669
+ exports.resolveManifestFirefox = __webpack_exports__.resolveManifestFirefox;
1670
+ exports.resolveManifestForTarget = __webpack_exports__.resolveManifestForTarget;
1671
+ exports.resolveManifestInput = __webpack_exports__.resolveManifestInput;
1672
+ exports.resolveScriptFromHtmlStrict = __webpack_exports__.resolveScriptFromHtmlStrict;
1673
+ exports.toReloadManagerEntries = __webpack_exports__.toReloadManagerEntries;
1674
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
1675
+ "ADDFOX_OUTPUT_ROOT",
1676
+ "BROWSER_OUTPUT_PREFIX",
1677
+ "CLI_COMMANDS",
1678
+ "CONFIG_FILES",
1679
+ "DEFAULT_APP_DIR",
1680
+ "DEFAULT_BROWSER",
1681
+ "DEFAULT_ENV_PREFIXES",
1682
+ "DEFAULT_OUT_DIR",
1683
+ "HMR_WS_PORT",
1684
+ "HTML_ENTRY_NAMES",
1685
+ "MANIFEST_DIR",
1686
+ "MANIFEST_ENTRY_KEYS",
1687
+ "MANIFEST_ENTRY_PATHS",
1688
+ "MANIFEST_FILE_NAMES",
1689
+ "ManifestLoader",
1690
+ "Pipeline",
1691
+ "RELOAD_MANAGER_ENTRY_NAMES",
1692
+ "RESERVED_ENTRY_NAMES",
1693
+ "RSTEST_CONFIG_FILES",
1694
+ "SCRIPT_EXTS",
1695
+ "SCRIPT_ONLY_ENTRY_NAMES",
1696
+ "SUPPORTED_BROWSERS",
1697
+ "SUPPORTED_LAUNCH_TARGETS",
1698
+ "buildForBrowser",
1699
+ "clearConfigCache",
1700
+ "defineConfig",
1701
+ "detectFrontendFramework",
1702
+ "discoverEntries",
1703
+ "extractEntriesFromManifest",
1704
+ "getAddfoxVersion",
1705
+ "getAllEntryNames",
1706
+ "getBrowserOutputDir",
1707
+ "getHtmlEntryNames",
1708
+ "getManifestRecordForTarget",
1709
+ "getResolvedConfigFilePath",
1710
+ "getResolvedRstestConfigFilePath",
1711
+ "getScriptInjectIfMatches",
1712
+ "getScriptOnlyEntryNames",
1713
+ "isScriptSrcRelative",
1714
+ "loadConfigFile",
1715
+ "parseAddfoxEntryFromHtml",
1716
+ "resolveAddfoxConfig",
1717
+ "resolveEntries",
1718
+ "resolveManifestChromium",
1719
+ "resolveManifestFirefox",
1720
+ "resolveManifestForTarget",
1721
+ "resolveManifestInput",
1722
+ "resolveScriptFromHtmlStrict",
1723
+ "toReloadManagerEntries"
1724
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
1725
+ Object.defineProperty(exports, '__esModule', {
1726
+ value: true
1727
+ });
1728
+
1729
+ //# sourceMappingURL=index.cjs.map