wxt 0.17.4 → 0.17.5

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
@@ -13,21 +13,229 @@ import glob from "fast-glob";
13
13
  // src/core/utils/paths.ts
14
14
  import systemPath from "node:path";
15
15
  import normalize from "normalize-path";
16
- function normalizePath(path8) {
17
- return normalize(path8);
16
+ function normalizePath(path10) {
17
+ return normalize(path10);
18
18
  }
19
- function unnormalizePath(path8) {
20
- return systemPath.normalize(path8);
19
+ function unnormalizePath(path10) {
20
+ return systemPath.normalize(path10);
21
21
  }
22
22
  var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
23
23
  var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
24
24
 
25
25
  // src/core/wxt.ts
26
26
  import { createHooks } from "hookable";
27
+
28
+ // src/core/package-managers/index.ts
29
+ import {
30
+ detectPackageManager,
31
+ addDependency,
32
+ addDevDependency,
33
+ ensureDependencyInstalled,
34
+ installDependencies,
35
+ removeDependency
36
+ } from "nypm";
37
+
38
+ // src/core/package-managers/npm.ts
39
+ import path from "node:path";
40
+ import { ensureDir } from "fs-extra";
41
+ var npm = {
42
+ overridesKey: "overrides",
43
+ async downloadDependency(id, downloadDir) {
44
+ await ensureDir(downloadDir);
45
+ const { execa } = await import("./execa-Y2EWTC4S.js");
46
+ const res = await execa("npm", ["pack", id, "--json"], {
47
+ cwd: downloadDir
48
+ });
49
+ const packed = JSON.parse(res.stdout);
50
+ return path.resolve(downloadDir, packed[0].filename);
51
+ },
52
+ async listDependencies(options) {
53
+ const args = ["ls", "--json"];
54
+ if (options?.all) {
55
+ args.push("--depth", "Infinity");
56
+ }
57
+ const { execa } = await import("./execa-Y2EWTC4S.js");
58
+ const res = await execa("npm", args, { cwd: options?.cwd });
59
+ const project = JSON.parse(res.stdout);
60
+ return flattenNpmListOutput([project]);
61
+ }
62
+ };
63
+ function flattenNpmListOutput(projects) {
64
+ const queue = projects.flatMap(
65
+ (project) => {
66
+ const acc = [];
67
+ if (project.dependencies)
68
+ acc.push(project.dependencies);
69
+ if (project.devDependencies)
70
+ acc.push(project.devDependencies);
71
+ return acc;
72
+ }
73
+ );
74
+ const dependencies = [];
75
+ while (queue.length > 0) {
76
+ Object.entries(queue.pop()).forEach(([name, meta]) => {
77
+ dependencies.push({
78
+ name,
79
+ version: meta.version
80
+ });
81
+ if (meta.dependencies)
82
+ queue.push(meta.dependencies);
83
+ if (meta.devDependencies)
84
+ queue.push(meta.devDependencies);
85
+ });
86
+ }
87
+ return dedupeDependencies(dependencies);
88
+ }
89
+ function dedupeDependencies(dependencies) {
90
+ const hashes = /* @__PURE__ */ new Set();
91
+ return dependencies.filter((dep) => {
92
+ const hash = `${dep.name}@${dep.version}`;
93
+ if (hashes.has(hash)) {
94
+ return false;
95
+ } else {
96
+ hashes.add(hash);
97
+ return true;
98
+ }
99
+ });
100
+ }
101
+
102
+ // src/core/package-managers/bun.ts
103
+ var bun = {
104
+ overridesKey: "overrides",
105
+ // But also supports "resolutions"
106
+ downloadDependency(...args) {
107
+ return npm.downloadDependency(...args);
108
+ },
109
+ async listDependencies(options) {
110
+ const args = ["pm", "ls"];
111
+ if (options?.all) {
112
+ args.push("--all");
113
+ }
114
+ const { execa } = await import("./execa-Y2EWTC4S.js");
115
+ const res = await execa("bun", args, { cwd: options?.cwd });
116
+ return dedupeDependencies(
117
+ res.stdout.split("\n").slice(1).map((line) => line.trim()).map((line) => /.* (@?\S+)@(\S+)$/.exec(line)).filter((match) => !!match).map(([_, name, version2]) => ({ name, version: version2 }))
118
+ );
119
+ }
120
+ };
121
+
122
+ // src/core/package-managers/yarn.ts
123
+ var yarn = {
124
+ overridesKey: "resolutions",
125
+ downloadDependency(...args) {
126
+ return npm.downloadDependency(...args);
127
+ },
128
+ async listDependencies(options) {
129
+ const args = ["list", "--json"];
130
+ if (options?.all) {
131
+ args.push("--depth", "Infinity");
132
+ }
133
+ const { execa } = await import("./execa-Y2EWTC4S.js");
134
+ const res = await execa("yarn", args, { cwd: options?.cwd });
135
+ const tree = res.stdout.split("\n").map((line) => JSON.parse(line)).find((line) => line.type === "tree")?.data;
136
+ if (tree == null)
137
+ throw Error("'yarn list --json' did not output a tree");
138
+ const queue = [...tree.trees];
139
+ const dependencies = [];
140
+ while (queue.length > 0) {
141
+ const { name: treeName, children } = queue.pop();
142
+ const match = /(@?\S+)@(\S+)$/.exec(treeName);
143
+ if (match) {
144
+ const [_, name, version2] = match;
145
+ dependencies.push({ name, version: version2 });
146
+ }
147
+ if (children != null) {
148
+ queue.push(...children);
149
+ }
150
+ }
151
+ return dedupeDependencies(dependencies);
152
+ }
153
+ };
154
+
155
+ // src/core/package-managers/pnpm.ts
156
+ var pnpm = {
157
+ overridesKey: "resolutions",
158
+ // "pnpm.overrides" has a higher priority, but I don't want to deal with nesting
159
+ downloadDependency(...args) {
160
+ return npm.downloadDependency(...args);
161
+ },
162
+ async listDependencies(options) {
163
+ const args = ["ls", "--json"];
164
+ if (options?.all) {
165
+ args.push("--depth", "Infinity");
166
+ }
167
+ if (typeof process !== "undefined" && process.env.WXT_PNPM_IGNORE_WORKSPACE === "true") {
168
+ args.push("--ignore-workspace");
169
+ }
170
+ const { execa } = await import("./execa-Y2EWTC4S.js");
171
+ const res = await execa("pnpm", args, { cwd: options?.cwd });
172
+ const projects = JSON.parse(res.stdout);
173
+ return flattenNpmListOutput(projects);
174
+ }
175
+ };
176
+
177
+ // src/core/package-managers/index.ts
178
+ async function createWxtPackageManager(root) {
179
+ const pm = await detectPackageManager(root, {
180
+ includeParentDirs: true
181
+ });
182
+ const requirePm = (cb) => {
183
+ if (pm == null)
184
+ throw Error("Could not detect package manager");
185
+ return cb(pm);
186
+ };
187
+ return {
188
+ get name() {
189
+ return requirePm((pm2) => pm2.name);
190
+ },
191
+ get command() {
192
+ return requirePm((pm2) => pm2.command);
193
+ },
194
+ get version() {
195
+ return requirePm((pm2) => pm2.version);
196
+ },
197
+ get majorVersion() {
198
+ return requirePm((pm2) => pm2.majorVersion);
199
+ },
200
+ get lockFile() {
201
+ return requirePm((pm2) => pm2.lockFile);
202
+ },
203
+ get files() {
204
+ return requirePm((pm2) => pm2.files);
205
+ },
206
+ addDependency,
207
+ addDevDependency,
208
+ ensureDependencyInstalled,
209
+ installDependencies,
210
+ removeDependency,
211
+ get overridesKey() {
212
+ return requirePm((pm2) => packageManagers[pm2.name].overridesKey);
213
+ },
214
+ downloadDependency(...args) {
215
+ return requirePm(
216
+ (pm2) => packageManagers[pm2.name].downloadDependency(...args)
217
+ );
218
+ },
219
+ listDependencies(...args) {
220
+ return requirePm(
221
+ (pm2) => packageManagers[pm2.name].listDependencies(...args)
222
+ );
223
+ }
224
+ };
225
+ }
226
+ var packageManagers = {
227
+ npm,
228
+ pnpm,
229
+ bun,
230
+ yarn
231
+ };
232
+
233
+ // src/core/wxt.ts
27
234
  var wxt;
28
235
  async function registerWxt(command, inlineConfig = {}, server) {
29
236
  const config = await resolveConfig(inlineConfig, command, server);
30
237
  const hooks = createHooks();
238
+ const pm = await createWxtPackageManager(config.root);
31
239
  wxt = {
32
240
  config,
33
241
  hooks,
@@ -36,7 +244,8 @@ async function registerWxt(command, inlineConfig = {}, server) {
36
244
  },
37
245
  async reloadConfig() {
38
246
  wxt.config = await resolveConfig(inlineConfig, command, server);
39
- }
247
+ },
248
+ pm
40
249
  };
41
250
  wxt.hooks.addHooks(config.hooks);
42
251
  await wxt.hooks.callHook("ready", wxt);
@@ -212,9 +421,9 @@ import JSON5 from "json5";
212
421
  import glob2 from "fast-glob";
213
422
 
214
423
  // src/core/utils/entrypoints.ts
215
- import path, { relative, resolve as resolve2 } from "node:path";
424
+ import path2, { relative, resolve as resolve2 } from "node:path";
216
425
  function getEntrypointName(entrypointsDir, inputPath) {
217
- const relativePath = path.relative(entrypointsDir, inputPath);
426
+ const relativePath = path2.relative(entrypointsDir, inputPath);
218
427
  const name = relativePath.split(/[\.\/\\]/, 2)[0];
219
428
  return name;
220
429
  }
@@ -258,7 +467,7 @@ async function findEntrypoints() {
258
467
  const inputPath = resolve3(wxt.config.entrypointsDir, relativePath);
259
468
  const name = getEntrypointName(wxt.config.entrypointsDir, inputPath);
260
469
  const matchingGlob = pathGlobs.find(
261
- (glob5) => minimatch(relativePath, glob5)
470
+ (glob6) => minimatch(relativePath, glob6)
262
471
  );
263
472
  if (matchingGlob) {
264
473
  const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
@@ -673,7 +882,7 @@ function getEntrypointGlobals(entrypointName) {
673
882
  }
674
883
 
675
884
  // src/core/utils/building/generate-wxt-dir.ts
676
- import path2 from "node:path";
885
+ import path3 from "node:path";
677
886
 
678
887
  // src/core/utils/i18n.ts
679
888
  var predefinedMessages = {
@@ -756,7 +965,7 @@ async function writePathsDeclarationFile(entrypoints) {
756
965
  wxt.config.outDir,
757
966
  isHtmlEntrypoint(entry) ? ".html" : ".js"
758
967
  )
759
- ).concat(await getPublicFiles()).map(normalizePath).map((path8) => ` | "/${path8}"`).sort().join("\n");
968
+ ).concat(await getPublicFiles()).map(normalizePath).map((path10) => ` | "/${path10}"`).sort().join("\n");
760
969
  const template = `// Generated by wxt
761
970
  import "wxt/browser";
762
971
 
@@ -800,7 +1009,7 @@ declare module "wxt/browser" {
800
1009
  `;
801
1010
  let messages;
802
1011
  if (defaultLocale) {
803
- const defaultLocalePath = path2.resolve(
1012
+ const defaultLocalePath = path3.resolve(
804
1013
  wxt.config.publicDir,
805
1014
  "_locales",
806
1015
  defaultLocale,
@@ -864,7 +1073,7 @@ async function writeMainDeclarationFile(references) {
864
1073
  }
865
1074
  async function writeTsConfigFile(mainReference) {
866
1075
  const dir = wxt.config.wxtDir;
867
- const getTsconfigPath = (path8) => normalizePath(relative3(dir, path8));
1076
+ const getTsconfigPath = (path10) => normalizePath(relative3(dir, path10));
868
1077
  const paths = Object.entries(wxt.config.alias).flatMap(([alias, absolutePath]) => {
869
1078
  const aliasPath = getTsconfigPath(absolutePath);
870
1079
  return [
@@ -900,23 +1109,23 @@ ${paths}
900
1109
 
901
1110
  // src/core/utils/building/resolve-config.ts
902
1111
  import { loadConfig } from "c12";
903
- import path4 from "node:path";
1112
+ import path5 from "node:path";
904
1113
 
905
1114
  // src/core/utils/cache.ts
906
- import fs5, { ensureDir } from "fs-extra";
1115
+ import fs5, { ensureDir as ensureDir2 } from "fs-extra";
907
1116
  import { dirname as dirname2, resolve as resolve5 } from "path";
908
1117
  function createFsCache(wxtDir) {
909
1118
  const getPath = (key) => resolve5(wxtDir, "cache", encodeURIComponent(key));
910
1119
  return {
911
1120
  async set(key, value) {
912
- const path8 = getPath(key);
913
- await ensureDir(dirname2(path8));
914
- await writeFileIfDifferent(path8, value);
1121
+ const path10 = getPath(key);
1122
+ await ensureDir2(dirname2(path10));
1123
+ await writeFileIfDifferent(path10, value);
915
1124
  },
916
1125
  async get(key) {
917
- const path8 = getPath(key);
1126
+ const path10 = getPath(key);
918
1127
  try {
919
- return await fs5.readFile(path8, "utf-8");
1128
+ return await fs5.readFile(path10, "utf-8");
920
1129
  } catch {
921
1130
  return void 0;
922
1131
  }
@@ -1050,10 +1259,10 @@ function pointToDevServer(config, server, id, document, querySelector, attr) {
1050
1259
  relative4(config.root, resolvedAbsolutePath)
1051
1260
  );
1052
1261
  if (relativePath.startsWith(".")) {
1053
- let path8 = normalizePath(resolvedAbsolutePath);
1054
- if (!path8.startsWith("/"))
1055
- path8 = "/" + path8;
1056
- element.setAttribute(attr, `${server.origin}/@fs${path8}`);
1262
+ let path10 = normalizePath(resolvedAbsolutePath);
1263
+ if (!path10.startsWith("/"))
1264
+ path10 = "/" + path10;
1265
+ element.setAttribute(attr, `${server.origin}/@fs${path10}`);
1057
1266
  } else {
1058
1267
  const url = new URL(relativePath, server.origin);
1059
1268
  element.setAttribute(attr, url.href);
@@ -1168,7 +1377,7 @@ function download(config) {
1168
1377
 
1169
1378
  // src/core/builders/vite/plugins/multipageMove.ts
1170
1379
  import { dirname as dirname4, extname, resolve as resolve7, join } from "node:path";
1171
- import fs6, { ensureDir as ensureDir2 } from "fs-extra";
1380
+ import fs6, { ensureDir as ensureDir3 } from "fs-extra";
1172
1381
  function multipageMove(entrypoints, config) {
1173
1382
  return {
1174
1383
  name: "wxt:multipage-move",
@@ -1197,7 +1406,7 @@ function multipageMove(entrypoints, config) {
1197
1406
  }
1198
1407
  const oldAbsPath = resolve7(config.outDir, oldBundlePath);
1199
1408
  const newAbsPath = resolve7(config.outDir, newBundlePath);
1200
- await ensureDir2(dirname4(newAbsPath));
1409
+ await ensureDir3(dirname4(newAbsPath));
1201
1410
  await fs6.move(oldAbsPath, newAbsPath, { overwrite: true });
1202
1411
  const renamedChunk = {
1203
1412
  ...bundle[oldBundlePath],
@@ -1347,12 +1556,12 @@ function cssEntrypoints(entrypoint, config) {
1347
1556
 
1348
1557
  // src/core/builders/vite/plugins/bundleAnalysis.ts
1349
1558
  import { visualizer } from "@aklinker1/rollup-plugin-visualizer";
1350
- import path3 from "node:path";
1559
+ import path4 from "node:path";
1351
1560
  var increment = 0;
1352
1561
  function bundleAnalysis(config) {
1353
1562
  return visualizer({
1354
1563
  template: "raw-data",
1355
- filename: path3.resolve(
1564
+ filename: path4.resolve(
1356
1565
  config.analysis.outputDir,
1357
1566
  `${config.analysis.outputName}-${increment++}.json`
1358
1567
  )
@@ -1697,21 +1906,21 @@ async function resolveConfig(inlineConfig, command, server) {
1697
1906
  const manifestVersion = mergedConfig.manifestVersion ?? (browser === "firefox" || browser === "safari" ? 2 : 3);
1698
1907
  const mode = mergedConfig.mode ?? (command === "build" ? "production" : "development");
1699
1908
  const env = { browser, command, manifestVersion, mode };
1700
- const root = path4.resolve(
1909
+ const root = path5.resolve(
1701
1910
  inlineConfig.root ?? userConfig.root ?? process.cwd()
1702
1911
  );
1703
- const wxtDir = path4.resolve(root, ".wxt");
1912
+ const wxtDir = path5.resolve(root, ".wxt");
1704
1913
  const wxtModuleDir = await resolveWxtModuleDir();
1705
- const srcDir = path4.resolve(root, mergedConfig.srcDir ?? root);
1706
- const entrypointsDir = path4.resolve(
1914
+ const srcDir = path5.resolve(root, mergedConfig.srcDir ?? root);
1915
+ const entrypointsDir = path5.resolve(
1707
1916
  srcDir,
1708
1917
  mergedConfig.entrypointsDir ?? "entrypoints"
1709
1918
  );
1710
1919
  const filterEntrypoints = !!mergedConfig.filterEntrypoints?.length ? new Set(mergedConfig.filterEntrypoints) : void 0;
1711
- const publicDir = path4.resolve(srcDir, mergedConfig.publicDir ?? "public");
1712
- const typesDir = path4.resolve(wxtDir, "types");
1713
- const outBaseDir = path4.resolve(root, mergedConfig.outDir ?? ".output");
1714
- const outDir = path4.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
1920
+ const publicDir = path5.resolve(srcDir, mergedConfig.publicDir ?? "public");
1921
+ const typesDir = path5.resolve(wxtDir, "types");
1922
+ const outBaseDir = path5.resolve(root, mergedConfig.outDir ?? ".output");
1923
+ const outDir = path5.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
1715
1924
  const reloadCommand = mergedConfig.dev?.reloadCommand ?? "Alt+R";
1716
1925
  const runnerConfig = await loadConfig({
1717
1926
  name: "web-ext",
@@ -1728,14 +1937,14 @@ async function resolveConfig(inlineConfig, command, server) {
1728
1937
  "~": srcDir,
1729
1938
  "@@": root,
1730
1939
  "~~": root
1731
- }).map(([key, value]) => [key, path4.resolve(root, value)])
1940
+ }).map(([key, value]) => [key, path5.resolve(root, value)])
1732
1941
  );
1733
- const analysisOutputFile = path4.resolve(
1942
+ const analysisOutputFile = path5.resolve(
1734
1943
  root,
1735
1944
  mergedConfig.analysis?.outputFile ?? "stats.html"
1736
1945
  );
1737
- const analysisOutputDir = path4.dirname(analysisOutputFile);
1738
- const analysisOutputName = path4.parse(analysisOutputFile).name;
1946
+ const analysisOutputDir = path5.dirname(analysisOutputFile);
1947
+ const analysisOutputName = path5.parse(analysisOutputFile).name;
1739
1948
  const finalConfig = {
1740
1949
  browser,
1741
1950
  command,
@@ -1860,6 +2069,7 @@ function mergeInlineConfig(inlineConfig, userConfig) {
1860
2069
  };
1861
2070
  }
1862
2071
  function resolveInternalZipConfig(root, mergedConfig) {
2072
+ const downloadedPackagesDir = path5.resolve(root, ".wxt/local_modules");
1863
2073
  return {
1864
2074
  name: void 0,
1865
2075
  sourcesTemplate: "{{name}}-{{version}}-sources.zip",
@@ -1878,7 +2088,9 @@ function resolveInternalZipConfig(root, mergedConfig) {
1878
2088
  "**/*.+(test|spec).?(c|m)+(j|t)s?(x)",
1879
2089
  // From user
1880
2090
  ...mergedConfig.zip?.excludeSources ?? []
1881
- ]
2091
+ ],
2092
+ downloadPackages: mergedConfig.zip?.downloadPackages ?? [],
2093
+ downloadedPackagesDir
1882
2094
  };
1883
2095
  }
1884
2096
  async function getUnimportOptions(wxtDir, logger, config) {
@@ -1910,7 +2122,7 @@ async function getUnimportOptions(wxtDir, logger, config) {
1910
2122
  dirs: ["components", "composables", "hooks", "utils"],
1911
2123
  eslintrc: {
1912
2124
  enabled,
1913
- filePath: path4.resolve(wxtDir, "eslintrc-auto-import.json"),
2125
+ filePath: path5.resolve(wxtDir, "eslintrc-auto-import.json"),
1914
2126
  globalsPropValue: true
1915
2127
  }
1916
2128
  };
@@ -1921,7 +2133,7 @@ async function getUnimportOptions(wxtDir, logger, config) {
1921
2133
  }
1922
2134
  async function resolveWxtModuleDir() {
1923
2135
  const requireResolve = __require?.resolve ?? (await import("node:module")).default.createRequire(import.meta.url).resolve;
1924
- return path4.resolve(requireResolve("wxt"), "../..");
2136
+ return path5.resolve(requireResolve("wxt"), "../..");
1925
2137
  }
1926
2138
 
1927
2139
  // src/core/utils/building/group-entrypoints.ts
@@ -1989,16 +2201,16 @@ ${noImports}`;
1989
2201
  // src/core/utils/building/import-entrypoint.ts
1990
2202
  import { transformSync } from "esbuild";
1991
2203
  import { fileURLToPath } from "node:url";
1992
- async function importEntrypointFile(path8) {
1993
- wxt.logger.debug("Loading file metadata:", path8);
1994
- const normalPath = normalizePath(path8);
2204
+ async function importEntrypointFile(path10) {
2205
+ wxt.logger.debug("Loading file metadata:", path10);
2206
+ const normalPath = normalizePath(path10);
1995
2207
  const unimport2 = createUnimport3({
1996
2208
  ...wxt.config.imports,
1997
2209
  // Only allow specific imports, not all from the project
1998
2210
  dirs: []
1999
2211
  });
2000
2212
  await unimport2.init();
2001
- const text = await fs9.readFile(path8, "utf-8");
2213
+ const text = await fs9.readFile(path10, "utf-8");
2002
2214
  const textNoImports = removeProjectImportStatements(text);
2003
2215
  const { code } = await unimport2.injectImports(textNoImports);
2004
2216
  wxt.logger.debug(
@@ -2041,10 +2253,10 @@ async function importEntrypointFile(path8) {
2041
2253
  }
2042
2254
  );
2043
2255
  try {
2044
- const res = await jiti(path8);
2256
+ const res = await jiti(path10);
2045
2257
  return res.default;
2046
2258
  } catch (err) {
2047
- const filePath = relative5(wxt.config.root, path8);
2259
+ const filePath = relative5(wxt.config.root, path10);
2048
2260
  if (err instanceof ReferenceError) {
2049
2261
  const variableName = err.message.replace(" is not defined", "");
2050
2262
  throw Error(
@@ -2079,7 +2291,7 @@ import fs12 from "fs-extra";
2079
2291
  import { resolve as resolve11 } from "path";
2080
2292
 
2081
2293
  // src/core/utils/log/printFileList.ts
2082
- import path5 from "node:path";
2294
+ import path6 from "node:path";
2083
2295
  import pc3 from "picocolors";
2084
2296
  import fs10 from "fs-extra";
2085
2297
  import { filesize } from "filesize";
@@ -2117,8 +2329,8 @@ async function printFileList(log, header, baseDir, files) {
2117
2329
  const fileRows = await Promise.all(
2118
2330
  files.map(async (file, i) => {
2119
2331
  const parts = [
2120
- path5.relative(process.cwd(), baseDir) + path5.sep,
2121
- path5.relative(baseDir, file)
2332
+ path6.relative(process.cwd(), baseDir) + path6.sep,
2333
+ path6.relative(baseDir, file)
2122
2334
  ];
2123
2335
  const prefix = i === files.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
2124
2336
  const color = getChunkColor(file);
@@ -2186,7 +2398,7 @@ function getChunkSortWeight(filename) {
2186
2398
  import pc4 from "picocolors";
2187
2399
 
2188
2400
  // package.json
2189
- var version = "0.17.4";
2401
+ var version = "0.17.5";
2190
2402
 
2191
2403
  // src/core/utils/log/printHeader.ts
2192
2404
  import { consola as consola2 } from "consola";
@@ -2958,7 +3170,7 @@ async function build(config) {
2958
3170
  }
2959
3171
 
2960
3172
  // src/core/clean.ts
2961
- import path6 from "node:path";
3173
+ import path7 from "node:path";
2962
3174
  import glob4 from "fast-glob";
2963
3175
  import fs13 from "fs-extra";
2964
3176
  import { consola as consola4 } from "consola";
@@ -2973,7 +3185,7 @@ async function clean(root = process.cwd()) {
2973
3185
  ];
2974
3186
  consola4.debug("Looking for:", tempDirs.map(pc6.cyan).join(", "));
2975
3187
  const directories = await glob4(tempDirs, {
2976
- cwd: path6.resolve(root),
3188
+ cwd: path7.resolve(root),
2977
3189
  absolute: true,
2978
3190
  onlyDirectories: true,
2979
3191
  deep: 2
@@ -2984,11 +3196,11 @@ async function clean(root = process.cwd()) {
2984
3196
  }
2985
3197
  consola4.debug(
2986
3198
  "Found:",
2987
- directories.map((dir) => pc6.cyan(path6.relative(root, dir))).join(", ")
3199
+ directories.map((dir) => pc6.cyan(path7.relative(root, dir))).join(", ")
2988
3200
  );
2989
3201
  for (const directory of directories) {
2990
3202
  await fs13.rm(directory, { force: true, recursive: true });
2991
- consola4.debug("Deleted " + pc6.cyan(path6.relative(root, directory)));
3203
+ consola4.debug("Deleted " + pc6.cyan(path7.relative(root, directory)));
2992
3204
  }
2993
3205
  }
2994
3206
 
@@ -3192,8 +3404,8 @@ async function createServer(inlineConfig) {
3192
3404
  reloadContentScript(payload) {
3193
3405
  server.ws.send("wxt:reload-content-script", payload);
3194
3406
  },
3195
- reloadPage(path8) {
3196
- server.ws.send("wxt:reload-page", path8);
3407
+ reloadPage(path10) {
3408
+ server.ws.send("wxt:reload-page", path10);
3197
3409
  },
3198
3410
  reloadExtension() {
3199
3411
  server.ws.send("wxt:reload-extension");
@@ -3224,11 +3436,11 @@ async function getPort() {
3224
3436
  function createFileReloader(server) {
3225
3437
  const fileChangedMutex = new Mutex();
3226
3438
  const changeQueue = [];
3227
- return async (event, path8) => {
3439
+ return async (event, path10) => {
3228
3440
  await wxt.reloadConfig();
3229
- if (path8.startsWith(wxt.config.outBaseDir))
3441
+ if (path10.startsWith(wxt.config.outBaseDir))
3230
3442
  return;
3231
- changeQueue.push([event, path8]);
3443
+ changeQueue.push([event, path10]);
3232
3444
  await fileChangedMutex.runExclusive(async () => {
3233
3445
  if (server.currentOutput == null)
3234
3446
  return;
@@ -3307,8 +3519,8 @@ function reloadContentScripts(steps, server) {
3307
3519
  function reloadHtmlPages(groups, server) {
3308
3520
  const htmlEntries = groups.flat().filter(isHtmlEntrypoint);
3309
3521
  htmlEntries.forEach((entry) => {
3310
- const path8 = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
3311
- server.reloadPage(path8);
3522
+ const path10 = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
3523
+ server.reloadPage(path10);
3312
3524
  });
3313
3525
  return {
3314
3526
  reloadedNames: htmlEntries.map((entry) => entry.name)
@@ -3339,7 +3551,7 @@ import prompts from "prompts";
3339
3551
  import { consola as consola6 } from "consola";
3340
3552
  import { downloadTemplate } from "giget";
3341
3553
  import fs14 from "fs-extra";
3342
- import path7 from "node:path";
3554
+ import path8 from "node:path";
3343
3555
  import pc8 from "picocolors";
3344
3556
  async function initialize(options) {
3345
3557
  consola6.info("Initalizing new project");
@@ -3387,7 +3599,7 @@ async function initialize(options) {
3387
3599
  input.template ??= defaultTemplate;
3388
3600
  input.packageManager ??= options.packageManager;
3389
3601
  await cloneProject(input);
3390
- const cdPath = path7.relative(process.cwd(), path7.resolve(input.directory));
3602
+ const cdPath = path8.relative(process.cwd(), path8.resolve(input.directory));
3391
3603
  console.log();
3392
3604
  consola6.log(
3393
3605
  `\u2728 WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`
@@ -3431,8 +3643,8 @@ async function cloneProject({
3431
3643
  force: true
3432
3644
  });
3433
3645
  await fs14.move(
3434
- path7.join(directory, "_gitignore"),
3435
- path7.join(directory, ".gitignore")
3646
+ path8.join(directory, "_gitignore"),
3647
+ path8.join(directory, ".gitignore")
3436
3648
  ).catch(
3437
3649
  (err) => consola6.warn("Failed to move _gitignore to .gitignore:", err)
3438
3650
  );
@@ -3464,10 +3676,11 @@ async function prepare(config) {
3464
3676
  }
3465
3677
 
3466
3678
  // src/core/zip.ts
3467
- import zipdir from "zip-dir";
3468
- import { dirname as dirname5, relative as relative11, resolve as resolve13 } from "node:path";
3679
+ import path9 from "node:path";
3469
3680
  import fs15 from "fs-extra";
3470
3681
  import { minimatch as minimatch2 } from "minimatch";
3682
+ import JSZip from "jszip";
3683
+ import glob5 from "fast-glob";
3471
3684
  async function zip(config) {
3472
3685
  await registerWxt("build", config);
3473
3686
  const output = await internalBuild();
@@ -3475,7 +3688,7 @@ async function zip(config) {
3475
3688
  wxt.logger.info("Zipping extension...");
3476
3689
  const zipFiles = [];
3477
3690
  const projectName = wxt.config.zip.name ?? kebabCaseAlphanumeric(
3478
- (await getPackageJson())?.name || dirname5(process.cwd())
3691
+ (await getPackageJson())?.name || path9.dirname(process.cwd())
3479
3692
  );
3480
3693
  const applyTemplate = (template) => template.replaceAll("{{name}}", projectName).replaceAll("{{browser}}", wxt.config.browser).replaceAll(
3481
3694
  "{{version}}",
@@ -3483,24 +3696,25 @@ async function zip(config) {
3483
3696
  ).replaceAll("{{manifestVersion}}", `mv${wxt.config.manifestVersion}`);
3484
3697
  await fs15.ensureDir(wxt.config.outBaseDir);
3485
3698
  const outZipFilename = applyTemplate(wxt.config.zip.artifactTemplate);
3486
- const outZipPath = resolve13(wxt.config.outBaseDir, outZipFilename);
3487
- await zipdir(wxt.config.outDir, {
3488
- saveTo: outZipPath
3489
- });
3699
+ const outZipPath = path9.resolve(wxt.config.outBaseDir, outZipFilename);
3700
+ await zipDir(wxt.config.outDir, outZipPath);
3490
3701
  zipFiles.push(outZipPath);
3491
3702
  if (wxt.config.browser === "firefox") {
3703
+ const { overrides, files: downloadedPackages } = await downloadPrivatePackages();
3492
3704
  const sourcesZipFilename = applyTemplate(wxt.config.zip.sourcesTemplate);
3493
- const sourcesZipPath = resolve13(wxt.config.outBaseDir, sourcesZipFilename);
3494
- await zipdir(wxt.config.zip.sourcesRoot, {
3495
- saveTo: sourcesZipPath,
3496
- filter(path8) {
3497
- const relativePath = relative11(wxt.config.zip.sourcesRoot, path8);
3498
- return wxt.config.zip.includeSources.some(
3499
- (pattern) => minimatch2(relativePath, pattern)
3500
- ) || !wxt.config.zip.excludeSources.some(
3501
- (pattern) => minimatch2(relativePath, pattern)
3502
- );
3503
- }
3705
+ const sourcesZipPath = path9.resolve(
3706
+ wxt.config.outBaseDir,
3707
+ sourcesZipFilename
3708
+ );
3709
+ await zipDir(wxt.config.zip.sourcesRoot, sourcesZipPath, {
3710
+ include: wxt.config.zip.includeSources,
3711
+ exclude: wxt.config.zip.excludeSources,
3712
+ transform(file, content) {
3713
+ if (file.endsWith("package.json")) {
3714
+ return addOverridesToPackageJson(content, overrides);
3715
+ }
3716
+ },
3717
+ additionalFiles: downloadedPackages
3504
3718
  });
3505
3719
  zipFiles.push(sourcesZipPath);
3506
3720
  }
@@ -3512,6 +3726,81 @@ async function zip(config) {
3512
3726
  );
3513
3727
  return zipFiles;
3514
3728
  }
3729
+ async function zipDir(directory, outputPath, options) {
3730
+ const archive = new JSZip();
3731
+ const files = (await glob5("**/*", {
3732
+ cwd: directory,
3733
+ // Ignore node_modules, otherwise this glob step takes forever
3734
+ ignore: ["**/node_modules"],
3735
+ onlyFiles: true
3736
+ })).filter((relativePath) => {
3737
+ return wxt.config.zip.includeSources.some(
3738
+ (pattern) => minimatch2(relativePath, pattern)
3739
+ ) || !wxt.config.zip.excludeSources.some(
3740
+ (pattern) => minimatch2(relativePath, pattern)
3741
+ );
3742
+ });
3743
+ const filesToZip = [
3744
+ ...files,
3745
+ ...(options?.additionalFiles ?? []).map(
3746
+ (file) => path9.relative(directory, file)
3747
+ )
3748
+ ];
3749
+ for (const file of filesToZip) {
3750
+ const absolutePath = path9.resolve(directory, file);
3751
+ if (file.endsWith(".json")) {
3752
+ const content = await fs15.readFile(absolutePath, "utf-8");
3753
+ archive.file(
3754
+ file,
3755
+ await options?.transform?.(file, content) || content
3756
+ );
3757
+ } else {
3758
+ const content = await fs15.readFile(absolutePath);
3759
+ archive.file(file, content);
3760
+ }
3761
+ }
3762
+ await options?.additionalWork?.(archive);
3763
+ const buffer = await archive.generateAsync({ type: "base64" });
3764
+ await fs15.writeFile(outputPath, buffer, "base64");
3765
+ }
3766
+ async function downloadPrivatePackages() {
3767
+ const overrides = {};
3768
+ const files = [];
3769
+ if (wxt.config.zip.downloadPackages.length > 0) {
3770
+ const _downloadPackages = new Set(wxt.config.zip.downloadPackages);
3771
+ const allPackages = await wxt.pm.listDependencies({
3772
+ all: true,
3773
+ cwd: wxt.config.root
3774
+ });
3775
+ const downloadPackages = allPackages.filter(
3776
+ (pkg) => _downloadPackages.has(pkg.name)
3777
+ );
3778
+ for (const pkg of downloadPackages) {
3779
+ wxt.logger.info(`Downloading package: ${pkg.name}@${pkg.version}`);
3780
+ const id = `${pkg.name}@${pkg.version}`;
3781
+ const tgzPath = await wxt.pm.downloadDependency(
3782
+ id,
3783
+ wxt.config.zip.downloadedPackagesDir
3784
+ );
3785
+ files.push(tgzPath);
3786
+ overrides[id] = "file://./" + normalizePath(path9.relative(wxt.config.root, tgzPath));
3787
+ }
3788
+ }
3789
+ return { overrides, files };
3790
+ }
3791
+ function addOverridesToPackageJson(content, overrides) {
3792
+ if (Object.keys(overrides).length === 0)
3793
+ return content;
3794
+ const oldPackage = JSON.parse(content);
3795
+ const newPackage = {
3796
+ ...oldPackage,
3797
+ [wxt.pm.overridesKey]: {
3798
+ ...oldPackage[wxt.pm.overridesKey],
3799
+ ...overrides
3800
+ }
3801
+ };
3802
+ return JSON.stringify(newPackage, null, 2);
3803
+ }
3515
3804
 
3516
3805
  // src/cli/cli-utils.ts
3517
3806
  import consola7, { LogLevels as LogLevels2 } from "consola";