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/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
@@ -1365,6 +1407,21 @@ function entrypointGroupGlobals(entrypointGroup) {
1365
1407
  };
1366
1408
  }
1367
1409
 
1410
+ // src/core/builders/vite/plugins/defineImportMeta.ts
1411
+ function defineImportMeta() {
1412
+ return {
1413
+ name: "wxt:define",
1414
+ config() {
1415
+ return {
1416
+ define: {
1417
+ // This works for all extension contexts, including background service worker
1418
+ "import.meta.url": "self.location.href"
1419
+ }
1420
+ };
1421
+ }
1422
+ };
1423
+ }
1424
+
1368
1425
  // src/core/builders/vite/index.ts
1369
1426
  async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
1370
1427
  const vite = await import("vite");
@@ -1401,7 +1458,8 @@ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
1401
1458
  tsconfigPaths(wxtConfig),
1402
1459
  noopBackground(),
1403
1460
  globals(wxtConfig),
1404
- excludeBrowserPolyfill(wxtConfig)
1461
+ excludeBrowserPolyfill(wxtConfig),
1462
+ defineImportMeta()
1405
1463
  );
1406
1464
  if (wxtConfig.analysis.enabled) {
1407
1465
  config.plugins.push(bundleAnalysis());
@@ -1579,9 +1637,9 @@ function getRollupEntry(entrypoint) {
1579
1637
  return virtualEntrypointType ? `virtual:wxt-${virtualEntrypointType}?${entrypoint.inputPath}` : entrypoint.inputPath;
1580
1638
  }
1581
1639
 
1582
- // src/core/utils/building/get-internal-config.ts
1640
+ // src/core/utils/building/resolve-config.ts
1583
1641
  import defu2 from "defu";
1584
- async function getInternalConfig(inlineConfig, command, server) {
1642
+ async function resolveConfig(inlineConfig, command, server) {
1585
1643
  let userConfig = {};
1586
1644
  let userConfigMetadata;
1587
1645
  if (inlineConfig.configFile !== false) {
@@ -1675,7 +1733,8 @@ async function getInternalConfig(inlineConfig, command, server) {
1675
1733
  server,
1676
1734
  dev: {
1677
1735
  reloadCommand
1678
- }
1736
+ },
1737
+ hooks: mergedConfig.hooks ?? {}
1679
1738
  };
1680
1739
  const builder = await createViteBuilder(
1681
1740
  inlineConfig,
@@ -1712,6 +1771,10 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1712
1771
  inlineConfig.zip ?? {},
1713
1772
  userConfig.zip ?? {}
1714
1773
  );
1774
+ const hooks = defu2(
1775
+ inlineConfig.hooks ?? {},
1776
+ userConfig.hooks ?? {}
1777
+ );
1715
1778
  return {
1716
1779
  root: inlineConfig.root ?? userConfig.root,
1717
1780
  browser: inlineConfig.browser ?? userConfig.browser,
@@ -1746,7 +1809,8 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1746
1809
  dev: {
1747
1810
  ...userConfig.dev,
1748
1811
  ...inlineConfig.dev
1749
- }
1812
+ },
1813
+ hooks
1750
1814
  };
1751
1815
  }
1752
1816
  function resolveInternalZipConfig(root, mergedConfig) {
@@ -1837,11 +1901,11 @@ ${noImports}`;
1837
1901
  // src/core/utils/building/import-entrypoint.ts
1838
1902
  import { transformSync } from "esbuild";
1839
1903
  import { fileURLToPath } from "node:url";
1840
- async function importEntrypointFile(path7, config) {
1841
- config.logger.debug("Loading file metadata:", path7);
1904
+ async function importEntrypointFile(path7) {
1905
+ wxt.logger.debug("Loading file metadata:", path7);
1842
1906
  const normalPath = normalizePath(path7);
1843
1907
  const unimport2 = createUnimport3({
1844
- ...getUnimportOptions(config),
1908
+ ...getUnimportOptions(wxt.config),
1845
1909
  // Only allow specific imports, not all from the project
1846
1910
  dirs: []
1847
1911
  });
@@ -1849,18 +1913,18 @@ async function importEntrypointFile(path7, config) {
1849
1913
  const text = await fs8.readFile(path7, "utf-8");
1850
1914
  const textNoImports = removeProjectImportStatements(text);
1851
1915
  const { code } = await unimport2.injectImports(textNoImports);
1852
- config.logger.debug(
1916
+ wxt.logger.debug(
1853
1917
  ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
1854
1918
  );
1855
1919
  const jiti = createJITI(
1856
1920
  typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url),
1857
1921
  {
1858
1922
  cache: false,
1859
- debug: config.debug,
1923
+ debug: wxt.config.debug,
1860
1924
  esmResolve: true,
1861
1925
  alias: {
1862
1926
  "webextension-polyfill": resolve9(
1863
- config.root,
1927
+ wxt.config.root,
1864
1928
  "node_modules/wxt/dist/virtual/mock-browser.js"
1865
1929
  )
1866
1930
  },
@@ -1892,7 +1956,7 @@ async function importEntrypointFile(path7, config) {
1892
1956
  const res = await jiti(path7);
1893
1957
  return res.default;
1894
1958
  } catch (err) {
1895
- const filePath = relative5(config.root, path7);
1959
+ const filePath = relative5(wxt.config.root, path7);
1896
1960
  if (err instanceof ReferenceError) {
1897
1961
  const variableName = err.message.replace(" is not defined", "");
1898
1962
  throw Error(
@@ -1900,7 +1964,7 @@ async function importEntrypointFile(path7, config) {
1900
1964
  { cause: err }
1901
1965
  );
1902
1966
  } else {
1903
- config.logger.error(err);
1967
+ wxt.logger.error(err);
1904
1968
  throw Error(`Failed to load entrypoint: ${filePath}`, { cause: err });
1905
1969
  }
1906
1970
  }
@@ -1994,7 +2058,7 @@ function getChunkColor(filename) {
1994
2058
  }
1995
2059
 
1996
2060
  // src/core/utils/log/printBuildSummary.ts
1997
- async function printBuildSummary(log, header, output, config) {
2061
+ async function printBuildSummary(log, header, output) {
1998
2062
  const chunks = [
1999
2063
  ...output.steps.flatMap((step) => step.chunks),
2000
2064
  ...output.publicAssets
@@ -2006,8 +2070,10 @@ async function printBuildSummary(log, header, output, config) {
2006
2070
  return diff;
2007
2071
  return l.fileName.localeCompare(r.fileName);
2008
2072
  });
2009
- const files = chunks.map((chunk) => resolve10(config.outDir, chunk.fileName));
2010
- 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);
2011
2077
  }
2012
2078
  var DEFAULT_SORT_WEIGHT = 100;
2013
2079
  var CHUNK_SORT_WEIGHTS = {
@@ -2027,7 +2093,7 @@ function getChunkSortWeight(filename) {
2027
2093
  import pc4 from "picocolors";
2028
2094
 
2029
2095
  // package.json
2030
- var version = "0.16.1";
2096
+ var version = "0.16.3";
2031
2097
 
2032
2098
  // src/core/utils/log/printHeader.ts
2033
2099
  import { consola as consola2 } from "consola";
@@ -2087,8 +2153,8 @@ var ContentSecurityPolicy = class _ContentSecurityPolicy {
2087
2153
  };
2088
2154
 
2089
2155
  // src/core/utils/content-scripts.ts
2090
- function hashContentScriptOptions(options, config) {
2091
- const simplifiedOptions = mapWxtOptionsToContentScript(options, config);
2156
+ function hashContentScriptOptions(options) {
2157
+ const simplifiedOptions = mapWxtOptionsToContentScript(options);
2092
2158
  Object.keys(simplifiedOptions).forEach((key) => {
2093
2159
  if (simplifiedOptions[key] == null)
2094
2160
  delete simplifiedOptions[key];
@@ -2114,31 +2180,31 @@ function hashContentScriptOptions(options, config) {
2114
2180
  }).sort((l, r) => l[0].localeCompare(r[0]))
2115
2181
  );
2116
2182
  }
2117
- function mapWxtOptionsToContentScript(options, config) {
2183
+ function mapWxtOptionsToContentScript(options) {
2118
2184
  return {
2119
- matches: resolvePerBrowserOption(options.matches, config.browser),
2120
- all_frames: resolvePerBrowserOption(options.allFrames, config.browser),
2185
+ matches: resolvePerBrowserOption(options.matches, wxt.config.browser),
2186
+ all_frames: resolvePerBrowserOption(options.allFrames, wxt.config.browser),
2121
2187
  match_about_blank: resolvePerBrowserOption(
2122
2188
  options.matchAboutBlank,
2123
- config.browser
2189
+ wxt.config.browser
2124
2190
  ),
2125
2191
  exclude_globs: resolvePerBrowserOption(
2126
2192
  options.excludeGlobs,
2127
- config.browser
2193
+ wxt.config.browser
2128
2194
  ),
2129
2195
  exclude_matches: resolvePerBrowserOption(
2130
2196
  options.excludeMatches,
2131
- config.browser
2197
+ wxt.config.browser
2132
2198
  ),
2133
2199
  include_globs: resolvePerBrowserOption(
2134
2200
  options.includeGlobs,
2135
- config.browser
2201
+ wxt.config.browser
2136
2202
  ),
2137
- run_at: resolvePerBrowserOption(options.runAt, config.browser),
2203
+ run_at: resolvePerBrowserOption(options.runAt, wxt.config.browser),
2138
2204
  // @ts-expect-error: untyped chrome options
2139
2205
  match_origin_as_fallback: resolvePerBrowserOption(
2140
2206
  options.matchOriginAsFallback,
2141
- config.browser
2207
+ wxt.config.browser
2142
2208
  ),
2143
2209
  world: options.world
2144
2210
  };
@@ -2147,12 +2213,12 @@ function mapWxtOptionsToContentScript(options, config) {
2147
2213
  // src/core/utils/package.ts
2148
2214
  import { resolve as resolve11 } from "node:path";
2149
2215
  import fs10 from "fs-extra";
2150
- async function getPackageJson(config) {
2151
- const file = resolve11(config.root, "package.json");
2216
+ async function getPackageJson() {
2217
+ const file = resolve11(wxt.config.root, "package.json");
2152
2218
  try {
2153
2219
  return await fs10.readJson(file);
2154
2220
  } catch (err) {
2155
- config.logger.debug(
2221
+ wxt.logger.debug(
2156
2222
  `Failed to read package.json at: ${file}. Returning undefined.`
2157
2223
  );
2158
2224
  return {};
@@ -2162,40 +2228,40 @@ async function getPackageJson(config) {
2162
2228
  // src/core/utils/manifest.ts
2163
2229
  import { produce } from "immer";
2164
2230
  import defu3 from "defu";
2165
- async function writeManifest(manifest, output, config) {
2166
- const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2167
- await fs11.ensureDir(config.outDir);
2168
- 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);
2169
2235
  output.publicAssets.unshift({
2170
2236
  type: "asset",
2171
2237
  fileName: "manifest.json"
2172
2238
  });
2173
2239
  }
2174
- async function generateManifest(entrypoints, buildOutput, config) {
2240
+ async function generateManifest(entrypoints, buildOutput) {
2175
2241
  const warnings = [];
2176
- const pkg = await getPackageJson(config);
2177
- 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;
2178
2244
  if (versionName == null) {
2179
2245
  versionName = "0.0.0";
2180
- config.logger.warn(
2246
+ wxt.logger.warn(
2181
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'
2182
2248
  );
2183
2249
  }
2184
- const version2 = config.manifest.version ?? simplifyVersion(versionName);
2250
+ const version2 = wxt.config.manifest.version ?? simplifyVersion(versionName);
2185
2251
  const baseManifest = {
2186
- manifest_version: config.manifestVersion,
2252
+ manifest_version: wxt.config.manifestVersion,
2187
2253
  name: pkg?.name,
2188
2254
  description: pkg?.description,
2189
2255
  version: version2,
2190
2256
  short_name: pkg?.shortName,
2191
2257
  icons: discoverIcons(buildOutput)
2192
2258
  };
2193
- const userManifest = config.manifest;
2259
+ const userManifest = wxt.config.manifest;
2194
2260
  const manifest = defu3(
2195
2261
  userManifest,
2196
2262
  baseManifest
2197
2263
  );
2198
- if (config.command === "serve" && config.dev.reloadCommand) {
2264
+ if (wxt.config.command === "serve" && wxt.config.dev.reloadCommand) {
2199
2265
  if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
2200
2266
  warnings.push([
2201
2267
  "Extension already has 4 registered commands, WXT's reload command is disabled"
@@ -2205,20 +2271,21 @@ async function generateManifest(entrypoints, buildOutput, config) {
2205
2271
  manifest.commands["wxt:reload-extension"] = {
2206
2272
  description: "Reload the extension during development",
2207
2273
  suggested_key: {
2208
- default: config.dev.reloadCommand
2274
+ default: wxt.config.dev.reloadCommand
2209
2275
  }
2210
2276
  };
2211
2277
  }
2212
2278
  }
2213
2279
  manifest.version = version2;
2214
2280
  manifest.version_name = // Firefox doesn't support version_name
2215
- config.browser === "firefox" || versionName === version2 ? void 0 : versionName;
2216
- addEntrypoints(manifest, entrypoints, buildOutput, config);
2217
- if (config.command === "serve")
2218
- addDevModeCsp(manifest, config);
2219
- if (config.command === "serve")
2220
- addDevModePermissions(manifest, config);
2221
- 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);
2222
2289
  if (finalManifest.name == null)
2223
2290
  throw Error(
2224
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"
@@ -2243,7 +2310,7 @@ function simplifyVersion(versionName) {
2243
2310
  );
2244
2311
  return version2;
2245
2312
  }
2246
- function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2313
+ function addEntrypoints(manifest, entrypoints, buildOutput) {
2247
2314
  const entriesByType = entrypoints.reduce((map, entrypoint) => {
2248
2315
  map[entrypoint.type] ??= [];
2249
2316
  map[entrypoint.type]?.push(entrypoint);
@@ -2260,13 +2327,17 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2260
2327
  const sandboxes = entriesByType["sandbox"];
2261
2328
  const sidepanels = entriesByType["sidepanel"];
2262
2329
  if (background) {
2263
- const script = getEntrypointBundlePath(background, config.outDir, ".js");
2264
- 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) {
2265
2336
  manifest.background = {
2266
2337
  type: background.options.type,
2267
2338
  scripts: [script]
2268
2339
  };
2269
- } else if (config.manifestVersion === 3) {
2340
+ } else if (wxt.config.manifestVersion === 3) {
2270
2341
  manifest.background = {
2271
2342
  type: background.options.type,
2272
2343
  service_worker: script
@@ -2279,29 +2350,29 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2279
2350
  }
2280
2351
  }
2281
2352
  if (bookmarks) {
2282
- if (config.browser === "firefox") {
2283
- config.logger.warn(
2353
+ if (wxt.config.browser === "firefox") {
2354
+ wxt.logger.warn(
2284
2355
  "Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest"
2285
2356
  );
2286
2357
  } else {
2287
2358
  manifest.chrome_url_overrides ??= {};
2288
2359
  manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(
2289
2360
  bookmarks,
2290
- config.outDir,
2361
+ wxt.config.outDir,
2291
2362
  ".html"
2292
2363
  );
2293
2364
  }
2294
2365
  }
2295
2366
  if (history) {
2296
- if (config.browser === "firefox") {
2297
- config.logger.warn(
2367
+ if (wxt.config.browser === "firefox") {
2368
+ wxt.logger.warn(
2298
2369
  "Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest"
2299
2370
  );
2300
2371
  } else {
2301
2372
  manifest.chrome_url_overrides ??= {};
2302
2373
  manifest.chrome_url_overrides.history = getEntrypointBundlePath(
2303
2374
  history,
2304
- config.outDir,
2375
+ wxt.config.outDir,
2305
2376
  ".html"
2306
2377
  );
2307
2378
  }
@@ -2310,14 +2381,14 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2310
2381
  manifest.chrome_url_overrides ??= {};
2311
2382
  manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(
2312
2383
  newtab,
2313
- config.outDir,
2384
+ wxt.config.outDir,
2314
2385
  ".html"
2315
2386
  );
2316
2387
  }
2317
2388
  if (popup) {
2318
2389
  const default_popup = getEntrypointBundlePath(
2319
2390
  popup,
2320
- config.outDir,
2391
+ wxt.config.outDir,
2321
2392
  ".html"
2322
2393
  );
2323
2394
  const options2 = {};
@@ -2345,28 +2416,28 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2345
2416
  if (devtools) {
2346
2417
  manifest.devtools_page = getEntrypointBundlePath(
2347
2418
  devtools,
2348
- config.outDir,
2419
+ wxt.config.outDir,
2349
2420
  ".html"
2350
2421
  );
2351
2422
  }
2352
2423
  if (options) {
2353
- const page = getEntrypointBundlePath(options, config.outDir, ".html");
2424
+ const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
2354
2425
  manifest.options_ui = {
2355
2426
  open_in_tab: options.options.openInTab,
2356
- browser_style: config.browser === "firefox" ? options.options.browserStyle : void 0,
2357
- 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,
2358
2429
  page
2359
2430
  };
2360
2431
  }
2361
2432
  if (sandboxes?.length) {
2362
- if (config.browser === "firefox") {
2363
- config.logger.warn(
2433
+ if (wxt.config.browser === "firefox") {
2434
+ wxt.logger.warn(
2364
2435
  "Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
2365
2436
  );
2366
2437
  } else {
2367
2438
  manifest.sandbox = {
2368
2439
  pages: sandboxes.map(
2369
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".html")
2440
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".html")
2370
2441
  )
2371
2442
  };
2372
2443
  }
@@ -2375,33 +2446,33 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2375
2446
  const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
2376
2447
  const page = getEntrypointBundlePath(
2377
2448
  defaultSidepanel,
2378
- config.outDir,
2449
+ wxt.config.outDir,
2379
2450
  ".html"
2380
2451
  );
2381
- if (config.browser === "firefox") {
2452
+ if (wxt.config.browser === "firefox") {
2382
2453
  manifest.sidebar_action = {
2383
2454
  // TODO: Add options to side panel
2384
2455
  // ...defaultSidepanel.options,
2385
2456
  default_panel: page
2386
2457
  };
2387
- } else if (config.manifestVersion === 3) {
2458
+ } else if (wxt.config.manifestVersion === 3) {
2388
2459
  manifest.side_panel = {
2389
2460
  default_path: page
2390
2461
  };
2391
2462
  } else {
2392
- config.logger.warn(
2463
+ wxt.logger.warn(
2393
2464
  "Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
2394
2465
  );
2395
2466
  }
2396
2467
  }
2397
2468
  if (contentScripts?.length) {
2398
2469
  const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
2399
- if (config.command === "serve" && config.manifestVersion === 3) {
2470
+ if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
2400
2471
  const hostPermissions = new Set(manifest.host_permissions ?? []);
2401
2472
  contentScripts.forEach((script) => {
2402
2473
  const matches = resolvePerBrowserOption(
2403
2474
  script.options.matches,
2404
- config.browser
2475
+ wxt.config.browser
2405
2476
  );
2406
2477
  matches.forEach((matchPattern) => {
2407
2478
  hostPermissions.add(matchPattern);
@@ -2412,7 +2483,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2412
2483
  );
2413
2484
  } else {
2414
2485
  const hashToEntrypointsMap = contentScripts.reduce((map, script) => {
2415
- const hash = hashContentScriptOptions(script.options, config);
2486
+ const hash = hashContentScriptOptions(script.options);
2416
2487
  if (map.has(hash))
2417
2488
  map.get(hash)?.push(script);
2418
2489
  else
@@ -2421,10 +2492,10 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2421
2492
  }, /* @__PURE__ */ new Map());
2422
2493
  const newContentScripts = Array.from(hashToEntrypointsMap.entries()).map(
2423
2494
  ([, scripts]) => ({
2424
- ...mapWxtOptionsToContentScript(scripts[0].options, config),
2495
+ ...mapWxtOptionsToContentScript(scripts[0].options),
2425
2496
  css: getContentScriptCssFiles(scripts, cssMap),
2426
2497
  js: scripts.map(
2427
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".js")
2498
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")
2428
2499
  )
2429
2500
  })
2430
2501
  );
@@ -2434,7 +2505,6 @@ function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2434
2505
  }
2435
2506
  }
2436
2507
  const contentScriptCssResources = getContentScriptCssWebAccessibleResources(
2437
- config,
2438
2508
  contentScripts,
2439
2509
  cssMap
2440
2510
  );
@@ -2477,9 +2547,9 @@ function discoverIcons(buildOutput) {
2477
2547
  });
2478
2548
  return icons.length > 0 ? Object.fromEntries(icons) : void 0;
2479
2549
  }
2480
- function addDevModeCsp(manifest, config) {
2481
- const permission = `http://${config.server?.hostname ?? ""}/*`;
2482
- 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:*";
2483
2553
  if (manifest.manifest_version === 3) {
2484
2554
  addHostPermission(manifest, permission);
2485
2555
  } else {
@@ -2492,7 +2562,7 @@ function addDevModeCsp(manifest, config) {
2492
2562
  ) : manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"
2493
2563
  // default CSP for MV2
2494
2564
  );
2495
- if (config.server)
2565
+ if (wxt.config.server)
2496
2566
  csp.add("script-src", allowedCsp);
2497
2567
  if (manifest.manifest_version === 3) {
2498
2568
  manifest.content_security_policy ??= {};
@@ -2501,9 +2571,9 @@ function addDevModeCsp(manifest, config) {
2501
2571
  manifest.content_security_policy = csp.toString();
2502
2572
  }
2503
2573
  }
2504
- function addDevModePermissions(manifest, config) {
2574
+ function addDevModePermissions(manifest) {
2505
2575
  addPermission(manifest, "tabs");
2506
- if (config.manifestVersion === 3)
2576
+ if (wxt.config.manifestVersion === 3)
2507
2577
  addPermission(manifest, "scripting");
2508
2578
  }
2509
2579
  function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
@@ -2521,7 +2591,7 @@ function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
2521
2591
  return css;
2522
2592
  return void 0;
2523
2593
  }
2524
- function getContentScriptCssWebAccessibleResources(config, contentScripts, contentScriptCssMap) {
2594
+ function getContentScriptCssWebAccessibleResources(contentScripts, contentScriptCssMap) {
2525
2595
  const resources = [];
2526
2596
  contentScripts.forEach((script) => {
2527
2597
  if (script.options.cssInjectionMode !== "ui")
@@ -2529,14 +2599,14 @@ function getContentScriptCssWebAccessibleResources(config, contentScripts, conte
2529
2599
  const cssFile = contentScriptCssMap[script.name];
2530
2600
  if (cssFile == null)
2531
2601
  return;
2532
- if (config.manifestVersion === 2) {
2602
+ if (wxt.config.manifestVersion === 2) {
2533
2603
  resources.push(cssFile);
2534
2604
  } else {
2535
2605
  resources.push({
2536
2606
  resources: [cssFile],
2537
2607
  matches: resolvePerBrowserOption(
2538
2608
  script.options.matches,
2539
- config.browser
2609
+ wxt.config.browser
2540
2610
  ).map((matchPattern) => stripPathFromMatchPattern(matchPattern))
2541
2611
  });
2542
2612
  }
@@ -2576,28 +2646,28 @@ function stripPathFromMatchPattern(pattern) {
2576
2646
  }
2577
2647
 
2578
2648
  // src/core/utils/building/rebuild.ts
2579
- async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
2649
+ async function rebuild(allEntrypoints, entrypointGroups, existingOutput = {
2580
2650
  steps: [],
2581
2651
  publicAssets: []
2582
2652
  }) {
2583
2653
  const { default: ora } = await import("ora");
2584
2654
  const spinner = ora(`Preparing...`).start();
2585
- await generateTypesDir(allEntrypoints, config).catch((err) => {
2586
- config.logger.warn("Failed to update .wxt directory:", err);
2587
- 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")
2588
2658
  throw err;
2589
2659
  });
2590
- const newOutput = await buildEntrypoints(entrypointGroups, config, spinner);
2660
+ const newOutput = await buildEntrypoints(entrypointGroups, spinner);
2591
2661
  const mergedOutput = {
2592
2662
  steps: [...existingOutput.steps, ...newOutput.steps],
2593
2663
  publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
2594
2664
  };
2595
- const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput, config);
2665
+ const { manifest: newManifest, warnings: manifestWarnings } = await generateManifest(allEntrypoints, mergedOutput);
2596
2666
  const finalOutput = {
2597
2667
  manifest: newManifest,
2598
2668
  ...newOutput
2599
2669
  };
2600
- await writeManifest(newManifest, finalOutput, config);
2670
+ await writeManifest(newManifest, finalOutput);
2601
2671
  spinner.clear().stop();
2602
2672
  return {
2603
2673
  output: {
@@ -2682,30 +2752,33 @@ import consola3 from "consola";
2682
2752
  import managePath from "manage-path";
2683
2753
  import { resolve as resolve13 } from "node:path";
2684
2754
  var managedPath = managePath(process.env);
2685
- var exec = async (config, file, args, options) => {
2755
+ var exec = async (file, args, options) => {
2686
2756
  managedPath.restore();
2687
- 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
+ );
2688
2760
  const { execa } = await import("./execa-Y2EWTC4S.js");
2689
2761
  return await execa(file, args, options);
2690
2762
  };
2691
2763
 
2692
2764
  // src/core/utils/building/internal-build.ts
2693
- async function internalBuild(config) {
2694
- const verb = config.command === "serve" ? "Pre-rendering" : "Building";
2695
- const target = `${config.browser}-mv${config.manifestVersion}`;
2696
- config.logger.info(
2697
- `${verb} ${pc5.cyan(target)} for ${pc5.cyan(config.mode)} with ${pc5.green(
2698
- `${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}`
2699
2772
  )}`
2700
2773
  );
2701
2774
  const startTime = Date.now();
2702
- await fs12.rm(config.outDir, { recursive: true, force: true });
2703
- await fs12.ensureDir(config.outDir);
2704
- const entrypoints = await findEntrypoints(config);
2705
- 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);
2706
2779
  const validationResults = validateEntrypoints(entrypoints);
2707
2780
  if (validationResults.errorCount + validationResults.warningCount > 0) {
2708
- printValidationResults(config, validationResults);
2781
+ printValidationResults(validationResults);
2709
2782
  }
2710
2783
  if (validationResults.errorCount > 0) {
2711
2784
  throw new ValidationError(`Entrypoint validation failed`, {
@@ -2713,45 +2786,44 @@ async function internalBuild(config) {
2713
2786
  });
2714
2787
  }
2715
2788
  const groups = groupEntrypoints(entrypoints);
2716
- const { output, warnings } = await rebuild(
2717
- config,
2718
- entrypoints,
2719
- groups,
2720
- void 0
2721
- );
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);
2722
2792
  await printBuildSummary(
2723
- config.logger.success,
2793
+ wxt.logger.success,
2724
2794
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
2725
- output,
2726
- config
2795
+ output
2727
2796
  );
2728
2797
  for (const warning of warnings) {
2729
- config.logger.warn(...warning);
2798
+ wxt.logger.warn(...warning);
2730
2799
  }
2731
- if (config.analysis.enabled) {
2732
- await combineAnalysisStats(config);
2733
- config.logger.info(
2800
+ if (wxt.config.analysis.enabled) {
2801
+ await combineAnalysisStats();
2802
+ wxt.logger.info(
2734
2803
  `Analysis complete:
2735
2804
  ${pc5.gray("\u2514\u2500")} ${pc5.yellow("stats.html")}`
2736
2805
  );
2737
2806
  }
2738
2807
  return output;
2739
2808
  }
2740
- async function combineAnalysisStats(config) {
2809
+ async function combineAnalysisStats() {
2741
2810
  const unixFiles = await glob3(`stats-*.json`, {
2742
- cwd: config.outDir,
2811
+ cwd: wxt.config.outDir,
2743
2812
  absolute: true
2744
2813
  });
2745
2814
  const absolutePaths = unixFiles.map(unnormalizePath);
2746
2815
  await exec(
2747
- config,
2748
2816
  "rollup-plugin-visualizer",
2749
- [...absolutePaths, "--template", config.analysis.template],
2750
- { cwd: config.root, stdio: "inherit" }
2817
+ [...absolutePaths, "--template", wxt.config.analysis.template],
2818
+ { cwd: wxt.config.root, stdio: "inherit" }
2751
2819
  );
2752
2820
  }
2753
- function printValidationResults(config, { errorCount, errors, warningCount }) {
2754
- (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)(
2755
2827
  `Entrypoint validation failed: ${errorCount} error${errorCount === 1 ? "" : "s"}, ${warningCount} warning${warningCount === 1 ? "" : "s"}`
2756
2828
  );
2757
2829
  const cwd = process.cwd();
@@ -2775,8 +2847,8 @@ function printValidationResults(config, { errorCount, errors, warningCount }) {
2775
2847
 
2776
2848
  // src/core/build.ts
2777
2849
  async function build(config) {
2778
- const internalConfig = await getInternalConfig(config ?? {}, "build");
2779
- return await internalBuild(internalConfig);
2850
+ await registerWxt("build", config);
2851
+ return await internalBuild();
2780
2852
  }
2781
2853
 
2782
2854
  // src/core/clean.ts
@@ -2818,11 +2890,11 @@ async function clean(root = process.cwd()) {
2818
2890
  import { relative as relative7 } from "node:path";
2819
2891
  function createWslRunner() {
2820
2892
  return {
2821
- async openBrowser(config) {
2822
- config.logger.warn(
2893
+ async openBrowser() {
2894
+ wxt.logger.warn(
2823
2895
  `Cannot open browser when using WSL. Load "${relative7(
2824
2896
  process.cwd(),
2825
- config.outDir
2897
+ wxt.config.outDir
2826
2898
  )}" as an unpacked extension manually`
2827
2899
  );
2828
2900
  },
@@ -2836,9 +2908,9 @@ import defu4 from "defu";
2836
2908
  function createWebExtRunner() {
2837
2909
  let runner;
2838
2910
  return {
2839
- async openBrowser(config) {
2911
+ async openBrowser() {
2840
2912
  const startTime = Date.now();
2841
- if (config.browser === "firefox" && config.manifestVersion === 3) {
2913
+ if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) {
2842
2914
  throw Error(
2843
2915
  "Dev mode does not support Firefox MV3. For alternatives, see https://github.com/wxt-dev/wxt/issues/230#issuecomment-1806881653"
2844
2916
  );
@@ -2846,22 +2918,22 @@ function createWebExtRunner() {
2846
2918
  const webExtLogger = await import("web-ext-run/util/logger");
2847
2919
  webExtLogger.consoleStream.write = ({ level, msg, name }) => {
2848
2920
  if (level >= ERROR_LOG_LEVEL)
2849
- config.logger.error(name, msg);
2921
+ wxt.logger.error(name, msg);
2850
2922
  if (level >= WARN_LOG_LEVEL)
2851
- config.logger.warn(msg);
2923
+ wxt.logger.warn(msg);
2852
2924
  };
2853
- const wxtUserConfig = config.runnerConfig.config;
2925
+ const wxtUserConfig = wxt.config.runnerConfig.config;
2854
2926
  const userConfig = {
2855
2927
  console: wxtUserConfig?.openConsole,
2856
2928
  devtools: wxtUserConfig?.openDevtools,
2857
2929
  startUrl: wxtUserConfig?.startUrls,
2858
- ...config.browser === "firefox" ? {
2930
+ ...wxt.config.browser === "firefox" ? {
2859
2931
  firefox: wxtUserConfig?.binaries?.firefox,
2860
2932
  firefoxProfile: wxtUserConfig?.firefoxProfile,
2861
2933
  prefs: wxtUserConfig?.firefoxPrefs,
2862
2934
  args: wxtUserConfig?.firefoxArgs
2863
2935
  } : {
2864
- chromiumBinary: wxtUserConfig?.binaries?.[config.browser],
2936
+ chromiumBinary: wxtUserConfig?.binaries?.[wxt.config.browser],
2865
2937
  chromiumProfile: wxtUserConfig?.chromiumProfile,
2866
2938
  chromiumPref: defu4(
2867
2939
  wxtUserConfig?.chromiumPref,
@@ -2872,8 +2944,8 @@ function createWebExtRunner() {
2872
2944
  };
2873
2945
  const finalConfig = {
2874
2946
  ...userConfig,
2875
- target: config.browser === "firefox" ? "firefox-desktop" : "chromium",
2876
- sourceDir: config.outDir,
2947
+ target: wxt.config.browser === "firefox" ? "firefox-desktop" : "chromium",
2948
+ sourceDir: wxt.config.outDir,
2877
2949
  // WXT handles reloads, so disable auto-reload behaviors in web-ext
2878
2950
  noReload: true,
2879
2951
  noInput: true
@@ -2882,12 +2954,12 @@ function createWebExtRunner() {
2882
2954
  // Don't call `process.exit(0)` after starting web-ext
2883
2955
  shouldExitProgram: false
2884
2956
  };
2885
- config.logger.debug("web-ext config:", finalConfig);
2886
- config.logger.debug("web-ext options:", options);
2957
+ wxt.logger.debug("web-ext config:", finalConfig);
2958
+ wxt.logger.debug("web-ext options:", options);
2887
2959
  const webExt = await import("web-ext-run");
2888
2960
  runner = await webExt.default.cmd.run(finalConfig, options);
2889
2961
  const duration = Date.now() - startTime;
2890
- config.logger.success(`Opened browser in ${formatDuration(duration)}`);
2962
+ wxt.logger.success(`Opened browser in ${formatDuration(duration)}`);
2891
2963
  },
2892
2964
  async closeBrowser() {
2893
2965
  return await runner?.exit();
@@ -2911,11 +2983,11 @@ var DEFAULT_CHROMIUM_PREFS = {
2911
2983
  import { relative as relative8 } from "node:path";
2912
2984
  function createSafariRunner() {
2913
2985
  return {
2914
- async openBrowser(config) {
2915
- config.logger.warn(
2986
+ async openBrowser() {
2987
+ wxt.logger.warn(
2916
2988
  `Cannot Safari using web-ext. Load "${relative8(
2917
2989
  process.cwd(),
2918
- config.outDir
2990
+ wxt.config.outDir
2919
2991
  )}" as an unpacked extension manually`
2920
2992
  );
2921
2993
  },
@@ -2928,11 +3000,11 @@ function createSafariRunner() {
2928
3000
  import { relative as relative9 } from "node:path";
2929
3001
  function createManualRunner() {
2930
3002
  return {
2931
- async openBrowser(config) {
2932
- config.logger.info(
3003
+ async openBrowser() {
3004
+ wxt.logger.info(
2933
3005
  `Load "${relative9(
2934
3006
  process.cwd(),
2935
- config.outDir
3007
+ wxt.config.outDir
2936
3008
  )}" as an unpacked extension manually`
2937
3009
  );
2938
3010
  },
@@ -2948,12 +3020,12 @@ async function isWsl() {
2948
3020
  }
2949
3021
 
2950
3022
  // src/core/runners/index.ts
2951
- async function createExtensionRunner(config) {
2952
- if (config.browser === "safari")
3023
+ async function createExtensionRunner() {
3024
+ if (wxt.config.browser === "safari")
2953
3025
  return createSafariRunner();
2954
3026
  if (await isWsl())
2955
3027
  return createWslRunner();
2956
- if (config.runnerConfig.config?.disabled)
3028
+ if (wxt.config.runnerConfig.config?.disabled)
2957
3029
  return createManualRunner();
2958
3030
  return createWebExtRunner();
2959
3031
  }
@@ -2973,13 +3045,13 @@ async function createServer(inlineConfig) {
2973
3045
  origin
2974
3046
  };
2975
3047
  const buildAndOpenBrowser = async () => {
2976
- server.currentOutput = await internalBuild(config);
2977
- await runner.openBrowser(config);
3048
+ server.currentOutput = await internalBuild();
3049
+ await runner.openBrowser();
2978
3050
  };
2979
3051
  const closeAndRecreateRunner = async () => {
2980
3052
  await runner.closeBrowser();
2981
- config = await getLatestConfig();
2982
- runner = await createExtensionRunner(config);
3053
+ await wxt.reloadConfig();
3054
+ runner = await createExtensionRunner();
2983
3055
  };
2984
3056
  const server = {
2985
3057
  ...serverInfo,
@@ -2992,7 +3064,7 @@ async function createServer(inlineConfig) {
2992
3064
  currentOutput: void 0,
2993
3065
  async start() {
2994
3066
  await builderServer.listen();
2995
- config.logger.success(`Started dev server @ ${serverInfo.origin}`);
3067
+ wxt.logger.success(`Started dev server @ ${serverInfo.origin}`);
2996
3068
  await buildAndOpenBrowser();
2997
3069
  },
2998
3070
  async stop() {
@@ -3017,27 +3089,20 @@ async function createServer(inlineConfig) {
3017
3089
  },
3018
3090
  async restartBrowser() {
3019
3091
  await closeAndRecreateRunner();
3020
- await runner.openBrowser(config);
3092
+ await runner.openBrowser();
3021
3093
  }
3022
3094
  };
3023
- const getLatestConfig = () => getInternalConfig(inlineConfig ?? {}, "serve", server);
3024
- let config = await getLatestConfig();
3095
+ await registerWxt("serve", inlineConfig, server);
3025
3096
  let [runner, builderServer] = await Promise.all([
3026
- createExtensionRunner(config),
3027
- config.builder.createServer(server)
3097
+ createExtensionRunner(),
3098
+ wxt.config.builder.createServer(server)
3028
3099
  ]);
3029
3100
  server.ws.on("wxt:background-initialized", () => {
3030
3101
  if (server.currentOutput == null)
3031
3102
  return;
3032
- reloadContentScripts(server.currentOutput.steps, config, server);
3033
- });
3034
- const reloadOnChange = createFileReloader({
3035
- server,
3036
- getLatestConfig,
3037
- updateConfig(newConfig) {
3038
- config = newConfig;
3039
- }
3103
+ reloadContentScripts(server.currentOutput.steps, server);
3040
3104
  });
3105
+ const reloadOnChange = createFileReloader(server);
3041
3106
  server.watcher.on("all", reloadOnChange);
3042
3107
  return server;
3043
3108
  }
@@ -3045,14 +3110,12 @@ async function getPort() {
3045
3110
  const { default: getPort2, portNumbers } = await import("get-port");
3046
3111
  return await getPort2({ port: portNumbers(3e3, 3010) });
3047
3112
  }
3048
- function createFileReloader(options) {
3049
- const { server, getLatestConfig, updateConfig } = options;
3113
+ function createFileReloader(server) {
3050
3114
  const fileChangedMutex = new Mutex();
3051
3115
  const changeQueue = [];
3052
3116
  return async (event, path7) => {
3053
- const config = await getLatestConfig();
3054
- updateConfig(config);
3055
- if (path7.startsWith(config.outBaseDir))
3117
+ await wxt.reloadConfig();
3118
+ if (path7.startsWith(wxt.config.outBaseDir))
3056
3119
  return;
3057
3120
  changeQueue.push([event, path7]);
3058
3121
  await fileChangedMutex.runExclusive(async () => {
@@ -3061,29 +3124,24 @@ function createFileReloader(options) {
3061
3124
  const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
3062
3125
  if (fileChanges.length === 0)
3063
3126
  return;
3064
- const changes = detectDevChanges(
3065
- config,
3066
- fileChanges,
3067
- server.currentOutput
3068
- );
3127
+ const changes = detectDevChanges(fileChanges, server.currentOutput);
3069
3128
  if (changes.type === "no-change")
3070
3129
  return;
3071
3130
  if (changes.type === "full-restart") {
3072
- config.logger.info("Config changed, restarting server...");
3131
+ wxt.logger.info("Config changed, restarting server...");
3073
3132
  server.restart();
3074
3133
  return;
3075
3134
  }
3076
3135
  if (changes.type === "browser-restart") {
3077
- config.logger.info("Runner config changed, restarting browser...");
3136
+ wxt.logger.info("Runner config changed, restarting browser...");
3078
3137
  server.restartBrowser();
3079
3138
  return;
3080
3139
  }
3081
- config.logger.info(
3082
- `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(", ")}`
3083
3142
  );
3084
- const allEntrypoints = await findEntrypoints(config);
3143
+ const allEntrypoints = await findEntrypoints();
3085
3144
  const { output: newOutput } = await rebuild(
3086
- config,
3087
3145
  allEntrypoints,
3088
3146
  // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
3089
3147
  changes.rebuildGroups,
@@ -3098,13 +3156,12 @@ function createFileReloader(options) {
3098
3156
  case "html-reload":
3099
3157
  const { reloadedNames } = reloadHtmlPages(
3100
3158
  changes.rebuildGroups,
3101
- server,
3102
- config
3159
+ server
3103
3160
  );
3104
3161
  consola5.success(`Reloaded: ${getFilenameList(reloadedNames)}`);
3105
3162
  break;
3106
3163
  case "content-script-reload":
3107
- reloadContentScripts(changes.changedSteps, config, server);
3164
+ reloadContentScripts(changes.changedSteps, server);
3108
3165
  const rebuiltNames = changes.rebuildGroups.flat().map((entry) => entry.name);
3109
3166
  consola5.success(`Reloaded: ${getFilenameList(rebuiltNames)}`);
3110
3167
  break;
@@ -3112,30 +3169,33 @@ function createFileReloader(options) {
3112
3169
  });
3113
3170
  };
3114
3171
  }
3115
- function reloadContentScripts(steps, config, server) {
3116
- if (config.manifestVersion === 3) {
3172
+ function reloadContentScripts(steps, server) {
3173
+ if (wxt.config.manifestVersion === 3) {
3117
3174
  steps.forEach((step) => {
3118
3175
  if (server.currentOutput == null)
3119
3176
  return;
3120
3177
  const entry = step.entrypoints;
3121
3178
  if (Array.isArray(entry) || entry.type !== "content-script")
3122
3179
  return;
3123
- const js = [getEntrypointBundlePath(entry, config.outDir, ".js")];
3180
+ const js = [getEntrypointBundlePath(entry, wxt.config.outDir, ".js")];
3124
3181
  const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
3125
3182
  const css = getContentScriptCssFiles([entry], cssMap);
3126
3183
  server.reloadContentScript({
3127
3184
  allFrames: resolvePerBrowserOption(
3128
3185
  entry.options.allFrames,
3129
- config.browser
3186
+ wxt.config.browser
3130
3187
  ),
3131
3188
  excludeMatches: resolvePerBrowserOption(
3132
3189
  entry.options.excludeMatches,
3133
- config.browser
3190
+ wxt.config.browser
3191
+ ),
3192
+ matches: resolvePerBrowserOption(
3193
+ entry.options.matches,
3194
+ wxt.config.browser
3134
3195
  ),
3135
- matches: resolvePerBrowserOption(entry.options.matches, config.browser),
3136
- runAt: resolvePerBrowserOption(entry.options.runAt, config.browser),
3196
+ runAt: resolvePerBrowserOption(entry.options.runAt, wxt.config.browser),
3137
3197
  // @ts-expect-error: Chrome accepts this, not typed in webextension-polyfill (https://developer.chrome.com/docs/extensions/reference/scripting/#type-RegisteredContentScript)
3138
- world: resolvePerBrowserOption(entry.options.world, config.browser),
3198
+ world: resolvePerBrowserOption(entry.options.world, wxt.config.browser),
3139
3199
  js,
3140
3200
  css
3141
3201
  });
@@ -3144,10 +3204,10 @@ function reloadContentScripts(steps, config, server) {
3144
3204
  server.reloadExtension();
3145
3205
  }
3146
3206
  }
3147
- function reloadHtmlPages(groups, server, config) {
3207
+ function reloadHtmlPages(groups, server) {
3148
3208
  const htmlEntries = groups.flat().filter((entry) => entry.inputPath.endsWith(".html"));
3149
3209
  htmlEntries.forEach((entry) => {
3150
- const path7 = getEntrypointBundlePath(entry, config.outDir, ".html");
3210
+ const path7 = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
3151
3211
  server.reloadPage(path7);
3152
3212
  });
3153
3213
  return {
@@ -3228,19 +3288,11 @@ async function initialize(options) {
3228
3288
  }
3229
3289
  async function listTemplates() {
3230
3290
  try {
3231
- const res = await fetch(
3232
- "https://api.github.com/repos/wxt-dev/wxt/contents/templates",
3233
- {
3234
- headers: {
3235
- Accept: "application/vnd.github+json",
3236
- "X-GitHub-Api-Version": "2022-11-28"
3237
- }
3238
- }
3239
- );
3291
+ const res = await fetch("https://ungh.cc/repos/wxt-dev/wxt/files/main");
3240
3292
  if (res.status >= 300)
3241
3293
  throw Error(`Request failed with status ${res.status} ${res.statusText}`);
3242
3294
  const data = await res.json();
3243
- 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) => {
3244
3296
  const lWeight = TEMPLATE_SORT_WEIGHT[l.name] ?? Number.MAX_SAFE_INTEGER;
3245
3297
  const rWeight = TEMPLATE_SORT_WEIGHT[r.name] ?? Number.MAX_SAFE_INTEGER;
3246
3298
  const diff = lWeight - rWeight;
@@ -3291,10 +3343,10 @@ var TEMPLATE_SORT_WEIGHT = {
3291
3343
 
3292
3344
  // src/core/prepare.ts
3293
3345
  async function prepare(config) {
3294
- const internalConfig = await getInternalConfig(config, "build");
3295
- internalConfig.logger.info("Generating types...");
3296
- const entrypoints = await findEntrypoints(internalConfig);
3297
- await generateTypesDir(entrypoints, internalConfig);
3346
+ await registerWxt("build", config);
3347
+ wxt.logger.info("Generating types...");
3348
+ const entrypoints = await findEntrypoints();
3349
+ await generateTypesDir(entrypoints);
3298
3350
  }
3299
3351
 
3300
3352
  // src/core/zip.ts
@@ -3303,40 +3355,35 @@ import { dirname as dirname5, relative as relative11, resolve as resolve14 } fro
3303
3355
  import fs15 from "fs-extra";
3304
3356
  import { minimatch as minimatch2 } from "minimatch";
3305
3357
  async function zip(config) {
3306
- const internalConfig = await getInternalConfig(config ?? {}, "build");
3307
- const output = await internalBuild(internalConfig);
3358
+ await registerWxt("build", config);
3359
+ const output = await internalBuild();
3308
3360
  const start = Date.now();
3309
- internalConfig.logger.info("Zipping extension...");
3361
+ wxt.logger.info("Zipping extension...");
3310
3362
  const zipFiles = [];
3311
- const projectName = internalConfig.zip.name ?? kebabCaseAlphanumeric(
3312
- (await getPackageJson(internalConfig))?.name || dirname5(process.cwd())
3363
+ const projectName = wxt.config.zip.name ?? kebabCaseAlphanumeric(
3364
+ (await getPackageJson())?.name || dirname5(process.cwd())
3313
3365
  );
3314
- 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(
3315
3367
  "{{version}}",
3316
3368
  output.manifest.version_name ?? output.manifest.version
3317
- ).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
3318
- await fs15.ensureDir(internalConfig.outBaseDir);
3319
- const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
3320
- const outZipPath = resolve14(internalConfig.outBaseDir, outZipFilename);
3321
- 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, {
3322
3374
  saveTo: outZipPath
3323
3375
  });
3324
3376
  zipFiles.push(outZipPath);
3325
- if (internalConfig.browser === "firefox") {
3326
- const sourcesZipFilename = applyTemplate(
3327
- internalConfig.zip.sourcesTemplate
3328
- );
3329
- const sourcesZipPath = resolve14(
3330
- internalConfig.outBaseDir,
3331
- sourcesZipFilename
3332
- );
3333
- 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, {
3334
3381
  saveTo: sourcesZipPath,
3335
3382
  filter(path7) {
3336
- const relativePath = relative11(internalConfig.zip.sourcesRoot, path7);
3337
- return internalConfig.zip.includeSources.some(
3383
+ const relativePath = relative11(wxt.config.zip.sourcesRoot, path7);
3384
+ return wxt.config.zip.includeSources.some(
3338
3385
  (pattern) => minimatch2(relativePath, pattern)
3339
- ) || !internalConfig.zip.excludeSources.some(
3386
+ ) || !wxt.config.zip.excludeSources.some(
3340
3387
  (pattern) => minimatch2(relativePath, pattern)
3341
3388
  );
3342
3389
  }
@@ -3344,9 +3391,9 @@ async function zip(config) {
3344
3391
  zipFiles.push(sourcesZipPath);
3345
3392
  }
3346
3393
  await printFileList(
3347
- internalConfig.logger.success,
3394
+ wxt.logger.success,
3348
3395
  `Zipped extension in ${formatDuration(Date.now() - start)}`,
3349
- internalConfig.outBaseDir,
3396
+ wxt.config.outBaseDir,
3350
3397
  zipFiles
3351
3398
  );
3352
3399
  return zipFiles;
@@ -3389,11 +3436,11 @@ var aliasCommandNames = /* @__PURE__ */ new Set();
3389
3436
  function createAliasedCommand(base, name, alias, docsUrl) {
3390
3437
  const aliasedCommand = base.command(name, `Alias for ${alias} (${docsUrl})`).allowUnknownOptions().action(async () => {
3391
3438
  try {
3392
- const config = await getInternalConfig({}, "build");
3439
+ await registerWxt("build");
3393
3440
  const args = process.argv.slice(
3394
3441
  process.argv.indexOf(aliasedCommand.name) + 1
3395
3442
  );
3396
- await exec(config, alias, args, {
3443
+ await exec(alias, args, {
3397
3444
  stdio: "inherit"
3398
3445
  });
3399
3446
  } catch {