wxt 0.16.2 → 0.16.3

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/dist/cli.js CHANGED
@@ -20,6 +20,26 @@ function unnormalizePath(path7) {
20
20
  var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
21
21
  var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
22
22
 
23
+ // src/core/wxt.ts
24
+ import { createHooks } from "hookable";
25
+ var wxt;
26
+ async function registerWxt(command, inlineConfig = {}, server) {
27
+ const config = await resolveConfig(inlineConfig, command, server);
28
+ const hooks = createHooks();
29
+ wxt = {
30
+ config,
31
+ hooks,
32
+ get logger() {
33
+ return config.logger;
34
+ },
35
+ async reloadConfig() {
36
+ wxt.config = await resolveConfig(inlineConfig, command, server);
37
+ }
38
+ };
39
+ wxt.hooks.addHooks(config.hooks);
40
+ await wxt.hooks.callHook("ready", wxt);
41
+ }
42
+
23
43
  // src/core/utils/fs.ts
24
44
  async function writeFileIfDifferent(file, newContents) {
25
45
  const existingContents = await fs.readFile(file, "utf-8").catch(() => void 0);
@@ -27,10 +47,10 @@ async function writeFileIfDifferent(file, newContents) {
27
47
  await fs.writeFile(file, newContents);
28
48
  }
29
49
  }
30
- async function getPublicFiles(config) {
31
- if (!await fs.exists(config.publicDir))
50
+ async function getPublicFiles() {
51
+ if (!await fs.exists(wxt.config.publicDir))
32
52
  return [];
33
- const files = await glob("**/*", { cwd: config.publicDir });
53
+ const files = await glob("**/*", { cwd: wxt.config.publicDir });
34
54
  return files.map(unnormalizePath);
35
55
  }
36
56
 
@@ -38,7 +58,7 @@ async function getPublicFiles(config) {
38
58
  import fs2 from "fs-extra";
39
59
  import { dirname, resolve } from "path";
40
60
  import pc from "picocolors";
41
- async function buildEntrypoints(groups, config, spinner) {
61
+ async function buildEntrypoints(groups, spinner) {
42
62
  const steps = [];
43
63
  for (let i = 0; i < groups.length; i++) {
44
64
  const group = groups[i];
@@ -46,22 +66,22 @@ async function buildEntrypoints(groups, config, spinner) {
46
66
  const groupNameColored = groupNames.join(pc.dim(", "));
47
67
  spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNameColored}`;
48
68
  try {
49
- steps.push(await config.builder.build(group));
69
+ steps.push(await wxt.config.builder.build(group));
50
70
  } catch (err) {
51
71
  throw Error(`Failed to build ${groupNames.join(", ")}`, { cause: err });
52
72
  }
53
73
  }
54
- const publicAssets = await copyPublicDirectory(config);
74
+ const publicAssets = await copyPublicDirectory();
55
75
  return { publicAssets, steps };
56
76
  }
57
- async function copyPublicDirectory(config) {
58
- const files = await getPublicFiles(config);
77
+ async function copyPublicDirectory() {
78
+ const files = await getPublicFiles();
59
79
  if (files.length === 0)
60
80
  return [];
61
81
  const publicAssets = [];
62
82
  for (const file of files) {
63
- const srcPath = resolve(config.publicDir, file);
64
- const outPath = resolve(config.outDir, file);
83
+ const srcPath = resolve(wxt.config.publicDir, file);
84
+ const outPath = resolve(wxt.config.outDir, file);
65
85
  await fs2.ensureDir(dirname(outPath));
66
86
  await fs2.copyFile(srcPath, outPath);
67
87
  publicAssets.push({
@@ -87,16 +107,16 @@ function some(array, predicate) {
87
107
  }
88
108
 
89
109
  // src/core/utils/building/detect-dev-changes.ts
90
- function detectDevChanges(config, changedFiles, currentOutput) {
110
+ function detectDevChanges(changedFiles, currentOutput) {
91
111
  const isConfigChange = some(
92
112
  changedFiles,
93
- (file) => file === config.userConfigMetadata.configFile
113
+ (file) => file === wxt.config.userConfigMetadata.configFile
94
114
  );
95
115
  if (isConfigChange)
96
116
  return { type: "full-restart" };
97
117
  const isRunnerChange = some(
98
118
  changedFiles,
99
- (file) => file === config.runnerConfig.configFile
119
+ (file) => file === wxt.config.runnerConfig.configFile
100
120
  );
101
121
  if (isRunnerChange)
102
122
  return { type: "browser-restart" };
@@ -214,15 +234,15 @@ var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
214
234
 
215
235
  // src/core/utils/building/find-entrypoints.ts
216
236
  import pc2 from "picocolors";
217
- async function findEntrypoints(config) {
237
+ async function findEntrypoints() {
218
238
  const relativePaths = await glob2(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
219
- cwd: config.entrypointsDir
239
+ cwd: wxt.config.entrypointsDir
220
240
  });
221
241
  relativePaths.sort();
222
242
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
223
243
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
224
- const inputPath = resolve3(config.entrypointsDir, relativePath);
225
- const name = getEntrypointName(config.entrypointsDir, inputPath);
244
+ const inputPath = resolve3(wxt.config.entrypointsDir, relativePath);
245
+ const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
226
246
  const matchingGlob = pathGlobs.find(
227
247
  (glob5) => minimatch(relativePath, glob5)
228
248
  );
@@ -232,36 +252,36 @@ async function findEntrypoints(config) {
232
252
  name,
233
253
  inputPath,
234
254
  type,
235
- skipped: config.filterEntrypoints != null && !config.filterEntrypoints.has(name)
255
+ skipped: wxt.config.filterEntrypoints != null && !wxt.config.filterEntrypoints.has(name)
236
256
  });
237
257
  }
238
258
  return results;
239
259
  }, []);
240
- preventNoEntrypoints(config, entrypointInfos);
241
- preventDuplicateEntrypointNames(config, entrypointInfos);
260
+ preventNoEntrypoints(entrypointInfos);
261
+ preventDuplicateEntrypointNames(entrypointInfos);
242
262
  let hasBackground = false;
243
263
  const entrypoints = await Promise.all(
244
264
  entrypointInfos.map(async (info) => {
245
265
  const { type } = info;
246
266
  switch (type) {
247
267
  case "popup":
248
- return await getPopupEntrypoint(config, info);
268
+ return await getPopupEntrypoint(info);
249
269
  case "options":
250
- return await getOptionsEntrypoint(config, info);
270
+ return await getOptionsEntrypoint(info);
251
271
  case "background":
252
272
  hasBackground = true;
253
- return await getBackgroundEntrypoint(config, info);
273
+ return await getBackgroundEntrypoint(info);
254
274
  case "content-script":
255
- return await getContentScriptEntrypoint(config, info);
275
+ return await getContentScriptEntrypoint(info);
256
276
  case "unlisted-page":
257
- return await getUnlistedPageEntrypoint(config, info);
277
+ return await getUnlistedPageEntrypoint(info);
258
278
  case "unlisted-script":
259
- return await getUnlistedScriptEntrypoint(config, info);
279
+ return await getUnlistedScriptEntrypoint(info);
260
280
  case "content-script-style":
261
281
  return {
262
282
  ...info,
263
283
  type,
264
- outputDir: resolve3(config.outDir, CONTENT_SCRIPT_OUT_DIR),
284
+ outputDir: resolve3(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
265
285
  options: {
266
286
  include: void 0,
267
287
  exclude: void 0
@@ -271,7 +291,7 @@ async function findEntrypoints(config) {
271
291
  return {
272
292
  ...info,
273
293
  type,
274
- outputDir: config.outDir,
294
+ outputDir: wxt.config.outDir,
275
295
  options: {
276
296
  include: void 0,
277
297
  exclude: void 0
@@ -280,9 +300,9 @@ async function findEntrypoints(config) {
280
300
  }
281
301
  })
282
302
  );
283
- if (config.command === "serve" && !hasBackground) {
303
+ if (wxt.config.command === "serve" && !hasBackground) {
284
304
  entrypoints.push(
285
- await getBackgroundEntrypoint(config, {
305
+ await getBackgroundEntrypoint({
286
306
  inputPath: VIRTUAL_NOOP_BACKGROUND_MODULE_ID,
287
307
  name: "background",
288
308
  type: "background",
@@ -290,10 +310,10 @@ async function findEntrypoints(config) {
290
310
  })
291
311
  );
292
312
  }
293
- config.logger.debug("All entrypoints:", entrypoints);
313
+ wxt.logger.debug("All entrypoints:", entrypoints);
294
314
  const skippedEntrypointNames = entrypointInfos.filter((item) => item.skipped).map((item) => item.name);
295
315
  if (skippedEntrypointNames.length) {
296
- config.logger.warn(
316
+ wxt.logger.warn(
297
317
  `Filter excluded the following entrypoints:
298
318
  ${skippedEntrypointNames.map((item) => `${pc2.dim("-")} ${pc2.cyan(item)}`).join("\n")}`
299
319
  );
@@ -301,26 +321,27 @@ ${skippedEntrypointNames.map((item) => `${pc2.dim("-")} ${pc2.cyan(item)}`).join
301
321
  const targetEntrypoints = entrypoints.filter((entry) => {
302
322
  const { include, exclude } = entry.options;
303
323
  if (include?.length && exclude?.length) {
304
- config.logger.warn(
324
+ wxt.logger.warn(
305
325
  `The ${entry.name} entrypoint lists both include and exclude, but only one can be used per entrypoint. Entrypoint ignored.`
306
326
  );
307
327
  return false;
308
328
  }
309
329
  if (exclude?.length && !include?.length) {
310
- return !exclude.includes(config.browser);
330
+ return !exclude.includes(wxt.config.browser);
311
331
  }
312
332
  if (include?.length && !exclude?.length) {
313
- return include.includes(config.browser);
333
+ return include.includes(wxt.config.browser);
314
334
  }
315
335
  if (skippedEntrypointNames.includes(entry.name)) {
316
336
  return false;
317
337
  }
318
338
  return true;
319
339
  });
320
- config.logger.debug(`${config.browser} entrypoints:`, targetEntrypoints);
340
+ wxt.logger.debug(`${wxt.config.browser} entrypoints:`, targetEntrypoints);
341
+ await wxt.hooks.callHook("entrypoints:resolved", wxt, targetEntrypoints);
321
342
  return targetEntrypoints;
322
343
  }
323
- function preventDuplicateEntrypointNames(config, files) {
344
+ function preventDuplicateEntrypointNames(files) {
324
345
  const namesToPaths = files.reduce(
325
346
  (map, { name, inputPath }) => {
326
347
  map[name] ??= [];
@@ -334,7 +355,7 @@ function preventDuplicateEntrypointNames(config, files) {
334
355
  if (absolutePaths.length > 1) {
335
356
  lines.push(`- ${name}`);
336
357
  absolutePaths.forEach((absolutePath) => {
337
- lines.push(` - ${relative2(config.root, absolutePath)}`);
358
+ lines.push(` - ${relative2(wxt.config.root, absolutePath)}`);
338
359
  });
339
360
  }
340
361
  return lines;
@@ -350,9 +371,9 @@ ${errorContent}`
350
371
  );
351
372
  }
352
373
  }
353
- function preventNoEntrypoints(config, files) {
374
+ function preventNoEntrypoints(files) {
354
375
  if (files.length === 0) {
355
- throw Error(`No entrypoints found in ${config.entrypointsDir}`);
376
+ throw Error(`No entrypoints found in ${wxt.config.entrypointsDir}`);
356
377
  }
357
378
  }
358
379
  function getHtmlBaseOptions(document) {
@@ -367,7 +388,11 @@ function getHtmlBaseOptions(document) {
367
388
  }
368
389
  return options;
369
390
  }
370
- async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
391
+ async function getPopupEntrypoint({
392
+ inputPath,
393
+ name,
394
+ skipped
395
+ }) {
371
396
  const content = await fs3.readFile(inputPath, "utf-8");
372
397
  const { document } = parseHTML(content);
373
398
  const options = getHtmlBaseOptions(document);
@@ -379,7 +404,7 @@ async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
379
404
  try {
380
405
  options.defaultIcon = JSON5.parse(defaultIconContent);
381
406
  } catch (err) {
382
- config.logger.fatal(
407
+ wxt.logger.fatal(
383
408
  `Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
384
409
  err
385
410
  );
@@ -398,11 +423,15 @@ async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
398
423
  name: "popup",
399
424
  options,
400
425
  inputPath,
401
- outputDir: config.outDir,
426
+ outputDir: wxt.config.outDir,
402
427
  skipped
403
428
  };
404
429
  }
405
- async function getOptionsEntrypoint(config, { inputPath, name, skipped }) {
430
+ async function getOptionsEntrypoint({
431
+ inputPath,
432
+ name,
433
+ skipped
434
+ }) {
406
435
  const content = await fs3.readFile(inputPath, "utf-8");
407
436
  const { document } = parseHTML(content);
408
437
  const options = getHtmlBaseOptions(document);
@@ -423,27 +452,32 @@ async function getOptionsEntrypoint(config, { inputPath, name, skipped }) {
423
452
  name: "options",
424
453
  options,
425
454
  inputPath,
426
- outputDir: config.outDir,
455
+ outputDir: wxt.config.outDir,
427
456
  skipped
428
457
  };
429
458
  }
430
- async function getUnlistedPageEntrypoint(config, { inputPath, name, skipped }) {
459
+ async function getUnlistedPageEntrypoint({
460
+ inputPath,
461
+ name,
462
+ skipped
463
+ }) {
431
464
  const content = await fs3.readFile(inputPath, "utf-8");
432
465
  const { document } = parseHTML(content);
433
466
  return {
434
467
  type: "unlisted-page",
435
- name: getEntrypointName(config.entrypointsDir, inputPath),
468
+ name: getEntrypointName(wxt.config.entrypointsDir, inputPath),
436
469
  inputPath,
437
- outputDir: config.outDir,
470
+ outputDir: wxt.config.outDir,
438
471
  options: getHtmlBaseOptions(document),
439
472
  skipped
440
473
  };
441
474
  }
442
- async function getUnlistedScriptEntrypoint(config, { inputPath, name, skipped }) {
443
- const defaultExport = await importEntrypointFile(
444
- inputPath,
445
- config
446
- );
475
+ async function getUnlistedScriptEntrypoint({
476
+ inputPath,
477
+ name,
478
+ skipped
479
+ }) {
480
+ const defaultExport = await importEntrypointFile(inputPath);
447
481
  if (defaultExport == null) {
448
482
  throw Error(
449
483
  `${name}: Default export not found, did you forget to call "export default defineUnlistedScript(...)"?`
@@ -455,18 +489,19 @@ async function getUnlistedScriptEntrypoint(config, { inputPath, name, skipped })
455
489
  type: "unlisted-script",
456
490
  name,
457
491
  inputPath,
458
- outputDir: config.outDir,
492
+ outputDir: wxt.config.outDir,
459
493
  options,
460
494
  skipped
461
495
  };
462
496
  }
463
- async function getBackgroundEntrypoint(config, { inputPath, name, skipped }) {
497
+ async function getBackgroundEntrypoint({
498
+ inputPath,
499
+ name,
500
+ skipped
501
+ }) {
464
502
  let options = {};
465
503
  if (inputPath !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
466
- const defaultExport = await importEntrypointFile(
467
- inputPath,
468
- config
469
- );
504
+ const defaultExport = await importEntrypointFile(inputPath);
470
505
  if (defaultExport == null) {
471
506
  throw Error(
472
507
  `${name}: Default export not found, did you forget to call "export default defineBackground(...)"?`
@@ -475,24 +510,31 @@ async function getBackgroundEntrypoint(config, { inputPath, name, skipped }) {
475
510
  const { main: _, ...moduleOptions } = defaultExport;
476
511
  options = moduleOptions;
477
512
  }
478
- if (config.manifestVersion !== 3) {
513
+ if (wxt.config.manifestVersion !== 3) {
479
514
  delete options.type;
480
515
  }
481
516
  return {
482
517
  type: "background",
483
518
  name,
484
519
  inputPath,
485
- outputDir: config.outDir,
520
+ outputDir: wxt.config.outDir,
486
521
  options: {
487
522
  ...options,
488
- type: resolvePerBrowserOption(options.type, config.browser),
489
- persistent: resolvePerBrowserOption(options.persistent, config.browser)
523
+ type: resolvePerBrowserOption(options.type, wxt.config.browser),
524
+ persistent: resolvePerBrowserOption(
525
+ options.persistent,
526
+ wxt.config.browser
527
+ )
490
528
  },
491
529
  skipped
492
530
  };
493
531
  }
494
- async function getContentScriptEntrypoint(config, { inputPath, name, skipped }) {
495
- const { main: _, ...options } = await importEntrypointFile(inputPath, config);
532
+ async function getContentScriptEntrypoint({
533
+ inputPath,
534
+ name,
535
+ skipped
536
+ }) {
537
+ const { main: _, ...options } = await importEntrypointFile(inputPath);
496
538
  if (options == null) {
497
539
  throw Error(
498
540
  `${name}: Default export not found, did you forget to call "export default defineContentScript(...)"?`
@@ -502,7 +544,7 @@ async function getContentScriptEntrypoint(config, { inputPath, name, skipped })
502
544
  type: "content-script",
503
545
  name,
504
546
  inputPath,
505
- outputDir: resolve3(config.outDir, CONTENT_SCRIPT_OUT_DIR),
547
+ outputDir: resolve3(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
506
548
  options,
507
549
  skipped
508
550
  };
@@ -672,23 +714,23 @@ function parseI18nMessages(messagesJson) {
672
714
  }
673
715
 
674
716
  // src/core/utils/building/generate-wxt-dir.ts
675
- async function generateTypesDir(entrypoints, config) {
676
- await fs4.ensureDir(config.typesDir);
717
+ async function generateTypesDir(entrypoints) {
718
+ await fs4.ensureDir(wxt.config.typesDir);
677
719
  const references = [];
678
- const imports = getUnimportOptions(config);
720
+ const imports = getUnimportOptions(wxt.config);
679
721
  if (imports !== false) {
680
- references.push(await writeImportsDeclarationFile(config, imports));
722
+ references.push(await writeImportsDeclarationFile(imports));
681
723
  }
682
- references.push(await writePathsDeclarationFile(entrypoints, config));
683
- references.push(await writeI18nDeclarationFile(config));
684
- references.push(await writeGlobalsDeclarationFile(config));
685
- const mainReference = await writeMainDeclarationFile(references, config);
686
- await writeTsConfigFile(mainReference, config);
724
+ references.push(await writePathsDeclarationFile(entrypoints));
725
+ references.push(await writeI18nDeclarationFile());
726
+ references.push(await writeGlobalsDeclarationFile());
727
+ const mainReference = await writeMainDeclarationFile(references);
728
+ await writeTsConfigFile(mainReference);
687
729
  }
688
- async function writeImportsDeclarationFile(config, unimportOptions) {
689
- const filePath = resolve4(config.typesDir, "imports.d.ts");
730
+ async function writeImportsDeclarationFile(unimportOptions) {
731
+ const filePath = resolve4(wxt.config.typesDir, "imports.d.ts");
690
732
  const unimport2 = createUnimport(unimportOptions);
691
- await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
733
+ await unimport2.scanImportsFromDir(void 0, { cwd: wxt.config.srcDir });
692
734
  await writeFileIfDifferent(
693
735
  filePath,
694
736
  ["// Generated by wxt", await unimport2.generateTypeDeclarations()].join(
@@ -697,15 +739,15 @@ async function writeImportsDeclarationFile(config, unimportOptions) {
697
739
  );
698
740
  return filePath;
699
741
  }
700
- async function writePathsDeclarationFile(entrypoints, config) {
701
- const filePath = resolve4(config.typesDir, "paths.d.ts");
742
+ async function writePathsDeclarationFile(entrypoints) {
743
+ const filePath = resolve4(wxt.config.typesDir, "paths.d.ts");
702
744
  const unions = entrypoints.map(
703
745
  (entry) => getEntrypointBundlePath(
704
746
  entry,
705
- config.outDir,
747
+ wxt.config.outDir,
706
748
  entry.inputPath.endsWith(".html") ? ".html" : ".js"
707
749
  )
708
- ).concat(await getPublicFiles(config)).map(normalizePath).map((path7) => ` | "/${path7}"`).sort().join("\n");
750
+ ).concat(await getPublicFiles()).map(normalizePath).map((path7) => ` | "/${path7}"`).sort().join("\n");
709
751
  const template = `// Generated by wxt
710
752
  import "wxt/browser";
711
753
 
@@ -725,9 +767,9 @@ declare module "wxt/browser" {
725
767
  );
726
768
  return filePath;
727
769
  }
728
- async function writeI18nDeclarationFile(config) {
729
- const filePath = resolve4(config.typesDir, "i18n.d.ts");
730
- const defaultLocale = config.manifest.default_locale;
770
+ async function writeI18nDeclarationFile() {
771
+ const filePath = resolve4(wxt.config.typesDir, "i18n.d.ts");
772
+ const defaultLocale = wxt.config.manifest.default_locale;
731
773
  const template = `// Generated by wxt
732
774
  import "wxt/browser";
733
775
 
@@ -750,7 +792,7 @@ declare module "wxt/browser" {
750
792
  let messages;
751
793
  if (defaultLocale) {
752
794
  const defaultLocalePath = path2.resolve(
753
- config.publicDir,
795
+ wxt.config.publicDir,
754
796
  "_locales",
755
797
  defaultLocale,
756
798
  "messages.json"
@@ -778,9 +820,9 @@ declare module "wxt/browser" {
778
820
  );
779
821
  return filePath;
780
822
  }
781
- async function writeGlobalsDeclarationFile(config) {
782
- const filePath = resolve4(config.typesDir, "globals.d.ts");
783
- const globals2 = [...getGlobals(config), ...getEntrypointGlobals("")];
823
+ async function writeGlobalsDeclarationFile() {
824
+ const filePath = resolve4(wxt.config.typesDir, "globals.d.ts");
825
+ const globals2 = [...getGlobals(wxt.config), ...getEntrypointGlobals("")];
784
826
  await writeFileIfDifferent(
785
827
  filePath,
786
828
  [
@@ -796,8 +838,8 @@ async function writeGlobalsDeclarationFile(config) {
796
838
  );
797
839
  return filePath;
798
840
  }
799
- async function writeMainDeclarationFile(references, config) {
800
- const dir = config.wxtDir;
841
+ async function writeMainDeclarationFile(references) {
842
+ const dir = wxt.config.wxtDir;
801
843
  const filePath = resolve4(dir, "wxt.d.ts");
802
844
  await writeFileIfDifferent(
803
845
  filePath,
@@ -811,10 +853,10 @@ async function writeMainDeclarationFile(references, config) {
811
853
  );
812
854
  return filePath;
813
855
  }
814
- async function writeTsConfigFile(mainReference, config) {
815
- const dir = config.wxtDir;
856
+ async function writeTsConfigFile(mainReference) {
857
+ const dir = wxt.config.wxtDir;
816
858
  const getTsconfigPath = (path7) => normalizePath(relative3(dir, path7));
817
- const paths = Object.entries(config.alias).flatMap(([alias, absolutePath]) => {
859
+ const paths = Object.entries(wxt.config.alias).flatMap(([alias, absolutePath]) => {
818
860
  const aliasPath = getTsconfigPath(absolutePath);
819
861
  return [
820
862
  ` "${alias}": ["${aliasPath}"]`,
@@ -839,15 +881,15 @@ ${paths}
839
881
  }
840
882
  },
841
883
  "include": [
842
- "${getTsconfigPath(config.root)}/**/*",
884
+ "${getTsconfigPath(wxt.config.root)}/**/*",
843
885
  "./${getTsconfigPath(mainReference)}"
844
886
  ],
845
- "exclude": ["${getTsconfigPath(config.outBaseDir)}"]
887
+ "exclude": ["${getTsconfigPath(wxt.config.outBaseDir)}"]
846
888
  }`
847
889
  );
848
890
  }
849
891
 
850
- // src/core/utils/building/get-internal-config.ts
892
+ // src/core/utils/building/resolve-config.ts
851
893
  import { loadConfig } from "c12";
852
894
  import path3 from "node:path";
853
895
 
@@ -873,7 +915,7 @@ function createFsCache(wxtDir) {
873
915
  };
874
916
  }
875
917
 
876
- // src/core/utils/building/get-internal-config.ts
918
+ // src/core/utils/building/resolve-config.ts
877
919
  import consola, { LogLevels } from "consola";
878
920
 
879
921
  // src/core/builders/vite/plugins/devHtmlPrerender.ts
@@ -1595,9 +1637,9 @@ function getRollupEntry(entrypoint) {
1595
1637
  return virtualEntrypointType ? `virtual:wxt-${virtualEntrypointType}?${entrypoint.inputPath}` : entrypoint.inputPath;
1596
1638
  }
1597
1639
 
1598
- // src/core/utils/building/get-internal-config.ts
1640
+ // src/core/utils/building/resolve-config.ts
1599
1641
  import defu2 from "defu";
1600
- async function getInternalConfig(inlineConfig, command, server) {
1642
+ async function resolveConfig(inlineConfig, command, server) {
1601
1643
  let userConfig = {};
1602
1644
  let userConfigMetadata;
1603
1645
  if (inlineConfig.configFile !== false) {
@@ -1691,7 +1733,8 @@ async function getInternalConfig(inlineConfig, command, server) {
1691
1733
  server,
1692
1734
  dev: {
1693
1735
  reloadCommand
1694
- }
1736
+ },
1737
+ hooks: mergedConfig.hooks ?? {}
1695
1738
  };
1696
1739
  const builder = await createViteBuilder(
1697
1740
  inlineConfig,
@@ -1728,6 +1771,10 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1728
1771
  inlineConfig.zip ?? {},
1729
1772
  userConfig.zip ?? {}
1730
1773
  );
1774
+ const hooks = defu2(
1775
+ inlineConfig.hooks ?? {},
1776
+ userConfig.hooks ?? {}
1777
+ );
1731
1778
  return {
1732
1779
  root: inlineConfig.root ?? userConfig.root,
1733
1780
  browser: inlineConfig.browser ?? userConfig.browser,
@@ -1762,7 +1809,8 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1762
1809
  dev: {
1763
1810
  ...userConfig.dev,
1764
1811
  ...inlineConfig.dev
1765
- }
1812
+ },
1813
+ hooks
1766
1814
  };
1767
1815
  }
1768
1816
  function resolveInternalZipConfig(root, mergedConfig) {
@@ -1853,11 +1901,11 @@ ${noImports}`;
1853
1901
  // src/core/utils/building/import-entrypoint.ts
1854
1902
  import { transformSync } from "esbuild";
1855
1903
  import { fileURLToPath } from "node:url";
1856
- async function importEntrypointFile(path7, config) {
1857
- config.logger.debug("Loading file metadata:", path7);
1904
+ async function importEntrypointFile(path7) {
1905
+ wxt.logger.debug("Loading file metadata:", path7);
1858
1906
  const normalPath = normalizePath(path7);
1859
1907
  const unimport2 = createUnimport3({
1860
- ...getUnimportOptions(config),
1908
+ ...getUnimportOptions(wxt.config),
1861
1909
  // Only allow specific imports, not all from the project
1862
1910
  dirs: []
1863
1911
  });
@@ -1865,18 +1913,18 @@ async function importEntrypointFile(path7, config) {
1865
1913
  const text = await fs8.readFile(path7, "utf-8");
1866
1914
  const textNoImports = removeProjectImportStatements(text);
1867
1915
  const { code } = await unimport2.injectImports(textNoImports);
1868
- config.logger.debug(
1916
+ wxt.logger.debug(
1869
1917
  ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
1870
1918
  );
1871
1919
  const jiti = createJITI(
1872
1920
  typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url),
1873
1921
  {
1874
1922
  cache: false,
1875
- debug: config.debug,
1923
+ debug: wxt.config.debug,
1876
1924
  esmResolve: true,
1877
1925
  alias: {
1878
1926
  "webextension-polyfill": resolve9(
1879
- config.root,
1927
+ wxt.config.root,
1880
1928
  "node_modules/wxt/dist/virtual/mock-browser.js"
1881
1929
  )
1882
1930
  },
@@ -1908,7 +1956,7 @@ async function importEntrypointFile(path7, config) {
1908
1956
  const res = await jiti(path7);
1909
1957
  return res.default;
1910
1958
  } catch (err) {
1911
- const filePath = relative5(config.root, path7);
1959
+ const filePath = relative5(wxt.config.root, path7);
1912
1960
  if (err instanceof ReferenceError) {
1913
1961
  const variableName = err.message.replace(" is not defined", "");
1914
1962
  throw Error(
@@ -1916,7 +1964,7 @@ async function importEntrypointFile(path7, config) {
1916
1964
  { cause: err }
1917
1965
  );
1918
1966
  } else {
1919
- config.logger.error(err);
1967
+ wxt.logger.error(err);
1920
1968
  throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
1921
1969
  }
1922
1970
  }
@@ -2010,7 +2058,7 @@ function getChunkColor(filename) {
2010
2058
  }
2011
2059
 
2012
2060
  // src/core/utils/log/printBuildSummary.ts
2013
- async function printBuildSummary(log, header, output, config) {
2061
+ async function printBuildSummary(log, header, output) {
2014
2062
  const chunks = [
2015
2063
  ...output.steps.flatMap((step) => step.chunks),
2016
2064
  ...output.publicAssets
@@ -2022,8 +2070,10 @@ async function printBuildSummary(log, header, output, config) {
2022
2070
  return diff;
2023
2071
  return l.fileName.localeCompare(r.fileName);
2024
2072
  });
2025
- const files = chunks.map((chunk) => resolve10(config.outDir, chunk.fileName));
2026
- await printFileList(log, header, config.outDir, files);
2073
+ const files = chunks.map(
2074
+ (chunk) => resolve10(wxt.config.outDir, chunk.fileName)
2075
+ );
2076
+ await printFileList(log, header, wxt.config.outDir, files);
2027
2077
  }
2028
2078
  var DEFAULT_SORT_WEIGHT = 100;
2029
2079
  var CHUNK_SORT_WEIGHTS = {
@@ -2043,7 +2093,7 @@ function getChunkSortWeight(filename) {
2043
2093
  import pc4 from "picocolors";
2044
2094
 
2045
2095
  // package.json
2046
- var version = "0.16.2";
2096
+ var version = "0.16.3";
2047
2097
 
2048
2098
  // src/core/utils/log/printHeader.ts
2049
2099
  import { consola as consola2 } from "consola";
@@ -2103,8 +2153,8 @@ var ContentSecurityPolicy = class _ContentSecurityPolicy {
2103
2153
  };
2104
2154
 
2105
2155
  // src/core/utils/content-scripts.ts
2106
- function hashContentScriptOptions(options, config) {
2107
- const simplifiedOptions = mapWxtOptionsToContentScript(options, config);
2156
+ function hashContentScriptOptions(options) {
2157
+ const simplifiedOptions = mapWxtOptionsToContentScript(options);
2108
2158
  Object.keys(simplifiedOptions).forEach((key) => {
2109
2159
  if (simplifiedOptions[key] == null)
2110
2160
  delete simplifiedOptions[key];
@@ -2130,31 +2180,31 @@ function hashContentScriptOptions(options, config) {
2130
2180
  }).sort((l, r) => l[0].localeCompare(r[0]))
2131
2181
  );
2132
2182
  }
2133
- function mapWxtOptionsToContentScript(options, config) {
2183
+ function mapWxtOptionsToContentScript(options) {
2134
2184
  return {
2135
- matches: resolvePerBrowserOption(options.matches, config.browser),
2136
- all_frames: resolvePerBrowserOption(options.allFrames, config.browser),
2185
+ matches: resolvePerBrowserOption(options.matches, wxt.config.browser),
2186
+ all_frames: resolvePerBrowserOption(options.allFrames, wxt.config.browser),
2137
2187
  match_about_blank: resolvePerBrowserOption(
2138
2188
  options.matchAboutBlank,
2139
- config.browser
2189
+ wxt.config.browser
2140
2190
  ),
2141
2191
  exclude_globs: resolvePerBrowserOption(
2142
2192
  options.excludeGlobs,
2143
- config.browser
2193
+ wxt.config.browser
2144
2194
  ),
2145
2195
  exclude_matches: resolvePerBrowserOption(
2146
2196
  options.excludeMatches,
2147
- config.browser
2197
+ wxt.config.browser
2148
2198
  ),
2149
2199
  include_globs: resolvePerBrowserOption(
2150
2200
  options.includeGlobs,
2151
- config.browser
2201
+ wxt.config.browser
2152
2202
  ),
2153
- run_at: resolvePerBrowserOption(options.runAt, config.browser),
2203
+ run_at: resolvePerBrowserOption(options.runAt, wxt.config.browser),
2154
2204
  // @ts-expect-error: untyped chrome options
2155
2205
  match_origin_as_fallback: resolvePerBrowserOption(
2156
2206
  options.matchOriginAsFallback,
2157
- config.browser
2207
+ wxt.config.browser
2158
2208
  ),
2159
2209
  world: options.world
2160
2210
  };
@@ -2163,12 +2213,12 @@ function mapWxtOptionsToContentScript(options, config) {
2163
2213
  // src/core/utils/package.ts
2164
2214
  import { resolve as resolve11 } from "node:path";
2165
2215
  import fs10 from "fs-extra";
2166
- async function getPackageJson(config) {
2167
- const file = resolve11(config.root, "package.json");
2216
+ async function getPackageJson() {
2217
+ const file = resolve11(wxt.config.root, "package.json");
2168
2218
  try {
2169
2219
  return await fs10.readJson(file);
2170
2220
  } catch (err) {
2171
- config.logger.debug(
2221
+ wxt.logger.debug(
2172
2222
  `Failed to read package.json at: ${file}. Returning undefined.`
2173
2223
  );
2174
2224
  return {};
@@ -2178,40 +2228,40 @@ async function getPackageJson(config) {
2178
2228
  // src/core/utils/manifest.ts
2179
2229
  import { produce } from "immer";
2180
2230
  import defu3 from "defu";
2181
- async function writeManifest(manifest, output, config) {
2182
- const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2183
- await fs11.ensureDir(config.outDir);
2184
- await writeFileIfDifferent(resolve12(config.outDir, "manifest.json"), str);
2231
+ async function writeManifest(manifest, output) {
2232
+ const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2233
+ await fs11.ensureDir(wxt.config.outDir);
2234
+ await writeFileIfDifferent(resolve12(wxt.config.outDir, "manifest.json"), str);
2185
2235
  output.publicAssets.unshift({
2186
2236
  type: "asset",
2187
2237
  fileName: "manifest.json"
2188
2238
  });
2189
2239
  }
2190
- async function generateManifest(entrypoints, buildOutput, config) {
2240
+ async function generateManifest(entrypoints, buildOutput) {
2191
2241
  const warnings = [];
2192
- const pkg = await getPackageJson(config);
2193
- let versionName = config.manifest.version_name ?? config.manifest.version ?? pkg?.version;
2242
+ const pkg = await getPackageJson();
2243
+ let versionName = wxt.config.manifest.version_name ?? wxt.config.manifest.version ?? pkg?.version;
2194
2244
  if (versionName == null) {
2195
2245
  versionName = "0.0.0";
2196
- config.logger.warn(
2246
+ wxt.logger.warn(
2197
2247
  'Extension version not found, defaulting to "0.0.0". Add a version to your `package.json` or `wxt.config.ts` file. For more details, see: https://wxt.dev/guide/manifest.html#version-and-version-name'
2198
2248
  );
2199
2249
  }
2200
- const version2 = config.manifest.version ?? simplifyVersion(versionName);
2250
+ const version2 = wxt.config.manifest.version ?? simplifyVersion(versionName);
2201
2251
  const baseManifest = {
2202
- manifest_version: config.manifestVersion,
2252
+ manifest_version: wxt.config.manifestVersion,
2203
2253
  name: pkg?.name,
2204
2254
  description: pkg?.description,
2205
2255
  version: version2,
2206
2256
  short_name: pkg?.shortName,
2207
2257
  icons: discoverIcons(buildOutput)
2208
2258
  };
2209
- const userManifest = config.manifest;
2259
+ const userManifest = wxt.config.manifest;
2210
2260
  const manifest = defu3(
2211
2261
  userManifest,
2212
2262
  baseManifest
2213
2263
  );
2214
- if (config.command === "serve" && config.dev.reloadCommand) {
2264
+ if (wxt.config.command === "serve" && wxt.config.dev.reloadCommand) {
2215
2265
  if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
2216
2266
  warnings.push([
2217
2267
  "Extension already has 4 registered commands, WXT's reload command is disabled"
@@ -2221,20 +2271,21 @@ async function generateManifest(entrypoints, buildOutput, config) {
2221
2271
  manifest.commands["wxt:reload-extension"] = {
2222
2272
  description: "Reload the extension during development",
2223
2273
  suggested_key: {
2224
- default: config.dev.reloadCommand
2274
+ default: wxt.config.dev.reloadCommand
2225
2275
  }
2226
2276
  };
2227
2277
  }
2228
2278
  }
2229
2279
  manifest.version = version2;
2230
2280
  manifest.version_name = // Firefox doesn't support version_name
2231
- config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
2232
- addEntrypoints(manifest, entrypoints, buildOutput, config);
2233
- if (config.command === "serve")
2234
- addDevModeCsp(manifest, config);
2235
- if (config.command === "serve")
2236
- addDevModePermissions(manifest, config);
2237
- const finalManifest = produce(manifest, config.transformManifest);
2281
+ wxt.config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
2282
+ addEntrypoints(manifest, entrypoints, buildOutput);
2283
+ if (wxt.config.command === "serve")
2284
+ addDevModeCsp(manifest);
2285
+ if (wxt.config.command === "serve")
2286
+ addDevModePermissions(manifest);
2287
+ const finalManifest = produce(manifest, wxt.config.transformManifest);
2288
+ await wxt.hooks.callHook("build:manifestGenerated", wxt, finalManifest);
2238
2289
  if (finalManifest.name == null)
2239
2290
  throw Error(
2240
2291
  "Manifest 'name' is missing. Either:\n1. Set the name in your <rootDir>/package.json\n2. Set a name via the manifest option in your wxt.config.ts"
@@ -2259,7 +2310,7 @@ function simplifyVersion(versionName) {
2259
2310
  );
2260
2311
  return version2;
2261
2312
  }
2262
- function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2313
+ function addEntrypoints(manifest, entrypoints, buildOutput) {
2263
2314
  const entriesByType = entrypoints.reduce((map, entrypoint) => {
2264
2315
  map[entrypoint.type] ??= [];
2265
2316
  map[entrypoint.type]?.push(entrypoint);
@@ -2276,13 +2327,17 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2276
2327
  const sandboxes = entriesByType["sandbox"];
2277
2328
  const sidepanels = entriesByType["sidepanel"];
2278
2329
  if (background) {
2279
- const script = getEntrypointBundlePath(background, config.outDir, ".js");
2280
- if (config.browser === "firefox" && config.manifestVersion === 3) {
2330
+ const script = getEntrypointBundlePath(
2331
+ background,
2332
+ wxt.config.outDir,
2333
+ ".js"
2334
+ );
2335
+ if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) {
2281
2336
  manifest.background = {
2282
2337
  type: background.options.type,
2283
2338
  scripts: [script]
2284
2339
  };
2285
- } else if (config.manifestVersion === 3) {
2340
+ } else if (wxt.config.manifestVersion === 3) {
2286
2341
  manifest.background = {
2287
2342
  type: background.options.type,
2288
2343
  service_worker: script
@@ -2295,29 +2350,29 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2295
2350
  }
2296
2351
  }
2297
2352
  if (bookmarks) {
2298
- if (config.browser === "firefox") {
2299
- config.logger.warn(
2353
+ if (wxt.config.browser === "firefox") {
2354
+ wxt.logger.warn(
2300
2355
  "Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest"
2301
2356
  );
2302
2357
  } else {
2303
2358
  manifest.chrome_url_overrides ??= {};
2304
2359
  manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(
2305
2360
  bookmarks,
2306
- config.outDir,
2361
+ wxt.config.outDir,
2307
2362
  ".html"
2308
2363
  );
2309
2364
  }
2310
2365
  }
2311
2366
  if (history) {
2312
- if (config.browser === "firefox") {
2313
- config.logger.warn(
2367
+ if (wxt.config.browser === "firefox") {
2368
+ wxt.logger.warn(
2314
2369
  "Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest"
2315
2370
  );
2316
2371
  } else {
2317
2372
  manifest.chrome_url_overrides ??= {};
2318
2373
  manifest.chrome_url_overrides.history = getEntrypointBundlePath(
2319
2374
  history,
2320
- config.outDir,
2375
+ wxt.config.outDir,
2321
2376
  ".html"
2322
2377
  );
2323
2378
  }
@@ -2326,14 +2381,14 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2326
2381
  manifest.chrome_url_overrides ??= {};
2327
2382
  manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(
2328
2383
  newtab,
2329
- config.outDir,
2384
+ wxt.config.outDir,
2330
2385
  ".html"
2331
2386
  );
2332
2387
  }
2333
2388
  if (popup) {
2334
2389
  const default_popup = getEntrypointBundlePath(
2335
2390
  popup,
2336
- config.outDir,
2391
+ wxt.config.outDir,
2337
2392
  ".html"
2338
2393
  );
2339
2394
  const options2 = {};
@@ -2361,28 +2416,28 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2361
2416
  if (devtools) {
2362
2417
  manifest.devtools_page = getEntrypointBundlePath(
2363
2418
  devtools,
2364
- config.outDir,
2419
+ wxt.config.outDir,
2365
2420
  ".html"
2366
2421
  );
2367
2422
  }
2368
2423
  if (options) {
2369
- const page = getEntrypointBundlePath(options, config.outDir, ".html");
2424
+ const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
2370
2425
  manifest.options_ui = {
2371
2426
  open_in_tab: options.options.openInTab,
2372
- browser_style: config.browser === "firefox" ? options.options.browserStyle : void 0,
2373
- chrome_style: config.browser !== "firefox" ? options.options.chromeStyle : void 0,
2427
+ browser_style: wxt.config.browser === "firefox" ? options.options.browserStyle : void 0,
2428
+ chrome_style: wxt.config.browser !== "firefox" ? options.options.chromeStyle : void 0,
2374
2429
  page
2375
2430
  };
2376
2431
  }
2377
2432
  if (sandboxes?.length) {
2378
- if (config.browser === "firefox") {
2379
- config.logger.warn(
2433
+ if (wxt.config.browser === "firefox") {
2434
+ wxt.logger.warn(
2380
2435
  "Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
2381
2436
  );
2382
2437
  } else {
2383
2438
  manifest.sandbox = {
2384
2439
  pages: sandboxes.map(
2385
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".html")
2440
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".html")
2386
2441
  )
2387
2442
  };
2388
2443
  }
@@ -2391,33 +2446,33 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2391
2446
  const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
2392
2447
  const page = getEntrypointBundlePath(
2393
2448
  defaultSidepanel,
2394
- config.outDir,
2449
+ wxt.config.outDir,
2395
2450
  ".html"
2396
2451
  );
2397
- if (config.browser === "firefox") {
2452
+ if (wxt.config.browser === "firefox") {
2398
2453
  manifest.sidebar_action = {
2399
2454
  // TODO: Add options to side panel
2400
2455
  // ...defaultSidepanel.options,
2401
2456
  default_panel: page
2402
2457
  };
2403
- } else if (config.manifestVersion === 3) {
2458
+ } else if (wxt.config.manifestVersion === 3) {
2404
2459
  manifest.side_panel = {
2405
2460
  default_path: page
2406
2461
  };
2407
2462
  } else {
2408
- config.logger.warn(
2463
+ wxt.logger.warn(
2409
2464
  "Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
2410
2465
  );
2411
2466
  }
2412
2467
  }
2413
2468
  if (contentScripts?.length) {
2414
2469
  const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
2415
- if (config.command === "serve" && config.manifestVersion === 3) {
2470
+ if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
2416
2471
  const hostPermissions = new Set(manifest.host_permissions ?? []);
2417
2472
  contentScripts.forEach((script) => {
2418
2473
  const matches = resolvePerBrowserOption(
2419
2474
  script.options.matches,
2420
- config.browser
2475
+ wxt.config.browser
2421
2476
  );
2422
2477
  matches.forEach((matchPattern) => {
2423
2478
  hostPermissions.add(matchPattern);
@@ -2428,7 +2483,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2428
2483
  );
2429
2484
  } else {
2430
2485
  const hashToEntrypointsMap = contentScripts.reduce((map, script) => {
2431
- const hash = hashContentScriptOptions(script.options, config);
2486
+ const hash = hashContentScriptOptions(script.options);
2432
2487
  if (map.has(hash))
2433
2488
  map.get(hash)?.push(script);
2434
2489
  else
@@ -2437,10 +2492,10 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2437
2492
  }, /* @__PURE__ */ new Map());
2438
2493
  const newContentScripts = Array.from(hashToEntrypointsMap.entries()).map(
2439
2494
  ([, scripts]) => ({
2440
- ...mapWxtOptionsToContentScript(scripts[0].options, config),
2495
+ ...mapWxtOptionsToContentScript(scripts[0].options),
2441
2496
  css: getContentScriptCssFiles(scripts, cssMap),
2442
2497
  js: scripts.map(
2443
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".js")
2498
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")
2444
2499
  )
2445
2500
  })
2446
2501
  );
@@ -2450,7 +2505,6 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2450
2505
  }
2451
2506
  }
2452
2507
  const contentScriptCssResources = getContentScriptCssWebAccessibleResources(
2453
- config,
2454
2508
  contentScripts,
2455
2509
  cssMap
2456
2510
  );
@@ -2493,9 +2547,9 @@ function discoverIcons(buildOutput) {
2493
2547
  });
2494
2548
  return icons.length > 0 ? Object.fromEntries(icons) : void 0;
2495
2549
  }
2496
- function addDevModeCsp(manifest, config) {
2497
- const permission = `http://${config.server?.hostname ?? ""}/*`;
2498
- const allowedCsp = config.server?.origin ?? "http://localhost:*";
2550
+ function addDevModeCsp(manifest) {
2551
+ const permission = `http://${wxt.config.server?.hostname ?? ""}/*`;
2552
+ const allowedCsp = wxt.config.server?.origin ?? "http://localhost:*";
2499
2553
  if (manifest.manifest_version === 3) {
2500
2554
  addHostPermission(manifest, permission);
2501
2555
  } else {
@@ -2508,7 +2562,7 @@ function addDevModeCsp(manifest, config) {
2508
2562
  ) : manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"
2509
2563
  // default CSP for MV2
2510
2564
  );
2511
- if (config.server)
2565
+ if (wxt.config.server)
2512
2566
  csp.add("script-src", allowedCsp);
2513
2567
  if (manifest.manifest_version === 3) {
2514
2568
  manifest.content_security_policy ??= {};
@@ -2517,9 +2571,9 @@ function addDevModeCsp(manifest, config) {
2517
2571
  manifest.content_security_policy = csp.toString();
2518
2572
  }
2519
2573
  }
2520
- function addDevModePermissions(manifest, config) {
2574
+ function addDevModePermissions(manifest) {
2521
2575
  addPermission(manifest, "tabs");
2522
- if (config.manifestVersion === 3)
2576
+ if (wxt.config.manifestVersion === 3)
2523
2577
  addPermission(manifest, "scripting");
2524
2578
  }
2525
2579
  function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
@@ -2537,7 +2591,7 @@ function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
2537
2591
  return css;
2538
2592
  return void 0;
2539
2593
  }
2540
- function getContentScriptCssWebAccessibleResources(config, contentScripts, contentScriptCssMap) {
2594
+ function getContentScriptCssWebAccessibleResources(contentScripts, contentScriptCssMap) {
2541
2595
  const resources = [];
2542
2596
  contentScripts.forEach((script) => {
2543
2597
  if (script.options.cssInjectionMode !== "ui")
@@ -2545,14 +2599,14 @@ function getContentScriptCssWebAccessibleResources(config, contentScripts, conte
2545
2599
  const cssFile = contentScriptCssMap[script.name];
2546
2600
  if (cssFile == null)
2547
2601
  return;
2548
- if (config.manifestVersion === 2) {
2602
+ if (wxt.config.manifestVersion === 2) {
2549
2603
  resources.push(cssFile);
2550
2604
  } else {
2551
2605
  resources.push({
2552
2606
  resources: [cssFile],
2553
2607
  matches: resolvePerBrowserOption(
2554
2608
  script.options.matches,
2555
- config.browser
2609
+ wxt.config.browser
2556
2610
  ).map((matchPattern) => stripPathFromMatchPattern(matchPattern))
2557
2611
  });
2558
2612
  }
@@ -2592,28 +2646,28 @@ function stripPathFromMatchPattern(pattern) {
2592
2646
  }
2593
2647
 
2594
2648
  // src/core/utils/building/rebuild.ts
2595
- async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
2649
+ async function rebuild(allEntrypoints, entrypointGroups, existingOutput = {
2596
2650
  steps: [],
2597
2651
  publicAssets: []
2598
2652
  }) {
2599
2653
  const { default: ora } = await import("ora");
2600
2654
  const spinner = ora(`Preparing...`).start();
2601
- await generateTypesDir(allEntrypoints, config).catch((err) => {
2602
- config.logger.warn("Failed to update .wxt directory:", err);
2603
- if (config.command === "build")
2655
+ await generateTypesDir(allEntrypoints).catch((err) => {
2656
+ wxt.logger.warn("Failed to update .wxt directory:", err);
2657
+ if (wxt.config.command === "build")
2604
2658
  throw err;
2605
2659
  });
2606
- const newOutput = await buildEntrypoints(entrypointGroups, config, spinner);
2660
+ const newOutput = await buildEntrypoints(entrypointGroups, spinner);
2607
2661
  const mergedOutput = {
2608
2662
  steps: [...existingOutput.steps, ...newOutput.steps],
2609
2663
  publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
2610
2664
  };
2611
- const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput, config);
2665
+ const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput);
2612
2666
  const finalOutput = {
2613
2667
  manifest: newManifest,
2614
2668
  ...newOutput
2615
2669
  };
2616
- await writeManifest(newManifest, finalOutput, config);
2670
+ await writeManifest(newManifest, finalOutput);
2617
2671
  spinner.clear().stop();
2618
2672
  return {
2619
2673
  output: {
@@ -2698,30 +2752,33 @@ import consola3 from "consola";
2698
2752
  import managePath from "manage-path";
2699
2753
  import { resolve as resolve13 } from "node:path";
2700
2754
  var managedPath = managePath(process.env);
2701
- var exec = async (config, file, args, options) => {
2755
+ var exec = async (file, args, options) => {
2702
2756
  managedPath.restore();
2703
- managedPath.push(resolve13(config.root, "node_modules/wxt/node_modules/.bin"));
2757
+ managedPath.push(
2758
+ resolve13(wxt.config.root, "node_modules/wxt/node_modules/.bin")
2759
+ );
2704
2760
  const { execa } = await import("./execa-Y2EWTC4S.js");
2705
2761
  return await execa(file, args, options);
2706
2762
  };
2707
2763
 
2708
2764
  // src/core/utils/building/internal-build.ts
2709
- async function internalBuild(config) {
2710
- const verb = config.command === "serve" ? "Pre-rendering" : "Building";
2711
- const target = `${config.browser}-mv${config.manifestVersion}`;
2712
- config.logger.info(
2713
- `${verb} ${pc5.cyan(target)} for ${pc5.cyan(config.mode)} with ${pc5.green(
2714
- `${config.builder.name} ${config.builder.version}`
2765
+ async function internalBuild() {
2766
+ await wxt.hooks.callHook("build:before", wxt);
2767
+ const verb = wxt.config.command === "serve" ? "Pre-rendering" : "Building";
2768
+ const target = `${wxt.config.browser}-mv${wxt.config.manifestVersion}`;
2769
+ wxt.logger.info(
2770
+ `${verb} ${pc5.cyan(target)} for ${pc5.cyan(wxt.config.mode)} with ${pc5.green(
2771
+ `${wxt.config.builder.name} ${wxt.config.builder.version}`
2715
2772
  )}`
2716
2773
  );
2717
2774
  const startTime = Date.now();
2718
- await fs12.rm(config.outDir, { recursive: true, force: true });
2719
- await fs12.ensureDir(config.outDir);
2720
- const entrypoints = await findEntrypoints(config);
2721
- config.logger.debug("Detected entrypoints:", entrypoints);
2775
+ await fs12.rm(wxt.config.outDir, { recursive: true, force: true });
2776
+ await fs12.ensureDir(wxt.config.outDir);
2777
+ const entrypoints = await findEntrypoints();
2778
+ wxt.logger.debug("Detected entrypoints:", entrypoints);
2722
2779
  const validationResults = validateEntrypoints(entrypoints);
2723
2780
  if (validationResults.errorCount + validationResults.warningCount > 0) {
2724
- printValidationResults(config, validationResults);
2781
+ printValidationResults(validationResults);
2725
2782
  }
2726
2783
  if (validationResults.errorCount > 0) {
2727
2784
  throw new ValidationError(`Entrypoint validation failed`, {
@@ -2729,45 +2786,44 @@ async function internalBuild(config) {
2729
2786
  });
2730
2787
  }
2731
2788
  const groups = groupEntrypoints(entrypoints);
2732
- const { output, warnings } = await rebuild(
2733
- config,
2734
- entrypoints,
2735
- groups,
2736
- void 0
2737
- );
2789
+ await wxt.hooks.callHook("entrypoints:grouped", wxt, groups);
2790
+ const { output, warnings } = await rebuild(entrypoints, groups, void 0);
2791
+ await wxt.hooks.callHook("build:done", wxt, output);
2738
2792
  await printBuildSummary(
2739
- config.logger.success,
2793
+ wxt.logger.success,
2740
2794
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
2741
- output,
2742
- config
2795
+ output
2743
2796
  );
2744
2797
  for (const warning of warnings) {
2745
- config.logger.warn(...warning);
2798
+ wxt.logger.warn(...warning);
2746
2799
  }
2747
- if (config.analysis.enabled) {
2748
- await combineAnalysisStats(config);
2749
- config.logger.info(
2800
+ if (wxt.config.analysis.enabled) {
2801
+ await combineAnalysisStats();
2802
+ wxt.logger.info(
2750
2803
  `Analysis complete:
2751
2804
  ${pc5.gray("\u2514\u2500")} ${pc5.yellow("stats.html")}`
2752
2805
  );
2753
2806
  }
2754
2807
  return output;
2755
2808
  }
2756
- async function combineAnalysisStats(config) {
2809
+ async function combineAnalysisStats() {
2757
2810
  const unixFiles = await glob3(`stats-*.json`, {
2758
- cwd: config.outDir,
2811
+ cwd: wxt.config.outDir,
2759
2812
  absolute: true
2760
2813
  });
2761
2814
  const absolutePaths = unixFiles.map(unnormalizePath);
2762
2815
  await exec(
2763
- config,
2764
2816
  "rollup-plugin-visualizer",
2765
- [...absolutePaths, "--template", config.analysis.template],
2766
- { cwd: config.root, stdio: "inherit" }
2817
+ [...absolutePaths, "--template", wxt.config.analysis.template],
2818
+ { cwd: wxt.config.root, stdio: "inherit" }
2767
2819
  );
2768
2820
  }
2769
- function printValidationResults(config, { errorCount, errors, warningCount }) {
2770
- (errorCount > 0 ? config.logger.error : config.logger.warn)(
2821
+ function printValidationResults({
2822
+ errorCount,
2823
+ errors,
2824
+ warningCount
2825
+ }) {
2826
+ (errorCount > 0 ? wxt.logger.error : wxt.logger.warn)(
2771
2827
  `Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
2772
2828
  );
2773
2829
  const cwd = process.cwd();
@@ -2791,8 +2847,8 @@ function printValidationResults(config, { errorCount, errors, warningCount }) {
2791
2847
 
2792
2848
  // src/core/build.ts
2793
2849
  async function build(config) {
2794
- const internalConfig = await getInternalConfig(config ?? {}, "build");
2795
- return await internalBuild(internalConfig);
2850
+ await registerWxt("build", config);
2851
+ return await internalBuild();
2796
2852
  }
2797
2853
 
2798
2854
  // src/core/clean.ts
@@ -2834,11 +2890,11 @@ async function clean(root = process.cwd()) {
2834
2890
  import { relative as relative7 } from "node:path";
2835
2891
  function createWslRunner() {
2836
2892
  return {
2837
- async openBrowser(config) {
2838
- config.logger.warn(
2893
+ async openBrowser() {
2894
+ wxt.logger.warn(
2839
2895
  `Cannot open browser when using WSL. Load "${relative7(
2840
2896
  process.cwd(),
2841
- config.outDir
2897
+ wxt.config.outDir
2842
2898
  )}" as an unpacked extension manually`
2843
2899
  );
2844
2900
  },
@@ -2852,9 +2908,9 @@ import defu4 from "defu";
2852
2908
  function createWebExtRunner() {
2853
2909
  let runner;
2854
2910
  return {
2855
- async openBrowser(config) {
2911
+ async openBrowser() {
2856
2912
  const startTime = Date.now();
2857
- if (config.browser === "firefox" && config.manifestVersion === 3) {
2913
+ if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) {
2858
2914
  throw Error(
2859
2915
  "Dev mode does not support Firefox MV3. For alternatives, see https://github.com/wxt-dev/wxt/issues/230#issuecomment-1806881653"
2860
2916
  );
@@ -2862,22 +2918,22 @@ function createWebExtRunner() {
2862
2918
  const webExtLogger = await import("web-ext-run/util/logger");
2863
2919
  webExtLogger.consoleStream.write = ({ level, msg, name }) => {
2864
2920
  if (level >= ERROR_LOG_LEVEL)
2865
- config.logger.error(name, msg);
2921
+ wxt.logger.error(name, msg);
2866
2922
  if (level >= WARN_LOG_LEVEL)
2867
- config.logger.warn(msg);
2923
+ wxt.logger.warn(msg);
2868
2924
  };
2869
- const wxtUserConfig = config.runnerConfig.config;
2925
+ const wxtUserConfig = wxt.config.runnerConfig.config;
2870
2926
  const userConfig = {
2871
2927
  console: wxtUserConfig?.openConsole,
2872
2928
  devtools: wxtUserConfig?.openDevtools,
2873
2929
  startUrl: wxtUserConfig?.startUrls,
2874
- ...config.browser === "firefox" ? {
2930
+ ...wxt.config.browser === "firefox" ? {
2875
2931
  firefox: wxtUserConfig?.binaries?.firefox,
2876
2932
  firefoxProfile: wxtUserConfig?.firefoxProfile,
2877
2933
  prefs: wxtUserConfig?.firefoxPrefs,
2878
2934
  args: wxtUserConfig?.firefoxArgs
2879
2935
  } : {
2880
- chromiumBinary: wxtUserConfig?.binaries?.[config.browser],
2936
+ chromiumBinary: wxtUserConfig?.binaries?.[wxt.config.browser],
2881
2937
  chromiumProfile: wxtUserConfig?.chromiumProfile,
2882
2938
  chromiumPref: defu4(
2883
2939
  wxtUserConfig?.chromiumPref,
@@ -2888,8 +2944,8 @@ function createWebExtRunner() {
2888
2944
  };
2889
2945
  const finalConfig = {
2890
2946
  ...userConfig,
2891
- target: config.browser === "firefox" ? "firefox-desktop" : "chromium",
2892
- sourceDir: config.outDir,
2947
+ target: wxt.config.browser === "firefox" ? "firefox-desktop" : "chromium",
2948
+ sourceDir: wxt.config.outDir,
2893
2949
  // WXT handles reloads, so disable auto-reload behaviors in web-ext
2894
2950
  noReload: true,
2895
2951
  noInput: true
@@ -2898,12 +2954,12 @@ function createWebExtRunner() {
2898
2954
  // Don't call `process.exit(0)` after starting web-ext
2899
2955
  shouldExitProgram: false
2900
2956
  };
2901
- config.logger.debug("web-ext config:", finalConfig);
2902
- config.logger.debug("web-ext options:", options);
2957
+ wxt.logger.debug("web-ext config:", finalConfig);
2958
+ wxt.logger.debug("web-ext options:", options);
2903
2959
  const webExt = await import("web-ext-run");
2904
2960
  runner = await webExt.default.cmd.run(finalConfig, options);
2905
2961
  const duration = Date.now() - startTime;
2906
- config.logger.success(`Opened browser in ${formatDuration(duration)}`);
2962
+ wxt.logger.success(`Opened browser in ${formatDuration(duration)}`);
2907
2963
  },
2908
2964
  async closeBrowser() {
2909
2965
  return await runner?.exit();
@@ -2927,11 +2983,11 @@ var DEFAULT_CHROMIUM_PREFS = {
2927
2983
  import { relative as relative8 } from "node:path";
2928
2984
  function createSafariRunner() {
2929
2985
  return {
2930
- async openBrowser(config) {
2931
- config.logger.warn(
2986
+ async openBrowser() {
2987
+ wxt.logger.warn(
2932
2988
  `Cannot Safari using web-ext. Load "${relative8(
2933
2989
  process.cwd(),
2934
- config.outDir
2990
+ wxt.config.outDir
2935
2991
  )}" as an unpacked extension manually`
2936
2992
  );
2937
2993
  },
@@ -2944,11 +3000,11 @@ function createSafariRunner() {
2944
3000
  import { relative as relative9 } from "node:path";
2945
3001
  function createManualRunner() {
2946
3002
  return {
2947
- async openBrowser(config) {
2948
- config.logger.info(
3003
+ async openBrowser() {
3004
+ wxt.logger.info(
2949
3005
  `Load "${relative9(
2950
3006
  process.cwd(),
2951
- config.outDir
3007
+ wxt.config.outDir
2952
3008
  )}" as an unpacked extension manually`
2953
3009
  );
2954
3010
  },
@@ -2964,12 +3020,12 @@ async function isWsl() {
2964
3020
  }
2965
3021
 
2966
3022
  // src/core/runners/index.ts
2967
- async function createExtensionRunner(config) {
2968
- if (config.browser === "safari")
3023
+ async function createExtensionRunner() {
3024
+ if (wxt.config.browser === "safari")
2969
3025
  return createSafariRunner();
2970
3026
  if (await isWsl())
2971
3027
  return createWslRunner();
2972
- if (config.runnerConfig.config?.disabled)
3028
+ if (wxt.config.runnerConfig.config?.disabled)
2973
3029
  return createManualRunner();
2974
3030
  return createWebExtRunner();
2975
3031
  }
@@ -2989,13 +3045,13 @@ async function createServer(inlineConfig) {
2989
3045
  origin
2990
3046
  };
2991
3047
  const buildAndOpenBrowser = async () => {
2992
- server.currentOutput = await internalBuild(config);
2993
- await runner.openBrowser(config);
3048
+ server.currentOutput = await internalBuild();
3049
+ await runner.openBrowser();
2994
3050
  };
2995
3051
  const closeAndRecreateRunner = async () => {
2996
3052
  await runner.closeBrowser();
2997
- config = await getLatestConfig();
2998
- runner = await createExtensionRunner(config);
3053
+ await wxt.reloadConfig();
3054
+ runner = await createExtensionRunner();
2999
3055
  };
3000
3056
  const server = {
3001
3057
  ...serverInfo,
@@ -3008,7 +3064,7 @@ async function createServer(inlineConfig) {
3008
3064
  currentOutput: void 0,
3009
3065
  async start() {
3010
3066
  await builderServer.listen();
3011
- config.logger.success(`Started dev server @ ${serverInfo.origin}`);
3067
+ wxt.logger.success(`Started dev server @ ${serverInfo.origin}`);
3012
3068
  await buildAndOpenBrowser();
3013
3069
  },
3014
3070
  async stop() {
@@ -3033,27 +3089,20 @@ async function createServer(inlineConfig) {
3033
3089
  },
3034
3090
  async restartBrowser() {
3035
3091
  await closeAndRecreateRunner();
3036
- await runner.openBrowser(config);
3092
+ await runner.openBrowser();
3037
3093
  }
3038
3094
  };
3039
- const getLatestConfig = () => getInternalConfig(inlineConfig ?? {}, "serve", server);
3040
- let config = await getLatestConfig();
3095
+ await registerWxt("serve", inlineConfig, server);
3041
3096
  let [runner, builderServer] = await Promise.all([
3042
- createExtensionRunner(config),
3043
- config.builder.createServer(server)
3097
+ createExtensionRunner(),
3098
+ wxt.config.builder.createServer(server)
3044
3099
  ]);
3045
3100
  server.ws.on("wxt:background-initialized", () => {
3046
3101
  if (server.currentOutput == null)
3047
3102
  return;
3048
- reloadContentScripts(server.currentOutput.steps, config, server);
3049
- });
3050
- const reloadOnChange = createFileReloader({
3051
- server,
3052
- getLatestConfig,
3053
- updateConfig(newConfig) {
3054
- config = newConfig;
3055
- }
3103
+ reloadContentScripts(server.currentOutput.steps, server);
3056
3104
  });
3105
+ const reloadOnChange = createFileReloader(server);
3057
3106
  server.watcher.on("all", reloadOnChange);
3058
3107
  return server;
3059
3108
  }
@@ -3061,14 +3110,12 @@ async function getPort() {
3061
3110
  const { default: getPort2, portNumbers } = await import("get-port");
3062
3111
  return await getPort2({ port: portNumbers(3e3, 3010) });
3063
3112
  }
3064
- function createFileReloader(options) {
3065
- const { server, getLatestConfig, updateConfig } = options;
3113
+ function createFileReloader(server) {
3066
3114
  const fileChangedMutex = new Mutex();
3067
3115
  const changeQueue = [];
3068
3116
  return async (event, path7) => {
3069
- const config = await getLatestConfig();
3070
- updateConfig(config);
3071
- if (path7.startsWith(config.outBaseDir))
3117
+ await wxt.reloadConfig();
3118
+ if (path7.startsWith(wxt.config.outBaseDir))
3072
3119
  return;
3073
3120
  changeQueue.push([event, path7]);
3074
3121
  await fileChangedMutex.runExclusive(async () => {
@@ -3077,29 +3124,24 @@ function createFileReloader(options) {
3077
3124
  const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
3078
3125
  if (fileChanges.length === 0)
3079
3126
  return;
3080
- const changes = detectDevChanges(
3081
- config,
3082
- fileChanges,
3083
- server.currentOutput
3084
- );
3127
+ const changes = detectDevChanges(fileChanges, server.currentOutput);
3085
3128
  if (changes.type === "no-change")
3086
3129
  return;
3087
3130
  if (changes.type === "full-restart") {
3088
- config.logger.info("Config changed, restarting server...");
3131
+ wxt.logger.info("Config changed, restarting server...");
3089
3132
  server.restart();
3090
3133
  return;
3091
3134
  }
3092
3135
  if (changes.type === "browser-restart") {
3093
- config.logger.info("Runner config changed, restarting browser...");
3136
+ wxt.logger.info("Runner config changed, restarting browser...");
3094
3137
  server.restartBrowser();
3095
3138
  return;
3096
3139
  }
3097
- config.logger.info(
3098
- `Changed: ${Array.from(new Set(fileChanges)).map((file) => pc7.dim(relative10(config.root, file))).join(", ")}`
3140
+ wxt.logger.info(
3141
+ `Changed: ${Array.from(new Set(fileChanges)).map((file) => pc7.dim(relative10(wxt.config.root, file))).join(", ")}`
3099
3142
  );
3100
- const allEntrypoints = await findEntrypoints(config);
3143
+ const allEntrypoints = await findEntrypoints();
3101
3144
  const { output: newOutput } = await rebuild(
3102
- config,
3103
3145
  allEntrypoints,
3104
3146
  // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
3105
3147
  changes.rebuildGroups,
@@ -3114,13 +3156,12 @@ function createFileReloader(options) {
3114
3156
  case "html-reload":
3115
3157
  const { reloadedNames } = reloadHtmlPages(
3116
3158
  changes.rebuildGroups,
3117
- server,
3118
- config
3159
+ server
3119
3160
  );
3120
3161
  consola5.success(`Reloaded: ${getFilenameList(reloadedNames)}`);
3121
3162
  break;
3122
3163
  case "content-script-reload":
3123
- reloadContentScripts(changes.changedSteps, config, server);
3164
+ reloadContentScripts(changes.changedSteps, server);
3124
3165
  const rebuiltNames = changes.rebuildGroups.flat().map((entry) => entry.name);
3125
3166
  consola5.success(`Reloaded: ${getFilenameList(rebuiltNames)}`);
3126
3167
  break;
@@ -3128,30 +3169,33 @@ function createFileReloader(options) {
3128
3169
  });
3129
3170
  };
3130
3171
  }
3131
- function reloadContentScripts(steps, config, server) {
3132
- if (config.manifestVersion === 3) {
3172
+ function reloadContentScripts(steps, server) {
3173
+ if (wxt.config.manifestVersion === 3) {
3133
3174
  steps.forEach((step) => {
3134
3175
  if (server.currentOutput == null)
3135
3176
  return;
3136
3177
  const entry = step.entrypoints;
3137
3178
  if (Array.isArray(entry) || entry.type !== "content-script")
3138
3179
  return;
3139
- const js = [getEntrypointBundlePath(entry, config.outDir, ".js")];
3180
+ const js = [getEntrypointBundlePath(entry, wxt.config.outDir, ".js")];
3140
3181
  const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
3141
3182
  const css = getContentScriptCssFiles([entry], cssMap);
3142
3183
  server.reloadContentScript({
3143
3184
  allFrames: resolvePerBrowserOption(
3144
3185
  entry.options.allFrames,
3145
- config.browser
3186
+ wxt.config.browser
3146
3187
  ),
3147
3188
  excludeMatches: resolvePerBrowserOption(
3148
3189
  entry.options.excludeMatches,
3149
- config.browser
3190
+ wxt.config.browser
3150
3191
  ),
3151
- matches: resolvePerBrowserOption(entry.options.matches, config.browser),
3152
- runAt: resolvePerBrowserOption(entry.options.runAt, config.browser),
3192
+ matches: resolvePerBrowserOption(
3193
+ entry.options.matches,
3194
+ wxt.config.browser
3195
+ ),
3196
+ runAt: resolvePerBrowserOption(entry.options.runAt, wxt.config.browser),
3153
3197
  // @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript)
3154
- world: resolvePerBrowserOption(entry.options.world, config.browser),
3198
+ world: resolvePerBrowserOption(entry.options.world, wxt.config.browser),
3155
3199
  js,
3156
3200
  css
3157
3201
  });
@@ -3160,10 +3204,10 @@ function reloadContentScripts(steps, config, server) {
3160
3204
  server.reloadExtension();
3161
3205
  }
3162
3206
  }
3163
- function reloadHtmlPages(groups, server, config) {
3207
+ function reloadHtmlPages(groups, server) {
3164
3208
  const htmlEntries = groups.flat().filter((entry) => entry.inputPath.endsWith(".html"));
3165
3209
  htmlEntries.forEach((entry) => {
3166
- const path7 = getEntrypointBundlePath(entry, config.outDir, ".html");
3210
+ const path7 = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
3167
3211
  server.reloadPage(path7);
3168
3212
  });
3169
3213
  return {
@@ -3244,19 +3288,11 @@ async function initialize(options) {
3244
3288
  }
3245
3289
  async function listTemplates() {
3246
3290
  try {
3247
- const res = await fetch(
3248
- "https://api.github.com/repos/wxt-dev/wxt/contents/templates",
3249
- {
3250
- headers: {
3251
- Accept: "application/vnd.github+json",
3252
- "X-GitHub-Api-Version": "2022-11-28"
3253
- }
3254
- }
3255
- );
3291
+ const res = await fetch("https://ungh.cc/repos/wxt-dev/wxt/files/main");
3256
3292
  if (res.status >= 300)
3257
3293
  throw Error(`Request failed with status ${res.status} ${res.statusText}`);
3258
3294
  const data = await res.json();
3259
- return data.filter((item) => item.type === "dir").map((item) => ({ name: item.name, path: item.path })).sort((l, r) => {
3295
+ return data.files.map((item) => item.path.match(/templates\/(.+)\/package\.json/)?.[1]).filter((name) => name != null).map((name) => ({ name, path: `templates/${name}` })).sort((l, r) => {
3260
3296
  const lWeight = TEMPLATE_SORT_WEIGHT[l.name] ?? Number.MAX_SAFE_INTEGER;
3261
3297
  const rWeight = TEMPLATE_SORT_WEIGHT[r.name] ?? Number.MAX_SAFE_INTEGER;
3262
3298
  const diff = lWeight - rWeight;
@@ -3307,10 +3343,10 @@ var TEMPLATE_SORT_WEIGHT = {
3307
3343
 
3308
3344
  // src/core/prepare.ts
3309
3345
  async function prepare(config) {
3310
- const internalConfig = await getInternalConfig(config, "build");
3311
- internalConfig.logger.info("Generating types...");
3312
- const entrypoints = await findEntrypoints(internalConfig);
3313
- await generateTypesDir(entrypoints, internalConfig);
3346
+ await registerWxt("build", config);
3347
+ wxt.logger.info("Generating types...");
3348
+ const entrypoints = await findEntrypoints();
3349
+ await generateTypesDir(entrypoints);
3314
3350
  }
3315
3351
 
3316
3352
  // src/core/zip.ts
@@ -3319,40 +3355,35 @@ import { dirname as dirname5, relative as relative11, resolve as resolve14 } fro
3319
3355
  import fs15 from "fs-extra";
3320
3356
  import { minimatch as minimatch2 } from "minimatch";
3321
3357
  async function zip(config) {
3322
- const internalConfig = await getInternalConfig(config ?? {}, "build");
3323
- const output = await internalBuild(internalConfig);
3358
+ await registerWxt("build", config);
3359
+ const output = await internalBuild();
3324
3360
  const start = Date.now();
3325
- internalConfig.logger.info("Zipping extension...");
3361
+ wxt.logger.info("Zipping extension...");
3326
3362
  const zipFiles = [];
3327
- const projectName = internalConfig.zip.name ?? kebabCaseAlphanumeric(
3328
- (await getPackageJson(internalConfig))?.name || dirname5(process.cwd())
3363
+ const projectName = wxt.config.zip.name ?? kebabCaseAlphanumeric(
3364
+ (await getPackageJson())?.name || dirname5(process.cwd())
3329
3365
  );
3330
- const applyTemplate = (template) => template.replaceAll("{{name}}", projectName).replaceAll("{{browser}}", internalConfig.browser).replaceAll(
3366
+ const applyTemplate = (template) => template.replaceAll("{{name}}", projectName).replaceAll("{{browser}}", wxt.config.browser).replaceAll(
3331
3367
  "{{version}}",
3332
3368
  output.manifest.version_name ?? output.manifest.version
3333
- ).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
3334
- await fs15.ensureDir(internalConfig.outBaseDir);
3335
- const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
3336
- const outZipPath = resolve14(internalConfig.outBaseDir, outZipFilename);
3337
- await zipdir(internalConfig.outDir, {
3369
+ ).replaceAll("{{manifestVersion}}", `mv${wxt.config.manifestVersion}`);
3370
+ await fs15.ensureDir(wxt.config.outBaseDir);
3371
+ const outZipFilename = applyTemplate(wxt.config.zip.artifactTemplate);
3372
+ const outZipPath = resolve14(wxt.config.outBaseDir, outZipFilename);
3373
+ await zipdir(wxt.config.outDir, {
3338
3374
  saveTo: outZipPath
3339
3375
  });
3340
3376
  zipFiles.push(outZipPath);
3341
- if (internalConfig.browser === "firefox") {
3342
- const sourcesZipFilename = applyTemplate(
3343
- internalConfig.zip.sourcesTemplate
3344
- );
3345
- const sourcesZipPath = resolve14(
3346
- internalConfig.outBaseDir,
3347
- sourcesZipFilename
3348
- );
3349
- await zipdir(internalConfig.zip.sourcesRoot, {
3377
+ if (wxt.config.browser === "firefox") {
3378
+ const sourcesZipFilename = applyTemplate(wxt.config.zip.sourcesTemplate);
3379
+ const sourcesZipPath = resolve14(wxt.config.outBaseDir, sourcesZipFilename);
3380
+ await zipdir(wxt.config.zip.sourcesRoot, {
3350
3381
  saveTo: sourcesZipPath,
3351
3382
  filter(path7) {
3352
- const relativePath = relative11(internalConfig.zip.sourcesRoot, path7);
3353
- return internalConfig.zip.includeSources.some(
3383
+ const relativePath = relative11(wxt.config.zip.sourcesRoot, path7);
3384
+ return wxt.config.zip.includeSources.some(
3354
3385
  (pattern) => minimatch2(relativePath, pattern)
3355
- ) || !internalConfig.zip.excludeSources.some(
3386
+ ) || !wxt.config.zip.excludeSources.some(
3356
3387
  (pattern) => minimatch2(relativePath, pattern)
3357
3388
  );
3358
3389
  }
@@ -3360,9 +3391,9 @@ async function zip(config) {
3360
3391
  zipFiles.push(sourcesZipPath);
3361
3392
  }
3362
3393
  await printFileList(
3363
- internalConfig.logger.success,
3394
+ wxt.logger.success,
3364
3395
  `Zipped extension in ${formatDuration(Date.now() - start)}`,
3365
- internalConfig.outBaseDir,
3396
+ wxt.config.outBaseDir,
3366
3397
  zipFiles
3367
3398
  );
3368
3399
  return zipFiles;
@@ -3405,11 +3436,11 @@ var aliasCommandNames = /* @__PURE__ */ new Set();
3405
3436
  function createAliasedCommand(base, name, alias, docsUrl) {
3406
3437
  const aliasedCommand = base.command(name, `Alias for ${alias} (${docsUrl})`).allowUnknownOptions().action(async () => {
3407
3438
  try {
3408
- const config = await getInternalConfig({}, "build");
3439
+ await registerWxt("build");
3409
3440
  const args = process.argv.slice(
3410
3441
  process.argv.indexOf(aliasedCommand.name) + 1
3411
3442
  );
3412
- await exec(config, alias, args, {
3443
+ await exec(alias, args, {
3413
3444
  stdio: "inherit"
3414
3445
  });
3415
3446
  } catch {