wxt 0.16.1 → 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/index.cjs CHANGED
@@ -2443,6 +2443,26 @@ function unnormalizePath(path10) {
2443
2443
  var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
2444
2444
  var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
2445
2445
 
2446
+ // src/core/wxt.ts
2447
+ var import_hookable = require("hookable");
2448
+ var wxt;
2449
+ async function registerWxt(command, inlineConfig = {}, server) {
2450
+ const config = await resolveConfig(inlineConfig, command, server);
2451
+ const hooks = (0, import_hookable.createHooks)();
2452
+ wxt = {
2453
+ config,
2454
+ hooks,
2455
+ get logger() {
2456
+ return config.logger;
2457
+ },
2458
+ async reloadConfig() {
2459
+ wxt.config = await resolveConfig(inlineConfig, command, server);
2460
+ }
2461
+ };
2462
+ wxt.hooks.addHooks(config.hooks);
2463
+ await wxt.hooks.callHook("ready", wxt);
2464
+ }
2465
+
2446
2466
  // src/core/utils/fs.ts
2447
2467
  async function writeFileIfDifferent(file, newContents) {
2448
2468
  const existingContents = await import_fs_extra.default.readFile(file, "utf-8").catch(() => void 0);
@@ -2450,10 +2470,10 @@ async function writeFileIfDifferent(file, newContents) {
2450
2470
  await import_fs_extra.default.writeFile(file, newContents);
2451
2471
  }
2452
2472
  }
2453
- async function getPublicFiles(config) {
2454
- if (!await import_fs_extra.default.exists(config.publicDir))
2473
+ async function getPublicFiles() {
2474
+ if (!await import_fs_extra.default.exists(wxt.config.publicDir))
2455
2475
  return [];
2456
- const files = await (0, import_fast_glob.default)("**/*", { cwd: config.publicDir });
2476
+ const files = await (0, import_fast_glob.default)("**/*", { cwd: wxt.config.publicDir });
2457
2477
  return files.map(unnormalizePath);
2458
2478
  }
2459
2479
 
@@ -2461,7 +2481,7 @@ async function getPublicFiles(config) {
2461
2481
  var import_fs_extra2 = __toESM(require("fs-extra"), 1);
2462
2482
  var import_path = require("path");
2463
2483
  var import_picocolors = __toESM(require("picocolors"), 1);
2464
- async function buildEntrypoints(groups, config, spinner) {
2484
+ async function buildEntrypoints(groups, spinner) {
2465
2485
  const steps = [];
2466
2486
  for (let i = 0; i < groups.length; i++) {
2467
2487
  const group = groups[i];
@@ -2469,22 +2489,22 @@ async function buildEntrypoints(groups, config, spinner) {
2469
2489
  const groupNameColored = groupNames.join(import_picocolors.default.dim(", "));
2470
2490
  spinner.text = import_picocolors.default.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNameColored}`;
2471
2491
  try {
2472
- steps.push(await config.builder.build(group));
2492
+ steps.push(await wxt.config.builder.build(group));
2473
2493
  } catch (err) {
2474
2494
  throw Error(`Failed to build ${groupNames.join(", ")}`, { cause: err });
2475
2495
  }
2476
2496
  }
2477
- const publicAssets = await copyPublicDirectory(config);
2497
+ const publicAssets = await copyPublicDirectory();
2478
2498
  return { publicAssets, steps };
2479
2499
  }
2480
- async function copyPublicDirectory(config) {
2481
- const files = await getPublicFiles(config);
2500
+ async function copyPublicDirectory() {
2501
+ const files = await getPublicFiles();
2482
2502
  if (files.length === 0)
2483
2503
  return [];
2484
2504
  const publicAssets = [];
2485
2505
  for (const file of files) {
2486
- const srcPath = (0, import_path.resolve)(config.publicDir, file);
2487
- const outPath = (0, import_path.resolve)(config.outDir, file);
2506
+ const srcPath = (0, import_path.resolve)(wxt.config.publicDir, file);
2507
+ const outPath = (0, import_path.resolve)(wxt.config.outDir, file);
2488
2508
  await import_fs_extra2.default.ensureDir((0, import_path.dirname)(outPath));
2489
2509
  await import_fs_extra2.default.copyFile(srcPath, outPath);
2490
2510
  publicAssets.push({
@@ -2510,16 +2530,16 @@ function some(array, predicate) {
2510
2530
  }
2511
2531
 
2512
2532
  // src/core/utils/building/detect-dev-changes.ts
2513
- function detectDevChanges(config, changedFiles, currentOutput) {
2533
+ function detectDevChanges(changedFiles, currentOutput) {
2514
2534
  const isConfigChange = some(
2515
2535
  changedFiles,
2516
- (file) => file === config.userConfigMetadata.configFile
2536
+ (file) => file === wxt.config.userConfigMetadata.configFile
2517
2537
  );
2518
2538
  if (isConfigChange)
2519
2539
  return { type: "full-restart" };
2520
2540
  const isRunnerChange = some(
2521
2541
  changedFiles,
2522
- (file) => file === config.runnerConfig.configFile
2542
+ (file) => file === wxt.config.runnerConfig.configFile
2523
2543
  );
2524
2544
  if (isRunnerChange)
2525
2545
  return { type: "browser-restart" };
@@ -2637,15 +2657,15 @@ var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
2637
2657
 
2638
2658
  // src/core/utils/building/find-entrypoints.ts
2639
2659
  var import_picocolors2 = __toESM(require("picocolors"), 1);
2640
- async function findEntrypoints(config) {
2660
+ async function findEntrypoints() {
2641
2661
  const relativePaths = await (0, import_fast_glob2.default)(Object.keys(PATH_GLOB_TO_TYPE_MAP), {
2642
- cwd: config.entrypointsDir
2662
+ cwd: wxt.config.entrypointsDir
2643
2663
  });
2644
2664
  relativePaths.sort();
2645
2665
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
2646
2666
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
2647
- const inputPath = (0, import_path2.resolve)(config.entrypointsDir, relativePath);
2648
- const name = getEntrypointName(config.entrypointsDir, inputPath);
2667
+ const inputPath = (0, import_path2.resolve)(wxt.config.entrypointsDir, relativePath);
2668
+ const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
2649
2669
  const matchingGlob = pathGlobs.find(
2650
2670
  (glob5) => (0, import_minimatch.minimatch)(relativePath, glob5)
2651
2671
  );
@@ -2655,36 +2675,36 @@ async function findEntrypoints(config) {
2655
2675
  name,
2656
2676
  inputPath,
2657
2677
  type,
2658
- skipped: config.filterEntrypoints != null && !config.filterEntrypoints.has(name)
2678
+ skipped: wxt.config.filterEntrypoints != null && !wxt.config.filterEntrypoints.has(name)
2659
2679
  });
2660
2680
  }
2661
2681
  return results;
2662
2682
  }, []);
2663
- preventNoEntrypoints(config, entrypointInfos);
2664
- preventDuplicateEntrypointNames(config, entrypointInfos);
2683
+ preventNoEntrypoints(entrypointInfos);
2684
+ preventDuplicateEntrypointNames(entrypointInfos);
2665
2685
  let hasBackground = false;
2666
2686
  const entrypoints = await Promise.all(
2667
2687
  entrypointInfos.map(async (info) => {
2668
2688
  const { type } = info;
2669
2689
  switch (type) {
2670
2690
  case "popup":
2671
- return await getPopupEntrypoint(config, info);
2691
+ return await getPopupEntrypoint(info);
2672
2692
  case "options":
2673
- return await getOptionsEntrypoint(config, info);
2693
+ return await getOptionsEntrypoint(info);
2674
2694
  case "background":
2675
2695
  hasBackground = true;
2676
- return await getBackgroundEntrypoint(config, info);
2696
+ return await getBackgroundEntrypoint(info);
2677
2697
  case "content-script":
2678
- return await getContentScriptEntrypoint(config, info);
2698
+ return await getContentScriptEntrypoint(info);
2679
2699
  case "unlisted-page":
2680
- return await getUnlistedPageEntrypoint(config, info);
2700
+ return await getUnlistedPageEntrypoint(info);
2681
2701
  case "unlisted-script":
2682
- return await getUnlistedScriptEntrypoint(config, info);
2702
+ return await getUnlistedScriptEntrypoint(info);
2683
2703
  case "content-script-style":
2684
2704
  return {
2685
2705
  ...info,
2686
2706
  type,
2687
- outputDir: (0, import_path2.resolve)(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2707
+ outputDir: (0, import_path2.resolve)(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
2688
2708
  options: {
2689
2709
  include: void 0,
2690
2710
  exclude: void 0
@@ -2694,7 +2714,7 @@ async function findEntrypoints(config) {
2694
2714
  return {
2695
2715
  ...info,
2696
2716
  type,
2697
- outputDir: config.outDir,
2717
+ outputDir: wxt.config.outDir,
2698
2718
  options: {
2699
2719
  include: void 0,
2700
2720
  exclude: void 0
@@ -2703,9 +2723,9 @@ async function findEntrypoints(config) {
2703
2723
  }
2704
2724
  })
2705
2725
  );
2706
- if (config.command === "serve" && !hasBackground) {
2726
+ if (wxt.config.command === "serve" && !hasBackground) {
2707
2727
  entrypoints.push(
2708
- await getBackgroundEntrypoint(config, {
2728
+ await getBackgroundEntrypoint({
2709
2729
  inputPath: VIRTUAL_NOOP_BACKGROUND_MODULE_ID,
2710
2730
  name: "background",
2711
2731
  type: "background",
@@ -2713,10 +2733,10 @@ async function findEntrypoints(config) {
2713
2733
  })
2714
2734
  );
2715
2735
  }
2716
- config.logger.debug("All entrypoints:", entrypoints);
2736
+ wxt.logger.debug("All entrypoints:", entrypoints);
2717
2737
  const skippedEntrypointNames = entrypointInfos.filter((item) => item.skipped).map((item) => item.name);
2718
2738
  if (skippedEntrypointNames.length) {
2719
- config.logger.warn(
2739
+ wxt.logger.warn(
2720
2740
  `Filter excluded the following entrypoints:
2721
2741
  ${skippedEntrypointNames.map((item) => `${import_picocolors2.default.dim("-")} ${import_picocolors2.default.cyan(item)}`).join("\n")}`
2722
2742
  );
@@ -2724,26 +2744,27 @@ ${skippedEntrypointNames.map((item) => `${import_picocolors2.default.dim("-")} $
2724
2744
  const targetEntrypoints = entrypoints.filter((entry) => {
2725
2745
  const { include, exclude } = entry.options;
2726
2746
  if (include?.length && exclude?.length) {
2727
- config.logger.warn(
2747
+ wxt.logger.warn(
2728
2748
  `The ${entry.name} entrypoint lists both include and exclude, but only one can be used per entrypoint. Entrypoint ignored.`
2729
2749
  );
2730
2750
  return false;
2731
2751
  }
2732
2752
  if (exclude?.length && !include?.length) {
2733
- return !exclude.includes(config.browser);
2753
+ return !exclude.includes(wxt.config.browser);
2734
2754
  }
2735
2755
  if (include?.length && !exclude?.length) {
2736
- return include.includes(config.browser);
2756
+ return include.includes(wxt.config.browser);
2737
2757
  }
2738
2758
  if (skippedEntrypointNames.includes(entry.name)) {
2739
2759
  return false;
2740
2760
  }
2741
2761
  return true;
2742
2762
  });
2743
- config.logger.debug(`${config.browser} entrypoints:`, targetEntrypoints);
2763
+ wxt.logger.debug(`${wxt.config.browser} entrypoints:`, targetEntrypoints);
2764
+ await wxt.hooks.callHook("entrypoints:resolved", wxt, targetEntrypoints);
2744
2765
  return targetEntrypoints;
2745
2766
  }
2746
- function preventDuplicateEntrypointNames(config, files) {
2767
+ function preventDuplicateEntrypointNames(files) {
2747
2768
  const namesToPaths = files.reduce(
2748
2769
  (map, { name, inputPath }) => {
2749
2770
  map[name] ??= [];
@@ -2757,7 +2778,7 @@ function preventDuplicateEntrypointNames(config, files) {
2757
2778
  if (absolutePaths.length > 1) {
2758
2779
  lines.push(`- ${name}`);
2759
2780
  absolutePaths.forEach((absolutePath) => {
2760
- lines.push(` - ${(0, import_path2.relative)(config.root, absolutePath)}`);
2781
+ lines.push(` - ${(0, import_path2.relative)(wxt.config.root, absolutePath)}`);
2761
2782
  });
2762
2783
  }
2763
2784
  return lines;
@@ -2773,9 +2794,9 @@ ${errorContent}`
2773
2794
  );
2774
2795
  }
2775
2796
  }
2776
- function preventNoEntrypoints(config, files) {
2797
+ function preventNoEntrypoints(files) {
2777
2798
  if (files.length === 0) {
2778
- throw Error(`No entrypoints found in ${config.entrypointsDir}`);
2799
+ throw Error(`No entrypoints found in ${wxt.config.entrypointsDir}`);
2779
2800
  }
2780
2801
  }
2781
2802
  function getHtmlBaseOptions(document) {
@@ -2790,7 +2811,11 @@ function getHtmlBaseOptions(document) {
2790
2811
  }
2791
2812
  return options;
2792
2813
  }
2793
- async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
2814
+ async function getPopupEntrypoint({
2815
+ inputPath,
2816
+ name,
2817
+ skipped
2818
+ }) {
2794
2819
  const content = await import_fs_extra3.default.readFile(inputPath, "utf-8");
2795
2820
  const { document } = (0, import_linkedom.parseHTML)(content);
2796
2821
  const options = getHtmlBaseOptions(document);
@@ -2802,7 +2827,7 @@ async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
2802
2827
  try {
2803
2828
  options.defaultIcon = import_json5.default.parse(defaultIconContent);
2804
2829
  } catch (err) {
2805
- config.logger.fatal(
2830
+ wxt.logger.fatal(
2806
2831
  `Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
2807
2832
  err
2808
2833
  );
@@ -2821,11 +2846,15 @@ async function getPopupEntrypoint(config, { inputPath, name, skipped }) {
2821
2846
  name: "popup",
2822
2847
  options,
2823
2848
  inputPath,
2824
- outputDir: config.outDir,
2849
+ outputDir: wxt.config.outDir,
2825
2850
  skipped
2826
2851
  };
2827
2852
  }
2828
- async function getOptionsEntrypoint(config, { inputPath, name, skipped }) {
2853
+ async function getOptionsEntrypoint({
2854
+ inputPath,
2855
+ name,
2856
+ skipped
2857
+ }) {
2829
2858
  const content = await import_fs_extra3.default.readFile(inputPath, "utf-8");
2830
2859
  const { document } = (0, import_linkedom.parseHTML)(content);
2831
2860
  const options = getHtmlBaseOptions(document);
@@ -2846,27 +2875,32 @@ async function getOptionsEntrypoint(config, { inputPath, name, skipped }) {
2846
2875
  name: "options",
2847
2876
  options,
2848
2877
  inputPath,
2849
- outputDir: config.outDir,
2878
+ outputDir: wxt.config.outDir,
2850
2879
  skipped
2851
2880
  };
2852
2881
  }
2853
- async function getUnlistedPageEntrypoint(config, { inputPath, name, skipped }) {
2882
+ async function getUnlistedPageEntrypoint({
2883
+ inputPath,
2884
+ name,
2885
+ skipped
2886
+ }) {
2854
2887
  const content = await import_fs_extra3.default.readFile(inputPath, "utf-8");
2855
2888
  const { document } = (0, import_linkedom.parseHTML)(content);
2856
2889
  return {
2857
2890
  type: "unlisted-page",
2858
- name: getEntrypointName(config.entrypointsDir, inputPath),
2891
+ name: getEntrypointName(wxt.config.entrypointsDir, inputPath),
2859
2892
  inputPath,
2860
- outputDir: config.outDir,
2893
+ outputDir: wxt.config.outDir,
2861
2894
  options: getHtmlBaseOptions(document),
2862
2895
  skipped
2863
2896
  };
2864
2897
  }
2865
- async function getUnlistedScriptEntrypoint(config, { inputPath, name, skipped }) {
2866
- const defaultExport = await importEntrypointFile(
2867
- inputPath,
2868
- config
2869
- );
2898
+ async function getUnlistedScriptEntrypoint({
2899
+ inputPath,
2900
+ name,
2901
+ skipped
2902
+ }) {
2903
+ const defaultExport = await importEntrypointFile(inputPath);
2870
2904
  if (defaultExport == null) {
2871
2905
  throw Error(
2872
2906
  `${name}: Default export not found, did you forget to call "export default defineUnlistedScript(...)"?`
@@ -2878,18 +2912,19 @@ async function getUnlistedScriptEntrypoint(config, { inputPath, name, skipped })
2878
2912
  type: "unlisted-script",
2879
2913
  name,
2880
2914
  inputPath,
2881
- outputDir: config.outDir,
2915
+ outputDir: wxt.config.outDir,
2882
2916
  options,
2883
2917
  skipped
2884
2918
  };
2885
2919
  }
2886
- async function getBackgroundEntrypoint(config, { inputPath, name, skipped }) {
2920
+ async function getBackgroundEntrypoint({
2921
+ inputPath,
2922
+ name,
2923
+ skipped
2924
+ }) {
2887
2925
  let options = {};
2888
2926
  if (inputPath !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
2889
- const defaultExport = await importEntrypointFile(
2890
- inputPath,
2891
- config
2892
- );
2927
+ const defaultExport = await importEntrypointFile(inputPath);
2893
2928
  if (defaultExport == null) {
2894
2929
  throw Error(
2895
2930
  `${name}: Default export not found, did you forget to call "export default defineBackground(...)"?`
@@ -2898,24 +2933,31 @@ async function getBackgroundEntrypoint(config, { inputPath, name, skipped }) {
2898
2933
  const { main: _, ...moduleOptions } = defaultExport;
2899
2934
  options = moduleOptions;
2900
2935
  }
2901
- if (config.manifestVersion !== 3) {
2936
+ if (wxt.config.manifestVersion !== 3) {
2902
2937
  delete options.type;
2903
2938
  }
2904
2939
  return {
2905
2940
  type: "background",
2906
2941
  name,
2907
2942
  inputPath,
2908
- outputDir: config.outDir,
2943
+ outputDir: wxt.config.outDir,
2909
2944
  options: {
2910
2945
  ...options,
2911
- type: resolvePerBrowserOption(options.type, config.browser),
2912
- persistent: resolvePerBrowserOption(options.persistent, config.browser)
2946
+ type: resolvePerBrowserOption(options.type, wxt.config.browser),
2947
+ persistent: resolvePerBrowserOption(
2948
+ options.persistent,
2949
+ wxt.config.browser
2950
+ )
2913
2951
  },
2914
2952
  skipped
2915
2953
  };
2916
2954
  }
2917
- async function getContentScriptEntrypoint(config, { inputPath, name, skipped }) {
2918
- const { main: _, ...options } = await importEntrypointFile(inputPath, config);
2955
+ async function getContentScriptEntrypoint({
2956
+ inputPath,
2957
+ name,
2958
+ skipped
2959
+ }) {
2960
+ const { main: _, ...options } = await importEntrypointFile(inputPath);
2919
2961
  if (options == null) {
2920
2962
  throw Error(
2921
2963
  `${name}: Default export not found, did you forget to call "export default defineContentScript(...)"?`
@@ -2925,7 +2967,7 @@ async function getContentScriptEntrypoint(config, { inputPath, name, skipped })
2925
2967
  type: "content-script",
2926
2968
  name,
2927
2969
  inputPath,
2928
- outputDir: (0, import_path2.resolve)(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2970
+ outputDir: (0, import_path2.resolve)(wxt.config.outDir, CONTENT_SCRIPT_OUT_DIR),
2929
2971
  options,
2930
2972
  skipped
2931
2973
  };
@@ -3095,23 +3137,23 @@ function parseI18nMessages(messagesJson) {
3095
3137
  }
3096
3138
 
3097
3139
  // src/core/utils/building/generate-wxt-dir.ts
3098
- async function generateTypesDir(entrypoints, config) {
3099
- await import_fs_extra4.default.ensureDir(config.typesDir);
3140
+ async function generateTypesDir(entrypoints) {
3141
+ await import_fs_extra4.default.ensureDir(wxt.config.typesDir);
3100
3142
  const references = [];
3101
- const imports = getUnimportOptions(config);
3143
+ const imports = getUnimportOptions(wxt.config);
3102
3144
  if (imports !== false) {
3103
- references.push(await writeImportsDeclarationFile(config, imports));
3145
+ references.push(await writeImportsDeclarationFile(imports));
3104
3146
  }
3105
- references.push(await writePathsDeclarationFile(entrypoints, config));
3106
- references.push(await writeI18nDeclarationFile(config));
3107
- references.push(await writeGlobalsDeclarationFile(config));
3108
- const mainReference = await writeMainDeclarationFile(references, config);
3109
- await writeTsConfigFile(mainReference, config);
3147
+ references.push(await writePathsDeclarationFile(entrypoints));
3148
+ references.push(await writeI18nDeclarationFile());
3149
+ references.push(await writeGlobalsDeclarationFile());
3150
+ const mainReference = await writeMainDeclarationFile(references);
3151
+ await writeTsConfigFile(mainReference);
3110
3152
  }
3111
- async function writeImportsDeclarationFile(config, unimportOptions) {
3112
- const filePath = (0, import_path3.resolve)(config.typesDir, "imports.d.ts");
3153
+ async function writeImportsDeclarationFile(unimportOptions) {
3154
+ const filePath = (0, import_path3.resolve)(wxt.config.typesDir, "imports.d.ts");
3113
3155
  const unimport2 = (0, import_unimport.createUnimport)(unimportOptions);
3114
- await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
3156
+ await unimport2.scanImportsFromDir(void 0, { cwd: wxt.config.srcDir });
3115
3157
  await writeFileIfDifferent(
3116
3158
  filePath,
3117
3159
  ["// Generated by wxt", await unimport2.generateTypeDeclarations()].join(
@@ -3120,15 +3162,15 @@ async function writeImportsDeclarationFile(config, unimportOptions) {
3120
3162
  );
3121
3163
  return filePath;
3122
3164
  }
3123
- async function writePathsDeclarationFile(entrypoints, config) {
3124
- const filePath = (0, import_path3.resolve)(config.typesDir, "paths.d.ts");
3165
+ async function writePathsDeclarationFile(entrypoints) {
3166
+ const filePath = (0, import_path3.resolve)(wxt.config.typesDir, "paths.d.ts");
3125
3167
  const unions = entrypoints.map(
3126
3168
  (entry) => getEntrypointBundlePath(
3127
3169
  entry,
3128
- config.outDir,
3170
+ wxt.config.outDir,
3129
3171
  entry.inputPath.endsWith(".html") ? ".html" : ".js"
3130
3172
  )
3131
- ).concat(await getPublicFiles(config)).map(normalizePath).map((path10) => ` | "/${path10}"`).sort().join("\n");
3173
+ ).concat(await getPublicFiles()).map(normalizePath).map((path10) => ` | "/${path10}"`).sort().join("\n");
3132
3174
  const template = `// Generated by wxt
3133
3175
  import "wxt/browser";
3134
3176
 
@@ -3148,9 +3190,9 @@ declare module "wxt/browser" {
3148
3190
  );
3149
3191
  return filePath;
3150
3192
  }
3151
- async function writeI18nDeclarationFile(config) {
3152
- const filePath = (0, import_path3.resolve)(config.typesDir, "i18n.d.ts");
3153
- const defaultLocale = config.manifest.default_locale;
3193
+ async function writeI18nDeclarationFile() {
3194
+ const filePath = (0, import_path3.resolve)(wxt.config.typesDir, "i18n.d.ts");
3195
+ const defaultLocale = wxt.config.manifest.default_locale;
3154
3196
  const template = `// Generated by wxt
3155
3197
  import "wxt/browser";
3156
3198
 
@@ -3173,7 +3215,7 @@ declare module "wxt/browser" {
3173
3215
  let messages;
3174
3216
  if (defaultLocale) {
3175
3217
  const defaultLocalePath = import_node_path3.default.resolve(
3176
- config.publicDir,
3218
+ wxt.config.publicDir,
3177
3219
  "_locales",
3178
3220
  defaultLocale,
3179
3221
  "messages.json"
@@ -3201,9 +3243,9 @@ declare module "wxt/browser" {
3201
3243
  );
3202
3244
  return filePath;
3203
3245
  }
3204
- async function writeGlobalsDeclarationFile(config) {
3205
- const filePath = (0, import_path3.resolve)(config.typesDir, "globals.d.ts");
3206
- const globals2 = [...getGlobals(config), ...getEntrypointGlobals("")];
3246
+ async function writeGlobalsDeclarationFile() {
3247
+ const filePath = (0, import_path3.resolve)(wxt.config.typesDir, "globals.d.ts");
3248
+ const globals2 = [...getGlobals(wxt.config), ...getEntrypointGlobals("")];
3207
3249
  await writeFileIfDifferent(
3208
3250
  filePath,
3209
3251
  [
@@ -3219,8 +3261,8 @@ async function writeGlobalsDeclarationFile(config) {
3219
3261
  );
3220
3262
  return filePath;
3221
3263
  }
3222
- async function writeMainDeclarationFile(references, config) {
3223
- const dir = config.wxtDir;
3264
+ async function writeMainDeclarationFile(references) {
3265
+ const dir = wxt.config.wxtDir;
3224
3266
  const filePath = (0, import_path3.resolve)(dir, "wxt.d.ts");
3225
3267
  await writeFileIfDifferent(
3226
3268
  filePath,
@@ -3234,10 +3276,10 @@ async function writeMainDeclarationFile(references, config) {
3234
3276
  );
3235
3277
  return filePath;
3236
3278
  }
3237
- async function writeTsConfigFile(mainReference, config) {
3238
- const dir = config.wxtDir;
3279
+ async function writeTsConfigFile(mainReference) {
3280
+ const dir = wxt.config.wxtDir;
3239
3281
  const getTsconfigPath = (path10) => normalizePath((0, import_path3.relative)(dir, path10));
3240
- const paths = Object.entries(config.alias).flatMap(([alias, absolutePath]) => {
3282
+ const paths = Object.entries(wxt.config.alias).flatMap(([alias, absolutePath]) => {
3241
3283
  const aliasPath = getTsconfigPath(absolutePath);
3242
3284
  return [
3243
3285
  ` "${alias}": ["${aliasPath}"]`,
@@ -3262,15 +3304,15 @@ ${paths}
3262
3304
  }
3263
3305
  },
3264
3306
  "include": [
3265
- "${getTsconfigPath(config.root)}/**/*",
3307
+ "${getTsconfigPath(wxt.config.root)}/**/*",
3266
3308
  "./${getTsconfigPath(mainReference)}"
3267
3309
  ],
3268
- "exclude": ["${getTsconfigPath(config.outBaseDir)}"]
3310
+ "exclude": ["${getTsconfigPath(wxt.config.outBaseDir)}"]
3269
3311
  }`
3270
3312
  );
3271
3313
  }
3272
3314
 
3273
- // src/core/utils/building/get-internal-config.ts
3315
+ // src/core/utils/building/resolve-config.ts
3274
3316
  var import_c12 = require("c12");
3275
3317
  var import_node_path7 = __toESM(require("path"), 1);
3276
3318
 
@@ -3296,7 +3338,7 @@ function createFsCache(wxtDir) {
3296
3338
  };
3297
3339
  }
3298
3340
 
3299
- // src/core/utils/building/get-internal-config.ts
3341
+ // src/core/utils/building/resolve-config.ts
3300
3342
  var import_consola = __toESM(require("consola"), 1);
3301
3343
 
3302
3344
  // src/core/builders/vite/plugins/devHtmlPrerender.ts
@@ -3791,6 +3833,21 @@ function entrypointGroupGlobals(entrypointGroup) {
3791
3833
  };
3792
3834
  }
3793
3835
 
3836
+ // src/core/builders/vite/plugins/defineImportMeta.ts
3837
+ function defineImportMeta() {
3838
+ return {
3839
+ name: "wxt:define",
3840
+ config() {
3841
+ return {
3842
+ define: {
3843
+ // This works for all extension contexts, including background service worker
3844
+ "import.meta.url": "self.location.href"
3845
+ }
3846
+ };
3847
+ }
3848
+ };
3849
+ }
3850
+
3794
3851
  // src/core/builders/vite/index.ts
3795
3852
  async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
3796
3853
  const vite = await import("vite");
@@ -3827,7 +3884,8 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
3827
3884
  tsconfigPaths(wxtConfig),
3828
3885
  noopBackground(),
3829
3886
  globals(wxtConfig),
3830
- excludeBrowserPolyfill(wxtConfig)
3887
+ excludeBrowserPolyfill(wxtConfig),
3888
+ defineImportMeta()
3831
3889
  );
3832
3890
  if (wxtConfig.analysis.enabled) {
3833
3891
  config.plugins.push(bundleAnalysis());
@@ -4005,9 +4063,9 @@ function getRollupEntry(entrypoint) {
4005
4063
  return virtualEntrypointType ? `virtual:wxt-${virtualEntrypointType}?${entrypoint.inputPath}` : entrypoint.inputPath;
4006
4064
  }
4007
4065
 
4008
- // src/core/utils/building/get-internal-config.ts
4066
+ // src/core/utils/building/resolve-config.ts
4009
4067
  var import_defu2 = __toESM(require("defu"), 1);
4010
- async function getInternalConfig(inlineConfig, command, server) {
4068
+ async function resolveConfig(inlineConfig, command, server) {
4011
4069
  let userConfig = {};
4012
4070
  let userConfigMetadata;
4013
4071
  if (inlineConfig.configFile !== false) {
@@ -4101,7 +4159,8 @@ async function getInternalConfig(inlineConfig, command, server) {
4101
4159
  server,
4102
4160
  dev: {
4103
4161
  reloadCommand
4104
- }
4162
+ },
4163
+ hooks: mergedConfig.hooks ?? {}
4105
4164
  };
4106
4165
  const builder = await createViteBuilder(
4107
4166
  inlineConfig,
@@ -4138,6 +4197,10 @@ function mergeInlineConfig(inlineConfig, userConfig) {
4138
4197
  inlineConfig.zip ?? {},
4139
4198
  userConfig.zip ?? {}
4140
4199
  );
4200
+ const hooks = (0, import_defu2.default)(
4201
+ inlineConfig.hooks ?? {},
4202
+ userConfig.hooks ?? {}
4203
+ );
4141
4204
  return {
4142
4205
  root: inlineConfig.root ?? userConfig.root,
4143
4206
  browser: inlineConfig.browser ?? userConfig.browser,
@@ -4172,7 +4235,8 @@ function mergeInlineConfig(inlineConfig, userConfig) {
4172
4235
  dev: {
4173
4236
  ...userConfig.dev,
4174
4237
  ...inlineConfig.dev
4175
- }
4238
+ },
4239
+ hooks
4176
4240
  };
4177
4241
  }
4178
4242
  function resolveInternalZipConfig(root, mergedConfig) {
@@ -4264,11 +4328,11 @@ ${noImports}`;
4264
4328
  var import_esbuild = require("esbuild");
4265
4329
  var import_node_url = require("url");
4266
4330
  var import_meta = {};
4267
- async function importEntrypointFile(path10, config) {
4268
- config.logger.debug("Loading file metadata:", path10);
4331
+ async function importEntrypointFile(path10) {
4332
+ wxt.logger.debug("Loading file metadata:", path10);
4269
4333
  const normalPath = normalizePath(path10);
4270
4334
  const unimport2 = (0, import_unimport5.createUnimport)({
4271
- ...getUnimportOptions(config),
4335
+ ...getUnimportOptions(wxt.config),
4272
4336
  // Only allow specific imports, not all from the project
4273
4337
  dirs: []
4274
4338
  });
@@ -4276,18 +4340,18 @@ async function importEntrypointFile(path10, config) {
4276
4340
  const text = await import_fs_extra8.default.readFile(path10, "utf-8");
4277
4341
  const textNoImports = removeProjectImportStatements(text);
4278
4342
  const { code } = await unimport2.injectImports(textNoImports);
4279
- config.logger.debug(
4343
+ wxt.logger.debug(
4280
4344
  ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
4281
4345
  );
4282
4346
  const jiti = (0, import_jiti.default)(
4283
4347
  typeof __filename !== "undefined" ? __filename : (0, import_node_url.fileURLToPath)(import_meta.url),
4284
4348
  {
4285
4349
  cache: false,
4286
- debug: config.debug,
4350
+ debug: wxt.config.debug,
4287
4351
  esmResolve: true,
4288
4352
  alias: {
4289
4353
  "webextension-polyfill": (0, import_node_path8.resolve)(
4290
- config.root,
4354
+ wxt.config.root,
4291
4355
  "node_modules/wxt/dist/virtual/mock-browser.js"
4292
4356
  )
4293
4357
  },
@@ -4319,7 +4383,7 @@ async function importEntrypointFile(path10, config) {
4319
4383
  const res = await jiti(path10);
4320
4384
  return res.default;
4321
4385
  } catch (err) {
4322
- const filePath = (0, import_node_path8.relative)(config.root, path10);
4386
+ const filePath = (0, import_node_path8.relative)(wxt.config.root, path10);
4323
4387
  if (err instanceof ReferenceError) {
4324
4388
  const variableName = err.message.replace(" is not defined", "");
4325
4389
  throw Error(
@@ -4327,7 +4391,7 @@ async function importEntrypointFile(path10, config) {
4327
4391
  { cause: err }
4328
4392
  );
4329
4393
  } else {
4330
- config.logger.error(err);
4394
+ wxt.logger.error(err);
4331
4395
  throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
4332
4396
  }
4333
4397
  }
@@ -4421,7 +4485,7 @@ function getChunkColor(filename) {
4421
4485
  }
4422
4486
 
4423
4487
  // src/core/utils/log/printBuildSummary.ts
4424
- async function printBuildSummary(log, header, output, config) {
4488
+ async function printBuildSummary(log, header, output) {
4425
4489
  const chunks = [
4426
4490
  ...output.steps.flatMap((step) => step.chunks),
4427
4491
  ...output.publicAssets
@@ -4433,8 +4497,10 @@ async function printBuildSummary(log, header, output, config) {
4433
4497
  return diff;
4434
4498
  return l.fileName.localeCompare(r.fileName);
4435
4499
  });
4436
- const files = chunks.map((chunk) => (0, import_path7.resolve)(config.outDir, chunk.fileName));
4437
- await printFileList(log, header, config.outDir, files);
4500
+ const files = chunks.map(
4501
+ (chunk) => (0, import_path7.resolve)(wxt.config.outDir, chunk.fileName)
4502
+ );
4503
+ await printFileList(log, header, wxt.config.outDir, files);
4438
4504
  }
4439
4505
  var DEFAULT_SORT_WEIGHT = 100;
4440
4506
  var CHUNK_SORT_WEIGHTS = {
@@ -4454,7 +4520,7 @@ function getChunkSortWeight(filename) {
4454
4520
  var import_picocolors4 = __toESM(require("picocolors"), 1);
4455
4521
 
4456
4522
  // package.json
4457
- var version = "0.16.1";
4523
+ var version = "0.16.3";
4458
4524
 
4459
4525
  // src/core/utils/log/printHeader.ts
4460
4526
  var import_consola2 = require("consola");
@@ -4510,8 +4576,8 @@ var ContentSecurityPolicy = class _ContentSecurityPolicy {
4510
4576
  };
4511
4577
 
4512
4578
  // src/core/utils/content-scripts.ts
4513
- function hashContentScriptOptions(options, config) {
4514
- const simplifiedOptions = mapWxtOptionsToContentScript(options, config);
4579
+ function hashContentScriptOptions(options) {
4580
+ const simplifiedOptions = mapWxtOptionsToContentScript(options);
4515
4581
  Object.keys(simplifiedOptions).forEach((key) => {
4516
4582
  if (simplifiedOptions[key] == null)
4517
4583
  delete simplifiedOptions[key];
@@ -4537,31 +4603,31 @@ function hashContentScriptOptions(options, config) {
4537
4603
  }).sort((l, r) => l[0].localeCompare(r[0]))
4538
4604
  );
4539
4605
  }
4540
- function mapWxtOptionsToContentScript(options, config) {
4606
+ function mapWxtOptionsToContentScript(options) {
4541
4607
  return {
4542
- matches: resolvePerBrowserOption(options.matches, config.browser),
4543
- all_frames: resolvePerBrowserOption(options.allFrames, config.browser),
4608
+ matches: resolvePerBrowserOption(options.matches, wxt.config.browser),
4609
+ all_frames: resolvePerBrowserOption(options.allFrames, wxt.config.browser),
4544
4610
  match_about_blank: resolvePerBrowserOption(
4545
4611
  options.matchAboutBlank,
4546
- config.browser
4612
+ wxt.config.browser
4547
4613
  ),
4548
4614
  exclude_globs: resolvePerBrowserOption(
4549
4615
  options.excludeGlobs,
4550
- config.browser
4616
+ wxt.config.browser
4551
4617
  ),
4552
4618
  exclude_matches: resolvePerBrowserOption(
4553
4619
  options.excludeMatches,
4554
- config.browser
4620
+ wxt.config.browser
4555
4621
  ),
4556
4622
  include_globs: resolvePerBrowserOption(
4557
4623
  options.includeGlobs,
4558
- config.browser
4624
+ wxt.config.browser
4559
4625
  ),
4560
- run_at: resolvePerBrowserOption(options.runAt, config.browser),
4626
+ run_at: resolvePerBrowserOption(options.runAt, wxt.config.browser),
4561
4627
  // @ts-expect-error: untyped chrome options
4562
4628
  match_origin_as_fallback: resolvePerBrowserOption(
4563
4629
  options.matchOriginAsFallback,
4564
- config.browser
4630
+ wxt.config.browser
4565
4631
  ),
4566
4632
  world: options.world
4567
4633
  };
@@ -4570,12 +4636,12 @@ function mapWxtOptionsToContentScript(options, config) {
4570
4636
  // src/core/utils/package.ts
4571
4637
  var import_node_path10 = require("path");
4572
4638
  var import_fs_extra10 = __toESM(require("fs-extra"), 1);
4573
- async function getPackageJson(config) {
4574
- const file = (0, import_node_path10.resolve)(config.root, "package.json");
4639
+ async function getPackageJson() {
4640
+ const file = (0, import_node_path10.resolve)(wxt.config.root, "package.json");
4575
4641
  try {
4576
4642
  return await import_fs_extra10.default.readJson(file);
4577
4643
  } catch (err) {
4578
- config.logger.debug(
4644
+ wxt.logger.debug(
4579
4645
  `Failed to read package.json at: ${file}. Returning undefined.`
4580
4646
  );
4581
4647
  return {};
@@ -4585,40 +4651,40 @@ async function getPackageJson(config) {
4585
4651
  // src/core/utils/manifest.ts
4586
4652
  var import_immer = require("immer");
4587
4653
  var import_defu3 = __toESM(require("defu"), 1);
4588
- async function writeManifest(manifest, output, config) {
4589
- const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
4590
- await import_fs_extra11.default.ensureDir(config.outDir);
4591
- await writeFileIfDifferent((0, import_path8.resolve)(config.outDir, "manifest.json"), str);
4654
+ async function writeManifest(manifest, output) {
4655
+ const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
4656
+ await import_fs_extra11.default.ensureDir(wxt.config.outDir);
4657
+ await writeFileIfDifferent((0, import_path8.resolve)(wxt.config.outDir, "manifest.json"), str);
4592
4658
  output.publicAssets.unshift({
4593
4659
  type: "asset",
4594
4660
  fileName: "manifest.json"
4595
4661
  });
4596
4662
  }
4597
- async function generateManifest(entrypoints, buildOutput, config) {
4663
+ async function generateManifest(entrypoints, buildOutput) {
4598
4664
  const warnings = [];
4599
- const pkg = await getPackageJson(config);
4600
- let versionName = config.manifest.version_name ?? config.manifest.version ?? pkg?.version;
4665
+ const pkg = await getPackageJson();
4666
+ let versionName = wxt.config.manifest.version_name ?? wxt.config.manifest.version ?? pkg?.version;
4601
4667
  if (versionName == null) {
4602
4668
  versionName = "0.0.0";
4603
- config.logger.warn(
4669
+ wxt.logger.warn(
4604
4670
  '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'
4605
4671
  );
4606
4672
  }
4607
- const version2 = config.manifest.version ?? simplifyVersion(versionName);
4673
+ const version2 = wxt.config.manifest.version ?? simplifyVersion(versionName);
4608
4674
  const baseManifest = {
4609
- manifest_version: config.manifestVersion,
4675
+ manifest_version: wxt.config.manifestVersion,
4610
4676
  name: pkg?.name,
4611
4677
  description: pkg?.description,
4612
4678
  version: version2,
4613
4679
  short_name: pkg?.shortName,
4614
4680
  icons: discoverIcons(buildOutput)
4615
4681
  };
4616
- const userManifest = config.manifest;
4682
+ const userManifest = wxt.config.manifest;
4617
4683
  const manifest = (0, import_defu3.default)(
4618
4684
  userManifest,
4619
4685
  baseManifest
4620
4686
  );
4621
- if (config.command === "serve" && config.dev.reloadCommand) {
4687
+ if (wxt.config.command === "serve" && wxt.config.dev.reloadCommand) {
4622
4688
  if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
4623
4689
  warnings.push([
4624
4690
  "Extension already has 4 registered commands, WXT's reload command is disabled"
@@ -4628,20 +4694,21 @@ async function generateManifest(entrypoints, buildOutput, config) {
4628
4694
  manifest.commands["wxt:reload-extension"] = {
4629
4695
  description: "Reload the extension during development",
4630
4696
  suggested_key: {
4631
- default: config.dev.reloadCommand
4697
+ default: wxt.config.dev.reloadCommand
4632
4698
  }
4633
4699
  };
4634
4700
  }
4635
4701
  }
4636
4702
  manifest.version = version2;
4637
4703
  manifest.version_name = // Firefox doesn't support version_name
4638
- config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
4639
- addEntrypoints(manifest, entrypoints, buildOutput, config);
4640
- if (config.command === "serve")
4641
- addDevModeCsp(manifest, config);
4642
- if (config.command === "serve")
4643
- addDevModePermissions(manifest, config);
4644
- const finalManifest = (0, import_immer.produce)(manifest, config.transformManifest);
4704
+ wxt.config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
4705
+ addEntrypoints(manifest, entrypoints, buildOutput);
4706
+ if (wxt.config.command === "serve")
4707
+ addDevModeCsp(manifest);
4708
+ if (wxt.config.command === "serve")
4709
+ addDevModePermissions(manifest);
4710
+ const finalManifest = (0, import_immer.produce)(manifest, wxt.config.transformManifest);
4711
+ await wxt.hooks.callHook("build:manifestGenerated", wxt, finalManifest);
4645
4712
  if (finalManifest.name == null)
4646
4713
  throw Error(
4647
4714
  "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"
@@ -4666,7 +4733,7 @@ function simplifyVersion(versionName) {
4666
4733
  );
4667
4734
  return version2;
4668
4735
  }
4669
- function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4736
+ function addEntrypoints(manifest, entrypoints, buildOutput) {
4670
4737
  const entriesByType = entrypoints.reduce((map, entrypoint) => {
4671
4738
  map[entrypoint.type] ??= [];
4672
4739
  map[entrypoint.type]?.push(entrypoint);
@@ -4683,13 +4750,17 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4683
4750
  const sandboxes = entriesByType["sandbox"];
4684
4751
  const sidepanels = entriesByType["sidepanel"];
4685
4752
  if (background) {
4686
- const script = getEntrypointBundlePath(background, config.outDir, ".js");
4687
- if (config.browser === "firefox" && config.manifestVersion === 3) {
4753
+ const script = getEntrypointBundlePath(
4754
+ background,
4755
+ wxt.config.outDir,
4756
+ ".js"
4757
+ );
4758
+ if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) {
4688
4759
  manifest.background = {
4689
4760
  type: background.options.type,
4690
4761
  scripts: [script]
4691
4762
  };
4692
- } else if (config.manifestVersion === 3) {
4763
+ } else if (wxt.config.manifestVersion === 3) {
4693
4764
  manifest.background = {
4694
4765
  type: background.options.type,
4695
4766
  service_worker: script
@@ -4702,29 +4773,29 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4702
4773
  }
4703
4774
  }
4704
4775
  if (bookmarks) {
4705
- if (config.browser === "firefox") {
4706
- config.logger.warn(
4776
+ if (wxt.config.browser === "firefox") {
4777
+ wxt.logger.warn(
4707
4778
  "Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest"
4708
4779
  );
4709
4780
  } else {
4710
4781
  manifest.chrome_url_overrides ??= {};
4711
4782
  manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(
4712
4783
  bookmarks,
4713
- config.outDir,
4784
+ wxt.config.outDir,
4714
4785
  ".html"
4715
4786
  );
4716
4787
  }
4717
4788
  }
4718
4789
  if (history) {
4719
- if (config.browser === "firefox") {
4720
- config.logger.warn(
4790
+ if (wxt.config.browser === "firefox") {
4791
+ wxt.logger.warn(
4721
4792
  "Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest"
4722
4793
  );
4723
4794
  } else {
4724
4795
  manifest.chrome_url_overrides ??= {};
4725
4796
  manifest.chrome_url_overrides.history = getEntrypointBundlePath(
4726
4797
  history,
4727
- config.outDir,
4798
+ wxt.config.outDir,
4728
4799
  ".html"
4729
4800
  );
4730
4801
  }
@@ -4733,14 +4804,14 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4733
4804
  manifest.chrome_url_overrides ??= {};
4734
4805
  manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(
4735
4806
  newtab,
4736
- config.outDir,
4807
+ wxt.config.outDir,
4737
4808
  ".html"
4738
4809
  );
4739
4810
  }
4740
4811
  if (popup) {
4741
4812
  const default_popup = getEntrypointBundlePath(
4742
4813
  popup,
4743
- config.outDir,
4814
+ wxt.config.outDir,
4744
4815
  ".html"
4745
4816
  );
4746
4817
  const options2 = {};
@@ -4768,28 +4839,28 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4768
4839
  if (devtools) {
4769
4840
  manifest.devtools_page = getEntrypointBundlePath(
4770
4841
  devtools,
4771
- config.outDir,
4842
+ wxt.config.outDir,
4772
4843
  ".html"
4773
4844
  );
4774
4845
  }
4775
4846
  if (options) {
4776
- const page = getEntrypointBundlePath(options, config.outDir, ".html");
4847
+ const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
4777
4848
  manifest.options_ui = {
4778
4849
  open_in_tab: options.options.openInTab,
4779
- browser_style: config.browser === "firefox" ? options.options.browserStyle : void 0,
4780
- chrome_style: config.browser !== "firefox" ? options.options.chromeStyle : void 0,
4850
+ browser_style: wxt.config.browser === "firefox" ? options.options.browserStyle : void 0,
4851
+ chrome_style: wxt.config.browser !== "firefox" ? options.options.chromeStyle : void 0,
4781
4852
  page
4782
4853
  };
4783
4854
  }
4784
4855
  if (sandboxes?.length) {
4785
- if (config.browser === "firefox") {
4786
- config.logger.warn(
4856
+ if (wxt.config.browser === "firefox") {
4857
+ wxt.logger.warn(
4787
4858
  "Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
4788
4859
  );
4789
4860
  } else {
4790
4861
  manifest.sandbox = {
4791
4862
  pages: sandboxes.map(
4792
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".html")
4863
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".html")
4793
4864
  )
4794
4865
  };
4795
4866
  }
@@ -4798,33 +4869,33 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4798
4869
  const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
4799
4870
  const page = getEntrypointBundlePath(
4800
4871
  defaultSidepanel,
4801
- config.outDir,
4872
+ wxt.config.outDir,
4802
4873
  ".html"
4803
4874
  );
4804
- if (config.browser === "firefox") {
4875
+ if (wxt.config.browser === "firefox") {
4805
4876
  manifest.sidebar_action = {
4806
4877
  // TODO: Add options to side panel
4807
4878
  // ...defaultSidepanel.options,
4808
4879
  default_panel: page
4809
4880
  };
4810
- } else if (config.manifestVersion === 3) {
4881
+ } else if (wxt.config.manifestVersion === 3) {
4811
4882
  manifest.side_panel = {
4812
4883
  default_path: page
4813
4884
  };
4814
4885
  } else {
4815
- config.logger.warn(
4886
+ wxt.logger.warn(
4816
4887
  "Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
4817
4888
  );
4818
4889
  }
4819
4890
  }
4820
4891
  if (contentScripts?.length) {
4821
4892
  const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
4822
- if (config.command === "serve" && config.manifestVersion === 3) {
4893
+ if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
4823
4894
  const hostPermissions = new Set(manifest.host_permissions ?? []);
4824
4895
  contentScripts.forEach((script) => {
4825
4896
  const matches = resolvePerBrowserOption(
4826
4897
  script.options.matches,
4827
- config.browser
4898
+ wxt.config.browser
4828
4899
  );
4829
4900
  matches.forEach((matchPattern) => {
4830
4901
  hostPermissions.add(matchPattern);
@@ -4835,7 +4906,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4835
4906
  );
4836
4907
  } else {
4837
4908
  const hashToEntrypointsMap = contentScripts.reduce((map, script) => {
4838
- const hash = hashContentScriptOptions(script.options, config);
4909
+ const hash = hashContentScriptOptions(script.options);
4839
4910
  if (map.has(hash))
4840
4911
  map.get(hash)?.push(script);
4841
4912
  else
@@ -4844,10 +4915,10 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4844
4915
  }, /* @__PURE__ */ new Map());
4845
4916
  const newContentScripts = Array.from(hashToEntrypointsMap.entries()).map(
4846
4917
  ([, scripts]) => ({
4847
- ...mapWxtOptionsToContentScript(scripts[0].options, config),
4918
+ ...mapWxtOptionsToContentScript(scripts[0].options),
4848
4919
  css: getContentScriptCssFiles(scripts, cssMap),
4849
4920
  js: scripts.map(
4850
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".js")
4921
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")
4851
4922
  )
4852
4923
  })
4853
4924
  );
@@ -4857,7 +4928,6 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
4857
4928
  }
4858
4929
  }
4859
4930
  const contentScriptCssResources = getContentScriptCssWebAccessibleResources(
4860
- config,
4861
4931
  contentScripts,
4862
4932
  cssMap
4863
4933
  );
@@ -4900,9 +4970,9 @@ function discoverIcons(buildOutput) {
4900
4970
  });
4901
4971
  return icons.length > 0 ? Object.fromEntries(icons) : void 0;
4902
4972
  }
4903
- function addDevModeCsp(manifest, config) {
4904
- const permission = `http://${config.server?.hostname ?? ""}/*`;
4905
- const allowedCsp = config.server?.origin ?? "http://localhost:*";
4973
+ function addDevModeCsp(manifest) {
4974
+ const permission = `http://${wxt.config.server?.hostname ?? ""}/*`;
4975
+ const allowedCsp = wxt.config.server?.origin ?? "http://localhost:*";
4906
4976
  if (manifest.manifest_version === 3) {
4907
4977
  addHostPermission(manifest, permission);
4908
4978
  } else {
@@ -4915,7 +4985,7 @@ function addDevModeCsp(manifest, config) {
4915
4985
  ) : manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"
4916
4986
  // default CSP for MV2
4917
4987
  );
4918
- if (config.server)
4988
+ if (wxt.config.server)
4919
4989
  csp.add("script-src", allowedCsp);
4920
4990
  if (manifest.manifest_version === 3) {
4921
4991
  manifest.content_security_policy ??= {};
@@ -4924,9 +4994,9 @@ function addDevModeCsp(manifest, config) {
4924
4994
  manifest.content_security_policy = csp.toString();
4925
4995
  }
4926
4996
  }
4927
- function addDevModePermissions(manifest, config) {
4997
+ function addDevModePermissions(manifest) {
4928
4998
  addPermission(manifest, "tabs");
4929
- if (config.manifestVersion === 3)
4999
+ if (wxt.config.manifestVersion === 3)
4930
5000
  addPermission(manifest, "scripting");
4931
5001
  }
4932
5002
  function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
@@ -4944,7 +5014,7 @@ function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
4944
5014
  return css;
4945
5015
  return void 0;
4946
5016
  }
4947
- function getContentScriptCssWebAccessibleResources(config, contentScripts, contentScriptCssMap) {
5017
+ function getContentScriptCssWebAccessibleResources(contentScripts, contentScriptCssMap) {
4948
5018
  const resources = [];
4949
5019
  contentScripts.forEach((script) => {
4950
5020
  if (script.options.cssInjectionMode !== "ui")
@@ -4952,14 +5022,14 @@ function getContentScriptCssWebAccessibleResources(config, contentScripts, conte
4952
5022
  const cssFile = contentScriptCssMap[script.name];
4953
5023
  if (cssFile == null)
4954
5024
  return;
4955
- if (config.manifestVersion === 2) {
5025
+ if (wxt.config.manifestVersion === 2) {
4956
5026
  resources.push(cssFile);
4957
5027
  } else {
4958
5028
  resources.push({
4959
5029
  resources: [cssFile],
4960
5030
  matches: resolvePerBrowserOption(
4961
5031
  script.options.matches,
4962
- config.browser
5032
+ wxt.config.browser
4963
5033
  ).map((matchPattern) => stripPathFromMatchPattern(matchPattern))
4964
5034
  });
4965
5035
  }
@@ -4999,28 +5069,28 @@ function stripPathFromMatchPattern(pattern) {
4999
5069
  }
5000
5070
 
5001
5071
  // src/core/utils/building/rebuild.ts
5002
- async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
5072
+ async function rebuild(allEntrypoints, entrypointGroups, existingOutput = {
5003
5073
  steps: [],
5004
5074
  publicAssets: []
5005
5075
  }) {
5006
5076
  const { default: ora } = await import("ora");
5007
5077
  const spinner = ora(`Preparing...`).start();
5008
- await generateTypesDir(allEntrypoints, config).catch((err) => {
5009
- config.logger.warn("Failed to update .wxt directory:", err);
5010
- if (config.command === "build")
5078
+ await generateTypesDir(allEntrypoints).catch((err) => {
5079
+ wxt.logger.warn("Failed to update .wxt directory:", err);
5080
+ if (wxt.config.command === "build")
5011
5081
  throw err;
5012
5082
  });
5013
- const newOutput = await buildEntrypoints(entrypointGroups, config, spinner);
5083
+ const newOutput = await buildEntrypoints(entrypointGroups, spinner);
5014
5084
  const mergedOutput = {
5015
5085
  steps: [...existingOutput.steps, ...newOutput.steps],
5016
5086
  publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
5017
5087
  };
5018
- const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput, config);
5088
+ const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput);
5019
5089
  const finalOutput = {
5020
5090
  manifest: newManifest,
5021
5091
  ...newOutput
5022
5092
  };
5023
- await writeManifest(newManifest, finalOutput, config);
5093
+ await writeManifest(newManifest, finalOutput);
5024
5094
  spinner.clear().stop();
5025
5095
  return {
5026
5096
  output: {
@@ -5105,30 +5175,33 @@ var import_consola3 = __toESM(require("consola"), 1);
5105
5175
  var import_manage_path = __toESM(require("manage-path"), 1);
5106
5176
  var import_node_path13 = require("path");
5107
5177
  var managedPath = (0, import_manage_path.default)(process.env);
5108
- var exec = async (config, file, args, options) => {
5178
+ var exec = async (file, args, options) => {
5109
5179
  managedPath.restore();
5110
- managedPath.push((0, import_node_path13.resolve)(config.root, "node_modules/wxt/node_modules/.bin"));
5180
+ managedPath.push(
5181
+ (0, import_node_path13.resolve)(wxt.config.root, "node_modules/wxt/node_modules/.bin")
5182
+ );
5111
5183
  const { execa: execa2 } = await Promise.resolve().then(() => (init_execa(), execa_exports));
5112
5184
  return await execa2(file, args, options);
5113
5185
  };
5114
5186
 
5115
5187
  // src/core/utils/building/internal-build.ts
5116
- async function internalBuild(config) {
5117
- const verb = config.command === "serve" ? "Pre-rendering" : "Building";
5118
- const target = `${config.browser}-mv${config.manifestVersion}`;
5119
- config.logger.info(
5120
- `${verb} ${import_picocolors5.default.cyan(target)} for ${import_picocolors5.default.cyan(config.mode)} with ${import_picocolors5.default.green(
5121
- `${config.builder.name} ${config.builder.version}`
5188
+ async function internalBuild() {
5189
+ await wxt.hooks.callHook("build:before", wxt);
5190
+ const verb = wxt.config.command === "serve" ? "Pre-rendering" : "Building";
5191
+ const target = `${wxt.config.browser}-mv${wxt.config.manifestVersion}`;
5192
+ wxt.logger.info(
5193
+ `${verb} ${import_picocolors5.default.cyan(target)} for ${import_picocolors5.default.cyan(wxt.config.mode)} with ${import_picocolors5.default.green(
5194
+ `${wxt.config.builder.name} ${wxt.config.builder.version}`
5122
5195
  )}`
5123
5196
  );
5124
5197
  const startTime = Date.now();
5125
- await import_fs_extra12.default.rm(config.outDir, { recursive: true, force: true });
5126
- await import_fs_extra12.default.ensureDir(config.outDir);
5127
- const entrypoints = await findEntrypoints(config);
5128
- config.logger.debug("Detected entrypoints:", entrypoints);
5198
+ await import_fs_extra12.default.rm(wxt.config.outDir, { recursive: true, force: true });
5199
+ await import_fs_extra12.default.ensureDir(wxt.config.outDir);
5200
+ const entrypoints = await findEntrypoints();
5201
+ wxt.logger.debug("Detected entrypoints:", entrypoints);
5129
5202
  const validationResults = validateEntrypoints(entrypoints);
5130
5203
  if (validationResults.errorCount + validationResults.warningCount > 0) {
5131
- printValidationResults(config, validationResults);
5204
+ printValidationResults(validationResults);
5132
5205
  }
5133
5206
  if (validationResults.errorCount > 0) {
5134
5207
  throw new ValidationError(`Entrypoint validation failed`, {
@@ -5136,45 +5209,44 @@ async function internalBuild(config) {
5136
5209
  });
5137
5210
  }
5138
5211
  const groups = groupEntrypoints(entrypoints);
5139
- const { output, warnings } = await rebuild(
5140
- config,
5141
- entrypoints,
5142
- groups,
5143
- void 0
5144
- );
5212
+ await wxt.hooks.callHook("entrypoints:grouped", wxt, groups);
5213
+ const { output, warnings } = await rebuild(entrypoints, groups, void 0);
5214
+ await wxt.hooks.callHook("build:done", wxt, output);
5145
5215
  await printBuildSummary(
5146
- config.logger.success,
5216
+ wxt.logger.success,
5147
5217
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
5148
- output,
5149
- config
5218
+ output
5150
5219
  );
5151
5220
  for (const warning of warnings) {
5152
- config.logger.warn(...warning);
5221
+ wxt.logger.warn(...warning);
5153
5222
  }
5154
- if (config.analysis.enabled) {
5155
- await combineAnalysisStats(config);
5156
- config.logger.info(
5223
+ if (wxt.config.analysis.enabled) {
5224
+ await combineAnalysisStats();
5225
+ wxt.logger.info(
5157
5226
  `Analysis complete:
5158
5227
  ${import_picocolors5.default.gray("\u2514\u2500")} ${import_picocolors5.default.yellow("stats.html")}`
5159
5228
  );
5160
5229
  }
5161
5230
  return output;
5162
5231
  }
5163
- async function combineAnalysisStats(config) {
5232
+ async function combineAnalysisStats() {
5164
5233
  const unixFiles = await (0, import_fast_glob3.default)(`stats-*.json`, {
5165
- cwd: config.outDir,
5234
+ cwd: wxt.config.outDir,
5166
5235
  absolute: true
5167
5236
  });
5168
5237
  const absolutePaths = unixFiles.map(unnormalizePath);
5169
5238
  await exec(
5170
- config,
5171
5239
  "rollup-plugin-visualizer",
5172
- [...absolutePaths, "--template", config.analysis.template],
5173
- { cwd: config.root, stdio: "inherit" }
5240
+ [...absolutePaths, "--template", wxt.config.analysis.template],
5241
+ { cwd: wxt.config.root, stdio: "inherit" }
5174
5242
  );
5175
5243
  }
5176
- function printValidationResults(config, { errorCount, errors, warningCount }) {
5177
- (errorCount > 0 ? config.logger.error : config.logger.warn)(
5244
+ function printValidationResults({
5245
+ errorCount,
5246
+ errors,
5247
+ warningCount
5248
+ }) {
5249
+ (errorCount > 0 ? wxt.logger.error : wxt.logger.warn)(
5178
5250
  `Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
5179
5251
  );
5180
5252
  const cwd = process.cwd();
@@ -5198,8 +5270,8 @@ function printValidationResults(config, { errorCount, errors, warningCount }) {
5198
5270
 
5199
5271
  // src/core/build.ts
5200
5272
  async function build(config) {
5201
- const internalConfig = await getInternalConfig(config ?? {}, "build");
5202
- return await internalBuild(internalConfig);
5273
+ await registerWxt("build", config);
5274
+ return await internalBuild();
5203
5275
  }
5204
5276
 
5205
5277
  // src/core/clean.ts
@@ -5251,11 +5323,11 @@ function defineRunnerConfig(config) {
5251
5323
  var import_node_path16 = require("path");
5252
5324
  function createWslRunner() {
5253
5325
  return {
5254
- async openBrowser(config) {
5255
- config.logger.warn(
5326
+ async openBrowser() {
5327
+ wxt.logger.warn(
5256
5328
  `Cannot open browser when using WSL. Load "${(0, import_node_path16.relative)(
5257
5329
  process.cwd(),
5258
- config.outDir
5330
+ wxt.config.outDir
5259
5331
  )}" as an unpacked extension manually`
5260
5332
  );
5261
5333
  },
@@ -5269,9 +5341,9 @@ var import_defu4 = __toESM(require("defu"), 1);
5269
5341
  function createWebExtRunner() {
5270
5342
  let runner;
5271
5343
  return {
5272
- async openBrowser(config) {
5344
+ async openBrowser() {
5273
5345
  const startTime = Date.now();
5274
- if (config.browser === "firefox" && config.manifestVersion === 3) {
5346
+ if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) {
5275
5347
  throw Error(
5276
5348
  "Dev mode does not support Firefox MV3. For alternatives, see https://github.com/wxt-dev/wxt/issues/230#issuecomment-1806881653"
5277
5349
  );
@@ -5279,22 +5351,22 @@ function createWebExtRunner() {
5279
5351
  const webExtLogger = await import("web-ext-run/util/logger");
5280
5352
  webExtLogger.consoleStream.write = ({ level, msg, name }) => {
5281
5353
  if (level >= ERROR_LOG_LEVEL)
5282
- config.logger.error(name, msg);
5354
+ wxt.logger.error(name, msg);
5283
5355
  if (level >= WARN_LOG_LEVEL)
5284
- config.logger.warn(msg);
5356
+ wxt.logger.warn(msg);
5285
5357
  };
5286
- const wxtUserConfig = config.runnerConfig.config;
5358
+ const wxtUserConfig = wxt.config.runnerConfig.config;
5287
5359
  const userConfig = {
5288
5360
  console: wxtUserConfig?.openConsole,
5289
5361
  devtools: wxtUserConfig?.openDevtools,
5290
5362
  startUrl: wxtUserConfig?.startUrls,
5291
- ...config.browser === "firefox" ? {
5363
+ ...wxt.config.browser === "firefox" ? {
5292
5364
  firefox: wxtUserConfig?.binaries?.firefox,
5293
5365
  firefoxProfile: wxtUserConfig?.firefoxProfile,
5294
5366
  prefs: wxtUserConfig?.firefoxPrefs,
5295
5367
  args: wxtUserConfig?.firefoxArgs
5296
5368
  } : {
5297
- chromiumBinary: wxtUserConfig?.binaries?.[config.browser],
5369
+ chromiumBinary: wxtUserConfig?.binaries?.[wxt.config.browser],
5298
5370
  chromiumProfile: wxtUserConfig?.chromiumProfile,
5299
5371
  chromiumPref: (0, import_defu4.default)(
5300
5372
  wxtUserConfig?.chromiumPref,
@@ -5305,8 +5377,8 @@ function createWebExtRunner() {
5305
5377
  };
5306
5378
  const finalConfig = {
5307
5379
  ...userConfig,
5308
- target: config.browser === "firefox" ? "firefox-desktop" : "chromium",
5309
- sourceDir: config.outDir,
5380
+ target: wxt.config.browser === "firefox" ? "firefox-desktop" : "chromium",
5381
+ sourceDir: wxt.config.outDir,
5310
5382
  // WXT handles reloads, so disable auto-reload behaviors in web-ext
5311
5383
  noReload: true,
5312
5384
  noInput: true
@@ -5315,12 +5387,12 @@ function createWebExtRunner() {
5315
5387
  // Don't call `process.exit(0)` after starting web-ext
5316
5388
  shouldExitProgram: false
5317
5389
  };
5318
- config.logger.debug("web-ext config:", finalConfig);
5319
- config.logger.debug("web-ext options:", options);
5390
+ wxt.logger.debug("web-ext config:", finalConfig);
5391
+ wxt.logger.debug("web-ext options:", options);
5320
5392
  const webExt = await import("web-ext-run");
5321
5393
  runner = await webExt.default.cmd.run(finalConfig, options);
5322
5394
  const duration = Date.now() - startTime;
5323
- config.logger.success(`Opened browser in ${formatDuration(duration)}`);
5395
+ wxt.logger.success(`Opened browser in ${formatDuration(duration)}`);
5324
5396
  },
5325
5397
  async closeBrowser() {
5326
5398
  return await runner?.exit();
@@ -5344,11 +5416,11 @@ var DEFAULT_CHROMIUM_PREFS = {
5344
5416
  var import_node_path17 = require("path");
5345
5417
  function createSafariRunner() {
5346
5418
  return {
5347
- async openBrowser(config) {
5348
- config.logger.warn(
5419
+ async openBrowser() {
5420
+ wxt.logger.warn(
5349
5421
  `Cannot Safari using web-ext. Load "${(0, import_node_path17.relative)(
5350
5422
  process.cwd(),
5351
- config.outDir
5423
+ wxt.config.outDir
5352
5424
  )}" as an unpacked extension manually`
5353
5425
  );
5354
5426
  },
@@ -5361,11 +5433,11 @@ function createSafariRunner() {
5361
5433
  var import_node_path18 = require("path");
5362
5434
  function createManualRunner() {
5363
5435
  return {
5364
- async openBrowser(config) {
5365
- config.logger.info(
5436
+ async openBrowser() {
5437
+ wxt.logger.info(
5366
5438
  `Load "${(0, import_node_path18.relative)(
5367
5439
  process.cwd(),
5368
- config.outDir
5440
+ wxt.config.outDir
5369
5441
  )}" as an unpacked extension manually`
5370
5442
  );
5371
5443
  },
@@ -5381,12 +5453,12 @@ async function isWsl() {
5381
5453
  }
5382
5454
 
5383
5455
  // src/core/runners/index.ts
5384
- async function createExtensionRunner(config) {
5385
- if (config.browser === "safari")
5456
+ async function createExtensionRunner() {
5457
+ if (wxt.config.browser === "safari")
5386
5458
  return createSafariRunner();
5387
5459
  if (await isWsl())
5388
5460
  return createWslRunner();
5389
- if (config.runnerConfig.config?.disabled)
5461
+ if (wxt.config.runnerConfig.config?.disabled)
5390
5462
  return createManualRunner();
5391
5463
  return createWebExtRunner();
5392
5464
  }
@@ -5406,13 +5478,13 @@ async function createServer(inlineConfig) {
5406
5478
  origin
5407
5479
  };
5408
5480
  const buildAndOpenBrowser = async () => {
5409
- server.currentOutput = await internalBuild(config);
5410
- await runner.openBrowser(config);
5481
+ server.currentOutput = await internalBuild();
5482
+ await runner.openBrowser();
5411
5483
  };
5412
5484
  const closeAndRecreateRunner = async () => {
5413
5485
  await runner.closeBrowser();
5414
- config = await getLatestConfig();
5415
- runner = await createExtensionRunner(config);
5486
+ await wxt.reloadConfig();
5487
+ runner = await createExtensionRunner();
5416
5488
  };
5417
5489
  const server = {
5418
5490
  ...serverInfo,
@@ -5425,7 +5497,7 @@ async function createServer(inlineConfig) {
5425
5497
  currentOutput: void 0,
5426
5498
  async start() {
5427
5499
  await builderServer.listen();
5428
- config.logger.success(`Started dev server @ ${serverInfo.origin}`);
5500
+ wxt.logger.success(`Started dev server @ ${serverInfo.origin}`);
5429
5501
  await buildAndOpenBrowser();
5430
5502
  },
5431
5503
  async stop() {
@@ -5450,27 +5522,20 @@ async function createServer(inlineConfig) {
5450
5522
  },
5451
5523
  async restartBrowser() {
5452
5524
  await closeAndRecreateRunner();
5453
- await runner.openBrowser(config);
5525
+ await runner.openBrowser();
5454
5526
  }
5455
5527
  };
5456
- const getLatestConfig = () => getInternalConfig(inlineConfig ?? {}, "serve", server);
5457
- let config = await getLatestConfig();
5528
+ await registerWxt("serve", inlineConfig, server);
5458
5529
  let [runner, builderServer] = await Promise.all([
5459
- createExtensionRunner(config),
5460
- config.builder.createServer(server)
5530
+ createExtensionRunner(),
5531
+ wxt.config.builder.createServer(server)
5461
5532
  ]);
5462
5533
  server.ws.on("wxt:background-initialized", () => {
5463
5534
  if (server.currentOutput == null)
5464
5535
  return;
5465
- reloadContentScripts(server.currentOutput.steps, config, server);
5466
- });
5467
- const reloadOnChange = createFileReloader({
5468
- server,
5469
- getLatestConfig,
5470
- updateConfig(newConfig) {
5471
- config = newConfig;
5472
- }
5536
+ reloadContentScripts(server.currentOutput.steps, server);
5473
5537
  });
5538
+ const reloadOnChange = createFileReloader(server);
5474
5539
  server.watcher.on("all", reloadOnChange);
5475
5540
  return server;
5476
5541
  }
@@ -5478,14 +5543,12 @@ async function getPort() {
5478
5543
  const { default: getPort2, portNumbers } = await import("get-port");
5479
5544
  return await getPort2({ port: portNumbers(3e3, 3010) });
5480
5545
  }
5481
- function createFileReloader(options) {
5482
- const { server, getLatestConfig, updateConfig } = options;
5546
+ function createFileReloader(server) {
5483
5547
  const fileChangedMutex = new import_async_mutex.Mutex();
5484
5548
  const changeQueue = [];
5485
5549
  return async (event, path10) => {
5486
- const config = await getLatestConfig();
5487
- updateConfig(config);
5488
- if (path10.startsWith(config.outBaseDir))
5550
+ await wxt.reloadConfig();
5551
+ if (path10.startsWith(wxt.config.outBaseDir))
5489
5552
  return;
5490
5553
  changeQueue.push([event, path10]);
5491
5554
  await fileChangedMutex.runExclusive(async () => {
@@ -5494,29 +5557,24 @@ function createFileReloader(options) {
5494
5557
  const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
5495
5558
  if (fileChanges.length === 0)
5496
5559
  return;
5497
- const changes = detectDevChanges(
5498
- config,
5499
- fileChanges,
5500
- server.currentOutput
5501
- );
5560
+ const changes = detectDevChanges(fileChanges, server.currentOutput);
5502
5561
  if (changes.type === "no-change")
5503
5562
  return;
5504
5563
  if (changes.type === "full-restart") {
5505
- config.logger.info("Config changed, restarting server...");
5564
+ wxt.logger.info("Config changed, restarting server...");
5506
5565
  server.restart();
5507
5566
  return;
5508
5567
  }
5509
5568
  if (changes.type === "browser-restart") {
5510
- config.logger.info("Runner config changed, restarting browser...");
5569
+ wxt.logger.info("Runner config changed, restarting browser...");
5511
5570
  server.restartBrowser();
5512
5571
  return;
5513
5572
  }
5514
- config.logger.info(
5515
- `Changed: ${Array.from(new Set(fileChanges)).map((file) => import_picocolors7.default.dim((0, import_node_path19.relative)(config.root, file))).join(", ")}`
5573
+ wxt.logger.info(
5574
+ `Changed: ${Array.from(new Set(fileChanges)).map((file) => import_picocolors7.default.dim((0, import_node_path19.relative)(wxt.config.root, file))).join(", ")}`
5516
5575
  );
5517
- const allEntrypoints = await findEntrypoints(config);
5576
+ const allEntrypoints = await findEntrypoints();
5518
5577
  const { output: newOutput } = await rebuild(
5519
- config,
5520
5578
  allEntrypoints,
5521
5579
  // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
5522
5580
  changes.rebuildGroups,
@@ -5531,13 +5589,12 @@ function createFileReloader(options) {
5531
5589
  case "html-reload":
5532
5590
  const { reloadedNames } = reloadHtmlPages(
5533
5591
  changes.rebuildGroups,
5534
- server,
5535
- config
5592
+ server
5536
5593
  );
5537
5594
  import_consola5.consola.success(`Reloaded: ${getFilenameList(reloadedNames)}`);
5538
5595
  break;
5539
5596
  case "content-script-reload":
5540
- reloadContentScripts(changes.changedSteps, config, server);
5597
+ reloadContentScripts(changes.changedSteps, server);
5541
5598
  const rebuiltNames = changes.rebuildGroups.flat().map((entry) => entry.name);
5542
5599
  import_consola5.consola.success(`Reloaded: ${getFilenameList(rebuiltNames)}`);
5543
5600
  break;
@@ -5545,30 +5602,33 @@ function createFileReloader(options) {
5545
5602
  });
5546
5603
  };
5547
5604
  }
5548
- function reloadContentScripts(steps, config, server) {
5549
- if (config.manifestVersion === 3) {
5605
+ function reloadContentScripts(steps, server) {
5606
+ if (wxt.config.manifestVersion === 3) {
5550
5607
  steps.forEach((step) => {
5551
5608
  if (server.currentOutput == null)
5552
5609
  return;
5553
5610
  const entry = step.entrypoints;
5554
5611
  if (Array.isArray(entry) || entry.type !== "content-script")
5555
5612
  return;
5556
- const js = [getEntrypointBundlePath(entry, config.outDir, ".js")];
5613
+ const js = [getEntrypointBundlePath(entry, wxt.config.outDir, ".js")];
5557
5614
  const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
5558
5615
  const css = getContentScriptCssFiles([entry], cssMap);
5559
5616
  server.reloadContentScript({
5560
5617
  allFrames: resolvePerBrowserOption(
5561
5618
  entry.options.allFrames,
5562
- config.browser
5619
+ wxt.config.browser
5563
5620
  ),
5564
5621
  excludeMatches: resolvePerBrowserOption(
5565
5622
  entry.options.excludeMatches,
5566
- config.browser
5623
+ wxt.config.browser
5624
+ ),
5625
+ matches: resolvePerBrowserOption(
5626
+ entry.options.matches,
5627
+ wxt.config.browser
5567
5628
  ),
5568
- matches: resolvePerBrowserOption(entry.options.matches, config.browser),
5569
- runAt: resolvePerBrowserOption(entry.options.runAt, config.browser),
5629
+ runAt: resolvePerBrowserOption(entry.options.runAt, wxt.config.browser),
5570
5630
  // @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript)
5571
- world: resolvePerBrowserOption(entry.options.world, config.browser),
5631
+ world: resolvePerBrowserOption(entry.options.world, wxt.config.browser),
5572
5632
  js,
5573
5633
  css
5574
5634
  });
@@ -5577,10 +5637,10 @@ function reloadContentScripts(steps, config, server) {
5577
5637
  server.reloadExtension();
5578
5638
  }
5579
5639
  }
5580
- function reloadHtmlPages(groups, server, config) {
5640
+ function reloadHtmlPages(groups, server) {
5581
5641
  const htmlEntries = groups.flat().filter((entry) => entry.inputPath.endsWith(".html"));
5582
5642
  htmlEntries.forEach((entry) => {
5583
- const path10 = getEntrypointBundlePath(entry, config.outDir, ".html");
5643
+ const path10 = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
5584
5644
  server.reloadPage(path10);
5585
5645
  });
5586
5646
  return {
@@ -5661,19 +5721,11 @@ async function initialize(options) {
5661
5721
  }
5662
5722
  async function listTemplates() {
5663
5723
  try {
5664
- const res = await fetch(
5665
- "https://api.github.com/repos/wxt-dev/wxt/contents/templates",
5666
- {
5667
- headers: {
5668
- Accept: "application/vnd.github+json",
5669
- "X-GitHub-Api-Version": "2022-11-28"
5670
- }
5671
- }
5672
- );
5724
+ const res = await fetch("https://ungh.cc/repos/wxt-dev/wxt/files/main");
5673
5725
  if (res.status >= 300)
5674
5726
  throw Error(`Request failed with status ${res.status} ${res.statusText}`);
5675
5727
  const data = await res.json();
5676
- return data.filter((item) => item.type === "dir").map((item) => ({ name: item.name, path: item.path })).sort((l, r) => {
5728
+ 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) => {
5677
5729
  const lWeight = TEMPLATE_SORT_WEIGHT[l.name] ?? Number.MAX_SAFE_INTEGER;
5678
5730
  const rWeight = TEMPLATE_SORT_WEIGHT[r.name] ?? Number.MAX_SAFE_INTEGER;
5679
5731
  const diff = lWeight - rWeight;
@@ -5724,10 +5776,10 @@ var TEMPLATE_SORT_WEIGHT = {
5724
5776
 
5725
5777
  // src/core/prepare.ts
5726
5778
  async function prepare(config) {
5727
- const internalConfig = await getInternalConfig(config, "build");
5728
- internalConfig.logger.info("Generating types...");
5729
- const entrypoints = await findEntrypoints(internalConfig);
5730
- await generateTypesDir(entrypoints, internalConfig);
5779
+ await registerWxt("build", config);
5780
+ wxt.logger.info("Generating types...");
5781
+ const entrypoints = await findEntrypoints();
5782
+ await generateTypesDir(entrypoints);
5731
5783
  }
5732
5784
 
5733
5785
  // src/core/zip.ts
@@ -5736,40 +5788,35 @@ var import_node_path21 = require("path");
5736
5788
  var import_fs_extra15 = __toESM(require("fs-extra"), 1);
5737
5789
  var import_minimatch2 = require("minimatch");
5738
5790
  async function zip(config) {
5739
- const internalConfig = await getInternalConfig(config ?? {}, "build");
5740
- const output = await internalBuild(internalConfig);
5791
+ await registerWxt("build", config);
5792
+ const output = await internalBuild();
5741
5793
  const start = Date.now();
5742
- internalConfig.logger.info("Zipping extension...");
5794
+ wxt.logger.info("Zipping extension...");
5743
5795
  const zipFiles = [];
5744
- const projectName = internalConfig.zip.name ?? kebabCaseAlphanumeric(
5745
- (await getPackageJson(internalConfig))?.name || (0, import_node_path21.dirname)(process.cwd())
5796
+ const projectName = wxt.config.zip.name ?? kebabCaseAlphanumeric(
5797
+ (await getPackageJson())?.name || (0, import_node_path21.dirname)(process.cwd())
5746
5798
  );
5747
- const applyTemplate = (template) => template.replaceAll("{{name}}", projectName).replaceAll("{{browser}}", internalConfig.browser).replaceAll(
5799
+ const applyTemplate = (template) => template.replaceAll("{{name}}", projectName).replaceAll("{{browser}}", wxt.config.browser).replaceAll(
5748
5800
  "{{version}}",
5749
5801
  output.manifest.version_name ?? output.manifest.version
5750
- ).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
5751
- await import_fs_extra15.default.ensureDir(internalConfig.outBaseDir);
5752
- const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
5753
- const outZipPath = (0, import_node_path21.resolve)(internalConfig.outBaseDir, outZipFilename);
5754
- await (0, import_zip_dir.default)(internalConfig.outDir, {
5802
+ ).replaceAll("{{manifestVersion}}", `mv${wxt.config.manifestVersion}`);
5803
+ await import_fs_extra15.default.ensureDir(wxt.config.outBaseDir);
5804
+ const outZipFilename = applyTemplate(wxt.config.zip.artifactTemplate);
5805
+ const outZipPath = (0, import_node_path21.resolve)(wxt.config.outBaseDir, outZipFilename);
5806
+ await (0, import_zip_dir.default)(wxt.config.outDir, {
5755
5807
  saveTo: outZipPath
5756
5808
  });
5757
5809
  zipFiles.push(outZipPath);
5758
- if (internalConfig.browser === "firefox") {
5759
- const sourcesZipFilename = applyTemplate(
5760
- internalConfig.zip.sourcesTemplate
5761
- );
5762
- const sourcesZipPath = (0, import_node_path21.resolve)(
5763
- internalConfig.outBaseDir,
5764
- sourcesZipFilename
5765
- );
5766
- await (0, import_zip_dir.default)(internalConfig.zip.sourcesRoot, {
5810
+ if (wxt.config.browser === "firefox") {
5811
+ const sourcesZipFilename = applyTemplate(wxt.config.zip.sourcesTemplate);
5812
+ const sourcesZipPath = (0, import_node_path21.resolve)(wxt.config.outBaseDir, sourcesZipFilename);
5813
+ await (0, import_zip_dir.default)(wxt.config.zip.sourcesRoot, {
5767
5814
  saveTo: sourcesZipPath,
5768
5815
  filter(path10) {
5769
- const relativePath = (0, import_node_path21.relative)(internalConfig.zip.sourcesRoot, path10);
5770
- return internalConfig.zip.includeSources.some(
5816
+ const relativePath = (0, import_node_path21.relative)(wxt.config.zip.sourcesRoot, path10);
5817
+ return wxt.config.zip.includeSources.some(
5771
5818
  (pattern) => (0, import_minimatch2.minimatch)(relativePath, pattern)
5772
- ) || !internalConfig.zip.excludeSources.some(
5819
+ ) || !wxt.config.zip.excludeSources.some(
5773
5820
  (pattern) => (0, import_minimatch2.minimatch)(relativePath, pattern)
5774
5821
  );
5775
5822
  }
@@ -5777,9 +5824,9 @@ async function zip(config) {
5777
5824
  zipFiles.push(sourcesZipPath);
5778
5825
  }
5779
5826
  await printFileList(
5780
- internalConfig.logger.success,
5827
+ wxt.logger.success,
5781
5828
  `Zipped extension in ${formatDuration(Date.now() - start)}`,
5782
- internalConfig.outBaseDir,
5829
+ wxt.config.outBaseDir,
5783
5830
  zipFiles
5784
5831
  );
5785
5832
  return zipFiles;