wxt 0.14.0 → 0.14.2-alpha2

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
@@ -40,7 +40,7 @@ var require_windows = __commonJS({
40
40
  module2.exports = isexe;
41
41
  isexe.sync = sync;
42
42
  var fs16 = require("fs");
43
- function checkPathExt(path10, options) {
43
+ function checkPathExt(path9, options) {
44
44
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
45
45
  if (!pathext) {
46
46
  return true;
@@ -51,25 +51,25 @@ var require_windows = __commonJS({
51
51
  }
52
52
  for (var i = 0; i < pathext.length; i++) {
53
53
  var p = pathext[i].toLowerCase();
54
- if (p && path10.substr(-p.length).toLowerCase() === p) {
54
+ if (p && path9.substr(-p.length).toLowerCase() === p) {
55
55
  return true;
56
56
  }
57
57
  }
58
58
  return false;
59
59
  }
60
- function checkStat(stat, path10, options) {
60
+ function checkStat(stat, path9, options) {
61
61
  if (!stat.isSymbolicLink() && !stat.isFile()) {
62
62
  return false;
63
63
  }
64
- return checkPathExt(path10, options);
64
+ return checkPathExt(path9, options);
65
65
  }
66
- function isexe(path10, options, cb) {
67
- fs16.stat(path10, function(er, stat) {
68
- cb(er, er ? false : checkStat(stat, path10, options));
66
+ function isexe(path9, options, cb) {
67
+ fs16.stat(path9, function(er, stat) {
68
+ cb(er, er ? false : checkStat(stat, path9, options));
69
69
  });
70
70
  }
71
- function sync(path10, options) {
72
- return checkStat(fs16.statSync(path10), path10, options);
71
+ function sync(path9, options) {
72
+ return checkStat(fs16.statSync(path9), path9, options);
73
73
  }
74
74
  }
75
75
  });
@@ -81,13 +81,13 @@ var require_mode = __commonJS({
81
81
  module2.exports = isexe;
82
82
  isexe.sync = sync;
83
83
  var fs16 = require("fs");
84
- function isexe(path10, options, cb) {
85
- fs16.stat(path10, function(er, stat) {
84
+ function isexe(path9, options, cb) {
85
+ fs16.stat(path9, function(er, stat) {
86
86
  cb(er, er ? false : checkStat(stat, options));
87
87
  });
88
88
  }
89
- function sync(path10, options) {
90
- return checkStat(fs16.statSync(path10), options);
89
+ function sync(path9, options) {
90
+ return checkStat(fs16.statSync(path9), options);
91
91
  }
92
92
  function checkStat(stat, options) {
93
93
  return stat.isFile() && checkMode(stat, options);
@@ -121,7 +121,7 @@ var require_isexe = __commonJS({
121
121
  }
122
122
  module2.exports = isexe;
123
123
  isexe.sync = sync;
124
- function isexe(path10, options, cb) {
124
+ function isexe(path9, options, cb) {
125
125
  if (typeof options === "function") {
126
126
  cb = options;
127
127
  options = {};
@@ -131,7 +131,7 @@ var require_isexe = __commonJS({
131
131
  throw new TypeError("callback not provided");
132
132
  }
133
133
  return new Promise(function(resolve14, reject) {
134
- isexe(path10, options || {}, function(er, is) {
134
+ isexe(path9, options || {}, function(er, is) {
135
135
  if (er) {
136
136
  reject(er);
137
137
  } else {
@@ -140,7 +140,7 @@ var require_isexe = __commonJS({
140
140
  });
141
141
  });
142
142
  }
143
- core(path10, options || {}, function(er, is) {
143
+ core(path9, options || {}, function(er, is) {
144
144
  if (er) {
145
145
  if (er.code === "EACCES" || options && options.ignoreErrors) {
146
146
  er = null;
@@ -150,9 +150,9 @@ var require_isexe = __commonJS({
150
150
  cb(er, is);
151
151
  });
152
152
  }
153
- function sync(path10, options) {
153
+ function sync(path9, options) {
154
154
  try {
155
- return core.sync(path10, options || {});
155
+ return core.sync(path9, options || {});
156
156
  } catch (er) {
157
157
  if (options && options.ignoreErrors || er.code === "EACCES") {
158
158
  return false;
@@ -169,7 +169,7 @@ var require_which = __commonJS({
169
169
  "node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module2) {
170
170
  "use strict";
171
171
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
172
- var path10 = require("path");
172
+ var path9 = require("path");
173
173
  var COLON = isWindows ? ";" : ":";
174
174
  var isexe = require_isexe();
175
175
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -207,7 +207,7 @@ var require_which = __commonJS({
207
207
  return opt.all && found.length ? resolve14(found) : reject(getNotFoundError(cmd));
208
208
  const ppRaw = pathEnv[i];
209
209
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
210
- const pCmd = path10.join(pathPart, cmd);
210
+ const pCmd = path9.join(pathPart, cmd);
211
211
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
212
212
  resolve14(subStep(p, i, 0));
213
213
  });
@@ -234,7 +234,7 @@ var require_which = __commonJS({
234
234
  for (let i = 0; i < pathEnv.length; i++) {
235
235
  const ppRaw = pathEnv[i];
236
236
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
237
- const pCmd = path10.join(pathPart, cmd);
237
+ const pCmd = path9.join(pathPart, cmd);
238
238
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
239
239
  for (let j = 0; j < pathExt.length; j++) {
240
240
  const cur = p + pathExt[j];
@@ -282,7 +282,7 @@ var require_path_key = __commonJS({
282
282
  var require_resolveCommand = __commonJS({
283
283
  "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module2) {
284
284
  "use strict";
285
- var path10 = require("path");
285
+ var path9 = require("path");
286
286
  var which = require_which();
287
287
  var getPathKey = require_path_key();
288
288
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -300,7 +300,7 @@ var require_resolveCommand = __commonJS({
300
300
  try {
301
301
  resolved = which.sync(parsed.command, {
302
302
  path: env[getPathKey({ env })],
303
- pathExt: withoutPathExt ? path10.delimiter : void 0
303
+ pathExt: withoutPathExt ? path9.delimiter : void 0
304
304
  });
305
305
  } catch (e) {
306
306
  } finally {
@@ -309,7 +309,7 @@ var require_resolveCommand = __commonJS({
309
309
  }
310
310
  }
311
311
  if (resolved) {
312
- resolved = path10.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
312
+ resolved = path9.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
313
313
  }
314
314
  return resolved;
315
315
  }
@@ -363,8 +363,8 @@ var require_shebang_command = __commonJS({
363
363
  if (!match) {
364
364
  return null;
365
365
  }
366
- const [path10, argument] = match[0].replace(/#! ?/, "").split(" ");
367
- const binary = path10.split("/").pop();
366
+ const [path9, argument] = match[0].replace(/#! ?/, "").split(" ");
367
+ const binary = path9.split("/").pop();
368
368
  if (binary === "env") {
369
369
  return argument;
370
370
  }
@@ -399,7 +399,7 @@ var require_readShebang = __commonJS({
399
399
  var require_parse = __commonJS({
400
400
  "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/parse.js"(exports, module2) {
401
401
  "use strict";
402
- var path10 = require("path");
402
+ var path9 = require("path");
403
403
  var resolveCommand = require_resolveCommand();
404
404
  var escape = require_escape();
405
405
  var readShebang = require_readShebang();
@@ -424,7 +424,7 @@ var require_parse = __commonJS({
424
424
  const needsShell = !isExecutableRegExp.test(commandFile);
425
425
  if (parsed.options.forceShell || needsShell) {
426
426
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
427
- parsed.command = path10.normalize(parsed.command);
427
+ parsed.command = path9.normalize(parsed.command);
428
428
  parsed.command = escape.command(parsed.command);
429
429
  parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
430
430
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -590,9 +590,9 @@ function npmRunPath(options = {}) {
590
590
  }
591
591
  function npmRunPathEnv({ env = import_node_process.default.env, ...options } = {}) {
592
592
  env = { ...env };
593
- const path10 = pathKey({ env });
594
- options.path = env[path10];
595
- env[path10] = npmRunPath(options);
593
+ const path9 = pathKey({ env });
594
+ options.path = env[path9];
595
+ env[path9] = npmRunPath(options);
596
596
  return env;
597
597
  }
598
598
  var import_node_process, import_node_path11, import_node_url2;
@@ -1891,12 +1891,12 @@ var require_merge_stream = __commonJS({
1891
1891
  });
1892
1892
 
1893
1893
  // node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/stream.js
1894
- var import_node_fs2, import_promises, import_merge_stream, validateInputOptions, getInputSync, handleInputSync, getInput, handleInput, makeAllStream, getBufferedData, getStreamPromise, applyEncoding, getSpawnedResult;
1894
+ var import_node_fs2, import_promises2, import_merge_stream, validateInputOptions, getInputSync, handleInputSync, getInput, handleInput, makeAllStream, getBufferedData, getStreamPromise, applyEncoding, getSpawnedResult;
1895
1895
  var init_stream = __esm({
1896
1896
  "node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/stream.js"() {
1897
1897
  "use strict";
1898
1898
  import_node_fs2 = require("fs");
1899
- import_promises = require("timers/promises");
1899
+ import_promises2 = require("timers/promises");
1900
1900
  init_is_stream();
1901
1901
  init_source();
1902
1902
  import_merge_stream = __toESM(require_merge_stream(), 1);
@@ -1954,7 +1954,7 @@ var init_stream = __esm({
1954
1954
  if (!stream || streamPromise === void 0) {
1955
1955
  return;
1956
1956
  }
1957
- await (0, import_promises.setTimeout)(0);
1957
+ await (0, import_promises2.setTimeout)(0);
1958
1958
  stream.destroy();
1959
1959
  try {
1960
1960
  return await streamPromise;
@@ -2434,11 +2434,11 @@ var import_fast_glob = __toESM(require("fast-glob"), 1);
2434
2434
  // src/core/utils/paths.ts
2435
2435
  var import_node_path = __toESM(require("path"), 1);
2436
2436
  var import_normalize_path = __toESM(require("normalize-path"), 1);
2437
- function normalizePath(path10) {
2438
- return (0, import_normalize_path.default)(path10);
2437
+ function normalizePath(path9) {
2438
+ return (0, import_normalize_path.default)(path9);
2439
2439
  }
2440
- function unnormalizePath(path10) {
2441
- return import_node_path.default.normalize(path10);
2440
+ function unnormalizePath(path9) {
2441
+ return import_node_path.default.normalize(path9);
2442
2442
  }
2443
2443
  var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
2444
2444
  var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
@@ -2459,8 +2459,145 @@ async function getPublicFiles(config) {
2459
2459
 
2460
2460
  // src/core/utils/building/build-entrypoints.ts
2461
2461
  var import_fs_extra2 = __toESM(require("fs-extra"), 1);
2462
- var import_path = require("path");
2462
+ var import_node_path2 = require("path");
2463
2463
  var import_picocolors = __toESM(require("picocolors"), 1);
2464
+
2465
+ // src/i18n/node.ts
2466
+ var import_promises = require("fs/promises");
2467
+ var import_json5 = __toESM(require("json5"), 1);
2468
+ var import_yaml = __toESM(require("yaml"), 1);
2469
+ async function readMessagesFile(file) {
2470
+ const text = await (0, import_promises.readFile)(file, "utf-8");
2471
+ return readMessagesText(text);
2472
+ }
2473
+ function readMessagesText(text) {
2474
+ const parsers = [
2475
+ JSON.parse,
2476
+ import_json5.default.parse,
2477
+ import_yaml.default.parse
2478
+ ];
2479
+ for (const parse of parsers) {
2480
+ try {
2481
+ const result = parse(text);
2482
+ if (typeof result === "object") {
2483
+ return readMessagesObject(result);
2484
+ }
2485
+ } catch {
2486
+ continue;
2487
+ }
2488
+ }
2489
+ throw Error("I18n messages text is not valid JSON, JSON5, or YAML");
2490
+ }
2491
+ function readMessagesObject(input) {
2492
+ const messagesFromInput = findEntries([], input);
2493
+ return [...messagesFromInput, ...PREDEFINED_MESSAGES];
2494
+ }
2495
+ function convertMessagesToManifest(messages) {
2496
+ return messages.filter((message) => !message.isBuiltin).reduce((schema, { name, entry }) => {
2497
+ schema[name] = entry;
2498
+ return schema;
2499
+ }, {});
2500
+ }
2501
+ function findEntries(keyPath, input) {
2502
+ const name = keyPath.join("_");
2503
+ if (isBasicEntry(input))
2504
+ return [
2505
+ {
2506
+ name,
2507
+ entry: { message: input }
2508
+ }
2509
+ ];
2510
+ if (isManifestEntry(input))
2511
+ return [
2512
+ {
2513
+ name,
2514
+ entry: input
2515
+ }
2516
+ ];
2517
+ if (isPluralEntry(input))
2518
+ return [
2519
+ {
2520
+ name,
2521
+ entry: {
2522
+ message: Object.values(input).join(" | ")
2523
+ },
2524
+ isPlural: true
2525
+ }
2526
+ ];
2527
+ return Object.entries(input).reduce((items, [key, child]) => {
2528
+ const nestedEntries = findEntries(keyPath.concat(key), child);
2529
+ return [...items, ...nestedEntries];
2530
+ }, []);
2531
+ }
2532
+ function isBasicEntry(entry) {
2533
+ return typeof entry === "string";
2534
+ }
2535
+ function isManifestEntry(entry) {
2536
+ const keys = Object.keys(entry);
2537
+ if (keys.length < 1 || keys.length > 3)
2538
+ return false;
2539
+ const knownKeys = /* @__PURE__ */ new Set(["message", "placeholders", "description"]);
2540
+ const unknownKeys = keys.filter((key) => !knownKeys.has(key));
2541
+ return unknownKeys.length === 0;
2542
+ }
2543
+ function isPluralEntry(entry) {
2544
+ const keys = Object.keys(entry);
2545
+ if (keys.length === 0)
2546
+ return false;
2547
+ const invalidKeys = keys.filter((key) => key !== "n" && isNaN(Number(key)));
2548
+ return invalidKeys.length === 0;
2549
+ }
2550
+ var PREDEFINED_MESSAGES = [
2551
+ {
2552
+ name: "@@extension_id",
2553
+ isBuiltin: true,
2554
+ entry: {
2555
+ message: "<browser.runtime.id>",
2556
+ description: "The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message.\nNote: You can't use this message in a manifest file."
2557
+ }
2558
+ },
2559
+ {
2560
+ name: "@@ui_locale",
2561
+ isBuiltin: true,
2562
+ entry: {
2563
+ message: "<browser.i18n.getUiLocale()>"
2564
+ }
2565
+ },
2566
+ {
2567
+ name: "@@bidi_dir",
2568
+ isBuiltin: true,
2569
+ entry: {
2570
+ message: "<ltr|rtl>",
2571
+ description: 'The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Japanese.'
2572
+ }
2573
+ },
2574
+ {
2575
+ name: "@@bidi_reversed_dir",
2576
+ isBuiltin: true,
2577
+ entry: {
2578
+ message: "<rtl|ltr>",
2579
+ description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
2580
+ }
2581
+ },
2582
+ {
2583
+ name: "@@bidi_start_edge",
2584
+ isBuiltin: true,
2585
+ entry: {
2586
+ message: "<left|right>",
2587
+ description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
2588
+ }
2589
+ },
2590
+ {
2591
+ name: "@@bidi_end_edge",
2592
+ isBuiltin: true,
2593
+ entry: {
2594
+ message: "<right|left>",
2595
+ description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
2596
+ }
2597
+ }
2598
+ ];
2599
+
2600
+ // src/core/utils/building/build-entrypoints.ts
2464
2601
  async function buildEntrypoints(groups, config, spinner) {
2465
2602
  const steps = [];
2466
2603
  for (let i = 0; i < groups.length; i++) {
@@ -2469,7 +2606,10 @@ async function buildEntrypoints(groups, config, spinner) {
2469
2606
  spinner.text = import_picocolors.default.dim(`[${i + 1}/${groups.length}]`) + ` ${groupNames}`;
2470
2607
  steps.push(await config.builder.build(group));
2471
2608
  }
2472
- const publicAssets = await copyPublicDirectory(config);
2609
+ const publicAssets = (await Promise.all([
2610
+ copyPublicDirectory(config),
2611
+ copyLocalesDirectory(config)
2612
+ ])).flat();
2473
2613
  return { publicAssets, steps };
2474
2614
  }
2475
2615
  async function copyPublicDirectory(config) {
@@ -2478,9 +2618,9 @@ async function copyPublicDirectory(config) {
2478
2618
  return [];
2479
2619
  const publicAssets = [];
2480
2620
  for (const file of files) {
2481
- const srcPath = (0, import_path.resolve)(config.publicDir, file);
2482
- const outPath = (0, import_path.resolve)(config.outDir, file);
2483
- await import_fs_extra2.default.ensureDir((0, import_path.dirname)(outPath));
2621
+ const srcPath = (0, import_node_path2.resolve)(config.publicDir, file);
2622
+ const outPath = (0, import_node_path2.resolve)(config.outDir, file);
2623
+ await import_fs_extra2.default.ensureDir((0, import_node_path2.dirname)(outPath));
2484
2624
  await import_fs_extra2.default.copyFile(srcPath, outPath);
2485
2625
  publicAssets.push({
2486
2626
  type: "asset",
@@ -2489,6 +2629,28 @@ async function copyPublicDirectory(config) {
2489
2629
  }
2490
2630
  return publicAssets;
2491
2631
  }
2632
+ async function copyLocalesDirectory(config) {
2633
+ const localesExist = await import_fs_extra2.default.exists(config.localesDir);
2634
+ if (!localesExist || config.manifest.default_locale == null)
2635
+ return [];
2636
+ const files = await import_fs_extra2.default.readdir(config.localesDir);
2637
+ return await Promise.all(
2638
+ files.map(async (file) => {
2639
+ const locale = file.replace((0, import_node_path2.extname)(file), "");
2640
+ const fileName = unnormalizePath(`_locales/${locale}/messages.json`);
2641
+ const srcPath = (0, import_node_path2.resolve)(config.localesDir, file);
2642
+ const outPath = (0, import_node_path2.resolve)(config.outDir, fileName);
2643
+ const messages = await readMessagesFile(srcPath);
2644
+ const json = convertMessagesToManifest(messages);
2645
+ await import_fs_extra2.default.ensureDir((0, import_node_path2.dirname)(outPath));
2646
+ await import_fs_extra2.default.writeJson(outPath, json);
2647
+ return {
2648
+ fileName,
2649
+ type: "asset"
2650
+ };
2651
+ })
2652
+ );
2653
+ }
2492
2654
 
2493
2655
  // src/core/utils/arrays.ts
2494
2656
  function every(array, predicate) {
@@ -2583,26 +2745,26 @@ function findEffectedSteps(changedFile, currentOutput) {
2583
2745
  }
2584
2746
 
2585
2747
  // src/core/utils/building/find-entrypoints.ts
2586
- var import_path2 = require("path");
2748
+ var import_path = require("path");
2587
2749
  var import_fs_extra3 = __toESM(require("fs-extra"), 1);
2588
2750
  var import_minimatch = require("minimatch");
2589
2751
  var import_linkedom = require("linkedom");
2590
- var import_json5 = __toESM(require("json5"), 1);
2752
+ var import_json52 = __toESM(require("json5"), 1);
2591
2753
  var import_fast_glob2 = __toESM(require("fast-glob"), 1);
2592
2754
 
2593
2755
  // src/core/utils/entrypoints.ts
2594
- var import_node_path2 = __toESM(require("path"), 1);
2756
+ var import_node_path3 = __toESM(require("path"), 1);
2595
2757
  function getEntrypointName(entrypointsDir, inputPath) {
2596
- const relativePath = import_node_path2.default.relative(entrypointsDir, inputPath);
2758
+ const relativePath = import_node_path3.default.relative(entrypointsDir, inputPath);
2597
2759
  const name = relativePath.split(/[\.\/\\]/, 2)[0];
2598
2760
  return name;
2599
2761
  }
2600
2762
  function getEntrypointOutputFile(entrypoint, ext) {
2601
- return (0, import_node_path2.resolve)(entrypoint.outputDir, `${entrypoint.name}${ext}`);
2763
+ return (0, import_node_path3.resolve)(entrypoint.outputDir, `${entrypoint.name}${ext}`);
2602
2764
  }
2603
2765
  function getEntrypointBundlePath(entrypoint, outDir, ext) {
2604
2766
  return normalizePath(
2605
- (0, import_node_path2.relative)(outDir, getEntrypointOutputFile(entrypoint, ext))
2767
+ (0, import_node_path3.relative)(outDir, getEntrypointOutputFile(entrypoint, ext))
2606
2768
  );
2607
2769
  }
2608
2770
  function resolvePerBrowserOption(option, browser) {
@@ -2622,10 +2784,10 @@ async function findEntrypoints(config) {
2622
2784
  relativePaths.sort();
2623
2785
  const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
2624
2786
  const entrypointInfos = relativePaths.reduce((results, relativePath) => {
2625
- const inputPath = (0, import_path2.resolve)(config.entrypointsDir, relativePath);
2787
+ const inputPath = (0, import_path.resolve)(config.entrypointsDir, relativePath);
2626
2788
  const name = getEntrypointName(config.entrypointsDir, inputPath);
2627
2789
  const matchingGlob = pathGlobs.find(
2628
- (glob5) => (0, import_minimatch.minimatch)(relativePath, glob5)
2790
+ (glob6) => (0, import_minimatch.minimatch)(relativePath, glob6)
2629
2791
  );
2630
2792
  if (matchingGlob) {
2631
2793
  const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
@@ -2657,7 +2819,7 @@ async function findEntrypoints(config) {
2657
2819
  return {
2658
2820
  ...info,
2659
2821
  type,
2660
- outputDir: (0, import_path2.resolve)(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2822
+ outputDir: (0, import_path.resolve)(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2661
2823
  options: {
2662
2824
  include: void 0,
2663
2825
  exclude: void 0
@@ -2719,7 +2881,7 @@ function preventDuplicateEntrypointNames(config, files) {
2719
2881
  if (absolutePaths.length > 1) {
2720
2882
  lines.push(`- ${name}`);
2721
2883
  absolutePaths.forEach((absolutePath) => {
2722
- lines.push(` - ${(0, import_path2.relative)(config.root, absolutePath)}`);
2884
+ lines.push(` - ${(0, import_path.relative)(config.root, absolutePath)}`);
2723
2885
  });
2724
2886
  }
2725
2887
  return lines;
@@ -2744,11 +2906,11 @@ function getHtmlBaseOptions(document) {
2744
2906
  const options = {};
2745
2907
  const includeContent = document.querySelector("meta[name='manifest.include']")?.getAttribute("content");
2746
2908
  if (includeContent) {
2747
- options.include = import_json5.default.parse(includeContent);
2909
+ options.include = import_json52.default.parse(includeContent);
2748
2910
  }
2749
2911
  const excludeContent = document.querySelector("meta[name='manifest.exclude']")?.getAttribute("content");
2750
2912
  if (excludeContent) {
2751
- options.exclude = import_json5.default.parse(excludeContent);
2913
+ options.exclude = import_json52.default.parse(excludeContent);
2752
2914
  }
2753
2915
  return options;
2754
2916
  }
@@ -2762,7 +2924,7 @@ async function getPopupEntrypoint(config, { inputPath, name }) {
2762
2924
  const defaultIconContent = document.querySelector("meta[name='manifest.default_icon']")?.getAttribute("content");
2763
2925
  if (defaultIconContent) {
2764
2926
  try {
2765
- options.defaultIcon = import_json5.default.parse(defaultIconContent);
2927
+ options.defaultIcon = import_json52.default.parse(defaultIconContent);
2766
2928
  } catch (err) {
2767
2929
  config.logger.fatal(
2768
2930
  `Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
@@ -2879,7 +3041,7 @@ async function getContentScriptEntrypoint(config, { inputPath, name }) {
2879
3041
  type: "content-script",
2880
3042
  name,
2881
3043
  inputPath,
2882
- outputDir: (0, import_path2.resolve)(config.outDir, CONTENT_SCRIPT_OUT_DIR),
3044
+ outputDir: (0, import_path.resolve)(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2883
3045
  options
2884
3046
  };
2885
3047
  }
@@ -2927,7 +3089,7 @@ var CONTENT_SCRIPT_OUT_DIR = "content-scripts";
2927
3089
  // src/core/utils/building/generate-wxt-dir.ts
2928
3090
  var import_unimport = require("unimport");
2929
3091
  var import_fs_extra4 = __toESM(require("fs-extra"), 1);
2930
- var import_path3 = require("path");
3092
+ var import_path2 = require("path");
2931
3093
 
2932
3094
  // src/core/utils/unimport.ts
2933
3095
  var import_defu = require("defu");
@@ -2938,7 +3100,8 @@ function getUnimportOptions(config) {
2938
3100
  debugLog: config.logger.debug,
2939
3101
  imports: [
2940
3102
  { name: "defineConfig", from: "wxt" },
2941
- { name: "fakeBrowser", from: "wxt/testing" }
3103
+ { name: "fakeBrowser", from: "wxt/testing" },
3104
+ { name: "i18n", from: "wxt/i18n" }
2942
3105
  ],
2943
3106
  presets: [
2944
3107
  { package: "wxt/client" },
@@ -3011,46 +3174,7 @@ function surroundInUnderscore(name) {
3011
3174
  }
3012
3175
 
3013
3176
  // src/core/utils/building/generate-wxt-dir.ts
3014
- var import_node_path3 = __toESM(require("path"), 1);
3015
-
3016
- // src/core/utils/i18n.ts
3017
- var predefinedMessages = {
3018
- "@@extension_id": {
3019
- message: "<browser.runtime.id>",
3020
- description: "The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even unlocalized extensions can use this message.\nNote: You can't use this message in a manifest file."
3021
- },
3022
- "@@ui_locale": {
3023
- message: "<browser.i18n.getUiLocale()>",
3024
- description: ""
3025
- },
3026
- "@@bidi_dir": {
3027
- message: "<ltr|rtl>",
3028
- description: 'The text direction for the current locale, either "ltr" for left-to-right languages such as English or "rtl" for right-to-left languages such as Japanese.'
3029
- },
3030
- "@@bidi_reversed_dir": {
3031
- message: "<rtl|ltr>",
3032
- description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
3033
- },
3034
- "@@bidi_start_edge": {
3035
- message: "<left|right>",
3036
- description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
3037
- },
3038
- "@@bidi_end_edge": {
3039
- message: "<right|left>",
3040
- description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
3041
- }
3042
- };
3043
- function parseI18nMessages(messagesJson) {
3044
- return Object.entries({
3045
- ...predefinedMessages,
3046
- ...messagesJson
3047
- }).map(([name, details]) => ({
3048
- name,
3049
- ...details
3050
- }));
3051
- }
3052
-
3053
- // src/core/utils/building/generate-wxt-dir.ts
3177
+ var import_fast_glob3 = __toESM(require("fast-glob"), 1);
3054
3178
  async function generateTypesDir(entrypoints, config) {
3055
3179
  await import_fs_extra4.default.ensureDir(config.typesDir);
3056
3180
  const references = [];
@@ -3065,7 +3189,7 @@ async function generateTypesDir(entrypoints, config) {
3065
3189
  await writeTsConfigFile(mainReference, config);
3066
3190
  }
3067
3191
  async function writeImportsDeclarationFile(config, unimportOptions) {
3068
- const filePath = (0, import_path3.resolve)(config.typesDir, "imports.d.ts");
3192
+ const filePath = (0, import_path2.resolve)(config.typesDir, "imports.d.ts");
3069
3193
  const unimport2 = (0, import_unimport.createUnimport)(unimportOptions);
3070
3194
  await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
3071
3195
  await writeFileIfDifferent(
@@ -3077,14 +3201,14 @@ async function writeImportsDeclarationFile(config, unimportOptions) {
3077
3201
  return filePath;
3078
3202
  }
3079
3203
  async function writePathsDeclarationFile(entrypoints, config) {
3080
- const filePath = (0, import_path3.resolve)(config.typesDir, "paths.d.ts");
3204
+ const filePath = (0, import_path2.resolve)(config.typesDir, "paths.d.ts");
3081
3205
  const unions = entrypoints.map(
3082
3206
  (entry) => getEntrypointBundlePath(
3083
3207
  entry,
3084
3208
  config.outDir,
3085
3209
  entry.inputPath.endsWith(".html") ? ".html" : ".js"
3086
3210
  )
3087
- ).concat(await getPublicFiles(config)).map(normalizePath).map((path10) => ` | "/${path10}"`).sort().join("\n");
3211
+ ).concat(await getPublicFiles(config)).map(normalizePath).map((path9) => ` | "/${path9}"`).sort().join("\n");
3088
3212
  const template = `// Generated by wxt
3089
3213
  import "wxt/browser";
3090
3214
 
@@ -3103,7 +3227,7 @@ declare module "wxt/browser" {
3103
3227
  return filePath;
3104
3228
  }
3105
3229
  async function writeI18nDeclarationFile(config) {
3106
- const filePath = (0, import_path3.resolve)(config.typesDir, "i18n.d.ts");
3230
+ const filePath = (0, import_path2.resolve)(config.typesDir, "i18n.d.ts");
3107
3231
  const defaultLocale = config.manifest.default_locale;
3108
3232
  const template = `// Generated by wxt
3109
3233
  import "wxt/browser";
@@ -3120,28 +3244,36 @@ declare module "wxt/browser" {
3120
3244
  }
3121
3245
 
3122
3246
  export interface WxtI18n extends I18n.Static {
3123
- {{ overrides }}
3247
+ {{ browserOverrides }}
3248
+ }
3249
+ }
3250
+
3251
+ declare module "wxt/i18n" {
3252
+ export interface WxtMessageSchema {
3253
+ t: {
3254
+ {{ translationTOverrides }}
3255
+ };
3256
+ tp: {
3257
+ {{ translationTpOverrides }}
3258
+ };
3124
3259
  }
3125
3260
  }
3126
3261
  `;
3127
3262
  let messages;
3128
3263
  if (defaultLocale) {
3129
- const defaultLocalePath = import_node_path3.default.resolve(
3130
- config.publicDir,
3131
- "_locales",
3132
- defaultLocale,
3133
- "messages.json"
3134
- );
3135
- const content = JSON.parse(await import_fs_extra4.default.readFile(defaultLocalePath, "utf-8"));
3136
- messages = parseI18nMessages(content);
3264
+ const [defaultLocalePath] = await (0, import_fast_glob3.default)(`${defaultLocale}.*`, {
3265
+ cwd: config.localesDir,
3266
+ absolute: true
3267
+ });
3268
+ messages = await readMessagesFile(defaultLocalePath);
3137
3269
  } else {
3138
- messages = parseI18nMessages({});
3270
+ messages = PREDEFINED_MESSAGES;
3139
3271
  }
3140
3272
  const overrides = messages.map((message) => {
3141
3273
  return ` /**
3142
- * ${message.description ?? "No message description."}
3274
+ * ${message.entry.description ?? "No message description."}
3143
3275
  *
3144
- * "${message.message}"
3276
+ * "${message.entry.message}"
3145
3277
  */
3146
3278
  getMessage(
3147
3279
  messageName: "${message.name}",
@@ -3151,12 +3283,18 @@ declare module "wxt/browser" {
3151
3283
  });
3152
3284
  await writeFileIfDifferent(
3153
3285
  filePath,
3154
- template.replace("{{ overrides }}", overrides.join("\n"))
3286
+ template.replace("{{ browserOverrides }}", overrides.join("\n")).replace(
3287
+ "{{ translationTOverrides }}",
3288
+ messages.filter((message) => !message.isPlural).map((message) => ` "${message.name}": any;`).join("\n")
3289
+ ).replace(
3290
+ "{{ translationTpOverrides }}",
3291
+ messages.filter((message) => message.isPlural).map((message) => ` "${message.name}": any;`).join("\n")
3292
+ )
3155
3293
  );
3156
3294
  return filePath;
3157
3295
  }
3158
3296
  async function writeGlobalsDeclarationFile(config) {
3159
- const filePath = (0, import_path3.resolve)(config.typesDir, "globals.d.ts");
3297
+ const filePath = (0, import_path2.resolve)(config.typesDir, "globals.d.ts");
3160
3298
  const globals2 = [...getGlobals(config), ...getEntrypointGlobals("")];
3161
3299
  await writeFileIfDifferent(
3162
3300
  filePath,
@@ -3172,14 +3310,14 @@ async function writeGlobalsDeclarationFile(config) {
3172
3310
  }
3173
3311
  async function writeMainDeclarationFile(references, config) {
3174
3312
  const dir = config.wxtDir;
3175
- const filePath = (0, import_path3.resolve)(dir, "wxt.d.ts");
3313
+ const filePath = (0, import_path2.resolve)(dir, "wxt.d.ts");
3176
3314
  await writeFileIfDifferent(
3177
3315
  filePath,
3178
3316
  [
3179
3317
  "// Generated by wxt",
3180
3318
  `/// <reference types="wxt/vite-builder-env" />`,
3181
3319
  ...references.map(
3182
- (ref) => `/// <reference types="./${normalizePath((0, import_path3.relative)(dir, ref))}" />`
3320
+ (ref) => `/// <reference types="./${normalizePath((0, import_path2.relative)(dir, ref))}" />`
3183
3321
  )
3184
3322
  ].join("\n") + "\n"
3185
3323
  );
@@ -3187,7 +3325,7 @@ async function writeMainDeclarationFile(references, config) {
3187
3325
  }
3188
3326
  async function writeTsConfigFile(mainReference, config) {
3189
3327
  const dir = config.wxtDir;
3190
- const getTsconfigPath = (path10) => normalizePath((0, import_path3.relative)(dir, path10));
3328
+ const getTsconfigPath = (path9) => normalizePath((0, import_path2.relative)(dir, path9));
3191
3329
  const paths = Object.entries(config.alias).flatMap(([alias, absolutePath]) => {
3192
3330
  const aliasPath = getTsconfigPath(absolutePath);
3193
3331
  return [
@@ -3196,7 +3334,7 @@ async function writeTsConfigFile(mainReference, config) {
3196
3334
  ];
3197
3335
  }).join(",\n");
3198
3336
  await writeFileIfDifferent(
3199
- (0, import_path3.resolve)(dir, "tsconfig.json"),
3337
+ (0, import_path2.resolve)(dir, "tsconfig.json"),
3200
3338
  `{
3201
3339
  "compilerOptions": {
3202
3340
  "target": "ESNext",
@@ -3227,19 +3365,19 @@ var import_node_path7 = __toESM(require("path"), 1);
3227
3365
 
3228
3366
  // src/core/utils/cache.ts
3229
3367
  var import_fs_extra5 = __toESM(require("fs-extra"), 1);
3230
- var import_path4 = require("path");
3368
+ var import_path3 = require("path");
3231
3369
  function createFsCache(wxtDir) {
3232
- const getPath = (key) => (0, import_path4.resolve)(wxtDir, "cache", encodeURIComponent(key));
3370
+ const getPath = (key) => (0, import_path3.resolve)(wxtDir, "cache", encodeURIComponent(key));
3233
3371
  return {
3234
3372
  async set(key, value) {
3235
- const path10 = getPath(key);
3236
- await (0, import_fs_extra5.ensureDir)((0, import_path4.dirname)(path10));
3237
- await writeFileIfDifferent(path10, value);
3373
+ const path9 = getPath(key);
3374
+ await (0, import_fs_extra5.ensureDir)((0, import_path3.dirname)(path9));
3375
+ await writeFileIfDifferent(path9, value);
3238
3376
  },
3239
3377
  async get(key) {
3240
- const path10 = getPath(key);
3378
+ const path9 = getPath(key);
3241
3379
  try {
3242
- return await import_fs_extra5.default.readFile(path10, "utf-8");
3380
+ return await import_fs_extra5.default.readFile(path9, "utf-8");
3243
3381
  } catch {
3244
3382
  return void 0;
3245
3383
  }
@@ -3521,7 +3659,7 @@ async function removeEmptyDirs(dir) {
3521
3659
 
3522
3660
  // src/core/builders/vite/plugins/unimport.ts
3523
3661
  var import_unimport3 = require("unimport");
3524
- var import_path5 = require("path");
3662
+ var import_path4 = require("path");
3525
3663
  var ENABLED_EXTENSIONS = /* @__PURE__ */ new Set([
3526
3664
  ".js",
3527
3665
  ".jsx",
@@ -3543,7 +3681,7 @@ function unimport(config) {
3543
3681
  async transform(code, id) {
3544
3682
  if (id.includes("node_modules"))
3545
3683
  return;
3546
- if (!ENABLED_EXTENSIONS.has((0, import_path5.extname)(id)))
3684
+ if (!ENABLED_EXTENSIONS.has((0, import_path4.extname)(id)))
3547
3685
  return;
3548
3686
  return unimport2.injectImports(code, id);
3549
3687
  }
@@ -3552,7 +3690,7 @@ function unimport(config) {
3552
3690
 
3553
3691
  // src/core/builders/vite/plugins/virtualEntrypoint.ts
3554
3692
  var import_fs_extra7 = __toESM(require("fs-extra"), 1);
3555
- var import_path6 = require("path");
3693
+ var import_path5 = require("path");
3556
3694
  function virtualEntrypoint(type, config) {
3557
3695
  const virtualId = `virtual:wxt-${type}?`;
3558
3696
  const resolvedVirtualId = `\0${virtualId}`;
@@ -3570,7 +3708,7 @@ function virtualEntrypoint(type, config) {
3570
3708
  return;
3571
3709
  const inputPath = id.replace(resolvedVirtualId, "");
3572
3710
  const template = await import_fs_extra7.default.readFile(
3573
- (0, import_path6.resolve)(
3711
+ (0, import_path5.resolve)(
3574
3712
  config.root,
3575
3713
  `node_modules/wxt/dist/virtual/${type}-entrypoint.js`
3576
3714
  ),
@@ -3710,7 +3848,7 @@ function entrypointGroupGlobals(entrypointGroup) {
3710
3848
  }
3711
3849
 
3712
3850
  // src/core/builders/vite/index.ts
3713
- async function craeteViteBuilder(inlineConfig, userConfig, wxtConfig) {
3851
+ async function createViteBuilder(inlineConfig, userConfig, wxtConfig) {
3714
3852
  const vite = await import("vite");
3715
3853
  const getBaseConfig = async () => {
3716
3854
  const resolvedInlineConfig = await inlineConfig.vite?.(wxtConfig.env) ?? {};
@@ -3948,6 +4086,7 @@ async function getInternalConfig(inlineConfig, command, server) {
3948
4086
  mergedConfig.entrypointsDir ?? "entrypoints"
3949
4087
  );
3950
4088
  const publicDir = import_node_path7.default.resolve(srcDir, mergedConfig.publicDir ?? "public");
4089
+ const localesDir = import_node_path7.default.resolve(srcDir, mergedConfig.localesDir ?? "locales");
3951
4090
  const typesDir = import_node_path7.default.resolve(wxtDir, "types");
3952
4091
  const outBaseDir = import_node_path7.default.resolve(root, mergedConfig.outDir ?? ".output");
3953
4092
  const outDir = import_node_path7.default.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
@@ -3983,6 +4122,7 @@ async function getInternalConfig(inlineConfig, command, server) {
3983
4122
  outBaseDir,
3984
4123
  outDir,
3985
4124
  publicDir,
4125
+ localesDir,
3986
4126
  root,
3987
4127
  runnerConfig,
3988
4128
  srcDir,
@@ -4004,7 +4144,7 @@ async function getInternalConfig(inlineConfig, command, server) {
4004
4144
  },
4005
4145
  server
4006
4146
  };
4007
- const builder = await craeteViteBuilder(
4147
+ const builder = await createViteBuilder(
4008
4148
  inlineConfig,
4009
4149
  userConfig,
4010
4150
  finalConfig
@@ -4051,6 +4191,7 @@ function mergeInlineConfig(inlineConfig, userConfig) {
4051
4191
  manifest,
4052
4192
  mode: inlineConfig.mode ?? userConfig.mode,
4053
4193
  publicDir: inlineConfig.publicDir ?? userConfig.publicDir,
4194
+ localesDir: inlineConfig.localesDir ?? userConfig.localesDir,
4054
4195
  runner,
4055
4196
  srcDir: inlineConfig.srcDir ?? userConfig.srcDir,
4056
4197
  outDir: inlineConfig.outDir ?? userConfig.outDir,
@@ -4156,16 +4297,16 @@ ${noImports}`;
4156
4297
  var import_esbuild = require("esbuild");
4157
4298
  var import_node_url = require("url");
4158
4299
  var import_meta = {};
4159
- async function importEntrypointFile(path10, config) {
4160
- config.logger.debug("Loading file metadata:", path10);
4161
- const normalPath = normalizePath(path10);
4300
+ async function importEntrypointFile(path9, config) {
4301
+ config.logger.debug("Loading file metadata:", path9);
4302
+ const normalPath = normalizePath(path9);
4162
4303
  const unimport2 = (0, import_unimport5.createUnimport)({
4163
4304
  ...getUnimportOptions(config),
4164
4305
  // Only allow specific imports, not all from the project
4165
4306
  dirs: []
4166
4307
  });
4167
4308
  await unimport2.init();
4168
- const text = await import_fs_extra8.default.readFile(path10, "utf-8");
4309
+ const text = await import_fs_extra8.default.readFile(path9, "utf-8");
4169
4310
  const textNoImports = removeProjectImportStatements(text);
4170
4311
  const { code } = await unimport2.injectImports(textNoImports);
4171
4312
  config.logger.debug(
@@ -4208,7 +4349,7 @@ async function importEntrypointFile(path10, config) {
4208
4349
  }
4209
4350
  );
4210
4351
  try {
4211
- const res = await jiti(path10);
4352
+ const res = await jiti(path9);
4212
4353
  return res.default;
4213
4354
  } catch (err) {
4214
4355
  config.logger.error(err);
@@ -4229,7 +4370,7 @@ var import_picocolors4 = __toESM(require("picocolors"), 1);
4229
4370
  var import_fs_extra12 = __toESM(require("fs-extra"), 1);
4230
4371
 
4231
4372
  // src/core/utils/log/printBuildSummary.ts
4232
- var import_path7 = require("path");
4373
+ var import_path6 = require("path");
4233
4374
 
4234
4375
  // src/core/utils/log/printFileList.ts
4235
4376
  var import_node_path9 = __toESM(require("path"), 1);
@@ -4316,7 +4457,7 @@ async function printBuildSummary(log, header, output, config) {
4316
4457
  return diff;
4317
4458
  return l.fileName.localeCompare(r.fileName);
4318
4459
  });
4319
- const files = chunks.map((chunk) => (0, import_path7.resolve)(config.outDir, chunk.fileName));
4460
+ const files = chunks.map((chunk) => (0, import_path6.resolve)(config.outDir, chunk.fileName));
4320
4461
  await printFileList(log, header, config.outDir, files);
4321
4462
  }
4322
4463
  var DEFAULT_SORT_WEIGHT = 100;
@@ -4337,17 +4478,17 @@ function getChunkSortWeight(filename) {
4337
4478
  var import_picocolors3 = __toESM(require("picocolors"), 1);
4338
4479
 
4339
4480
  // package.json
4340
- var version = "0.14.0";
4481
+ var version = "0.14.2-alpha2";
4341
4482
 
4342
4483
  // src/core/utils/log/printHeader.ts
4343
4484
  var import_consola2 = require("consola");
4344
4485
 
4345
4486
  // src/core/utils/building/internal-build.ts
4346
- var import_fast_glob3 = __toESM(require("fast-glob"), 1);
4487
+ var import_fast_glob4 = __toESM(require("fast-glob"), 1);
4347
4488
 
4348
4489
  // src/core/utils/manifest.ts
4349
4490
  var import_fs_extra11 = __toESM(require("fs-extra"), 1);
4350
- var import_path8 = require("path");
4491
+ var import_path7 = require("path");
4351
4492
 
4352
4493
  // src/core/utils/content-security-policy.ts
4353
4494
  var ContentSecurityPolicy = class _ContentSecurityPolicy {
@@ -4471,7 +4612,7 @@ var import_defu3 = __toESM(require("defu"), 1);
4471
4612
  async function writeManifest(manifest, output, config) {
4472
4613
  const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
4473
4614
  await import_fs_extra11.default.ensureDir(config.outDir);
4474
- await writeFileIfDifferent((0, import_path8.resolve)(config.outDir, "manifest.json"), str);
4615
+ await writeFileIfDifferent((0, import_path7.resolve)(config.outDir, "manifest.json"), str);
4475
4616
  output.publicAssets.unshift({
4476
4617
  type: "asset",
4477
4618
  fileName: "manifest.json"
@@ -4500,7 +4641,7 @@ async function generateManifest(entrypoints, buildOutput, config) {
4500
4641
  "wxt:reload-extension": {
4501
4642
  description: "Reload the extension during development",
4502
4643
  suggested_key: {
4503
- default: "Ctrl+E"
4644
+ default: "Alt+R"
4504
4645
  }
4505
4646
  }
4506
4647
  };
@@ -4873,13 +5014,12 @@ function stripPathFromMatchPattern(pattern) {
4873
5014
  }
4874
5015
 
4875
5016
  // src/core/utils/building/rebuild.ts
4876
- async function rebuild(config, entrypointGroups, existingOutput = {
5017
+ async function rebuild(config, allEntrypoints, entrypointGroups, existingOutput = {
4877
5018
  steps: [],
4878
5019
  publicAssets: []
4879
5020
  }) {
4880
5021
  const { default: ora } = await import("ora");
4881
5022
  const spinner = ora(`Preparing...`).start();
4882
- const allEntrypoints = await findEntrypoints(config);
4883
5023
  await generateTypesDir(allEntrypoints, config).catch((err) => {
4884
5024
  config.logger.warn("Failed to update .wxt directory:", err);
4885
5025
  if (config.command === "build")
@@ -4929,7 +5069,7 @@ async function internalBuild(config) {
4929
5069
  const entrypoints = await findEntrypoints(config);
4930
5070
  config.logger.debug("Detected entrypoints:", entrypoints);
4931
5071
  const groups = groupEntrypoints(entrypoints);
4932
- const { output } = await rebuild(config, groups, void 0);
5072
+ const { output } = await rebuild(config, entrypoints, groups, void 0);
4933
5073
  await printBuildSummary(
4934
5074
  config.logger.success,
4935
5075
  `Built extension in ${formatDuration(Date.now() - startTime)}`,
@@ -4947,7 +5087,7 @@ async function internalBuild(config) {
4947
5087
  }
4948
5088
  async function combineAnalysisStats(config) {
4949
5089
  const { execaCommand: execaCommand2 } = await Promise.resolve().then(() => (init_execa(), execa_exports));
4950
- const unixFiles = await (0, import_fast_glob3.default)(`stats-*.json`, {
5090
+ const unixFiles = await (0, import_fast_glob4.default)(`stats-*.json`, {
4951
5091
  cwd: config.outDir,
4952
5092
  absolute: true
4953
5093
  });
@@ -4966,7 +5106,7 @@ async function build(config) {
4966
5106
 
4967
5107
  // src/core/clean.ts
4968
5108
  var import_node_path13 = __toESM(require("path"), 1);
4969
- var import_fast_glob4 = __toESM(require("fast-glob"), 1);
5109
+ var import_fast_glob5 = __toESM(require("fast-glob"), 1);
4970
5110
  var import_fs_extra13 = __toESM(require("fs-extra"), 1);
4971
5111
  var import_consola3 = require("consola");
4972
5112
  var import_picocolors5 = __toESM(require("picocolors"), 1);
@@ -4979,7 +5119,7 @@ async function clean(root = process.cwd()) {
4979
5119
  ".output/*"
4980
5120
  ];
4981
5121
  import_consola3.consola.debug("Looking for:", tempDirs.map(import_picocolors5.default.cyan).join(", "));
4982
- const directories = await (0, import_fast_glob4.default)(tempDirs, {
5122
+ const directories = await (0, import_fast_glob5.default)(tempDirs, {
4983
5123
  cwd: import_node_path13.default.resolve(root),
4984
5124
  absolute: true,
4985
5125
  onlyDirectories: true,
@@ -5171,8 +5311,8 @@ async function createServer(inlineConfig) {
5171
5311
  reloadContentScript(contentScript) {
5172
5312
  server.ws.send("wxt:reload-content-script", contentScript);
5173
5313
  },
5174
- reloadPage(path10) {
5175
- server.ws.send("wxt:reload-page", path10);
5314
+ reloadPage(path9) {
5315
+ server.ws.send("wxt:reload-page", path9);
5176
5316
  },
5177
5317
  reloadExtension() {
5178
5318
  server.ws.send("wxt:reload-extension");
@@ -5207,12 +5347,12 @@ function createFileReloader(options) {
5207
5347
  const { server, getLatestConfig, updateConfig } = options;
5208
5348
  const fileChangedMutex = new import_async_mutex.Mutex();
5209
5349
  const changeQueue = [];
5210
- return async (event, path10) => {
5350
+ return async (event, path9) => {
5211
5351
  const config = await getLatestConfig();
5212
5352
  updateConfig(config);
5213
- if (path10.startsWith(config.outBaseDir))
5353
+ if (path9.startsWith(config.outBaseDir))
5214
5354
  return;
5215
- changeQueue.push([event, path10]);
5355
+ changeQueue.push([event, path9]);
5216
5356
  await fileChangedMutex.runExclusive(async () => {
5217
5357
  const fileChanges = changeQueue.splice(0, changeQueue.length);
5218
5358
  if (fileChanges.length === 0)
@@ -5228,8 +5368,10 @@ function createFileReloader(options) {
5228
5368
  (0, import_node_path17.relative)(config.outDir, getEntrypointOutputFile(entry, ""))
5229
5369
  );
5230
5370
  }).join(import_picocolors6.default.dim(", "));
5371
+ const allEntrypoints = await findEntrypoints(config);
5231
5372
  const { output: newOutput } = await rebuild(
5232
5373
  config,
5374
+ allEntrypoints,
5233
5375
  // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
5234
5376
  changes.rebuildGroups,
5235
5377
  changes.cachedOutput
@@ -5282,8 +5424,8 @@ function reloadContentScripts(steps, config, server) {
5282
5424
  }
5283
5425
  function reloadHtmlPages(groups, server, config) {
5284
5426
  groups.flat().forEach((entry) => {
5285
- const path10 = getEntrypointBundlePath(entry, config.outDir, ".html");
5286
- server.reloadPage(path10);
5427
+ const path9 = getEntrypointBundlePath(entry, config.outDir, ".html");
5428
+ server.reloadPage(path9);
5287
5429
  });
5288
5430
  }
5289
5431
 
@@ -5459,8 +5601,8 @@ async function zip(config) {
5459
5601
  );
5460
5602
  await (0, import_zip_dir.default)(internalConfig.zip.sourcesRoot, {
5461
5603
  saveTo: sourcesZipPath,
5462
- filter(path10) {
5463
- const relativePath = (0, import_node_path19.relative)(internalConfig.zip.sourcesRoot, path10);
5604
+ filter(path9) {
5605
+ const relativePath = (0, import_node_path19.relative)(internalConfig.zip.sourcesRoot, path9);
5464
5606
  const matchedPattern = internalConfig.zip.ignoredSources.find(
5465
5607
  (pattern) => (0, import_minimatch2.minimatch)(relativePath, pattern)
5466
5608
  );