wxt 0.8.4 → 0.8.6

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.
Files changed (36) hide show
  1. package/README.md +3 -2
  2. package/dist/browser.js +3 -4
  3. package/dist/chunk-FNTE2L27.js +7 -0
  4. package/dist/chunk-VFZ5667B.js +2410 -0
  5. package/dist/chunk-YUG22S6W.js +38 -0
  6. package/dist/cli.cjs +3941 -3775
  7. package/dist/cli.d.cts +2 -0
  8. package/dist/client.d.ts +5 -171
  9. package/dist/client.js +128 -131
  10. package/dist/execa-WKZHVHC5.js +2043 -0
  11. package/dist/external-9107db91.d.ts +176 -0
  12. package/dist/external-cb0967d6.d.ts +572 -0
  13. package/dist/index.cjs +2727 -2355
  14. package/dist/index.d.cts +36 -583
  15. package/dist/index.d.ts +36 -583
  16. package/dist/index.js +330 -4484
  17. package/dist/sandbox.d.ts +2 -23
  18. package/dist/sandbox.js +1 -2
  19. package/dist/testing.cjs +161 -35
  20. package/dist/testing.d.cts +7 -273
  21. package/dist/testing.d.ts +7 -273
  22. package/dist/testing.js +12 -676
  23. package/dist/{virtual-modules → virtual}/background-entrypoint.js +6 -7
  24. package/dist/{virtual-modules → virtual}/content-script-entrypoint.js +4 -5
  25. package/dist/virtual/mock-browser.js +152 -0
  26. package/dist/{virtual-modules → virtual}/reload-html.js +2 -3
  27. package/dist/{virtual-modules → virtual}/unlisted-script-entrypoint.js +2 -3
  28. package/package.json +6 -5
  29. package/dist/index.cjs.map +0 -1
  30. package/dist/index.js.map +0 -1
  31. package/dist/virtual-modules/background-entrypoint.js.map +0 -1
  32. package/dist/virtual-modules/content-script-entrypoint.js.map +0 -1
  33. package/dist/virtual-modules/fake-browser.cjs +0 -31
  34. package/dist/virtual-modules/fake-browser.js +0 -8
  35. package/dist/virtual-modules/reload-html.js.map +0 -1
  36. package/dist/virtual-modules/unlisted-script-entrypoint.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,4383 +1,84 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
- }) : x)(function(x) {
10
- if (typeof require !== "undefined")
11
- return require.apply(this, arguments);
12
- throw Error('Dynamic require of "' + x + '" is not supported');
13
- });
14
- var __commonJS = (cb, mod) => function __require2() {
15
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
16
- };
17
- var __copyProps = (to, from, except, desc) => {
18
- if (from && typeof from === "object" || typeof from === "function") {
19
- for (let key of __getOwnPropNames(from))
20
- if (!__hasOwnProp.call(to, key) && key !== except)
21
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
- }
23
- return to;
24
- };
25
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
26
- // If the importer is in node compatibility mode or this is not an ESM
27
- // file that has been converted to a CommonJS file using a Babel-
28
- // compatible transform (i.e. "__esModule" has not been set), then set
29
- // "default" to the CommonJS "module.exports" for node compatibility.
30
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
31
- mod
32
- ));
33
-
34
- // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js
35
- var require_windows = __commonJS({
36
- "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module) {
37
- "use strict";
38
- module.exports = isexe;
39
- isexe.sync = sync;
40
- var fs16 = __require("fs");
41
- function checkPathExt(path9, options) {
42
- var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
43
- if (!pathext) {
44
- return true;
45
- }
46
- pathext = pathext.split(";");
47
- if (pathext.indexOf("") !== -1) {
48
- return true;
49
- }
50
- for (var i = 0; i < pathext.length; i++) {
51
- var p = pathext[i].toLowerCase();
52
- if (p && path9.substr(-p.length).toLowerCase() === p) {
53
- return true;
54
- }
55
- }
56
- return false;
57
- }
58
- function checkStat(stat, path9, options) {
59
- if (!stat.isSymbolicLink() && !stat.isFile()) {
60
- return false;
61
- }
62
- return checkPathExt(path9, options);
63
- }
64
- function isexe(path9, options, cb) {
65
- fs16.stat(path9, function(er, stat) {
66
- cb(er, er ? false : checkStat(stat, path9, options));
67
- });
68
- }
69
- function sync(path9, options) {
70
- return checkStat(fs16.statSync(path9), path9, options);
71
- }
72
- }
73
- });
74
-
75
- // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js
76
- var require_mode = __commonJS({
77
- "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module) {
78
- "use strict";
79
- module.exports = isexe;
80
- isexe.sync = sync;
81
- var fs16 = __require("fs");
82
- function isexe(path9, options, cb) {
83
- fs16.stat(path9, function(er, stat) {
84
- cb(er, er ? false : checkStat(stat, options));
85
- });
86
- }
87
- function sync(path9, options) {
88
- return checkStat(fs16.statSync(path9), options);
89
- }
90
- function checkStat(stat, options) {
91
- return stat.isFile() && checkMode(stat, options);
92
- }
93
- function checkMode(stat, options) {
94
- var mod = stat.mode;
95
- var uid = stat.uid;
96
- var gid = stat.gid;
97
- var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
98
- var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
99
- var u = parseInt("100", 8);
100
- var g = parseInt("010", 8);
101
- var o = parseInt("001", 8);
102
- var ug = u | g;
103
- var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
104
- return ret;
105
- }
106
- }
107
- });
108
-
109
- // node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
110
- var require_isexe = __commonJS({
111
- "node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module) {
112
- "use strict";
113
- var fs16 = __require("fs");
114
- var core;
115
- if (process.platform === "win32" || global.TESTING_WINDOWS) {
116
- core = require_windows();
117
- } else {
118
- core = require_mode();
119
- }
120
- module.exports = isexe;
121
- isexe.sync = sync;
122
- function isexe(path9, options, cb) {
123
- if (typeof options === "function") {
124
- cb = options;
125
- options = {};
126
- }
127
- if (!cb) {
128
- if (typeof Promise !== "function") {
129
- throw new TypeError("callback not provided");
130
- }
131
- return new Promise(function(resolve13, reject) {
132
- isexe(path9, options || {}, function(er, is) {
133
- if (er) {
134
- reject(er);
135
- } else {
136
- resolve13(is);
137
- }
138
- });
139
- });
140
- }
141
- core(path9, options || {}, function(er, is) {
142
- if (er) {
143
- if (er.code === "EACCES" || options && options.ignoreErrors) {
144
- er = null;
145
- is = false;
146
- }
147
- }
148
- cb(er, is);
149
- });
150
- }
151
- function sync(path9, options) {
152
- try {
153
- return core.sync(path9, options || {});
154
- } catch (er) {
155
- if (options && options.ignoreErrors || er.code === "EACCES") {
156
- return false;
157
- } else {
158
- throw er;
159
- }
160
- }
161
- }
162
- }
163
- });
164
-
165
- // node_modules/.pnpm/which@2.0.2/node_modules/which/which.js
166
- var require_which = __commonJS({
167
- "node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports, module) {
168
- "use strict";
169
- var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
170
- var path9 = __require("path");
171
- var COLON = isWindows ? ";" : ":";
172
- var isexe = require_isexe();
173
- var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
174
- var getPathInfo = (cmd, opt) => {
175
- const colon = opt.colon || COLON;
176
- const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
177
- // windows always checks the cwd first
178
- ...isWindows ? [process.cwd()] : [],
179
- ...(opt.path || process.env.PATH || /* istanbul ignore next: very unusual */
180
- "").split(colon)
181
- ];
182
- const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
183
- const pathExt = isWindows ? pathExtExe.split(colon) : [""];
184
- if (isWindows) {
185
- if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
186
- pathExt.unshift("");
187
- }
188
- return {
189
- pathEnv,
190
- pathExt,
191
- pathExtExe
192
- };
193
- };
194
- var which = (cmd, opt, cb) => {
195
- if (typeof opt === "function") {
196
- cb = opt;
197
- opt = {};
198
- }
199
- if (!opt)
200
- opt = {};
201
- const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
202
- const found = [];
203
- const step = (i) => new Promise((resolve13, reject) => {
204
- if (i === pathEnv.length)
205
- return opt.all && found.length ? resolve13(found) : reject(getNotFoundError(cmd));
206
- const ppRaw = pathEnv[i];
207
- const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
208
- const pCmd = path9.join(pathPart, cmd);
209
- const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
210
- resolve13(subStep(p, i, 0));
211
- });
212
- const subStep = (p, i, ii) => new Promise((resolve13, reject) => {
213
- if (ii === pathExt.length)
214
- return resolve13(step(i + 1));
215
- const ext = pathExt[ii];
216
- isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
217
- if (!er && is) {
218
- if (opt.all)
219
- found.push(p + ext);
220
- else
221
- return resolve13(p + ext);
222
- }
223
- return resolve13(subStep(p, i, ii + 1));
224
- });
225
- });
226
- return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
227
- };
228
- var whichSync = (cmd, opt) => {
229
- opt = opt || {};
230
- const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
231
- const found = [];
232
- for (let i = 0; i < pathEnv.length; i++) {
233
- const ppRaw = pathEnv[i];
234
- const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
235
- const pCmd = path9.join(pathPart, cmd);
236
- const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
237
- for (let j = 0; j < pathExt.length; j++) {
238
- const cur = p + pathExt[j];
239
- try {
240
- const is = isexe.sync(cur, { pathExt: pathExtExe });
241
- if (is) {
242
- if (opt.all)
243
- found.push(cur);
244
- else
245
- return cur;
246
- }
247
- } catch (ex) {
248
- }
249
- }
250
- }
251
- if (opt.all && found.length)
252
- return found;
253
- if (opt.nothrow)
254
- return null;
255
- throw getNotFoundError(cmd);
256
- };
257
- module.exports = which;
258
- which.sync = whichSync;
259
- }
260
- });
261
-
262
- // node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js
263
- var require_path_key = __commonJS({
264
- "node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js"(exports, module) {
265
- "use strict";
266
- var pathKey2 = (options = {}) => {
267
- const environment = options.env || process.env;
268
- const platform = options.platform || process.platform;
269
- if (platform !== "win32") {
270
- return "PATH";
271
- }
272
- return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
273
- };
274
- module.exports = pathKey2;
275
- module.exports.default = pathKey2;
276
- }
277
- });
278
-
279
- // node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/resolveCommand.js
280
- var require_resolveCommand = __commonJS({
281
- "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
282
- "use strict";
283
- var path9 = __require("path");
284
- var which = require_which();
285
- var getPathKey = require_path_key();
286
- function resolveCommandAttempt(parsed, withoutPathExt) {
287
- const env = parsed.options.env || process.env;
288
- const cwd = process.cwd();
289
- const hasCustomCwd = parsed.options.cwd != null;
290
- const shouldSwitchCwd = hasCustomCwd && process.chdir !== void 0 && !process.chdir.disabled;
291
- if (shouldSwitchCwd) {
292
- try {
293
- process.chdir(parsed.options.cwd);
294
- } catch (err) {
295
- }
296
- }
297
- let resolved;
298
- try {
299
- resolved = which.sync(parsed.command, {
300
- path: env[getPathKey({ env })],
301
- pathExt: withoutPathExt ? path9.delimiter : void 0
302
- });
303
- } catch (e) {
304
- } finally {
305
- if (shouldSwitchCwd) {
306
- process.chdir(cwd);
307
- }
308
- }
309
- if (resolved) {
310
- resolved = path9.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
311
- }
312
- return resolved;
313
- }
314
- function resolveCommand(parsed) {
315
- return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
316
- }
317
- module.exports = resolveCommand;
318
- }
319
- });
320
-
321
- // node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/escape.js
322
- var require_escape = __commonJS({
323
- "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/escape.js"(exports, module) {
324
- "use strict";
325
- var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
326
- function escapeCommand(arg) {
327
- arg = arg.replace(metaCharsRegExp, "^$1");
328
- return arg;
329
- }
330
- function escapeArgument(arg, doubleEscapeMetaChars) {
331
- arg = `${arg}`;
332
- arg = arg.replace(/(\\*)"/g, '$1$1\\"');
333
- arg = arg.replace(/(\\*)$/, "$1$1");
334
- arg = `"${arg}"`;
335
- arg = arg.replace(metaCharsRegExp, "^$1");
336
- if (doubleEscapeMetaChars) {
337
- arg = arg.replace(metaCharsRegExp, "^$1");
338
- }
339
- return arg;
340
- }
341
- module.exports.command = escapeCommand;
342
- module.exports.argument = escapeArgument;
343
- }
344
- });
345
-
346
- // node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
347
- var require_shebang_regex = __commonJS({
348
- "node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.js"(exports, module) {
349
- "use strict";
350
- module.exports = /^#!(.*)/;
351
- }
352
- });
353
-
354
- // node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js
355
- var require_shebang_command = __commonJS({
356
- "node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.js"(exports, module) {
357
- "use strict";
358
- var shebangRegex = require_shebang_regex();
359
- module.exports = (string = "") => {
360
- const match = string.match(shebangRegex);
361
- if (!match) {
362
- return null;
363
- }
364
- const [path9, argument] = match[0].replace(/#! ?/, "").split(" ");
365
- const binary = path9.split("/").pop();
366
- if (binary === "env") {
367
- return argument;
368
- }
369
- return argument ? `${binary} ${argument}` : binary;
370
- };
371
- }
372
- });
373
-
374
- // node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/readShebang.js
375
- var require_readShebang = __commonJS({
376
- "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module) {
377
- "use strict";
378
- var fs16 = __require("fs");
379
- var shebangCommand = require_shebang_command();
380
- function readShebang(command) {
381
- const size = 150;
382
- const buffer = Buffer.alloc(size);
383
- let fd;
384
- try {
385
- fd = fs16.openSync(command, "r");
386
- fs16.readSync(fd, buffer, 0, size, 0);
387
- fs16.closeSync(fd);
388
- } catch (e) {
389
- }
390
- return shebangCommand(buffer.toString());
391
- }
392
- module.exports = readShebang;
393
- }
394
- });
395
-
396
- // node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/parse.js
397
- var require_parse = __commonJS({
398
- "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/parse.js"(exports, module) {
399
- "use strict";
400
- var path9 = __require("path");
401
- var resolveCommand = require_resolveCommand();
402
- var escape = require_escape();
403
- var readShebang = require_readShebang();
404
- var isWin = process.platform === "win32";
405
- var isExecutableRegExp = /\.(?:com|exe)$/i;
406
- var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
407
- function detectShebang(parsed) {
408
- parsed.file = resolveCommand(parsed);
409
- const shebang = parsed.file && readShebang(parsed.file);
410
- if (shebang) {
411
- parsed.args.unshift(parsed.file);
412
- parsed.command = shebang;
413
- return resolveCommand(parsed);
414
- }
415
- return parsed.file;
416
- }
417
- function parseNonShell(parsed) {
418
- if (!isWin) {
419
- return parsed;
420
- }
421
- const commandFile = detectShebang(parsed);
422
- const needsShell = !isExecutableRegExp.test(commandFile);
423
- if (parsed.options.forceShell || needsShell) {
424
- const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
425
- parsed.command = path9.normalize(parsed.command);
426
- parsed.command = escape.command(parsed.command);
427
- parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
428
- const shellCommand = [parsed.command].concat(parsed.args).join(" ");
429
- parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
430
- parsed.command = process.env.comspec || "cmd.exe";
431
- parsed.options.windowsVerbatimArguments = true;
432
- }
433
- return parsed;
434
- }
435
- function parse(command, args, options) {
436
- if (args && !Array.isArray(args)) {
437
- options = args;
438
- args = null;
439
- }
440
- args = args ? args.slice(0) : [];
441
- options = Object.assign({}, options);
442
- const parsed = {
443
- command,
444
- args,
445
- options,
446
- file: void 0,
447
- original: {
448
- command,
449
- args
450
- }
451
- };
452
- return options.shell ? parsed : parseNonShell(parsed);
453
- }
454
- module.exports = parse;
455
- }
456
- });
457
-
458
- // node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/enoent.js
459
- var require_enoent = __commonJS({
460
- "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/lib/enoent.js"(exports, module) {
461
- "use strict";
462
- var isWin = process.platform === "win32";
463
- function notFoundError(original, syscall) {
464
- return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
465
- code: "ENOENT",
466
- errno: "ENOENT",
467
- syscall: `${syscall} ${original.command}`,
468
- path: original.command,
469
- spawnargs: original.args
470
- });
471
- }
472
- function hookChildProcess(cp, parsed) {
473
- if (!isWin) {
474
- return;
475
- }
476
- const originalEmit = cp.emit;
477
- cp.emit = function(name, arg1) {
478
- if (name === "exit") {
479
- const err = verifyENOENT(arg1, parsed, "spawn");
480
- if (err) {
481
- return originalEmit.call(cp, "error", err);
482
- }
483
- }
484
- return originalEmit.apply(cp, arguments);
485
- };
486
- }
487
- function verifyENOENT(status, parsed) {
488
- if (isWin && status === 1 && !parsed.file) {
489
- return notFoundError(parsed.original, "spawn");
490
- }
491
- return null;
492
- }
493
- function verifyENOENTSync(status, parsed) {
494
- if (isWin && status === 1 && !parsed.file) {
495
- return notFoundError(parsed.original, "spawnSync");
496
- }
497
- return null;
498
- }
499
- module.exports = {
500
- hookChildProcess,
501
- verifyENOENT,
502
- verifyENOENTSync,
503
- notFoundError
504
- };
505
- }
506
- });
507
-
508
- // node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/index.js
509
- var require_cross_spawn = __commonJS({
510
- "node_modules/.pnpm/cross-spawn@7.0.3/node_modules/cross-spawn/index.js"(exports, module) {
511
- "use strict";
512
- var cp = __require("child_process");
513
- var parse = require_parse();
514
- var enoent = require_enoent();
515
- function spawn(command, args, options) {
516
- const parsed = parse(command, args, options);
517
- const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
518
- enoent.hookChildProcess(spawned, parsed);
519
- return spawned;
520
- }
521
- function spawnSync(command, args, options) {
522
- const parsed = parse(command, args, options);
523
- const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
524
- result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
525
- return result;
526
- }
527
- module.exports = spawn;
528
- module.exports.spawn = spawn;
529
- module.exports.sync = spawnSync;
530
- module.exports._parse = parse;
531
- module.exports._enoent = enoent;
532
- }
533
- });
534
-
535
- // node_modules/.pnpm/signal-exit@3.0.7/node_modules/signal-exit/signals.js
536
- var require_signals = __commonJS({
537
- "node_modules/.pnpm/signal-exit@3.0.7/node_modules/signal-exit/signals.js"(exports, module) {
538
- "use strict";
539
- module.exports = [
540
- "SIGABRT",
541
- "SIGALRM",
542
- "SIGHUP",
543
- "SIGINT",
544
- "SIGTERM"
545
- ];
546
- if (process.platform !== "win32") {
547
- module.exports.push(
548
- "SIGVTALRM",
549
- "SIGXCPU",
550
- "SIGXFSZ",
551
- "SIGUSR2",
552
- "SIGTRAP",
553
- "SIGSYS",
554
- "SIGQUIT",
555
- "SIGIOT"
556
- // should detect profiler and enable/disable accordingly.
557
- // see #21
558
- // 'SIGPROF'
559
- );
560
- }
561
- if (process.platform === "linux") {
562
- module.exports.push(
563
- "SIGIO",
564
- "SIGPOLL",
565
- "SIGPWR",
566
- "SIGSTKFLT",
567
- "SIGUNUSED"
568
- );
569
- }
570
- }
571
- });
572
-
573
- // node_modules/.pnpm/signal-exit@3.0.7/node_modules/signal-exit/index.js
574
- var require_signal_exit = __commonJS({
575
- "node_modules/.pnpm/signal-exit@3.0.7/node_modules/signal-exit/index.js"(exports, module) {
576
- "use strict";
577
- var process6 = global.process;
578
- var processOk = function(process7) {
579
- return process7 && typeof process7 === "object" && typeof process7.removeListener === "function" && typeof process7.emit === "function" && typeof process7.reallyExit === "function" && typeof process7.listeners === "function" && typeof process7.kill === "function" && typeof process7.pid === "number" && typeof process7.on === "function";
580
- };
581
- if (!processOk(process6)) {
582
- module.exports = function() {
583
- return function() {
584
- };
585
- };
586
- } else {
587
- assert = __require("assert");
588
- signals = require_signals();
589
- isWin = /^win/i.test(process6.platform);
590
- EE = __require("events");
591
- if (typeof EE !== "function") {
592
- EE = EE.EventEmitter;
593
- }
594
- if (process6.__signal_exit_emitter__) {
595
- emitter = process6.__signal_exit_emitter__;
596
- } else {
597
- emitter = process6.__signal_exit_emitter__ = new EE();
598
- emitter.count = 0;
599
- emitter.emitted = {};
600
- }
601
- if (!emitter.infinite) {
602
- emitter.setMaxListeners(Infinity);
603
- emitter.infinite = true;
604
- }
605
- module.exports = function(cb, opts) {
606
- if (!processOk(global.process)) {
607
- return function() {
608
- };
609
- }
610
- assert.equal(typeof cb, "function", "a callback must be provided for exit handler");
611
- if (loaded === false) {
612
- load();
613
- }
614
- var ev = "exit";
615
- if (opts && opts.alwaysLast) {
616
- ev = "afterexit";
617
- }
618
- var remove = function() {
619
- emitter.removeListener(ev, cb);
620
- if (emitter.listeners("exit").length === 0 && emitter.listeners("afterexit").length === 0) {
621
- unload();
622
- }
623
- };
624
- emitter.on(ev, cb);
625
- return remove;
626
- };
627
- unload = function unload2() {
628
- if (!loaded || !processOk(global.process)) {
629
- return;
630
- }
631
- loaded = false;
632
- signals.forEach(function(sig) {
633
- try {
634
- process6.removeListener(sig, sigListeners[sig]);
635
- } catch (er) {
636
- }
637
- });
638
- process6.emit = originalProcessEmit;
639
- process6.reallyExit = originalProcessReallyExit;
640
- emitter.count -= 1;
641
- };
642
- module.exports.unload = unload;
643
- emit = function emit2(event, code, signal) {
644
- if (emitter.emitted[event]) {
645
- return;
646
- }
647
- emitter.emitted[event] = true;
648
- emitter.emit(event, code, signal);
649
- };
650
- sigListeners = {};
651
- signals.forEach(function(sig) {
652
- sigListeners[sig] = function listener() {
653
- if (!processOk(global.process)) {
654
- return;
655
- }
656
- var listeners = process6.listeners(sig);
657
- if (listeners.length === emitter.count) {
658
- unload();
659
- emit("exit", null, sig);
660
- emit("afterexit", null, sig);
661
- if (isWin && sig === "SIGHUP") {
662
- sig = "SIGINT";
663
- }
664
- process6.kill(process6.pid, sig);
665
- }
666
- };
667
- });
668
- module.exports.signals = function() {
669
- return signals;
670
- };
671
- loaded = false;
672
- load = function load2() {
673
- if (loaded || !processOk(global.process)) {
674
- return;
675
- }
676
- loaded = true;
677
- emitter.count += 1;
678
- signals = signals.filter(function(sig) {
679
- try {
680
- process6.on(sig, sigListeners[sig]);
681
- return true;
682
- } catch (er) {
683
- return false;
684
- }
685
- });
686
- process6.emit = processEmit;
687
- process6.reallyExit = processReallyExit;
688
- };
689
- module.exports.load = load;
690
- originalProcessReallyExit = process6.reallyExit;
691
- processReallyExit = function processReallyExit2(code) {
692
- if (!processOk(global.process)) {
693
- return;
694
- }
695
- process6.exitCode = code || /* istanbul ignore next */
696
- 0;
697
- emit("exit", process6.exitCode, null);
698
- emit("afterexit", process6.exitCode, null);
699
- originalProcessReallyExit.call(process6, process6.exitCode);
700
- };
701
- originalProcessEmit = process6.emit;
702
- processEmit = function processEmit2(ev, arg) {
703
- if (ev === "exit" && processOk(global.process)) {
704
- if (arg !== void 0) {
705
- process6.exitCode = arg;
706
- }
707
- var ret = originalProcessEmit.apply(this, arguments);
708
- emit("exit", process6.exitCode, null);
709
- emit("afterexit", process6.exitCode, null);
710
- return ret;
711
- } else {
712
- return originalProcessEmit.apply(this, arguments);
713
- }
714
- };
715
- }
716
- var assert;
717
- var signals;
718
- var isWin;
719
- var EE;
720
- var emitter;
721
- var unload;
722
- var emit;
723
- var sigListeners;
724
- var loaded;
725
- var load;
726
- var originalProcessReallyExit;
727
- var processReallyExit;
728
- var originalProcessEmit;
729
- var processEmit;
730
- }
731
- });
732
-
733
- // node_modules/.pnpm/get-stream@6.0.1/node_modules/get-stream/buffer-stream.js
734
- var require_buffer_stream = __commonJS({
735
- "node_modules/.pnpm/get-stream@6.0.1/node_modules/get-stream/buffer-stream.js"(exports, module) {
736
- "use strict";
737
- var { PassThrough: PassThroughStream } = __require("stream");
738
- module.exports = (options) => {
739
- options = { ...options };
740
- const { array } = options;
741
- let { encoding } = options;
742
- const isBuffer = encoding === "buffer";
743
- let objectMode = false;
744
- if (array) {
745
- objectMode = !(encoding || isBuffer);
746
- } else {
747
- encoding = encoding || "utf8";
748
- }
749
- if (isBuffer) {
750
- encoding = null;
751
- }
752
- const stream = new PassThroughStream({ objectMode });
753
- if (encoding) {
754
- stream.setEncoding(encoding);
755
- }
756
- let length = 0;
757
- const chunks = [];
758
- stream.on("data", (chunk) => {
759
- chunks.push(chunk);
760
- if (objectMode) {
761
- length = chunks.length;
762
- } else {
763
- length += chunk.length;
764
- }
765
- });
766
- stream.getBufferedValue = () => {
767
- if (array) {
768
- return chunks;
769
- }
770
- return isBuffer ? Buffer.concat(chunks, length) : chunks.join("");
771
- };
772
- stream.getBufferedLength = () => length;
773
- return stream;
774
- };
775
- }
776
- });
777
-
778
- // node_modules/.pnpm/get-stream@6.0.1/node_modules/get-stream/index.js
779
- var require_get_stream = __commonJS({
780
- "node_modules/.pnpm/get-stream@6.0.1/node_modules/get-stream/index.js"(exports, module) {
781
- "use strict";
782
- var { constants: BufferConstants } = __require("buffer");
783
- var stream = __require("stream");
784
- var { promisify } = __require("util");
785
- var bufferStream = require_buffer_stream();
786
- var streamPipelinePromisified = promisify(stream.pipeline);
787
- var MaxBufferError = class extends Error {
788
- constructor() {
789
- super("maxBuffer exceeded");
790
- this.name = "MaxBufferError";
791
- }
792
- };
793
- async function getStream2(inputStream, options) {
794
- if (!inputStream) {
795
- throw new Error("Expected a stream");
796
- }
797
- options = {
798
- maxBuffer: Infinity,
799
- ...options
800
- };
801
- const { maxBuffer } = options;
802
- const stream2 = bufferStream(options);
803
- await new Promise((resolve13, reject) => {
804
- const rejectPromise = (error) => {
805
- if (error && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
806
- error.bufferedData = stream2.getBufferedValue();
807
- }
808
- reject(error);
809
- };
810
- (async () => {
811
- try {
812
- await streamPipelinePromisified(inputStream, stream2);
813
- resolve13();
814
- } catch (error) {
815
- rejectPromise(error);
816
- }
817
- })();
818
- stream2.on("data", () => {
819
- if (stream2.getBufferedLength() > maxBuffer) {
820
- rejectPromise(new MaxBufferError());
821
- }
822
- });
823
- });
824
- return stream2.getBufferedValue();
825
- }
826
- module.exports = getStream2;
827
- module.exports.buffer = (stream2, options) => getStream2(stream2, { ...options, encoding: "buffer" });
828
- module.exports.array = (stream2, options) => getStream2(stream2, { ...options, array: true });
829
- module.exports.MaxBufferError = MaxBufferError;
830
- }
831
- });
832
-
833
- // node_modules/.pnpm/merge-stream@2.0.0/node_modules/merge-stream/index.js
834
- var require_merge_stream = __commonJS({
835
- "node_modules/.pnpm/merge-stream@2.0.0/node_modules/merge-stream/index.js"(exports, module) {
836
- "use strict";
837
- var { PassThrough } = __require("stream");
838
- module.exports = function() {
839
- var sources = [];
840
- var output = new PassThrough({ objectMode: true });
841
- output.setMaxListeners(0);
842
- output.add = add;
843
- output.isEmpty = isEmpty;
844
- output.on("unpipe", remove);
845
- Array.prototype.slice.call(arguments).forEach(add);
846
- return output;
847
- function add(source) {
848
- if (Array.isArray(source)) {
849
- source.forEach(add);
850
- return this;
851
- }
852
- sources.push(source);
853
- source.once("end", remove.bind(null, source));
854
- source.once("error", output.emit.bind(output, "error"));
855
- source.pipe(output, { end: false });
856
- return this;
857
- }
858
- function isEmpty() {
859
- return sources.length == 0;
860
- }
861
- function remove(source) {
862
- sources = sources.filter(function(it) {
863
- return it !== source;
864
- });
865
- if (!sources.length && output.readable) {
866
- output.end();
867
- }
868
- }
869
- };
870
- }
871
- });
872
-
873
- // src/core/utils/getInternalConfig.ts
874
- import { loadConfig } from "c12";
875
- import path2 from "node:path";
876
- import * as vite2 from "vite";
877
-
878
- // src/core/utils/createFsCache.ts
879
- import fs2, { ensureDir } from "fs-extra";
880
- import { dirname, resolve } from "path";
881
-
882
- // src/core/utils/fs.ts
883
- import fs from "fs-extra";
884
- async function writeFileIfDifferent(file, newContents) {
885
- const existingContents = await fs.readFile(file, "utf-8").catch(() => void 0);
886
- if (existingContents !== newContents) {
887
- await fs.writeFile(file, newContents);
888
- }
889
- }
890
-
891
- // src/core/utils/createFsCache.ts
892
- function createFsCache(wxtDir) {
893
- const getPath = (key) => resolve(wxtDir, "cache", encodeURIComponent(key));
894
- return {
895
- async set(key, value) {
896
- const path9 = getPath(key);
897
- await ensureDir(dirname(path9));
898
- await writeFileIfDifferent(path9, value);
899
- },
900
- async get(key) {
901
- const path9 = getPath(key);
902
- try {
903
- return await fs2.readFile(path9, "utf-8");
904
- } catch {
905
- return void 0;
906
- }
907
- }
908
- };
909
- }
910
-
911
- // src/core/utils/getInternalConfig.ts
912
- import consola, { LogLevels } from "consola";
913
-
914
- // src/core/utils/entrypoints.ts
915
- import path, { relative, resolve as resolve2 } from "node:path";
916
-
917
- // src/core/utils/paths.ts
918
- import nodePath from "node:path";
919
- import * as vite from "vite";
920
- function normalizePath2(path9) {
921
- return vite.normalizePath(path9);
922
- }
923
- function unnormalizePath(path9) {
924
- return nodePath.normalize(path9);
925
- }
926
- var CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
927
- var CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
928
-
929
- // src/core/utils/entrypoints.ts
930
- function getEntrypointName(entrypointsDir, inputPath) {
931
- const relativePath = path.relative(entrypointsDir, inputPath);
932
- const name = relativePath.split(/[\.\/\\]/, 2)[0];
933
- return name;
934
- }
935
- function getEntrypointOutputFile(entrypoint, ext) {
936
- return resolve2(entrypoint.outputDir, `${entrypoint.name}${ext}`);
937
- }
938
- function getEntrypointBundlePath(entrypoint, outDir, ext) {
939
- return normalizePath2(
940
- relative(outDir, getEntrypointOutputFile(entrypoint, ext))
941
- );
942
- }
943
- function resolvePerBrowserOption(option, browser) {
944
- if (typeof option === "object" && !Array.isArray(option))
945
- return option[browser];
946
- return option;
947
- }
948
-
949
- // src/core/vite-plugins/devHtmlPrerender.ts
950
- import { parseHTML } from "linkedom";
951
- import { dirname as dirname2, isAbsolute, relative as relative2, resolve as resolve3 } from "path";
952
- var reactRefreshPreamble = "";
953
- function devHtmlPrerender(config) {
954
- const htmlReloadId = "@wxt/reload-html";
955
- const resolvedHtmlReloadId = resolve3(
956
- config.root,
957
- "node_modules/wxt/dist/virtual-modules/reload-html.js"
958
- );
959
- const virtualReactRefreshId = "@wxt/virtual-react-refresh";
960
- const resolvedVirtualReactRefreshId = "\0" + virtualReactRefreshId;
961
- return [
962
- {
963
- apply: "build",
964
- name: "wxt:dev-html-prerender",
965
- config() {
966
- return {
967
- resolve: {
968
- alias: {
969
- [htmlReloadId]: resolvedHtmlReloadId
970
- }
971
- }
972
- };
973
- },
974
- // Convert scripts like src="./main.tsx" -> src="http://localhost:3000/entrypoints/popup/main.tsx"
975
- // before the paths are replaced with their bundled path
976
- transform(code, id) {
977
- const server = config.server;
978
- if (config.command !== "serve" || server == null || !id.endsWith(".html"))
979
- return;
980
- const { document } = parseHTML(code);
981
- const pointToDevServer = (querySelector, attr) => {
982
- document.querySelectorAll(querySelector).forEach((element) => {
983
- const src = element.getAttribute(attr);
984
- if (!src)
985
- return;
986
- if (isAbsolute(src)) {
987
- element.setAttribute(attr, server.origin + src);
988
- } else if (src.startsWith(".")) {
989
- const abs = resolve3(dirname2(id), src);
990
- const pathname = relative2(config.root, abs);
991
- element.setAttribute(attr, `${server.origin}/${pathname}`);
992
- }
993
- });
994
- };
995
- pointToDevServer("script[type=module]", "src");
996
- pointToDevServer("link[rel=stylesheet]", "href");
997
- const reloader = document.createElement("script");
998
- reloader.src = htmlReloadId;
999
- reloader.type = "module";
1000
- document.head.appendChild(reloader);
1001
- const newHtml = document.toString();
1002
- config.logger.debug("transform " + id);
1003
- config.logger.debug("Old HTML:\n" + code);
1004
- config.logger.debug("New HTML:\n" + newHtml);
1005
- return newHtml;
1006
- },
1007
- // Pass the HTML through the dev server to add dev-mode specific code
1008
- async transformIndexHtml(html, ctx) {
1009
- const server = config.server;
1010
- if (config.command !== "serve" || server == null)
1011
- return;
1012
- const originalUrl = `${server.origin}${ctx.path}`;
1013
- const name = getEntrypointName(config.entrypointsDir, ctx.filename);
1014
- const url2 = `${server.origin}/${name}.html`;
1015
- const serverHtml = await server.transformIndexHtml(
1016
- url2,
1017
- html,
1018
- originalUrl
1019
- );
1020
- const { document } = parseHTML(serverHtml);
1021
- const reactRefreshScript = Array.from(
1022
- document.querySelectorAll("script[type=module]")
1023
- ).find((script) => script.innerHTML.includes("@react-refresh"));
1024
- if (reactRefreshScript) {
1025
- reactRefreshPreamble = reactRefreshScript.innerHTML;
1026
- const virtualScript = document.createElement("script");
1027
- virtualScript.type = "module";
1028
- virtualScript.src = `${server.origin}/${virtualReactRefreshId}`;
1029
- reactRefreshScript.replaceWith(virtualScript);
1030
- }
1031
- const viteClientScript = document.querySelector(
1032
- "script[src='/@vite/client']"
1033
- );
1034
- if (viteClientScript) {
1035
- viteClientScript.src = `${server.origin}${viteClientScript.src}`;
1036
- }
1037
- const newHtml = document.toString();
1038
- config.logger.debug("transformIndexHtml " + ctx.filename);
1039
- config.logger.debug("Old HTML:\n" + html);
1040
- config.logger.debug("New HTML:\n" + newHtml);
1041
- return newHtml;
1042
- }
1043
- },
1044
- {
1045
- name: "wxt:virtualize-react-refresh",
1046
- apply: "serve",
1047
- resolveId(id) {
1048
- if (id === `/${virtualReactRefreshId}`) {
1049
- return resolvedVirtualReactRefreshId;
1050
- }
1051
- if (id.startsWith("/chunks/")) {
1052
- return "\0noop";
1053
- }
1054
- },
1055
- load(id) {
1056
- if (id === resolvedVirtualReactRefreshId) {
1057
- return reactRefreshPreamble;
1058
- }
1059
- if (id === "\0noop") {
1060
- return "";
1061
- }
1062
- }
1063
- }
1064
- ];
1065
- }
1066
-
1067
- // src/core/vite-plugins/devServerGlobals.ts
1068
- function devServerGlobals(internalConfig) {
1069
- return {
1070
- name: "wxt:dev-server-globals",
1071
- config() {
1072
- if (internalConfig.server == null || internalConfig.command == "build")
1073
- return;
1074
- return {
1075
- define: {
1076
- __DEV_SERVER_PROTOCOL__: JSON.stringify("ws:"),
1077
- __DEV_SERVER_HOSTNAME__: JSON.stringify(
1078
- internalConfig.server.hostname
1079
- ),
1080
- __DEV_SERVER_PORT__: JSON.stringify(internalConfig.server.port)
1081
- }
1082
- };
1083
- }
1084
- };
1085
- }
1086
-
1087
- // src/core/utils/network.ts
1088
- import dns from "node:dns";
1089
-
1090
- // src/core/utils/promises.ts
1091
- function withTimeout(promise, duration) {
1092
- return new Promise((res, rej) => {
1093
- const timeout = setTimeout(() => {
1094
- rej(`Promise timed out after ${duration}ms`);
1095
- }, duration);
1096
- promise.then(res).catch(rej).finally(() => clearTimeout(timeout));
1097
- });
1098
- }
1099
-
1100
- // src/core/utils/network.ts
1101
- function isOffline() {
1102
- const isOffline2 = new Promise((res) => {
1103
- dns.resolve("google.com", (err) => {
1104
- if (err == null) {
1105
- res(false);
1106
- } else {
1107
- res(true);
1108
- }
1109
- });
1110
- });
1111
- return withTimeout(isOffline2, 1e3).catch(() => true);
1112
- }
1113
- async function isOnline() {
1114
- const offline = await isOffline();
1115
- return !offline;
1116
- }
1117
- async function fetchCached(url2, config) {
1118
- let content = "";
1119
- if (await isOnline()) {
1120
- const res = await fetch(url2);
1121
- if (res.status < 300) {
1122
- content = await res.text();
1123
- await config.fsCache.set(url2, content);
1124
- } else {
1125
- config.logger.debug(
1126
- `Failed to download "${url2}", falling back to cache...`
1127
- );
1128
- }
1129
- }
1130
- if (!content)
1131
- content = await config.fsCache.get(url2) ?? "";
1132
- if (!content)
1133
- throw Error(
1134
- `Offline and "${url2}" has not been cached. Try again when online.`
1135
- );
1136
- return content;
1137
- }
1138
-
1139
- // src/core/vite-plugins/download.ts
1140
- function download(config) {
1141
- return {
1142
- name: "wxt:download",
1143
- resolveId(id) {
1144
- if (id.startsWith("url:"))
1145
- return "\0" + id;
1146
- },
1147
- async load(id) {
1148
- if (!id.startsWith("\0url:"))
1149
- return;
1150
- const url2 = id.replace("\0url:", "");
1151
- return await fetchCached(url2, config);
1152
- }
1153
- };
1154
- }
1155
-
1156
- // src/core/vite-plugins/multipageMove.ts
1157
- import { dirname as dirname3, extname, resolve as resolve4 } from "node:path";
1158
- import fs3, { ensureDir as ensureDir2 } from "fs-extra";
1159
- function multipageMove(entrypoints, config) {
1160
- return {
1161
- name: "wxt:multipage-move",
1162
- async writeBundle(_, bundle) {
1163
- for (const oldBundlePath in bundle) {
1164
- const entrypoint = entrypoints.find(
1165
- (entry) => !!normalizePath2(entry.inputPath).endsWith(oldBundlePath)
1166
- );
1167
- if (entrypoint == null) {
1168
- config.logger.debug(
1169
- `No entrypoint found for ${oldBundlePath}, leaving in chunks directory`
1170
- );
1171
- continue;
1172
- }
1173
- const newBundlePath = getEntrypointBundlePath(
1174
- entrypoint,
1175
- config.outDir,
1176
- extname(oldBundlePath)
1177
- );
1178
- if (newBundlePath === oldBundlePath) {
1179
- config.logger.debug(
1180
- "HTML file is already in the correct location",
1181
- oldBundlePath
1182
- );
1183
- continue;
1184
- }
1185
- const oldAbsPath = resolve4(config.outDir, oldBundlePath);
1186
- const newAbsPath = resolve4(config.outDir, newBundlePath);
1187
- await ensureDir2(dirname3(newAbsPath));
1188
- await fs3.move(oldAbsPath, newAbsPath, { overwrite: true });
1189
- const renamedChunk = {
1190
- ...bundle[oldBundlePath],
1191
- fileName: newBundlePath
1192
- };
1193
- delete bundle[oldBundlePath];
1194
- bundle[newBundlePath] = renamedChunk;
1195
- }
1196
- }
1197
- };
1198
- }
1199
-
1200
- // src/core/vite-plugins/unimport.ts
1201
- import { createUnimport } from "unimport";
1202
-
1203
- // src/core/utils/auto-imports.ts
1204
- import { mergeConfig } from "vite";
1205
- function getUnimportOptions(config) {
1206
- if (config.imports === false)
1207
- return false;
1208
- const defaultOptions = {
1209
- debugLog: config.logger.debug,
1210
- imports: [
1211
- { name: "defineConfig", from: "wxt" },
1212
- { name: "fakeBrowser", from: "wxt/testing" }
1213
- ],
1214
- presets: [
1215
- { package: "wxt/client" },
1216
- { package: "wxt/browser" },
1217
- { package: "wxt/sandbox" }
1218
- ],
1219
- warn: config.logger.warn,
1220
- dirs: ["components", "composables", "hooks", "utils"]
1221
- };
1222
- return mergeConfig(
1223
- defaultOptions,
1224
- config.imports
1225
- );
1226
- }
1227
-
1228
- // src/core/vite-plugins/unimport.ts
1229
- import { extname as extname2 } from "path";
1230
- var ENABLED_EXTENSIONS = {
1231
- ".js": true,
1232
- ".jsx": true,
1233
- ".ts": true,
1234
- ".tsx": true,
1235
- ".vue": true,
1236
- ".svelte": true
1237
- };
1238
- function unimport(config) {
1239
- const options = getUnimportOptions(config);
1240
- if (options === false)
1241
- return [];
1242
- const unimport2 = createUnimport(options);
1243
- return {
1244
- name: "wxt:unimport",
1245
- async config() {
1246
- await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
1247
- },
1248
- async transform(code, id) {
1249
- const ext = extname2(id);
1250
- if (ENABLED_EXTENSIONS[ext])
1251
- return unimport2.injectImports(code, id);
1252
- }
1253
- };
1254
- }
1255
-
1256
- // src/core/vite-plugins/virtualEntrypoint.ts
1257
- import fs4 from "fs-extra";
1258
- import { resolve as resolve5 } from "path";
1259
- function virtualEntrypoint(type, config) {
1260
- const virtualId = `virtual:wxt-${type}?`;
1261
- const resolvedVirtualId = `\0${virtualId}`;
1262
- return {
1263
- name: `wxt:virtual-entrypoint`,
1264
- resolveId(id) {
1265
- const index = id.indexOf(virtualId);
1266
- if (index === -1)
1267
- return;
1268
- const inputPath = normalizePath2(id.substring(index + virtualId.length));
1269
- return resolvedVirtualId + inputPath;
1270
- },
1271
- async load(id) {
1272
- if (!id.startsWith(resolvedVirtualId))
1273
- return;
1274
- const inputPath = id.replace(resolvedVirtualId, "");
1275
- const template = await fs4.readFile(
1276
- resolve5(
1277
- config.root,
1278
- `node_modules/wxt/dist/virtual-modules/${type}-entrypoint.js`
1279
- ),
1280
- "utf-8"
1281
- );
1282
- return template.replace(`virtual:user-${type}`, inputPath);
1283
- }
1284
- };
1285
- }
1286
-
1287
- // src/core/vite-plugins/tsconfigPaths.ts
1288
- function tsconfigPaths(config) {
1289
- return {
1290
- name: "wxt:aliases",
1291
- async config() {
1292
- return {
1293
- resolve: {
1294
- alias: {
1295
- "@@": config.root,
1296
- "~~": config.root,
1297
- "@": config.srcDir,
1298
- "~": config.srcDir
1299
- }
1300
- }
1301
- };
1302
- }
1303
- };
1304
- }
1305
-
1306
- // src/core/vite-plugins/noopBackground.ts
1307
- function noopBackground() {
1308
- const virtualModuleId = VIRTUAL_NOOP_BACKGROUND_MODULE_ID;
1309
- const resolvedVirtualModuleId = "\0" + virtualModuleId;
1310
- return {
1311
- name: "wxt:noop-background",
1312
- resolveId(id) {
1313
- if (id === virtualModuleId)
1314
- return resolvedVirtualModuleId;
1315
- },
1316
- load(id) {
1317
- if (id === resolvedVirtualModuleId) {
1318
- return `import { defineBackground } from 'wxt/client';
1319
- export default defineBackground(() => void 0)`;
1320
- }
1321
- }
1322
- };
1323
- }
1324
- var VIRTUAL_NOOP_BACKGROUND_MODULE_ID = "virtual:user-background";
1325
-
1326
- // src/core/vite-plugins/cssEntrypoints.ts
1327
- function cssEntrypoints(entrypoint, config) {
1328
- return {
1329
- name: "wxt:css-entrypoint",
1330
- config() {
1331
- return {
1332
- build: {
1333
- rollupOptions: {
1334
- output: {
1335
- assetFileNames: () => getEntrypointBundlePath(entrypoint, config.outDir, ".css")
1336
- }
1337
- }
1338
- }
1339
- };
1340
- },
1341
- generateBundle(_, bundle) {
1342
- Object.keys(bundle).forEach((file) => {
1343
- if (file.endsWith(".js"))
1344
- delete bundle[file];
1345
- });
1346
- }
1347
- };
1348
- }
1349
-
1350
- // src/core/vite-plugins/bundleAnalysis.ts
1351
- import { visualizer } from "rollup-plugin-visualizer";
1352
- var increment = 0;
1353
- function bundleAnalysis() {
1354
- return visualizer({
1355
- emitFile: true,
1356
- template: "raw-data",
1357
- filename: `stats-${increment++}.json`
1358
- });
1359
- }
1360
-
1361
- // src/core/utils/globals.ts
1362
- function getGlobals(config) {
1363
- return [
1364
- {
1365
- name: surroundInUnderscore("MANIFEST_VERSION"),
1366
- value: config.manifestVersion,
1367
- type: `2 | 3`
1368
- },
1369
- {
1370
- name: surroundInUnderscore("BROWSER"),
1371
- value: config.browser,
1372
- type: `string`
1373
- },
1374
- {
1375
- name: surroundInUnderscore("IS_CHROME"),
1376
- value: config.browser === "chrome",
1377
- type: `boolean`
1378
- },
1379
- {
1380
- name: surroundInUnderscore("IS_FIREFOX"),
1381
- value: config.browser === "firefox",
1382
- type: `boolean`
1383
- },
1384
- {
1385
- name: surroundInUnderscore("IS_SAFARI"),
1386
- value: config.browser === "safari",
1387
- type: `boolean`
1388
- },
1389
- {
1390
- name: surroundInUnderscore("IS_EDGE"),
1391
- value: config.browser === "edge",
1392
- type: `boolean`
1393
- },
1394
- {
1395
- name: surroundInUnderscore("IS_OPERA"),
1396
- value: config.browser === "opera",
1397
- type: `boolean`
1398
- },
1399
- {
1400
- name: surroundInUnderscore("COMMAND"),
1401
- value: config.command,
1402
- type: `"build" | "serve"`
1403
- }
1404
- ];
1405
- }
1406
- function getEntrypointGlobals(config, entrypointName) {
1407
- return [
1408
- {
1409
- name: surroundInUnderscore("ENTRYPOINT"),
1410
- value: entrypointName,
1411
- type: `string`
1412
- }
1413
- ];
1414
- }
1415
- function surroundInUnderscore(name) {
1416
- return `__${name}__`;
1417
- }
1418
-
1419
- // src/core/vite-plugins/globals.ts
1420
- function globals(config) {
1421
- return {
1422
- name: "wxt:globals",
1423
- config() {
1424
- const define = {};
1425
- for (const global2 of getGlobals(config)) {
1426
- define[global2.name] = JSON.stringify(global2.value);
1427
- }
1428
- return {
1429
- define
1430
- };
1431
- }
1432
- };
1433
- }
1434
-
1435
- // src/core/utils/getInternalConfig.ts
1436
- async function getInternalConfig(inlineConfig, command) {
1437
- let userConfig = {};
1438
- let userConfigMetadata;
1439
- if (inlineConfig.configFile !== false) {
1440
- const { config: loadedConfig, ...metadata } = await loadConfig({
1441
- name: "wxt",
1442
- cwd: inlineConfig.root ?? process.cwd(),
1443
- rcFile: false
1444
- });
1445
- userConfig = loadedConfig ?? {};
1446
- userConfigMetadata = metadata;
1447
- }
1448
- const mergedConfig = mergeInlineConfig(inlineConfig, userConfig);
1449
- const debug = mergedConfig.debug ?? false;
1450
- const logger = mergedConfig.logger ?? consola;
1451
- if (debug)
1452
- logger.level = LogLevels.debug;
1453
- const browser = mergedConfig.browser ?? "chrome";
1454
- const manifestVersion = mergedConfig.manifestVersion ?? (browser === "firefox" || browser === "safari" ? 2 : 3);
1455
- const mode = mergedConfig.mode ?? (command === "build" ? "production" : "development");
1456
- const env = { browser, command, manifestVersion, mode };
1457
- const root = path2.resolve(
1458
- inlineConfig.root ?? userConfig.root ?? process.cwd()
1459
- );
1460
- const wxtDir = path2.resolve(root, ".wxt");
1461
- const srcDir = path2.resolve(root, mergedConfig.srcDir ?? root);
1462
- const entrypointsDir = path2.resolve(
1463
- srcDir,
1464
- mergedConfig.entrypointsDir ?? "entrypoints"
1465
- );
1466
- const publicDir = path2.resolve(srcDir, mergedConfig.publicDir ?? "public");
1467
- const typesDir = path2.resolve(wxtDir, "types");
1468
- const outBaseDir = path2.resolve(root, ".output");
1469
- const outDir = path2.resolve(outBaseDir, `${browser}-mv${manifestVersion}`);
1470
- const runnerConfig = await loadConfig({
1471
- name: "web-ext",
1472
- cwd: root,
1473
- globalRc: true,
1474
- rcFile: ".webextrc",
1475
- overrides: inlineConfig.runner,
1476
- defaults: userConfig.runner
1477
- });
1478
- const finalConfig = {
1479
- browser,
1480
- command,
1481
- debug,
1482
- entrypointsDir,
1483
- env,
1484
- fsCache: createFsCache(wxtDir),
1485
- imports: mergedConfig.imports ?? {},
1486
- logger,
1487
- manifest: await resolveManifestConfig(env, mergedConfig.manifest),
1488
- manifestVersion,
1489
- mode,
1490
- outBaseDir,
1491
- outDir,
1492
- publicDir,
1493
- root,
1494
- runnerConfig,
1495
- srcDir,
1496
- typesDir,
1497
- vite: () => ({}),
1498
- // Real value added after this object is initialized.
1499
- wxtDir,
1500
- zip: resolveInternalZipConfig(root, mergedConfig),
1501
- transformManifest(manifest) {
1502
- userConfig.transformManifest?.(manifest);
1503
- inlineConfig.transformManifest?.(manifest);
1504
- },
1505
- analysis: {
1506
- enabled: mergedConfig.analysis?.enabled ?? false,
1507
- template: mergedConfig.analysis?.template ?? "treemap"
1508
- },
1509
- userConfigMetadata: userConfigMetadata ?? {}
1510
- };
1511
- finalConfig.vite = (env2) => resolveInternalViteConfig(env2, mergedConfig, finalConfig);
1512
- return finalConfig;
1513
- }
1514
- async function resolveManifestConfig(env, manifest) {
1515
- return await (typeof manifest === "function" ? manifest(env) : manifest ?? {});
1516
- }
1517
- function mergeInlineConfig(inlineConfig, userConfig) {
1518
- let imports;
1519
- if (inlineConfig.imports === false || userConfig.imports === false) {
1520
- imports = false;
1521
- } else if (userConfig.imports == null && inlineConfig.imports == null) {
1522
- imports = void 0;
1523
- } else {
1524
- imports = vite2.mergeConfig(
1525
- userConfig.imports ?? {},
1526
- inlineConfig.imports ?? {}
1527
- );
1528
- }
1529
- const manifest = async (env) => {
1530
- const user = await resolveManifestConfig(env, userConfig.manifest);
1531
- const inline = await resolveManifestConfig(env, inlineConfig.manifest);
1532
- return vite2.mergeConfig(user, inline);
1533
- };
1534
- const viteConfig = async (env) => {
1535
- const user = await userConfig.vite?.(env);
1536
- const inline = await inlineConfig.vite?.(env);
1537
- return vite2.mergeConfig(user ?? {}, inline ?? {});
1538
- };
1539
- const runner = vite2.mergeConfig(
1540
- userConfig.runner ?? {},
1541
- inlineConfig.runner ?? {}
1542
- );
1543
- const zip = vite2.mergeConfig(
1544
- userConfig.zip ?? {},
1545
- inlineConfig.zip ?? {}
1546
- );
1547
- return {
1548
- root: inlineConfig.root ?? userConfig.root,
1549
- browser: inlineConfig.browser ?? userConfig.browser,
1550
- manifestVersion: inlineConfig.manifestVersion ?? userConfig.manifestVersion,
1551
- configFile: inlineConfig.configFile,
1552
- debug: inlineConfig.debug ?? userConfig.debug,
1553
- entrypointsDir: inlineConfig.entrypointsDir ?? userConfig.entrypointsDir,
1554
- imports,
1555
- logger: inlineConfig.logger ?? userConfig.logger,
1556
- manifest,
1557
- mode: inlineConfig.mode ?? userConfig.mode,
1558
- publicDir: inlineConfig.publicDir ?? userConfig.publicDir,
1559
- runner,
1560
- srcDir: inlineConfig.srcDir ?? userConfig.srcDir,
1561
- vite: viteConfig,
1562
- zip,
1563
- analysis: {
1564
- enabled: inlineConfig.analysis?.enabled ?? userConfig.analysis?.enabled,
1565
- template: inlineConfig.analysis?.template ?? userConfig.analysis?.template
1566
- }
1567
- };
1568
- }
1569
- function resolveInternalZipConfig(root, mergedConfig) {
1570
- return {
1571
- sourcesTemplate: "{{name}}-{{version}}-sources.zip",
1572
- artifactTemplate: "{{name}}-{{version}}-{{browser}}.zip",
1573
- sourcesRoot: root,
1574
- ...mergedConfig.zip,
1575
- ignoredSources: [
1576
- "**/node_modules",
1577
- // WXT files
1578
- "**/web-ext.config.ts",
1579
- // Hidden files
1580
- "**/.*",
1581
- // Tests
1582
- "**/__tests__/**",
1583
- "**/*.+(test|spec).?(c|m)+(j|t)s?(x)",
1584
- // From user
1585
- ...mergedConfig.zip?.ignoredSources ?? []
1586
- ]
1587
- };
1588
- }
1589
- async function resolveInternalViteConfig(env, mergedConfig, finalConfig) {
1590
- const internalVite = await mergedConfig.vite?.(env) ?? {};
1591
- internalVite.root = finalConfig.root;
1592
- internalVite.configFile = false;
1593
- internalVite.logLevel = "warn";
1594
- internalVite.mode = env.mode;
1595
- internalVite.build ??= {};
1596
- internalVite.build.outDir = finalConfig.outDir;
1597
- internalVite.build.emptyOutDir = false;
1598
- internalVite.plugins ??= [];
1599
- internalVite.plugins.push(download(finalConfig));
1600
- internalVite.plugins.push(devHtmlPrerender(finalConfig));
1601
- internalVite.plugins.push(unimport(finalConfig));
1602
- internalVite.plugins.push(
1603
- virtualEntrypoint("background", finalConfig)
1604
- );
1605
- internalVite.plugins.push(
1606
- virtualEntrypoint("content-script", finalConfig)
1607
- );
1608
- internalVite.plugins.push(
1609
- virtualEntrypoint("unlisted-script", finalConfig)
1610
- );
1611
- internalVite.plugins.push(devServerGlobals(finalConfig));
1612
- internalVite.plugins.push(tsconfigPaths(finalConfig));
1613
- internalVite.plugins.push(noopBackground());
1614
- if (finalConfig.analysis.enabled) {
1615
- internalVite.plugins.push(bundleAnalysis());
1616
- }
1617
- internalVite.plugins.push(globals(finalConfig));
1618
- return internalVite;
1619
- }
1620
-
1621
- // src/index.ts
1622
- import pc5 from "picocolors";
1623
-
1624
- // src/core/utils/arrays.ts
1625
- function every(array, predicate) {
1626
- for (let i = 0; i < array.length; i++)
1627
- if (!predicate(array[i], i))
1628
- return false;
1629
- return true;
1630
- }
1631
-
1632
- // src/core/utils/detectDevChanges.ts
1633
- function detectDevChanges(changedFiles, currentOutput) {
1634
- if (currentOutput == null)
1635
- return { type: "no-change" };
1636
- const changedSteps = new Set(
1637
- changedFiles.flatMap(
1638
- (changedFile) => findEffectedSteps(changedFile, currentOutput)
1639
- )
1640
- );
1641
- if (changedSteps.size === 0)
1642
- return { type: "no-change" };
1643
- const unchangedOutput = {
1644
- manifest: currentOutput.manifest,
1645
- steps: [],
1646
- publicAssets: []
1647
- };
1648
- const changedOutput = {
1649
- manifest: currentOutput.manifest,
1650
- steps: [],
1651
- publicAssets: []
1652
- };
1653
- for (const step of currentOutput.steps) {
1654
- if (changedSteps.has(step)) {
1655
- changedOutput.steps.push(step);
1656
- } else {
1657
- unchangedOutput.steps.push(step);
1658
- }
1659
- }
1660
- for (const asset of currentOutput.publicAssets) {
1661
- if (changedSteps.has(asset)) {
1662
- changedOutput.publicAssets.push(asset);
1663
- } else {
1664
- unchangedOutput.publicAssets.push(asset);
1665
- }
1666
- }
1667
- const isOnlyHtmlChanges = changedFiles.length > 0 && every(changedFiles, ([_, file]) => file.endsWith(".html"));
1668
- if (isOnlyHtmlChanges) {
1669
- return {
1670
- type: "html-reload",
1671
- cachedOutput: unchangedOutput,
1672
- rebuildGroups: changedOutput.steps.map((step) => step.entrypoints)
1673
- };
1674
- }
1675
- const isOnlyContentScripts = changedOutput.steps.length > 0 && every(
1676
- changedOutput.steps.flatMap((step) => step.entrypoints),
1677
- (entry) => entry.type === "content-script"
1678
- );
1679
- if (isOnlyContentScripts) {
1680
- return {
1681
- type: "content-script-reload",
1682
- cachedOutput: unchangedOutput,
1683
- changedSteps: changedOutput.steps,
1684
- rebuildGroups: changedOutput.steps.map((step) => step.entrypoints)
1685
- };
1686
- }
1687
- return {
1688
- type: "extension-reload",
1689
- cachedOutput: unchangedOutput,
1690
- rebuildGroups: changedOutput.steps.map((step) => step.entrypoints)
1691
- };
1692
- }
1693
- function findEffectedSteps(changedFile, currentOutput) {
1694
- const changes = [];
1695
- const changedPath = normalizePath2(changedFile[1]);
1696
- const isChunkEffected = (chunk) => (
1697
- // If it's an HTML file with the same path, is is effected because HTML files need to be pre-rendered
1698
- // fileName is normalized, relative bundle path
1699
- chunk.type === "asset" && changedPath.endsWith(chunk.fileName) || // If it's a chunk that depends on the changed file, it is effected
1700
- // moduleIds are absolute, normalized paths
1701
- chunk.type === "chunk" && chunk.moduleIds.includes(changedPath)
1702
- );
1703
- for (const step of currentOutput.steps) {
1704
- const effectedChunk = step.chunks.find((chunk) => isChunkEffected(chunk));
1705
- if (effectedChunk)
1706
- changes.push(step);
1707
- }
1708
- const effectedAsset = currentOutput.publicAssets.find(
1709
- (chunk) => isChunkEffected(chunk)
1710
- );
1711
- if (effectedAsset)
1712
- changes.push(effectedAsset);
1713
- return changes;
1714
- }
1715
-
1716
- // src/index.ts
1717
- import { Mutex } from "async-mutex";
1718
- import { consola as consola3 } from "consola";
1719
- import { relative as relative8 } from "node:path";
1720
-
1721
- // src/core/build/buildEntrypoints.ts
1722
- import * as vite3 from "vite";
1723
-
1724
- // src/core/utils/removeEmptyDirs.ts
1725
- import fs5 from "fs-extra";
1726
- import path3 from "path";
1727
- async function removeEmptyDirs(dir) {
1728
- const files = await fs5.readdir(dir);
1729
- for (const file of files) {
1730
- const filePath = path3.join(dir, file);
1731
- const stats = await fs5.stat(filePath);
1732
- if (stats.isDirectory()) {
1733
- await removeEmptyDirs(filePath);
1734
- }
1735
- }
1736
- try {
1737
- await fs5.rmdir(dir);
1738
- } catch {
1739
- }
1740
- }
1741
-
1742
- // src/core/build/buildEntrypoints.ts
1743
- import fs7 from "fs-extra";
1744
- import { dirname as dirname4, resolve as resolve6 } from "path";
1745
-
1746
- // src/core/utils/public.ts
1747
- import fs6 from "fs-extra";
1748
- import glob from "fast-glob";
1749
- async function getPublicFiles(config) {
1750
- if (!await fs6.exists(config.publicDir))
1751
- return [];
1752
- const files = await glob("**/*", { cwd: config.publicDir });
1753
- return files.map(unnormalizePath);
1754
- }
1755
-
1756
- // src/core/build/buildEntrypoints.ts
1757
- import pc from "picocolors";
1758
- async function buildEntrypoints(groups, config, spinner) {
1759
- const steps = [];
1760
- for (let i = 0; i < groups.length; i++) {
1761
- const group = groups[i];
1762
- spinner.text = pc.dim(`[${i + 1}/${groups.length}]`) + ` ${[group].flat().map((e) => e.name).join(pc.dim(", "))}`;
1763
- const step = Array.isArray(group) ? await buildMultipleEntrypoints(group, config) : await buildSingleEntrypoint(group, config);
1764
- steps.push(step);
1765
- }
1766
- const publicAssets = await copyPublicDirectory(config);
1767
- await removeEmptyDirs(config.outDir);
1768
- return { publicAssets, steps };
1769
- }
1770
- async function buildSingleEntrypoint(entrypoint, config) {
1771
- const isVirtual = [
1772
- "background",
1773
- "content-script",
1774
- "unlisted-script"
1775
- ].includes(entrypoint.type);
1776
- const entry = isVirtual ? `virtual:wxt-${entrypoint.type}?${entrypoint.inputPath}` : entrypoint.inputPath;
1777
- const plugins = [];
1778
- if (entrypoint.type === "content-script-style" || entrypoint.type === "unlisted-style") {
1779
- plugins.push(cssEntrypoints(entrypoint, config));
1780
- }
1781
- const libMode = {
1782
- plugins,
1783
- build: {
1784
- lib: {
1785
- entry,
1786
- formats: ["iife"],
1787
- name: "_",
1788
- fileName: entrypoint.name
1789
- },
1790
- rollupOptions: {
1791
- output: {
1792
- // There's only a single output for this build, so we use the desired bundle path for the
1793
- // entry output (like "content-scripts/overlay.js")
1794
- entryFileNames: getEntrypointBundlePath(
1795
- entrypoint,
1796
- config.outDir,
1797
- ".js"
1798
- ),
1799
- // Output content script CSS to `content-scripts/`, but all other scripts are written to
1800
- // `assets/`.
1801
- assetFileNames: ({ name }) => {
1802
- if (entrypoint.type === "content-script" && name?.endsWith("css")) {
1803
- return `content-scripts/${entrypoint.name}.[ext]`;
1804
- } else {
1805
- return `assets/${entrypoint.name}.[ext]`;
1806
- }
1807
- }
1808
- }
1809
- }
1810
- },
1811
- define: {
1812
- // See https://github.com/aklinker1/vite-plugin-web-extension/issues/96
1813
- "process.env.NODE_ENV": JSON.stringify(config.mode)
1814
- }
1815
- };
1816
- for (const global2 of getEntrypointGlobals(config, entrypoint.name)) {
1817
- libMode.define[global2.name] = JSON.stringify(global2.value);
1818
- }
1819
- const entryConfig = vite3.mergeConfig(
1820
- libMode,
1821
- await config.vite(config.env)
1822
- );
1823
- const result = await vite3.build(entryConfig);
1824
- return {
1825
- entrypoints: entrypoint,
1826
- chunks: getBuildOutputChunks(result)
1827
- };
1828
- }
1829
- async function buildMultipleEntrypoints(entrypoints, config) {
1830
- const multiPage = {
1831
- plugins: [multipageMove(entrypoints, config)],
1832
- build: {
1833
- rollupOptions: {
1834
- input: entrypoints.reduce((input, entry) => {
1835
- input[entry.name] = entry.inputPath;
1836
- return input;
1837
- }, {}),
1838
- output: {
1839
- // Include a hash to prevent conflicts
1840
- chunkFileNames: "chunks/[name]-[hash].js",
1841
- // Include a hash to prevent conflicts
1842
- entryFileNames: "chunks/[name]-[hash].js",
1843
- // We can't control the "name", so we need a hash to prevent conflicts
1844
- assetFileNames: "assets/[name]-[hash].[ext]"
1845
- }
1846
- }
1847
- },
1848
- define: {}
1849
- };
1850
- for (const global2 of getEntrypointGlobals(config, "html")) {
1851
- multiPage.define[global2.name] = JSON.stringify(global2.value);
1852
- }
1853
- const entryConfig = vite3.mergeConfig(
1854
- multiPage,
1855
- await config.vite(config.env)
1856
- );
1857
- const result = await vite3.build(entryConfig);
1858
- return {
1859
- entrypoints,
1860
- chunks: getBuildOutputChunks(result)
1861
- };
1862
- }
1863
- function getBuildOutputChunks(result) {
1864
- if ("on" in result)
1865
- throw Error("wxt does not support vite watch mode.");
1866
- if (Array.isArray(result))
1867
- return result.flatMap(({ output }) => output);
1868
- return result.output;
1869
- }
1870
- async function copyPublicDirectory(config) {
1871
- const files = await getPublicFiles(config);
1872
- if (files.length === 0)
1873
- return [];
1874
- const publicAssets = [];
1875
- for (const file of files) {
1876
- const srcPath = resolve6(config.publicDir, file);
1877
- const outPath = resolve6(config.outDir, file);
1878
- await fs7.ensureDir(dirname4(outPath));
1879
- await fs7.copyFile(srcPath, outPath);
1880
- publicAssets.push({
1881
- type: "asset",
1882
- fileName: file,
1883
- name: file,
1884
- needsCodeReference: false,
1885
- source: await fs7.readFile(srcPath)
1886
- });
1887
- }
1888
- return publicAssets;
1889
- }
1890
-
1891
- // src/core/build/findEntrypoints.ts
1892
- import { relative as relative3, resolve as resolve8 } from "path";
1893
- import fs9 from "fs-extra";
1894
- import { minimatch } from "minimatch";
1895
- import { parseHTML as parseHTML2 } from "linkedom";
1896
- import JSON5 from "json5";
1897
-
1898
- // src/core/utils/importEntrypointFile.ts
1899
- import createJITI from "jiti";
1900
- import { createUnimport as createUnimport2 } from "unimport";
1901
- import fs8 from "fs-extra";
1902
- import { resolve as resolve7 } from "path";
1903
-
1904
- // src/core/utils/strings.ts
1905
- function removeImportStatements(text) {
1906
- return text.replace(
1907
- /(import\s?[{\w][\s\S]*?from\s?["'][\s\S]*?["'];?|import\s?["'][\s\S]*?["'];?)/gm,
1908
- ""
1909
- );
1910
- }
1911
- function removeProjectImportStatements(text) {
1912
- const noImports = removeImportStatements(text);
1913
- return `import { defineContentScript, defineBackground } from 'wxt/client';
1914
- import { defineUnlistedScript } from 'wxt/sandbox';
1915
-
1916
- ${noImports}`;
1917
- }
1918
-
1919
- // src/core/utils/importEntrypointFile.ts
1920
- import { transformSync } from "esbuild";
1921
- async function importEntrypointFile(path9, config) {
1922
- config.logger.debug("Loading file metadata:", path9);
1923
- const normalPath = normalizePath2(path9);
1924
- const unimport2 = createUnimport2({
1925
- ...getUnimportOptions(config),
1926
- // Only allow specific imports, not all from the project
1927
- dirs: []
1928
- });
1929
- await unimport2.init();
1930
- const text = await fs8.readFile(path9, "utf-8");
1931
- const textNoImports = removeProjectImportStatements(text);
1932
- const { code } = await unimport2.injectImports(textNoImports);
1933
- config.logger.debug(
1934
- ["Text:", text, "No imports:", textNoImports, "Code:", code].join("\n")
1935
- );
1936
- const jiti = createJITI(__filename, {
1937
- cache: false,
1938
- debug: config.debug,
1939
- esmResolve: true,
1940
- alias: {
1941
- "webextension-polyfill": resolve7(
1942
- config.root,
1943
- "node_modules/wxt/dist/virtual-modules/fake-browser.js"
1944
- )
1945
- },
1946
- // List of extensions to transform with esbuild
1947
- extensions: [".ts", ".cts", ".mts", ".tsx", ".js", ".cjs", ".mjs", ".jsx"],
1948
- transform(opts) {
1949
- const isEntrypoint = opts.filename === normalPath;
1950
- return transformSync(
1951
- // Use modified source code for entrypoints
1952
- isEntrypoint ? code : opts.source,
1953
- getEsbuildOptions(opts)
1954
- );
1955
- }
1956
- });
1957
- try {
1958
- const res = await jiti(path9);
1959
- return res.default;
1960
- } catch (err) {
1961
- config.logger.error(err);
1962
- throw err;
1963
- }
1964
- }
1965
- function getEsbuildOptions(opts) {
1966
- const isJsx = opts.filename?.endsWith("x");
1967
- return {
1968
- format: "cjs",
1969
- loader: isJsx ? "tsx" : "ts",
1970
- jsx: isJsx ? "automatic" : void 0
1971
- };
1972
- }
1973
-
1974
- // src/core/build/findEntrypoints.ts
1975
- import glob2 from "fast-glob";
1976
- async function findEntrypoints(config) {
1977
- const relativePaths = await glob2("**/*", {
1978
- cwd: config.entrypointsDir
1979
- });
1980
- relativePaths.sort();
1981
- const pathGlobs = Object.keys(PATH_GLOB_TO_TYPE_MAP);
1982
- let hasBackground = false;
1983
- const possibleEntrypoints = await Promise.all(
1984
- relativePaths.map(async (relativePath) => {
1985
- const path9 = resolve8(config.entrypointsDir, relativePath);
1986
- const matchingGlob = pathGlobs.find(
1987
- (glob5) => minimatch(relativePath, glob5)
1988
- );
1989
- if (matchingGlob == null) {
1990
- config.logger.warn(
1991
- `${relativePath} does not match any known entrypoint. Known entrypoints:
1992
- ${JSON.stringify(
1993
- PATH_GLOB_TO_TYPE_MAP,
1994
- null,
1995
- 2
1996
- )}`
1997
- );
1998
- return;
1999
- }
2000
- const type = PATH_GLOB_TO_TYPE_MAP[matchingGlob];
2001
- if (type === "ignored")
2002
- return;
2003
- switch (type) {
2004
- case "popup":
2005
- return await getPopupEntrypoint(config, path9);
2006
- case "options":
2007
- return await getOptionsEntrypoint(config, path9);
2008
- case "background":
2009
- hasBackground = true;
2010
- return await getBackgroundEntrypoint(config, path9);
2011
- case "content-script":
2012
- return await getContentScriptEntrypoint(config, path9);
2013
- case "unlisted-page":
2014
- return await getUnlistedPageEntrypoint(config, path9);
2015
- case "unlisted-script":
2016
- return await getUnlistedScriptEntrypoint(config, path9);
2017
- case "content-script-style":
2018
- return {
2019
- type,
2020
- name: getEntrypointName(config.entrypointsDir, path9),
2021
- inputPath: path9,
2022
- outputDir: resolve8(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2023
- options: {
2024
- include: void 0,
2025
- exclude: void 0
2026
- }
2027
- };
2028
- default:
2029
- return {
2030
- type,
2031
- name: getEntrypointName(config.entrypointsDir, path9),
2032
- inputPath: path9,
2033
- outputDir: config.outDir,
2034
- options: {
2035
- include: void 0,
2036
- exclude: void 0
2037
- }
2038
- };
2039
- }
2040
- })
2041
- );
2042
- const entrypoints = possibleEntrypoints.filter(
2043
- (entry) => !!entry
2044
- );
2045
- const existingNames = {};
2046
- entrypoints.forEach((entrypoint) => {
2047
- const withSameName = existingNames[entrypoint.name];
2048
- if (withSameName) {
2049
- throw Error(
2050
- `Multiple entrypoints with the name "${entrypoint.name}" detected, but only one is allowed: ${[
2051
- relative3(config.root, withSameName.inputPath),
2052
- relative3(config.root, entrypoint.inputPath)
2053
- ].join(", ")}`
2054
- );
2055
- }
2056
- existingNames[entrypoint.name] = entrypoint;
2057
- });
2058
- if (config.command === "serve" && !hasBackground) {
2059
- entrypoints.push(
2060
- await getBackgroundEntrypoint(config, VIRTUAL_NOOP_BACKGROUND_MODULE_ID)
2061
- );
2062
- }
2063
- config.logger.debug("All entrypoints:", entrypoints);
2064
- const targetEntrypoints = entrypoints.filter((entry) => {
2065
- const { include, exclude } = entry.options;
2066
- if (include?.length && exclude?.length) {
2067
- config.logger.warn(
2068
- `The ${entry.name} entrypoint lists both include and exclude, but only one can be used per entrypoint. Entrypoint ignored.`
2069
- );
2070
- return false;
2071
- }
2072
- if (exclude?.length && !include?.length) {
2073
- return !exclude.includes(config.browser);
2074
- }
2075
- if (include?.length && !exclude?.length) {
2076
- return include.includes(config.browser);
2077
- }
2078
- return true;
2079
- });
2080
- config.logger.debug(`${config.browser} entrypoints:`, targetEntrypoints);
2081
- return targetEntrypoints;
2082
- }
2083
- function getHtmlBaseOptions(document) {
2084
- const options = {};
2085
- const includeContent = document.querySelector("meta[name='manifest.include']")?.getAttribute("content");
2086
- if (includeContent) {
2087
- options.include = JSON5.parse(includeContent);
2088
- }
2089
- const excludeContent = document.querySelector("meta[name='manifest.exclude']")?.getAttribute("content");
2090
- if (excludeContent) {
2091
- options.exclude = JSON5.parse(excludeContent);
2092
- }
2093
- return options;
2094
- }
2095
- async function getPopupEntrypoint(config, path9) {
2096
- const content = await fs9.readFile(path9, "utf-8");
2097
- const { document } = parseHTML2(content);
2098
- const options = getHtmlBaseOptions(document);
2099
- const title = document.querySelector("title");
2100
- if (title != null)
2101
- options.defaultTitle = title.textContent ?? void 0;
2102
- const defaultIconContent = document.querySelector("meta[name='manifest.default_icon']")?.getAttribute("content");
2103
- if (defaultIconContent) {
2104
- try {
2105
- options.defaultIcon = JSON5.parse(defaultIconContent);
2106
- } catch (err) {
2107
- config.logger.fatal(
2108
- `Failed to parse default_icon meta tag content as JSON5. content=${defaultIconContent}`,
2109
- err
2110
- );
2111
- }
2112
- }
2113
- const mv2TypeContent = document.querySelector("meta[name='manifest.type']")?.getAttribute("content");
2114
- if (mv2TypeContent) {
2115
- options.mv2Key = mv2TypeContent === "page_action" ? "page_action" : "browser_action";
2116
- }
2117
- const browserStyleContent = document.querySelector("meta[name='manifest.browser_style']")?.getAttribute("content");
2118
- if (browserStyleContent) {
2119
- options.browserStyle = browserStyleContent === "true";
2120
- }
2121
- return {
2122
- type: "popup",
2123
- name: "popup",
2124
- options,
2125
- inputPath: path9,
2126
- outputDir: config.outDir
2127
- };
2128
- }
2129
- async function getOptionsEntrypoint(config, path9) {
2130
- const content = await fs9.readFile(path9, "utf-8");
2131
- const { document } = parseHTML2(content);
2132
- const options = getHtmlBaseOptions(document);
2133
- const openInTabContent = document.querySelector("meta[name='manifest.open_in_tab']")?.getAttribute("content");
2134
- if (openInTabContent) {
2135
- options.openInTab = openInTabContent === "true";
2136
- }
2137
- const chromeStyleContent = document.querySelector("meta[name='manifest.chrome_style']")?.getAttribute("content");
2138
- if (chromeStyleContent) {
2139
- options.chromeStyle = chromeStyleContent === "true";
2140
- }
2141
- const browserStyleContent = document.querySelector("meta[name='manifest.browser_style']")?.getAttribute("content");
2142
- if (browserStyleContent) {
2143
- options.browserStyle = browserStyleContent === "true";
2144
- }
2145
- return {
2146
- type: "options",
2147
- name: "options",
2148
- options,
2149
- inputPath: path9,
2150
- outputDir: config.outDir
2151
- };
2152
- }
2153
- async function getUnlistedPageEntrypoint(config, path9) {
2154
- const content = await fs9.readFile(path9, "utf-8");
2155
- const { document } = parseHTML2(content);
2156
- return {
2157
- type: "unlisted-page",
2158
- name: getEntrypointName(config.entrypointsDir, path9),
2159
- inputPath: path9,
2160
- outputDir: config.outDir,
2161
- options: getHtmlBaseOptions(document)
2162
- };
2163
- }
2164
- async function getUnlistedScriptEntrypoint(config, path9) {
2165
- const name = getEntrypointName(config.entrypointsDir, path9);
2166
- const defaultExport = await importEntrypointFile(
2167
- path9,
2168
- config
2169
- );
2170
- if (defaultExport == null) {
2171
- throw Error(
2172
- `${name}: Default export not found, did you forget to call "export default defineUnlistedScript(...)"?`
2173
- );
2174
- }
2175
- const { main: _, ...moduleOptions } = defaultExport;
2176
- const options = moduleOptions;
2177
- return {
2178
- type: "unlisted-script",
2179
- name,
2180
- inputPath: path9,
2181
- outputDir: config.outDir,
2182
- options
2183
- };
2184
- }
2185
- async function getBackgroundEntrypoint(config, path9) {
2186
- const name = "background";
2187
- let options = {};
2188
- if (path9 !== VIRTUAL_NOOP_BACKGROUND_MODULE_ID) {
2189
- const defaultExport = await importEntrypointFile(
2190
- path9,
2191
- config
2192
- );
2193
- if (defaultExport == null) {
2194
- throw Error(
2195
- `${name}: Default export not found, did you forget to call "export default defineBackground(...)"?`
2196
- );
2197
- }
2198
- const { main: _, ...moduleOptions } = defaultExport;
2199
- options = moduleOptions;
2200
- }
2201
- return {
2202
- type: "background",
2203
- name,
2204
- inputPath: path9,
2205
- outputDir: config.outDir,
2206
- options: {
2207
- ...options,
2208
- type: resolvePerBrowserOption(options.type, config.browser),
2209
- persistent: resolvePerBrowserOption(options.persistent, config.browser)
2210
- }
2211
- };
2212
- }
2213
- async function getContentScriptEntrypoint(config, path9) {
2214
- const name = getEntrypointName(config.entrypointsDir, path9);
2215
- const { main: _, ...options } = await importEntrypointFile(path9, config);
2216
- if (options == null) {
2217
- throw Error(
2218
- `${name}: Default export not found, did you forget to call "export default defineContentScript(...)"?`
2219
- );
2220
- }
2221
- return {
2222
- type: "content-script",
2223
- name,
2224
- inputPath: path9,
2225
- outputDir: resolve8(config.outDir, CONTENT_SCRIPT_OUT_DIR),
2226
- options
2227
- };
2228
- }
2229
- var PATH_GLOB_TO_TYPE_MAP = {
2230
- "sandbox.html": "sandbox",
2231
- "sandbox/index.html": "sandbox",
2232
- "*.sandbox.html": "sandbox",
2233
- "*.sandbox/index.html": "sandbox",
2234
- "bookmarks.html": "bookmarks",
2235
- "bookmarks/index.html": "bookmarks",
2236
- "history.html": "history",
2237
- "history/index.html": "history",
2238
- "newtab.html": "newtab",
2239
- "newtab/index.html": "newtab",
2240
- "sidepanel.html": "sidepanel",
2241
- "sidepanel/index.html": "sidepanel",
2242
- "*.sidepanel.html": "sidepanel",
2243
- "*.sidepanel/index.html": "sidepanel",
2244
- "devtools.html": "devtools",
2245
- "devtools/index.html": "devtools",
2246
- "background.[jt]s": "background",
2247
- "background/index.[jt]s": "background",
2248
- [VIRTUAL_NOOP_BACKGROUND_MODULE_ID]: "background",
2249
- "content.[jt]s?(x)": "content-script",
2250
- "content/index.[jt]s?(x)": "content-script",
2251
- "*.content.[jt]s?(x)": "content-script",
2252
- "*.content/index.[jt]s?(x)": "content-script",
2253
- [`content.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
2254
- [`*.content.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
2255
- [`content/index.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
2256
- [`*.content/index.${CSS_EXTENSIONS_PATTERN}`]: "content-script-style",
2257
- "popup.html": "popup",
2258
- "popup/index.html": "popup",
2259
- "options.html": "options",
2260
- "options/index.html": "options",
2261
- "*.html": "unlisted-page",
2262
- "*/index.html": "unlisted-page",
2263
- "*.[jt]s": "unlisted-script",
2264
- "*/index.ts": "unlisted-script",
2265
- [`*.${CSS_EXTENSIONS_PATTERN}`]: "unlisted-style",
2266
- [`*/index.${CSS_EXTENSIONS_PATTERN}`]: "unlisted-style",
2267
- // Don't warn about any files in subdirectories, like CSS or JS entrypoints for HTML files or tests
2268
- "*/**": "ignored"
2269
- };
2270
- var CONTENT_SCRIPT_OUT_DIR = "content-scripts";
2271
-
2272
- // src/core/build/generateTypesDir.ts
2273
- import { createUnimport as createUnimport3 } from "unimport";
2274
- import fs10 from "fs-extra";
2275
- import { relative as relative4, resolve as resolve9 } from "path";
2276
- import path4 from "node:path";
2277
-
2278
- // src/core/utils/i18n.ts
2279
- var predefinedMessages = {
2280
- "@@extension_id": {
2281
- message: "<browser.runtime.id>",
2282
- 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."
2283
- },
2284
- "@@ui_locale": {
2285
- message: "<browser.i18n.getUiLocale()>",
2286
- description: ""
2287
- },
2288
- "@@bidi_dir": {
2289
- message: "<ltr|rtl>",
2290
- 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.'
2291
- },
2292
- "@@bidi_reversed_dir": {
2293
- message: "<rtl|ltr>",
2294
- description: `If the @@bidi_dir is "ltr", then this is "rtl"; otherwise, it's "ltr".`
2295
- },
2296
- "@@bidi_start_edge": {
2297
- message: "<left|right>",
2298
- description: `If the @@bidi_dir is "ltr", then this is "left"; otherwise, it's "right".`
2299
- },
2300
- "@@bidi_end_edge": {
2301
- message: "<right|left>",
2302
- description: `If the @@bidi_dir is "ltr", then this is "right"; otherwise, it's "left".`
2303
- }
2304
- };
2305
- function parseI18nMessages(messagesJson) {
2306
- return Object.entries({
2307
- ...predefinedMessages,
2308
- ...messagesJson
2309
- }).map(([name, details]) => ({
2310
- name,
2311
- ...details
2312
- }));
2313
- }
2314
-
2315
- // src/core/build/generateTypesDir.ts
2316
- async function generateTypesDir(entrypoints, config) {
2317
- await fs10.ensureDir(config.typesDir);
2318
- const references = [];
2319
- const imports = getUnimportOptions(config);
2320
- if (imports !== false) {
2321
- references.push(await writeImportsDeclarationFile(config, imports));
2322
- }
2323
- references.push(await writePathsDeclarationFile(entrypoints, config));
2324
- references.push(await writeI18nDeclarationFile(config));
2325
- references.push(await writeGlobalsDeclarationFile(config));
2326
- const mainReference = await writeMainDeclarationFile(references, config);
2327
- await writeTsConfigFile(mainReference, config);
2328
- }
2329
- async function writeImportsDeclarationFile(config, unimportOptions) {
2330
- const filePath = resolve9(config.typesDir, "imports.d.ts");
2331
- const unimport2 = createUnimport3(unimportOptions);
2332
- await unimport2.scanImportsFromDir(void 0, { cwd: config.srcDir });
2333
- await writeFileIfDifferent(
2334
- filePath,
2335
- ["// Generated by wxt", await unimport2.generateTypeDeclarations()].join(
2336
- "\n"
2337
- ) + "\n"
2338
- );
2339
- return filePath;
2340
- }
2341
- async function writePathsDeclarationFile(entrypoints, config) {
2342
- const filePath = resolve9(config.typesDir, "paths.d.ts");
2343
- const unions = entrypoints.map(
2344
- (entry) => getEntrypointBundlePath(
2345
- entry,
2346
- config.outDir,
2347
- entry.inputPath.endsWith(".html") ? ".html" : ".js"
2348
- )
2349
- ).concat(await getPublicFiles(config)).map(normalizePath2).map((path9) => ` | "/${path9}"`).sort().join("\n");
2350
- const template = `// Generated by wxt
2351
- import "wxt/browser";
2352
-
2353
- declare module "wxt/browser" {
2354
- type PublicPath =
2355
- {{ union }}
2356
- export interface WxtRuntime extends Runtime.Static {
2357
- getURL(path: PublicPath): string;
2358
- }
2359
- }
2360
- `;
2361
- await writeFileIfDifferent(
2362
- filePath,
2363
- template.replace("{{ union }}", unions || " | never")
2364
- );
2365
- return filePath;
2366
- }
2367
- async function writeI18nDeclarationFile(config) {
2368
- const filePath = resolve9(config.typesDir, "i18n.d.ts");
2369
- const defaultLocale = config.manifest.default_locale;
2370
- const template = `// Generated by wxt
2371
- import "wxt/browser";
2372
-
2373
- declare module "wxt/browser" {
2374
- /**
2375
- * See https://developer.chrome.com/docs/extensions/reference/i18n/#method-getMessage
2376
- */
2377
- interface GetMessageOptions {
2378
- /**
2379
- * See https://developer.chrome.com/docs/extensions/reference/i18n/#method-getMessage
2380
- */
2381
- escapeLt?: boolean
2382
- }
2383
-
2384
- export interface WxtI18n extends I18n.Static {
2385
- {{ overrides }}
2386
- }
2387
- }
2388
- `;
2389
- let messages;
2390
- if (defaultLocale) {
2391
- const defaultLocalePath = path4.resolve(
2392
- config.publicDir,
2393
- "_locales",
2394
- defaultLocale,
2395
- "messages.json"
2396
- );
2397
- const content = JSON.parse(await fs10.readFile(defaultLocalePath, "utf-8"));
2398
- messages = parseI18nMessages(content);
2399
- } else {
2400
- messages = parseI18nMessages({});
2401
- }
2402
- const overrides = messages.map((message) => {
2403
- return ` /**
2404
- * ${message.description ?? "No message description."}
2405
- *
2406
- * "${message.message}"
2407
- */
2408
- getMessage(
2409
- messageName: "${message.name}",
2410
- substitutions?: string | string[],
2411
- options?: GetMessageOptions,
2412
- ): string;`;
2413
- });
2414
- await writeFileIfDifferent(
2415
- filePath,
2416
- template.replace("{{ overrides }}", overrides.join("\n"))
2417
- );
2418
- return filePath;
2419
- }
2420
- async function writeGlobalsDeclarationFile(config) {
2421
- const filePath = resolve9(config.typesDir, "globals.d.ts");
2422
- const globals2 = [...getGlobals(config), ...getEntrypointGlobals(config, "")];
2423
- await writeFileIfDifferent(
2424
- filePath,
2425
- [
2426
- "// Generated by wxt",
2427
- "export {}",
2428
- "declare global {",
2429
- ...globals2.map((global2) => ` const ${global2.name}: ${global2.type};`),
2430
- "}"
2431
- ].join("\n") + "\n"
2432
- );
2433
- return filePath;
2434
- }
2435
- async function writeMainDeclarationFile(references, config) {
2436
- const dir = config.wxtDir;
2437
- const filePath = resolve9(dir, "wxt.d.ts");
2438
- await writeFileIfDifferent(
2439
- filePath,
2440
- [
2441
- "// Generated by wxt",
2442
- `/// <reference types="vite/client" />`,
2443
- ...references.map(
2444
- (ref) => `/// <reference types="./${normalizePath2(relative4(dir, ref))}" />`
2445
- )
2446
- ].join("\n") + "\n"
2447
- );
2448
- return filePath;
2449
- }
2450
- async function writeTsConfigFile(mainReference, config) {
2451
- const dir = config.wxtDir;
2452
- const rootPath = normalizePath2(relative4(dir, config.root));
2453
- const srcPath = normalizePath2(relative4(dir, config.srcDir));
2454
- await writeFileIfDifferent(
2455
- resolve9(dir, "tsconfig.json"),
2456
- `{
2457
- "compilerOptions": {
2458
- "target": "ESNext",
2459
- "module": "ESNext",
2460
- "moduleResolution": "Bundler",
2461
- "noEmit": true,
2462
- "esModuleInterop": true,
2463
- "forceConsistentCasingInFileNames": true,
2464
- "resolveJsonModule": true,
2465
- "strict": true,
2466
- "lib": ["DOM", "WebWorker"],
2467
- "skipLibCheck": true,
2468
- "paths": {
2469
- "@": ["${srcPath}"],
2470
- "@/*": ["${srcPath}/*"],
2471
- "~": ["${srcPath}"],
2472
- "~/*": ["${srcPath}/*"],
2473
- "@@": ["${rootPath}"],
2474
- "@@/*": ["${rootPath}/*"],
2475
- "~~": ["${rootPath}"],
2476
- "~~/*": ["${rootPath}/*"]
2477
- }
2478
- },
2479
- "include": [
2480
- "${normalizePath2(relative4(dir, config.root))}/**/*",
2481
- "./${normalizePath2(relative4(dir, mainReference))}"
2482
- ],
2483
- "exclude": ["${normalizePath2(relative4(dir, config.outBaseDir))}"]
2484
- }`
2485
- );
2486
- }
2487
-
2488
- // src/core/utils/manifest.ts
2489
- import fs12 from "fs-extra";
2490
- import { resolve as resolve11 } from "path";
2491
-
2492
- // src/core/utils/ContentSecurityPolicy.ts
2493
- var ContentSecurityPolicy = class _ContentSecurityPolicy {
2494
- static DIRECTIVE_ORDER = {
2495
- "default-src": 0,
2496
- "script-src": 1,
2497
- "object-src": 2
2498
- };
2499
- data;
2500
- constructor(csp) {
2501
- if (csp) {
2502
- const sections = csp.split(";").map((section) => section.trim());
2503
- this.data = sections.reduce((data, section) => {
2504
- const [key, ...values] = section.split(" ").map((item) => item.trim());
2505
- if (key)
2506
- data[key] = values;
2507
- return data;
2508
- }, {});
2509
- } else {
2510
- this.data = {};
2511
- }
2512
- }
2513
- /**
2514
- * Ensure a set of values are listed under a directive.
2515
- */
2516
- add(directive, ...newValues) {
2517
- const values = this.data[directive] ?? [];
2518
- newValues.forEach((newValue) => {
2519
- if (!values.includes(newValue))
2520
- values.push(newValue);
2521
- });
2522
- this.data[directive] = values;
2523
- return this;
2524
- }
2525
- toString() {
2526
- const directives = Object.entries(this.data).sort(([l], [r]) => {
2527
- const lo = _ContentSecurityPolicy.DIRECTIVE_ORDER[l] ?? 2;
2528
- const ro = _ContentSecurityPolicy.DIRECTIVE_ORDER[r] ?? 2;
2529
- return lo - ro;
2530
- });
2531
- return directives.map((entry) => entry.flat().join(" ")).join("; ") + ";";
2532
- }
2533
- };
2534
-
2535
- // src/core/utils/content-scripts.ts
2536
- function hashContentScriptOptions(options, config) {
2537
- const simplifiedOptions = mapWxtOptionsToContentScript(options, config);
2538
- Object.keys(simplifiedOptions).forEach((key) => {
2539
- if (simplifiedOptions[key] == null)
2540
- delete simplifiedOptions[key];
2541
- });
2542
- const withDefaults = {
2543
- exclude_globs: [],
2544
- exclude_matches: [],
2545
- include_globs: [],
2546
- match_about_blank: false,
2547
- run_at: "document_idle",
2548
- all_frames: false,
2549
- // @ts-expect-error - not in type
2550
- match_origin_as_fallback: false,
2551
- world: "ISOLATED",
2552
- ...simplifiedOptions
2553
- };
2554
- return JSON.stringify(
2555
- Object.entries(withDefaults).map(([key, value]) => {
2556
- if (Array.isArray(value))
2557
- return [key, value.sort()];
2558
- else
2559
- return [key, value];
2560
- }).sort((l, r) => l[0].localeCompare(r[0]))
2561
- );
2562
- }
2563
- function mapWxtOptionsToContentScript(options, config) {
2564
- return {
2565
- matches: resolvePerBrowserOption(options.matches, config.browser),
2566
- all_frames: resolvePerBrowserOption(options.allFrames, config.browser),
2567
- match_about_blank: resolvePerBrowserOption(
2568
- options.matchAboutBlank,
2569
- config.browser
2570
- ),
2571
- exclude_globs: resolvePerBrowserOption(
2572
- options.excludeGlobs,
2573
- config.browser
2574
- ),
2575
- exclude_matches: resolvePerBrowserOption(
2576
- options.excludeMatches,
2577
- config.browser
2578
- ),
2579
- include_globs: resolvePerBrowserOption(
2580
- options.includeGlobs,
2581
- config.browser
2582
- ),
2583
- run_at: resolvePerBrowserOption(options.runAt, config.browser),
2584
- // @ts-expect-error: untyped chrome options
2585
- match_origin_as_fallback: resolvePerBrowserOption(
2586
- options.matchOriginAsFallback,
2587
- config.browser
2588
- ),
2589
- world: options.world
2590
- };
2591
- }
2592
-
2593
- // src/core/utils/package.ts
2594
- import { resolve as resolve10 } from "node:path";
2595
- import fs11 from "fs-extra";
2596
- async function getPackageJson(config) {
2597
- const file = resolve10(config.root, "package.json");
2598
- try {
2599
- return await fs11.readJson(file);
2600
- } catch (err) {
2601
- config.logger.debug(
2602
- `Failed to read package.json at: ${file}. Returning undefined.`
2603
- );
2604
- return {};
2605
- }
2606
- }
2607
-
2608
- // src/core/utils/manifest.ts
2609
- import { produce } from "immer";
2610
- import * as vite4 from "vite";
2611
- async function writeManifest(manifest, output, config) {
2612
- const str = config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
2613
- await fs12.ensureDir(config.outDir);
2614
- await writeFileIfDifferent(resolve11(config.outDir, "manifest.json"), str);
2615
- output.publicAssets.unshift({
2616
- type: "asset",
2617
- fileName: "manifest.json",
2618
- name: "manifest",
2619
- needsCodeReference: false,
2620
- source: str
2621
- });
2622
- }
2623
- async function generateMainfest(entrypoints, buildOutput, config) {
2624
- const pkg = await getPackageJson(config);
2625
- const versionName = config.manifest.version_name ?? pkg?.version;
2626
- const version3 = config.manifest.version ?? simplifyVersion(pkg?.version);
2627
- const baseManifest = {
2628
- manifest_version: config.manifestVersion,
2629
- name: pkg?.name,
2630
- description: pkg?.description,
2631
- version: version3,
2632
- version_name: (
2633
- // Firefox doesn't support version_name
2634
- config.browser === "firefox" || versionName === version3 ? void 0 : versionName
2635
- ),
2636
- short_name: pkg?.shortName,
2637
- icons: discoverIcons(buildOutput)
2638
- };
2639
- const userManifest = config.manifest;
2640
- const manifest = vite4.mergeConfig(
2641
- baseManifest,
2642
- userManifest
2643
- );
2644
- addEntrypoints(manifest, entrypoints, buildOutput, config);
2645
- if (config.command === "serve")
2646
- addDevModeCsp(manifest, config);
2647
- if (config.command === "serve")
2648
- addDevModePermissions(manifest, config);
2649
- const finalManifest = produce(manifest, config.transformManifest);
2650
- if (finalManifest.name == null)
2651
- throw Error(
2652
- "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"
2653
- );
2654
- if (finalManifest.version == null) {
2655
- throw Error(
2656
- "Manifest 'version' is missing. Either:\n1. Add a version in your <rootDir>/package.json\n2. Pass the version via the manifest option in your wxt.config.ts"
2657
- );
2658
- }
2659
- return finalManifest;
2660
- }
2661
- function simplifyVersion(versionName) {
2662
- const version3 = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(
2663
- versionName
2664
- )?.[1];
2665
- if (version3 == null)
2666
- throw Error(
2667
- `Cannot simplify package.json version "${versionName}" to a valid extension version, "X.Y.Z"`
2668
- );
2669
- return version3;
2670
- }
2671
- function addEntrypoints(manifest, entrypoints, buildOutput, config) {
2672
- const entriesByType = entrypoints.reduce((map, entrypoint) => {
2673
- map[entrypoint.type] ??= [];
2674
- map[entrypoint.type]?.push(entrypoint);
2675
- return map;
2676
- }, {});
2677
- const background = entriesByType["background"]?.[0];
2678
- const bookmarks = entriesByType["bookmarks"]?.[0];
2679
- const contentScripts = entriesByType["content-script"];
2680
- const devtools = entriesByType["devtools"]?.[0];
2681
- const history = entriesByType["history"]?.[0];
2682
- const newtab = entriesByType["newtab"]?.[0];
2683
- const options = entriesByType["options"]?.[0];
2684
- const popup = entriesByType["popup"]?.[0];
2685
- const sandboxes = entriesByType["sandbox"];
2686
- const sidepanels = entriesByType["sidepanel"];
2687
- if (background) {
2688
- const script = getEntrypointBundlePath(background, config.outDir, ".js");
2689
- if (manifest.manifest_version === 3) {
2690
- manifest.background = {
2691
- type: background.options.type,
2692
- service_worker: script
2693
- };
2694
- } else {
2695
- manifest.background = {
2696
- persistent: background.options.persistent,
2697
- scripts: [script]
2698
- };
2699
- }
2700
- }
2701
- if (bookmarks) {
2702
- if (config.browser === "firefox") {
2703
- config.logger.warn(
2704
- "Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest"
2705
- );
2706
- } else {
2707
- manifest.chrome_url_overrides ??= {};
2708
- manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(
2709
- bookmarks,
2710
- config.outDir,
2711
- ".html"
2712
- );
2713
- }
2714
- }
2715
- if (history) {
2716
- if (config.browser === "firefox") {
2717
- config.logger.warn(
2718
- "Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest"
2719
- );
2720
- } else {
2721
- manifest.chrome_url_overrides ??= {};
2722
- manifest.chrome_url_overrides.history = getEntrypointBundlePath(
2723
- history,
2724
- config.outDir,
2725
- ".html"
2726
- );
2727
- }
2728
- }
2729
- if (newtab) {
2730
- manifest.chrome_url_overrides ??= {};
2731
- manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(
2732
- newtab,
2733
- config.outDir,
2734
- ".html"
2735
- );
2736
- }
2737
- if (popup) {
2738
- const default_popup = getEntrypointBundlePath(
2739
- popup,
2740
- config.outDir,
2741
- ".html"
2742
- );
2743
- const options2 = {};
2744
- if (popup.options.defaultIcon)
2745
- options2.default_icon = popup.options.defaultIcon;
2746
- if (popup.options.defaultTitle)
2747
- options2.default_title = popup.options.defaultTitle;
2748
- if (popup.options.browserStyle)
2749
- options2.browser_style = popup.options.browserStyle;
2750
- if (manifest.manifest_version === 3) {
2751
- manifest.action = {
2752
- ...manifest.action ?? {},
2753
- ...options2,
2754
- default_popup
2755
- };
2756
- } else {
2757
- const key = popup.options.mv2Key ?? "browser_action";
2758
- manifest[key] = {
2759
- ...manifest[key] ?? {},
2760
- ...options2,
2761
- default_popup
2762
- };
2763
- }
2764
- }
2765
- if (devtools) {
2766
- manifest.devtools_page = getEntrypointBundlePath(
2767
- devtools,
2768
- config.outDir,
2769
- ".html"
2770
- );
2771
- }
2772
- if (options) {
2773
- const page = getEntrypointBundlePath(options, config.outDir, ".html");
2774
- manifest.options_ui = {
2775
- open_in_tab: options.options.openInTab,
2776
- browser_style: config.browser === "firefox" ? options.options.browserStyle : void 0,
2777
- chrome_style: config.browser !== "firefox" ? options.options.chromeStyle : void 0,
2778
- page
2779
- };
2780
- }
2781
- if (sandboxes?.length) {
2782
- if (config.browser === "firefox") {
2783
- config.logger.warn(
2784
- "Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
2785
- );
2786
- } else {
2787
- manifest.sandbox = {
2788
- pages: sandboxes.map(
2789
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".html")
2790
- )
2791
- };
2792
- }
2793
- }
2794
- if (sidepanels?.length) {
2795
- const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
2796
- const page = getEntrypointBundlePath(
2797
- defaultSidepanel,
2798
- config.outDir,
2799
- ".html"
2800
- );
2801
- if (config.browser === "firefox") {
2802
- manifest.sidebar_action = {
2803
- // TODO: Add options to side panel
2804
- // ...defaultSidepanel.options,
2805
- default_panel: page
2806
- };
2807
- } else if (config.manifestVersion === 3) {
2808
- manifest.side_panel = {
2809
- default_path: page
2810
- };
2811
- } else {
2812
- config.logger.warn(
2813
- "Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
2814
- );
2815
- }
2816
- }
2817
- if (contentScripts?.length) {
2818
- const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
2819
- if (config.command === "serve" && config.manifestVersion === 3) {
2820
- const hostPermissions = new Set(manifest.host_permissions ?? []);
2821
- contentScripts.forEach((script) => {
2822
- const matches = resolvePerBrowserOption(
2823
- script.options.matches,
2824
- config.browser
2825
- );
2826
- matches.forEach((matchPattern) => {
2827
- hostPermissions.add(matchPattern);
2828
- });
2829
- });
2830
- hostPermissions.forEach(
2831
- (permission) => addHostPermission(manifest, permission)
2832
- );
2833
- } else {
2834
- const hashToEntrypointsMap = contentScripts.reduce((map, script) => {
2835
- const hash = hashContentScriptOptions(script.options, config);
2836
- if (map.has(hash))
2837
- map.get(hash)?.push(script);
2838
- else
2839
- map.set(hash, [script]);
2840
- return map;
2841
- }, /* @__PURE__ */ new Map());
2842
- const newContentScripts = Array.from(hashToEntrypointsMap.entries()).map(
2843
- ([, scripts]) => ({
2844
- ...mapWxtOptionsToContentScript(scripts[0].options, config),
2845
- css: getContentScriptCssFiles(scripts, cssMap),
2846
- js: scripts.map(
2847
- (entry) => getEntrypointBundlePath(entry, config.outDir, ".js")
2848
- )
2849
- })
2850
- );
2851
- if (newContentScripts.length >= 0) {
2852
- manifest.content_scripts ??= [];
2853
- manifest.content_scripts.push(...newContentScripts);
2854
- }
2855
- }
2856
- const contentScriptCssResources = getContentScriptCssWebAccessibleResources(
2857
- config,
2858
- contentScripts,
2859
- cssMap
2860
- );
2861
- if (contentScriptCssResources.length > 0) {
2862
- manifest.web_accessible_resources ??= [];
2863
- manifest.web_accessible_resources.push(...contentScriptCssResources);
2864
- }
2865
- }
2866
- }
2867
- function discoverIcons(buildOutput) {
2868
- const icons = [];
2869
- const iconRegex = [
2870
- /^icon-([0-9]+)\.(png|bmp|jpeg|jpg|ico|gif)$/,
2871
- // icon-16.png
2872
- /^icon-([0-9]+)x[0-9]+\.(png|bmp|jpeg|jpg|ico|gif)$/,
2873
- // icon-16x16.png
2874
- /^icon@([0-9]+)w\.(png|bmp|jpeg|jpg|ico|gif)$/,
2875
- // icon@16w.png
2876
- /^icon@([0-9]+)h\.(png|bmp|jpeg|jpg|ico|gif)$/,
2877
- // icon@16h.png
2878
- /^icon@([0-9]+)\.(png|bmp|jpeg|jpg|ico|gif)$/,
2879
- // icon@16.png
2880
- /^icon[\/\\]([0-9]+)\.(png|bmp|jpeg|jpg|ico|gif)$/,
2881
- // icon/16.png
2882
- /^icon[\/\\]([0-9]+)x[0-9]+\.(png|bmp|jpeg|jpg|ico|gif)$/
2883
- // icon/16x16.png
2884
- ];
2885
- buildOutput.publicAssets.forEach((asset) => {
2886
- let size;
2887
- for (const regex of iconRegex) {
2888
- const match = asset.fileName.match(regex);
2889
- if (match?.[1] != null) {
2890
- size = match[1];
2891
- break;
2892
- }
2893
- }
2894
- if (size == null)
2895
- return;
2896
- icons.push([size, normalizePath2(asset.fileName)]);
2897
- });
2898
- return icons.length > 0 ? Object.fromEntries(icons) : void 0;
2899
- }
2900
- function addDevModeCsp(manifest, config) {
2901
- const permission = `http://${config.server?.hostname ?? ""}/*`;
2902
- const allowedCsp = config.server?.origin ?? "http://localhost:*";
2903
- if (manifest.manifest_version === 3) {
2904
- addHostPermission(manifest, permission);
2905
- } else {
2906
- addPermission(manifest, permission);
2907
- }
2908
- const csp = new ContentSecurityPolicy(
2909
- manifest.manifest_version === 3 ? (
2910
- // @ts-expect-error: extension_pages is not typed
2911
- manifest.content_security_policy?.extension_pages ?? "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
2912
- ) : manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"
2913
- // default CSP for MV2
2914
- );
2915
- if (config.server)
2916
- csp.add("script-src", allowedCsp);
2917
- if (manifest.manifest_version === 3) {
2918
- manifest.content_security_policy ??= {};
2919
- manifest.content_security_policy.extension_pages = csp.toString();
2920
- } else {
2921
- manifest.content_security_policy = csp.toString();
2922
- }
2923
- }
2924
- function addDevModePermissions(manifest, config) {
2925
- addPermission(manifest, "tabs");
2926
- if (config.manifestVersion === 3)
2927
- addPermission(manifest, "scripting");
2928
- }
2929
- function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
2930
- const css = [];
2931
- contentScripts.forEach((script) => {
2932
- if (script.options.cssInjectionMode === "manual" || script.options.cssInjectionMode === "ui")
2933
- return;
2934
- const cssFile = contentScriptCssMap[script.name];
2935
- if (cssFile == null)
2936
- return;
2937
- if (cssFile)
2938
- css.push(cssFile);
2939
- });
2940
- if (css.length > 0)
2941
- return css;
2942
- return void 0;
2943
- }
2944
- function getContentScriptCssWebAccessibleResources(config, contentScripts, contentScriptCssMap) {
2945
- const resources = [];
2946
- contentScripts.forEach((script) => {
2947
- if (script.options.cssInjectionMode !== "ui")
2948
- return;
2949
- const cssFile = contentScriptCssMap[script.name];
2950
- if (cssFile == null)
2951
- return;
2952
- if (config.manifestVersion === 2) {
2953
- resources.push(cssFile);
2954
- } else {
2955
- resources.push({
2956
- resources: [cssFile],
2957
- matches: script.options.matches
2958
- });
2959
- }
2960
- });
2961
- return resources;
2962
- }
2963
- function getContentScriptsCssMap(buildOutput, scripts) {
2964
- const map = {};
2965
- const allChunks = buildOutput.steps.flatMap((step) => step.chunks);
2966
- scripts.forEach((script) => {
2967
- const relatedCss = allChunks.find(
2968
- (chunk) => chunk.fileName === `content-scripts/${script.name}.css`
2969
- );
2970
- if (relatedCss != null)
2971
- map[script.name] = relatedCss.fileName;
2972
- });
2973
- return map;
2974
- }
2975
- function addPermission(manifest, permission) {
2976
- manifest.permissions ??= [];
2977
- if (manifest.permissions.includes(permission))
2978
- return;
2979
- manifest.permissions.push(permission);
2980
- }
2981
- function addHostPermission(manifest, hostPermission) {
2982
- manifest.host_permissions ??= [];
2983
- if (manifest.host_permissions.includes(hostPermission))
2984
- return;
2985
- manifest.host_permissions.push(hostPermission);
2986
- }
2987
-
2988
- // src/core/build.ts
2989
- import pc3 from "picocolors";
2990
- import * as vite5 from "vite";
2991
- import fs14 from "fs-extra";
2992
-
2993
- // src/core/utils/groupEntrypoints.ts
2994
- function groupEntrypoints(entrypoints) {
2995
- const groupIndexMap = {};
2996
- const groups = [];
2997
- for (const entry of entrypoints) {
2998
- const group = ENTRY_TYPE_TO_GROUP_MAP[entry.type];
2999
- if (group === "no-group") {
3000
- groups.push(entry);
3001
- } else {
3002
- let groupIndex = groupIndexMap[group];
3003
- if (groupIndex == null) {
3004
- groupIndex = groups.push([]) - 1;
3005
- groupIndexMap[group] = groupIndex;
3006
- }
3007
- groups[groupIndex].push(entry);
3008
- }
3009
- }
3010
- return groups;
3011
- }
3012
- var ENTRY_TYPE_TO_GROUP_MAP = {
3013
- sandbox: "sandbox-page",
3014
- popup: "extension-page",
3015
- newtab: "extension-page",
3016
- history: "extension-page",
3017
- options: "extension-page",
3018
- devtools: "extension-page",
3019
- bookmarks: "extension-page",
3020
- sidepanel: "extension-page",
3021
- "unlisted-page": "extension-page",
3022
- background: "no-group",
3023
- "content-script": "no-group",
3024
- "unlisted-script": "no-group",
3025
- "unlisted-style": "no-group",
3026
- "content-script-style": "no-group"
3027
- };
3028
-
3029
- // src/core/utils/formatDuration.ts
3030
- function formatDuration(duration) {
3031
- if (duration < 1e3)
3032
- return `${duration} ms`;
3033
- if (duration < 1e4)
3034
- return `${(duration / 1e3).toFixed(3)} s`;
3035
- if (duration < 6e4)
3036
- return `${(duration / 1e3).toFixed(1)} s`;
3037
- return `${(duration / 1e3).toFixed(0)} s`;
3038
- }
3039
-
3040
- // src/core/log/printBuildSummary.ts
3041
- import { resolve as resolve12 } from "path";
3042
-
3043
- // src/core/log/printFileList.ts
3044
- import path5 from "node:path";
3045
- import pc2 from "picocolors";
3046
- import fs13 from "fs-extra";
3047
- import { filesize } from "filesize";
3048
-
3049
- // src/core/log/printTable.ts
3050
- function printTable(log, header, rows, gap = 2) {
3051
- if (rows.length === 0)
3052
- return;
3053
- const columnWidths = rows.reduce(
3054
- (widths, row) => {
3055
- for (let i = 0; i < Math.max(widths.length, row.length); i++) {
3056
- widths[i] = Math.max(row[i]?.length ?? 0, widths[i] ?? 0);
3057
- }
3058
- return widths;
3059
- },
3060
- rows[0].map((column) => column.length)
3061
- );
3062
- let str = "";
3063
- rows.forEach((row, i) => {
3064
- row.forEach((col, j) => {
3065
- str += col.padEnd(columnWidths[j], " ");
3066
- if (j !== row.length - 1)
3067
- str += "".padEnd(gap, " ");
3068
- });
3069
- if (i !== rows.length - 1)
3070
- str += "\n";
3071
- });
3072
- log(`${header}
3073
- ${str}`);
3074
- }
3075
-
3076
- // src/core/log/printFileList.ts
3077
- async function printFileList(log, header, baseDir, files) {
3078
- let totalSize = 0;
3079
- const fileRows = await Promise.all(
3080
- files.map(async (file, i) => {
3081
- const parts = [
3082
- path5.relative(process.cwd(), baseDir) + path5.sep,
3083
- path5.relative(baseDir, file)
3084
- ];
3085
- const prefix = i === files.length - 1 ? " \u2514\u2500" : " \u251C\u2500";
3086
- const color = getChunkColor(file);
3087
- const stats = await fs13.lstat(file);
3088
- totalSize += stats.size;
3089
- const size = String(filesize(stats.size));
3090
- return [
3091
- `${pc2.gray(prefix)} ${pc2.dim(parts[0])}${color(parts[1])}`,
3092
- pc2.dim(size)
3093
- ];
3094
- })
3095
- );
3096
- fileRows.push([`${pc2.cyan("\u03A3 Total size:")} ${String(filesize(totalSize))}`]);
3097
- printTable(log, header, fileRows);
3098
- }
3099
- var DEFAULT_COLOR = pc2.blue;
3100
- var CHUNK_COLORS = {
3101
- ".js.map": pc2.gray,
3102
- ".html": pc2.green,
3103
- ".css": pc2.magenta,
3104
- ".js": pc2.cyan,
3105
- ".zip": pc2.yellow
3106
- };
3107
- function getChunkColor(filename) {
3108
- return Object.entries(CHUNK_COLORS).find(([key]) => filename.endsWith(key))?.[1] ?? DEFAULT_COLOR;
3109
- }
3110
-
3111
- // src/core/log/printBuildSummary.ts
3112
- async function printBuildSummary(log, header, output, config) {
3113
- const chunks = [
3114
- ...output.steps.flatMap((step) => step.chunks),
3115
- ...output.publicAssets
3116
- ].sort((l, r) => {
3117
- const lWeight = getChunkSortWeight(l.fileName);
3118
- const rWeight = getChunkSortWeight(r.fileName);
3119
- const diff = lWeight - rWeight;
3120
- if (diff !== 0)
3121
- return diff;
3122
- return l.fileName.localeCompare(r.fileName);
3123
- });
3124
- const files = chunks.map((chunk) => resolve12(config.outDir, chunk.fileName));
3125
- await printFileList(log, header, config.outDir, files);
3126
- }
3127
- var DEFAULT_SORT_WEIGHT = 100;
3128
- var CHUNK_SORT_WEIGHTS = {
3129
- "manifest.json": 0,
3130
- ".html": 1,
3131
- ".js.map": 2,
3132
- ".js": 2,
3133
- ".css": 3
3134
- };
3135
- function getChunkSortWeight(filename) {
3136
- return Object.entries(CHUNK_SORT_WEIGHTS).find(
3137
- ([key]) => filename.endsWith(key)
3138
- )?.[1] ?? DEFAULT_SORT_WEIGHT;
3139
- }
3140
-
3141
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/index.js
3142
- var import_cross_spawn = __toESM(require_cross_spawn(), 1);
3143
- import { Buffer as Buffer3 } from "node:buffer";
3144
- import path7 from "node:path";
3145
- import childProcess from "node:child_process";
3146
- import process5 from "node:process";
3147
-
3148
- // node_modules/.pnpm/strip-final-newline@3.0.0/node_modules/strip-final-newline/index.js
3149
- function stripFinalNewline(input) {
3150
- const LF = typeof input === "string" ? "\n" : "\n".charCodeAt();
3151
- const CR = typeof input === "string" ? "\r" : "\r".charCodeAt();
3152
- if (input[input.length - 1] === LF) {
3153
- input = input.slice(0, -1);
3154
- }
3155
- if (input[input.length - 1] === CR) {
3156
- input = input.slice(0, -1);
3157
- }
3158
- return input;
3159
- }
3160
-
3161
- // node_modules/.pnpm/npm-run-path@5.1.0/node_modules/npm-run-path/index.js
3162
- import process2 from "node:process";
3163
- import path6 from "node:path";
3164
- import url from "node:url";
3165
-
3166
- // node_modules/.pnpm/path-key@4.0.0/node_modules/path-key/index.js
3167
- function pathKey(options = {}) {
3168
- const {
3169
- env = process.env,
3170
- platform = process.platform
3171
- } = options;
3172
- if (platform !== "win32") {
3173
- return "PATH";
3174
- }
3175
- return Object.keys(env).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
3176
- }
3177
-
3178
- // node_modules/.pnpm/npm-run-path@5.1.0/node_modules/npm-run-path/index.js
3179
- function npmRunPath(options = {}) {
3180
- const {
3181
- cwd = process2.cwd(),
3182
- path: path_ = process2.env[pathKey()],
3183
- execPath = process2.execPath
3184
- } = options;
3185
- let previous;
3186
- const cwdString = cwd instanceof URL ? url.fileURLToPath(cwd) : cwd;
3187
- let cwdPath = path6.resolve(cwdString);
3188
- const result = [];
3189
- while (previous !== cwdPath) {
3190
- result.push(path6.join(cwdPath, "node_modules/.bin"));
3191
- previous = cwdPath;
3192
- cwdPath = path6.resolve(cwdPath, "..");
3193
- }
3194
- result.push(path6.resolve(cwdString, execPath, ".."));
3195
- return [...result, path_].join(path6.delimiter);
3196
- }
3197
- function npmRunPathEnv({ env = process2.env, ...options } = {}) {
3198
- env = { ...env };
3199
- const path9 = pathKey({ env });
3200
- options.path = env[path9];
3201
- env[path9] = npmRunPath(options);
3202
- return env;
3203
- }
3204
-
3205
- // node_modules/.pnpm/mimic-fn@4.0.0/node_modules/mimic-fn/index.js
3206
- var copyProperty = (to, from, property, ignoreNonConfigurable) => {
3207
- if (property === "length" || property === "prototype") {
3208
- return;
3209
- }
3210
- if (property === "arguments" || property === "caller") {
3211
- return;
3212
- }
3213
- const toDescriptor = Object.getOwnPropertyDescriptor(to, property);
3214
- const fromDescriptor = Object.getOwnPropertyDescriptor(from, property);
3215
- if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) {
3216
- return;
3217
- }
3218
- Object.defineProperty(to, property, fromDescriptor);
3219
- };
3220
- var canCopyProperty = function(toDescriptor, fromDescriptor) {
3221
- return toDescriptor === void 0 || toDescriptor.configurable || toDescriptor.writable === fromDescriptor.writable && toDescriptor.enumerable === fromDescriptor.enumerable && toDescriptor.configurable === fromDescriptor.configurable && (toDescriptor.writable || toDescriptor.value === fromDescriptor.value);
3222
- };
3223
- var changePrototype = (to, from) => {
3224
- const fromPrototype = Object.getPrototypeOf(from);
3225
- if (fromPrototype === Object.getPrototypeOf(to)) {
3226
- return;
3227
- }
3228
- Object.setPrototypeOf(to, fromPrototype);
3229
- };
3230
- var wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/
3231
- ${fromBody}`;
3232
- var toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, "toString");
3233
- var toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, "name");
3234
- var changeToString = (to, from, name) => {
3235
- const withName = name === "" ? "" : `with ${name.trim()}() `;
3236
- const newToString = wrappedToString.bind(null, withName, from.toString());
3237
- Object.defineProperty(newToString, "name", toStringName);
3238
- Object.defineProperty(to, "toString", { ...toStringDescriptor, value: newToString });
3239
- };
3240
- function mimicFunction(to, from, { ignoreNonConfigurable = false } = {}) {
3241
- const { name } = to;
3242
- for (const property of Reflect.ownKeys(from)) {
3243
- copyProperty(to, from, property, ignoreNonConfigurable);
3244
- }
3245
- changePrototype(to, from);
3246
- changeToString(to, from, name);
3247
- return to;
3248
- }
3249
-
3250
- // node_modules/.pnpm/onetime@6.0.0/node_modules/onetime/index.js
3251
- var calledFunctions = /* @__PURE__ */ new WeakMap();
3252
- var onetime = (function_, options = {}) => {
3253
- if (typeof function_ !== "function") {
3254
- throw new TypeError("Expected a function");
3255
- }
3256
- let returnValue;
3257
- let callCount = 0;
3258
- const functionName = function_.displayName || function_.name || "<anonymous>";
3259
- const onetime2 = function(...arguments_) {
3260
- calledFunctions.set(onetime2, ++callCount);
3261
- if (callCount === 1) {
3262
- returnValue = function_.apply(this, arguments_);
3263
- function_ = null;
3264
- } else if (options.throw === true) {
3265
- throw new Error(`Function \`${functionName}\` can only be called once`);
3266
- }
3267
- return returnValue;
3268
- };
3269
- mimicFunction(onetime2, function_);
3270
- calledFunctions.set(onetime2, callCount);
3271
- return onetime2;
3272
- };
3273
- onetime.callCount = (function_) => {
3274
- if (!calledFunctions.has(function_)) {
3275
- throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`);
3276
- }
3277
- return calledFunctions.get(function_);
3278
- };
3279
- var onetime_default = onetime;
3280
-
3281
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/error.js
3282
- import process3 from "node:process";
3283
-
3284
- // node_modules/.pnpm/human-signals@4.3.1/node_modules/human-signals/build/src/main.js
3285
- import { constants as constants2 } from "node:os";
3286
-
3287
- // node_modules/.pnpm/human-signals@4.3.1/node_modules/human-signals/build/src/realtime.js
3288
- var getRealtimeSignals = () => {
3289
- const length = SIGRTMAX - SIGRTMIN + 1;
3290
- return Array.from({ length }, getRealtimeSignal);
3291
- };
3292
- var getRealtimeSignal = (value, index) => ({
3293
- name: `SIGRT${index + 1}`,
3294
- number: SIGRTMIN + index,
3295
- action: "terminate",
3296
- description: "Application-specific signal (realtime)",
3297
- standard: "posix"
3298
- });
3299
- var SIGRTMIN = 34;
3300
- var SIGRTMAX = 64;
3301
-
3302
- // node_modules/.pnpm/human-signals@4.3.1/node_modules/human-signals/build/src/signals.js
3303
- import { constants } from "node:os";
3304
-
3305
- // node_modules/.pnpm/human-signals@4.3.1/node_modules/human-signals/build/src/core.js
3306
- var SIGNALS = [
3307
- {
3308
- name: "SIGHUP",
3309
- number: 1,
3310
- action: "terminate",
3311
- description: "Terminal closed",
3312
- standard: "posix"
3313
- },
3314
- {
3315
- name: "SIGINT",
3316
- number: 2,
3317
- action: "terminate",
3318
- description: "User interruption with CTRL-C",
3319
- standard: "ansi"
3320
- },
3321
- {
3322
- name: "SIGQUIT",
3323
- number: 3,
3324
- action: "core",
3325
- description: "User interruption with CTRL-\\",
3326
- standard: "posix"
3327
- },
3328
- {
3329
- name: "SIGILL",
3330
- number: 4,
3331
- action: "core",
3332
- description: "Invalid machine instruction",
3333
- standard: "ansi"
3334
- },
3335
- {
3336
- name: "SIGTRAP",
3337
- number: 5,
3338
- action: "core",
3339
- description: "Debugger breakpoint",
3340
- standard: "posix"
3341
- },
3342
- {
3343
- name: "SIGABRT",
3344
- number: 6,
3345
- action: "core",
3346
- description: "Aborted",
3347
- standard: "ansi"
3348
- },
3349
- {
3350
- name: "SIGIOT",
3351
- number: 6,
3352
- action: "core",
3353
- description: "Aborted",
3354
- standard: "bsd"
3355
- },
3356
- {
3357
- name: "SIGBUS",
3358
- number: 7,
3359
- action: "core",
3360
- description: "Bus error due to misaligned, non-existing address or paging error",
3361
- standard: "bsd"
3362
- },
3363
- {
3364
- name: "SIGEMT",
3365
- number: 7,
3366
- action: "terminate",
3367
- description: "Command should be emulated but is not implemented",
3368
- standard: "other"
3369
- },
3370
- {
3371
- name: "SIGFPE",
3372
- number: 8,
3373
- action: "core",
3374
- description: "Floating point arithmetic error",
3375
- standard: "ansi"
3376
- },
3377
- {
3378
- name: "SIGKILL",
3379
- number: 9,
3380
- action: "terminate",
3381
- description: "Forced termination",
3382
- standard: "posix",
3383
- forced: true
3384
- },
3385
- {
3386
- name: "SIGUSR1",
3387
- number: 10,
3388
- action: "terminate",
3389
- description: "Application-specific signal",
3390
- standard: "posix"
3391
- },
3392
- {
3393
- name: "SIGSEGV",
3394
- number: 11,
3395
- action: "core",
3396
- description: "Segmentation fault",
3397
- standard: "ansi"
3398
- },
3399
- {
3400
- name: "SIGUSR2",
3401
- number: 12,
3402
- action: "terminate",
3403
- description: "Application-specific signal",
3404
- standard: "posix"
3405
- },
3406
- {
3407
- name: "SIGPIPE",
3408
- number: 13,
3409
- action: "terminate",
3410
- description: "Broken pipe or socket",
3411
- standard: "posix"
3412
- },
3413
- {
3414
- name: "SIGALRM",
3415
- number: 14,
3416
- action: "terminate",
3417
- description: "Timeout or timer",
3418
- standard: "posix"
3419
- },
3420
- {
3421
- name: "SIGTERM",
3422
- number: 15,
3423
- action: "terminate",
3424
- description: "Termination",
3425
- standard: "ansi"
3426
- },
3427
- {
3428
- name: "SIGSTKFLT",
3429
- number: 16,
3430
- action: "terminate",
3431
- description: "Stack is empty or overflowed",
3432
- standard: "other"
3433
- },
3434
- {
3435
- name: "SIGCHLD",
3436
- number: 17,
3437
- action: "ignore",
3438
- description: "Child process terminated, paused or unpaused",
3439
- standard: "posix"
3440
- },
3441
- {
3442
- name: "SIGCLD",
3443
- number: 17,
3444
- action: "ignore",
3445
- description: "Child process terminated, paused or unpaused",
3446
- standard: "other"
3447
- },
3448
- {
3449
- name: "SIGCONT",
3450
- number: 18,
3451
- action: "unpause",
3452
- description: "Unpaused",
3453
- standard: "posix",
3454
- forced: true
3455
- },
3456
- {
3457
- name: "SIGSTOP",
3458
- number: 19,
3459
- action: "pause",
3460
- description: "Paused",
3461
- standard: "posix",
3462
- forced: true
3463
- },
3464
- {
3465
- name: "SIGTSTP",
3466
- number: 20,
3467
- action: "pause",
3468
- description: 'Paused using CTRL-Z or "suspend"',
3469
- standard: "posix"
3470
- },
3471
- {
3472
- name: "SIGTTIN",
3473
- number: 21,
3474
- action: "pause",
3475
- description: "Background process cannot read terminal input",
3476
- standard: "posix"
3477
- },
3478
- {
3479
- name: "SIGBREAK",
3480
- number: 21,
3481
- action: "terminate",
3482
- description: "User interruption with CTRL-BREAK",
3483
- standard: "other"
3484
- },
3485
- {
3486
- name: "SIGTTOU",
3487
- number: 22,
3488
- action: "pause",
3489
- description: "Background process cannot write to terminal output",
3490
- standard: "posix"
3491
- },
3492
- {
3493
- name: "SIGURG",
3494
- number: 23,
3495
- action: "ignore",
3496
- description: "Socket received out-of-band data",
3497
- standard: "bsd"
3498
- },
3499
- {
3500
- name: "SIGXCPU",
3501
- number: 24,
3502
- action: "core",
3503
- description: "Process timed out",
3504
- standard: "bsd"
3505
- },
3506
- {
3507
- name: "SIGXFSZ",
3508
- number: 25,
3509
- action: "core",
3510
- description: "File too big",
3511
- standard: "bsd"
3512
- },
3513
- {
3514
- name: "SIGVTALRM",
3515
- number: 26,
3516
- action: "terminate",
3517
- description: "Timeout or timer",
3518
- standard: "bsd"
3519
- },
3520
- {
3521
- name: "SIGPROF",
3522
- number: 27,
3523
- action: "terminate",
3524
- description: "Timeout or timer",
3525
- standard: "bsd"
3526
- },
3527
- {
3528
- name: "SIGWINCH",
3529
- number: 28,
3530
- action: "ignore",
3531
- description: "Terminal window size changed",
3532
- standard: "bsd"
3533
- },
3534
- {
3535
- name: "SIGIO",
3536
- number: 29,
3537
- action: "terminate",
3538
- description: "I/O is available",
3539
- standard: "other"
3540
- },
3541
- {
3542
- name: "SIGPOLL",
3543
- number: 29,
3544
- action: "terminate",
3545
- description: "Watched event",
3546
- standard: "other"
3547
- },
3548
- {
3549
- name: "SIGINFO",
3550
- number: 29,
3551
- action: "ignore",
3552
- description: "Request for process information",
3553
- standard: "other"
3554
- },
3555
- {
3556
- name: "SIGPWR",
3557
- number: 30,
3558
- action: "terminate",
3559
- description: "Device running out of power",
3560
- standard: "systemv"
3561
- },
3562
- {
3563
- name: "SIGSYS",
3564
- number: 31,
3565
- action: "core",
3566
- description: "Invalid system call",
3567
- standard: "other"
3568
- },
3569
- {
3570
- name: "SIGUNUSED",
3571
- number: 31,
3572
- action: "terminate",
3573
- description: "Invalid system call",
3574
- standard: "other"
3575
- }
3576
- ];
3577
-
3578
- // node_modules/.pnpm/human-signals@4.3.1/node_modules/human-signals/build/src/signals.js
3579
- var getSignals = () => {
3580
- const realtimeSignals = getRealtimeSignals();
3581
- const signals = [...SIGNALS, ...realtimeSignals].map(normalizeSignal);
3582
- return signals;
3583
- };
3584
- var normalizeSignal = ({
3585
- name,
3586
- number: defaultNumber,
3587
- description,
3588
- action,
3589
- forced = false,
3590
- standard
3591
- }) => {
3592
- const {
3593
- signals: { [name]: constantSignal }
3594
- } = constants;
3595
- const supported = constantSignal !== void 0;
3596
- const number = supported ? constantSignal : defaultNumber;
3597
- return { name, number, description, supported, action, forced, standard };
3598
- };
3599
-
3600
- // node_modules/.pnpm/human-signals@4.3.1/node_modules/human-signals/build/src/main.js
3601
- var getSignalsByName = () => {
3602
- const signals = getSignals();
3603
- return Object.fromEntries(signals.map(getSignalByName));
3604
- };
3605
- var getSignalByName = ({
3606
- name,
3607
- number,
3608
- description,
3609
- supported,
3610
- action,
3611
- forced,
3612
- standard
3613
- }) => [name, { name, number, description, supported, action, forced, standard }];
3614
- var signalsByName = getSignalsByName();
3615
- var getSignalsByNumber = () => {
3616
- const signals = getSignals();
3617
- const length = SIGRTMAX + 1;
3618
- const signalsA = Array.from({ length }, (value, number) => getSignalByNumber(number, signals));
3619
- return Object.assign({}, ...signalsA);
3620
- };
3621
- var getSignalByNumber = (number, signals) => {
3622
- const signal = findSignalByNumber(number, signals);
3623
- if (signal === void 0) {
3624
- return {};
3625
- }
3626
- const { name, description, supported, action, forced, standard } = signal;
3627
- return {
3628
- [number]: {
3629
- name,
3630
- number,
3631
- description,
3632
- supported,
3633
- action,
3634
- forced,
3635
- standard
3636
- }
3637
- };
3638
- };
3639
- var findSignalByNumber = (number, signals) => {
3640
- const signal = signals.find(({ name }) => constants2.signals[name] === number);
3641
- if (signal !== void 0) {
3642
- return signal;
3643
- }
3644
- return signals.find((signalA) => signalA.number === number);
3645
- };
3646
- var signalsByNumber = getSignalsByNumber();
3647
-
3648
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/error.js
3649
- var getErrorPrefix = ({ timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled }) => {
3650
- if (timedOut) {
3651
- return `timed out after ${timeout} milliseconds`;
3652
- }
3653
- if (isCanceled) {
3654
- return "was canceled";
3655
- }
3656
- if (errorCode !== void 0) {
3657
- return `failed with ${errorCode}`;
3658
- }
3659
- if (signal !== void 0) {
3660
- return `was killed with ${signal} (${signalDescription})`;
3661
- }
3662
- if (exitCode !== void 0) {
3663
- return `failed with exit code ${exitCode}`;
3664
- }
3665
- return "failed";
3666
- };
3667
- var makeError = ({
3668
- stdout,
3669
- stderr,
3670
- all,
3671
- error,
3672
- signal,
3673
- exitCode,
3674
- command,
3675
- escapedCommand,
3676
- timedOut,
3677
- isCanceled,
3678
- killed,
3679
- parsed: { options: { timeout, cwd = process3.cwd() } }
3680
- }) => {
3681
- exitCode = exitCode === null ? void 0 : exitCode;
3682
- signal = signal === null ? void 0 : signal;
3683
- const signalDescription = signal === void 0 ? void 0 : signalsByName[signal].description;
3684
- const errorCode = error && error.code;
3685
- const prefix = getErrorPrefix({ timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled });
3686
- const execaMessage = `Command ${prefix}: ${command}`;
3687
- const isError = Object.prototype.toString.call(error) === "[object Error]";
3688
- const shortMessage = isError ? `${execaMessage}
3689
- ${error.message}` : execaMessage;
3690
- const message = [shortMessage, stderr, stdout].filter(Boolean).join("\n");
3691
- if (isError) {
3692
- error.originalMessage = error.message;
3693
- error.message = message;
3694
- } else {
3695
- error = new Error(message);
3696
- }
3697
- error.shortMessage = shortMessage;
3698
- error.command = command;
3699
- error.escapedCommand = escapedCommand;
3700
- error.exitCode = exitCode;
3701
- error.signal = signal;
3702
- error.signalDescription = signalDescription;
3703
- error.stdout = stdout;
3704
- error.stderr = stderr;
3705
- error.cwd = cwd;
3706
- if (all !== void 0) {
3707
- error.all = all;
3708
- }
3709
- if ("bufferedData" in error) {
3710
- delete error.bufferedData;
3711
- }
3712
- error.failed = true;
3713
- error.timedOut = Boolean(timedOut);
3714
- error.isCanceled = isCanceled;
3715
- error.killed = killed && !timedOut;
3716
- return error;
3717
- };
3718
-
3719
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/stdio.js
3720
- var aliases = ["stdin", "stdout", "stderr"];
3721
- var hasAlias = (options) => aliases.some((alias) => options[alias] !== void 0);
3722
- var normalizeStdio = (options) => {
3723
- if (!options) {
3724
- return;
3725
- }
3726
- const { stdio } = options;
3727
- if (stdio === void 0) {
3728
- return aliases.map((alias) => options[alias]);
3729
- }
3730
- if (hasAlias(options)) {
3731
- throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map((alias) => `\`${alias}\``).join(", ")}`);
3732
- }
3733
- if (typeof stdio === "string") {
3734
- return stdio;
3735
- }
3736
- if (!Array.isArray(stdio)) {
3737
- throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``);
3738
- }
3739
- const length = Math.max(stdio.length, aliases.length);
3740
- return Array.from({ length }, (value, index) => stdio[index]);
3741
- };
3742
-
3743
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/kill.js
3744
- var import_signal_exit = __toESM(require_signal_exit(), 1);
3745
- import os from "node:os";
3746
- var DEFAULT_FORCE_KILL_TIMEOUT = 1e3 * 5;
3747
- var spawnedKill = (kill, signal = "SIGTERM", options = {}) => {
3748
- const killResult = kill(signal);
3749
- setKillTimeout(kill, signal, options, killResult);
3750
- return killResult;
3751
- };
3752
- var setKillTimeout = (kill, signal, options, killResult) => {
3753
- if (!shouldForceKill(signal, options, killResult)) {
3754
- return;
3755
- }
3756
- const timeout = getForceKillAfterTimeout(options);
3757
- const t = setTimeout(() => {
3758
- kill("SIGKILL");
3759
- }, timeout);
3760
- if (t.unref) {
3761
- t.unref();
3762
- }
3763
- };
3764
- var shouldForceKill = (signal, { forceKillAfterTimeout }, killResult) => isSigterm(signal) && forceKillAfterTimeout !== false && killResult;
3765
- var isSigterm = (signal) => signal === os.constants.signals.SIGTERM || typeof signal === "string" && signal.toUpperCase() === "SIGTERM";
3766
- var getForceKillAfterTimeout = ({ forceKillAfterTimeout = true }) => {
3767
- if (forceKillAfterTimeout === true) {
3768
- return DEFAULT_FORCE_KILL_TIMEOUT;
3769
- }
3770
- if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) {
3771
- throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`);
3772
- }
3773
- return forceKillAfterTimeout;
3774
- };
3775
- var spawnedCancel = (spawned, context) => {
3776
- const killResult = spawned.kill();
3777
- if (killResult) {
3778
- context.isCanceled = true;
3779
- }
3780
- };
3781
- var timeoutKill = (spawned, signal, reject) => {
3782
- spawned.kill(signal);
3783
- reject(Object.assign(new Error("Timed out"), { timedOut: true, signal }));
3784
- };
3785
- var setupTimeout = (spawned, { timeout, killSignal = "SIGTERM" }, spawnedPromise) => {
3786
- if (timeout === 0 || timeout === void 0) {
3787
- return spawnedPromise;
3788
- }
3789
- let timeoutId;
3790
- const timeoutPromise = new Promise((resolve13, reject) => {
3791
- timeoutId = setTimeout(() => {
3792
- timeoutKill(spawned, killSignal, reject);
3793
- }, timeout);
3794
- });
3795
- const safeSpawnedPromise = spawnedPromise.finally(() => {
3796
- clearTimeout(timeoutId);
3797
- });
3798
- return Promise.race([timeoutPromise, safeSpawnedPromise]);
3799
- };
3800
- var validateTimeout = ({ timeout }) => {
3801
- if (timeout !== void 0 && (!Number.isFinite(timeout) || timeout < 0)) {
3802
- throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`);
3803
- }
3804
- };
3805
- var setExitHandler = async (spawned, { cleanup, detached }, timedPromise) => {
3806
- if (!cleanup || detached) {
3807
- return timedPromise;
3808
- }
3809
- const removeExitHandler = (0, import_signal_exit.default)(() => {
3810
- spawned.kill();
3811
- });
3812
- return timedPromise.finally(() => {
3813
- removeExitHandler();
3814
- });
3815
- };
3816
-
3817
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/pipe.js
3818
- import { createWriteStream } from "node:fs";
3819
- import { ChildProcess } from "node:child_process";
3820
-
3821
- // node_modules/.pnpm/is-stream@3.0.0/node_modules/is-stream/index.js
3822
- function isStream(stream) {
3823
- return stream !== null && typeof stream === "object" && typeof stream.pipe === "function";
3824
- }
3825
- function isWritableStream(stream) {
3826
- return isStream(stream) && stream.writable !== false && typeof stream._write === "function" && typeof stream._writableState === "object";
3827
- }
3828
-
3829
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/pipe.js
3830
- var isExecaChildProcess = (target) => target instanceof ChildProcess && typeof target.then === "function";
3831
- var pipeToTarget = (spawned, streamName, target) => {
3832
- if (typeof target === "string") {
3833
- spawned[streamName].pipe(createWriteStream(target));
3834
- return spawned;
3835
- }
3836
- if (isWritableStream(target)) {
3837
- spawned[streamName].pipe(target);
3838
- return spawned;
3839
- }
3840
- if (!isExecaChildProcess(target)) {
3841
- throw new TypeError("The second argument must be a string, a stream or an Execa child process.");
3842
- }
3843
- if (!isWritableStream(target.stdin)) {
3844
- throw new TypeError("The target child process's stdin must be available.");
3845
- }
3846
- spawned[streamName].pipe(target.stdin);
3847
- return target;
3848
- };
3849
- var addPipeMethods = (spawned) => {
3850
- if (spawned.stdout !== null) {
3851
- spawned.pipeStdout = pipeToTarget.bind(void 0, spawned, "stdout");
3852
- }
3853
- if (spawned.stderr !== null) {
3854
- spawned.pipeStderr = pipeToTarget.bind(void 0, spawned, "stderr");
3855
- }
3856
- if (spawned.all !== void 0) {
3857
- spawned.pipeAll = pipeToTarget.bind(void 0, spawned, "all");
3858
- }
3859
- };
3860
-
3861
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/stream.js
3862
- import { createReadStream, readFileSync } from "node:fs";
3863
- var import_get_stream = __toESM(require_get_stream(), 1);
3864
- var import_merge_stream = __toESM(require_merge_stream(), 1);
3865
- var validateInputOptions = (input) => {
3866
- if (input !== void 0) {
3867
- throw new TypeError("The `input` and `inputFile` options cannot be both set.");
3868
- }
3869
- };
3870
- var getInputSync = ({ input, inputFile }) => {
3871
- if (typeof inputFile !== "string") {
3872
- return input;
3873
- }
3874
- validateInputOptions(input);
3875
- return readFileSync(inputFile);
3876
- };
3877
- var handleInputSync = (options) => {
3878
- const input = getInputSync(options);
3879
- if (isStream(input)) {
3880
- throw new TypeError("The `input` option cannot be a stream in sync mode");
3881
- }
3882
- return input;
3883
- };
3884
- var getInput = ({ input, inputFile }) => {
3885
- if (typeof inputFile !== "string") {
3886
- return input;
3887
- }
3888
- validateInputOptions(input);
3889
- return createReadStream(inputFile);
3890
- };
3891
- var handleInput = (spawned, options) => {
3892
- const input = getInput(options);
3893
- if (input === void 0) {
3894
- return;
3895
- }
3896
- if (isStream(input)) {
3897
- input.pipe(spawned.stdin);
3898
- } else {
3899
- spawned.stdin.end(input);
3900
- }
3901
- };
3902
- var makeAllStream = (spawned, { all }) => {
3903
- if (!all || !spawned.stdout && !spawned.stderr) {
3904
- return;
3905
- }
3906
- const mixed = (0, import_merge_stream.default)();
3907
- if (spawned.stdout) {
3908
- mixed.add(spawned.stdout);
3909
- }
3910
- if (spawned.stderr) {
3911
- mixed.add(spawned.stderr);
3912
- }
3913
- return mixed;
3914
- };
3915
- var getBufferedData = async (stream, streamPromise) => {
3916
- if (!stream || streamPromise === void 0) {
3917
- return;
3918
- }
3919
- stream.destroy();
3920
- try {
3921
- return await streamPromise;
3922
- } catch (error) {
3923
- return error.bufferedData;
3924
- }
3925
- };
3926
- var getStreamPromise = (stream, { encoding, buffer, maxBuffer }) => {
3927
- if (!stream || !buffer) {
3928
- return;
3929
- }
3930
- if (encoding) {
3931
- return (0, import_get_stream.default)(stream, { encoding, maxBuffer });
3932
- }
3933
- return import_get_stream.default.buffer(stream, { maxBuffer });
3934
- };
3935
- var getSpawnedResult = async ({ stdout, stderr, all }, { encoding, buffer, maxBuffer }, processDone) => {
3936
- const stdoutPromise = getStreamPromise(stdout, { encoding, buffer, maxBuffer });
3937
- const stderrPromise = getStreamPromise(stderr, { encoding, buffer, maxBuffer });
3938
- const allPromise = getStreamPromise(all, { encoding, buffer, maxBuffer: maxBuffer * 2 });
3939
- try {
3940
- return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]);
3941
- } catch (error) {
3942
- return Promise.all([
3943
- { error, signal: error.signal, timedOut: error.timedOut },
3944
- getBufferedData(stdout, stdoutPromise),
3945
- getBufferedData(stderr, stderrPromise),
3946
- getBufferedData(all, allPromise)
3947
- ]);
3948
- }
3949
- };
3950
-
3951
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/promise.js
3952
- var nativePromisePrototype = (/* @__PURE__ */ (async () => {
3953
- })()).constructor.prototype;
3954
- var descriptors = ["then", "catch", "finally"].map((property) => [
3955
- property,
3956
- Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property)
3957
- ]);
3958
- var mergePromise = (spawned, promise) => {
3959
- for (const [property, descriptor] of descriptors) {
3960
- const value = typeof promise === "function" ? (...args) => Reflect.apply(descriptor.value, promise(), args) : descriptor.value.bind(promise);
3961
- Reflect.defineProperty(spawned, property, { ...descriptor, value });
3962
- }
3963
- };
3964
- var getSpawnedPromise = (spawned) => new Promise((resolve13, reject) => {
3965
- spawned.on("exit", (exitCode, signal) => {
3966
- resolve13({ exitCode, signal });
3967
- });
3968
- spawned.on("error", (error) => {
3969
- reject(error);
3970
- });
3971
- if (spawned.stdin) {
3972
- spawned.stdin.on("error", (error) => {
3973
- reject(error);
3974
- });
3975
- }
3976
- });
3977
-
3978
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/command.js
3979
- import { Buffer as Buffer2 } from "node:buffer";
3980
- import { ChildProcess as ChildProcess2 } from "node:child_process";
3981
- var normalizeArgs = (file, args = []) => {
3982
- if (!Array.isArray(args)) {
3983
- return [file];
3984
- }
3985
- return [file, ...args];
3986
- };
3987
- var NO_ESCAPE_REGEXP = /^[\w.-]+$/;
3988
- var DOUBLE_QUOTES_REGEXP = /"/g;
3989
- var escapeArg = (arg) => {
3990
- if (typeof arg !== "string" || NO_ESCAPE_REGEXP.test(arg)) {
3991
- return arg;
3992
- }
3993
- return `"${arg.replace(DOUBLE_QUOTES_REGEXP, '\\"')}"`;
3994
- };
3995
- var joinCommand = (file, args) => normalizeArgs(file, args).join(" ");
3996
- var getEscapedCommand = (file, args) => normalizeArgs(file, args).map((arg) => escapeArg(arg)).join(" ");
3997
- var SPACES_REGEXP = / +/g;
3998
- var parseCommand = (command) => {
3999
- const tokens = [];
4000
- for (const token of command.trim().split(SPACES_REGEXP)) {
4001
- const previousToken = tokens[tokens.length - 1];
4002
- if (previousToken && previousToken.endsWith("\\")) {
4003
- tokens[tokens.length - 1] = `${previousToken.slice(0, -1)} ${token}`;
4004
- } else {
4005
- tokens.push(token);
4006
- }
4007
- }
4008
- return tokens;
4009
- };
4010
- var parseExpression = (expression) => {
4011
- const typeOfExpression = typeof expression;
4012
- if (typeOfExpression === "string") {
4013
- return expression;
4014
- }
4015
- if (typeOfExpression === "number") {
4016
- return String(expression);
4017
- }
4018
- if (typeOfExpression === "object" && expression !== null && !(expression instanceof ChildProcess2) && "stdout" in expression) {
4019
- const typeOfStdout = typeof expression.stdout;
4020
- if (typeOfStdout === "string") {
4021
- return expression.stdout;
4022
- }
4023
- if (Buffer2.isBuffer(expression.stdout)) {
4024
- return expression.stdout.toString();
4025
- }
4026
- throw new TypeError(`Unexpected "${typeOfStdout}" stdout in template expression`);
4027
- }
4028
- throw new TypeError(`Unexpected "${typeOfExpression}" in template expression`);
4029
- };
4030
- var concatTokens = (tokens, nextTokens, isNew) => isNew || tokens.length === 0 || nextTokens.length === 0 ? [...tokens, ...nextTokens] : [
4031
- ...tokens.slice(0, -1),
4032
- `${tokens[tokens.length - 1]}${nextTokens[0]}`,
4033
- ...nextTokens.slice(1)
4034
- ];
4035
- var parseTemplate = ({ templates, expressions, tokens, index, template }) => {
4036
- const templateString = template ?? templates.raw[index];
4037
- const templateTokens = templateString.split(SPACES_REGEXP).filter(Boolean);
4038
- const newTokens = concatTokens(
4039
- tokens,
4040
- templateTokens,
4041
- templateString.startsWith(" ")
4042
- );
4043
- if (index === expressions.length) {
4044
- return newTokens;
4045
- }
4046
- const expression = expressions[index];
4047
- const expressionTokens = Array.isArray(expression) ? expression.map((expression2) => parseExpression(expression2)) : [parseExpression(expression)];
4048
- return concatTokens(
4049
- newTokens,
4050
- expressionTokens,
4051
- templateString.endsWith(" ")
4052
- );
4053
- };
4054
- var parseTemplates = (templates, expressions) => {
4055
- let tokens = [];
4056
- for (const [index, template] of templates.entries()) {
4057
- tokens = parseTemplate({ templates, expressions, tokens, index, template });
4058
- }
4059
- return tokens;
4060
- };
4061
-
4062
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/lib/verbose.js
4063
- import { debuglog } from "node:util";
4064
- import process4 from "node:process";
4065
- var verboseDefault = debuglog("execa").enabled;
4066
- var padField = (field, padding) => String(field).padStart(padding, "0");
4067
- var getTimestamp = () => {
4068
- const date = /* @__PURE__ */ new Date();
4069
- return `${padField(date.getHours(), 2)}:${padField(date.getMinutes(), 2)}:${padField(date.getSeconds(), 2)}.${padField(date.getMilliseconds(), 3)}`;
4070
- };
4071
- var logCommand = (escapedCommand, { verbose }) => {
4072
- if (!verbose) {
4073
- return;
4074
- }
4075
- process4.stderr.write(`[${getTimestamp()}] ${escapedCommand}
4076
- `);
4077
- };
1
+ import {
2
+ detectDevChanges,
3
+ findEntrypoints,
4
+ formatDuration,
5
+ generateTypesDir,
6
+ getContentScriptCssFiles,
7
+ getContentScriptsCssMap,
8
+ getEntrypointBundlePath,
9
+ getEntrypointOutputFile,
10
+ getInternalConfig,
11
+ getPackageJson,
12
+ internalBuild,
13
+ kebabCaseAlphanumeric,
14
+ printFileList,
15
+ rebuild,
16
+ resolvePerBrowserOption,
17
+ version
18
+ } from "./chunk-VFZ5667B.js";
19
+ import "./chunk-YUG22S6W.js";
4078
20
 
4079
- // node_modules/.pnpm/execa@7.2.0/node_modules/execa/index.js
4080
- var DEFAULT_MAX_BUFFER = 1e3 * 1e3 * 100;
4081
- var getEnv = ({ env: envOption, extendEnv, preferLocal, localDir, execPath }) => {
4082
- const env = extendEnv ? { ...process5.env, ...envOption } : envOption;
4083
- if (preferLocal) {
4084
- return npmRunPathEnv({ env, cwd: localDir, execPath });
4085
- }
4086
- return env;
4087
- };
4088
- var handleArguments = (file, args, options = {}) => {
4089
- const parsed = import_cross_spawn.default._parse(file, args, options);
4090
- file = parsed.command;
4091
- args = parsed.args;
4092
- options = parsed.options;
4093
- options = {
4094
- maxBuffer: DEFAULT_MAX_BUFFER,
4095
- buffer: true,
4096
- stripFinalNewline: true,
4097
- extendEnv: true,
4098
- preferLocal: false,
4099
- localDir: options.cwd || process5.cwd(),
4100
- execPath: process5.execPath,
4101
- encoding: "utf8",
4102
- reject: true,
4103
- cleanup: true,
4104
- all: false,
4105
- windowsHide: true,
4106
- verbose: verboseDefault,
4107
- ...options
4108
- };
4109
- options.env = getEnv(options);
4110
- options.stdio = normalizeStdio(options);
4111
- if (process5.platform === "win32" && path7.basename(file, ".exe") === "cmd") {
4112
- args.unshift("/q");
4113
- }
4114
- return { file, args, options, parsed };
4115
- };
4116
- var handleOutput = (options, value, error) => {
4117
- if (typeof value !== "string" && !Buffer3.isBuffer(value)) {
4118
- return error === void 0 ? void 0 : "";
4119
- }
4120
- if (options.stripFinalNewline) {
4121
- return stripFinalNewline(value);
4122
- }
4123
- return value;
4124
- };
4125
- function execa(file, args, options) {
4126
- const parsed = handleArguments(file, args, options);
4127
- const command = joinCommand(file, args);
4128
- const escapedCommand = getEscapedCommand(file, args);
4129
- logCommand(escapedCommand, parsed.options);
4130
- validateTimeout(parsed.options);
4131
- let spawned;
4132
- try {
4133
- spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options);
4134
- } catch (error) {
4135
- const dummySpawned = new childProcess.ChildProcess();
4136
- const errorPromise = Promise.reject(makeError({
4137
- error,
4138
- stdout: "",
4139
- stderr: "",
4140
- all: "",
4141
- command,
4142
- escapedCommand,
4143
- parsed,
4144
- timedOut: false,
4145
- isCanceled: false,
4146
- killed: false
4147
- }));
4148
- mergePromise(dummySpawned, errorPromise);
4149
- return dummySpawned;
4150
- }
4151
- const spawnedPromise = getSpawnedPromise(spawned);
4152
- const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise);
4153
- const processDone = setExitHandler(spawned, parsed.options, timedPromise);
4154
- const context = { isCanceled: false };
4155
- spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned));
4156
- spawned.cancel = spawnedCancel.bind(null, spawned, context);
4157
- const handlePromise = async () => {
4158
- const [{ error, exitCode, signal, timedOut }, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone);
4159
- const stdout = handleOutput(parsed.options, stdoutResult);
4160
- const stderr = handleOutput(parsed.options, stderrResult);
4161
- const all = handleOutput(parsed.options, allResult);
4162
- if (error || exitCode !== 0 || signal !== null) {
4163
- const returnedError = makeError({
4164
- error,
4165
- exitCode,
4166
- signal,
4167
- stdout,
4168
- stderr,
4169
- all,
4170
- command,
4171
- escapedCommand,
4172
- parsed,
4173
- timedOut,
4174
- isCanceled: context.isCanceled || (parsed.options.signal ? parsed.options.signal.aborted : false),
4175
- killed: spawned.killed
4176
- });
4177
- if (!parsed.options.reject) {
4178
- return returnedError;
4179
- }
4180
- throw returnedError;
4181
- }
4182
- return {
4183
- command,
4184
- escapedCommand,
4185
- exitCode: 0,
4186
- stdout,
4187
- stderr,
4188
- all,
4189
- failed: false,
4190
- timedOut: false,
4191
- isCanceled: false,
4192
- killed: false
4193
- };
4194
- };
4195
- const handlePromiseOnce = onetime_default(handlePromise);
4196
- handleInput(spawned, parsed.options);
4197
- spawned.all = makeAllStream(spawned, parsed.options);
4198
- addPipeMethods(spawned);
4199
- mergePromise(spawned, handlePromiseOnce);
4200
- return spawned;
4201
- }
4202
- function execaSync(file, args, options) {
4203
- const parsed = handleArguments(file, args, options);
4204
- const command = joinCommand(file, args);
4205
- const escapedCommand = getEscapedCommand(file, args);
4206
- logCommand(escapedCommand, parsed.options);
4207
- const input = handleInputSync(parsed.options);
4208
- let result;
4209
- try {
4210
- result = childProcess.spawnSync(parsed.file, parsed.args, { ...parsed.options, input });
4211
- } catch (error) {
4212
- throw makeError({
4213
- error,
4214
- stdout: "",
4215
- stderr: "",
4216
- all: "",
4217
- command,
4218
- escapedCommand,
4219
- parsed,
4220
- timedOut: false,
4221
- isCanceled: false,
4222
- killed: false
4223
- });
4224
- }
4225
- const stdout = handleOutput(parsed.options, result.stdout, result.error);
4226
- const stderr = handleOutput(parsed.options, result.stderr, result.error);
4227
- if (result.error || result.status !== 0 || result.signal !== null) {
4228
- const error = makeError({
4229
- stdout,
4230
- stderr,
4231
- error: result.error,
4232
- signal: result.signal,
4233
- exitCode: result.status,
4234
- command,
4235
- escapedCommand,
4236
- parsed,
4237
- timedOut: result.error && result.error.code === "ETIMEDOUT",
4238
- isCanceled: false,
4239
- killed: result.signal !== null
4240
- });
4241
- if (!parsed.options.reject) {
4242
- return error;
4243
- }
4244
- throw error;
4245
- }
4246
- return {
4247
- command,
4248
- escapedCommand,
4249
- exitCode: 0,
4250
- stdout,
4251
- stderr,
4252
- failed: false,
4253
- timedOut: false,
4254
- isCanceled: false,
4255
- killed: false
4256
- };
4257
- }
4258
- var normalizeScriptStdin = ({ input, inputFile, stdio }) => input === void 0 && inputFile === void 0 && stdio === void 0 ? { stdin: "inherit" } : {};
4259
- var normalizeScriptOptions = (options = {}) => ({
4260
- preferLocal: true,
4261
- ...normalizeScriptStdin(options),
4262
- ...options
4263
- });
4264
- function create$(options) {
4265
- function $2(templatesOrOptions, ...expressions) {
4266
- if (!Array.isArray(templatesOrOptions)) {
4267
- return create$({ ...options, ...templatesOrOptions });
4268
- }
4269
- const [file, ...args] = parseTemplates(templatesOrOptions, expressions);
4270
- return execa(file, args, normalizeScriptOptions(options));
4271
- }
4272
- $2.sync = (templates, ...expressions) => {
4273
- if (!Array.isArray(templates)) {
4274
- throw new TypeError("Please use $(options).sync`command` instead of $.sync(options)`command`.");
4275
- }
4276
- const [file, ...args] = parseTemplates(templates, expressions);
4277
- return execaSync(file, args, normalizeScriptOptions(options));
4278
- };
4279
- return $2;
4280
- }
4281
- var $ = create$();
4282
- function execaCommand(command, options) {
4283
- const [file, ...args] = parseCommand(command);
4284
- return execa(file, args, options);
21
+ // src/core/build.ts
22
+ async function build(config) {
23
+ const internalConfig = await getInternalConfig(config ?? {}, "build");
24
+ return await internalBuild(internalConfig);
4285
25
  }
4286
26
 
4287
- // src/core/build.ts
4288
- import glob3 from "fast-glob";
4289
- async function buildInternal(config) {
4290
- const verb = config.command === "serve" ? "Pre-rendering" : "Building";
4291
- const target = `${config.browser}-mv${config.manifestVersion}`;
4292
- config.logger.info(
4293
- `${verb} ${pc3.cyan(target)} for ${pc3.cyan(config.mode)} with ${pc3.green(
4294
- `Vite ${vite5.version}`
4295
- )}`
4296
- );
4297
- const startTime = Date.now();
4298
- await fs14.rm(config.outDir, { recursive: true, force: true });
4299
- await fs14.ensureDir(config.outDir);
4300
- const entrypoints = await findEntrypoints(config);
4301
- config.logger.debug("Detected entrypoints:", entrypoints);
4302
- const groups = groupEntrypoints(entrypoints);
4303
- const { output } = await rebuild(config, groups, void 0);
4304
- await printBuildSummary(
4305
- config.logger.success,
4306
- `Built extension in ${formatDuration(Date.now() - startTime)}`,
4307
- output,
4308
- config
27
+ // src/core/clean.ts
28
+ import path from "node:path";
29
+ import glob from "fast-glob";
30
+ import fs from "fs-extra";
31
+ import { consola } from "consola";
32
+ import pc from "picocolors";
33
+ async function clean(root = process.cwd()) {
34
+ consola.info("Cleaning Project");
35
+ const tempDirs = [
36
+ "node_modules/.vite",
37
+ "node_modules/.cache",
38
+ "**/.wxt",
39
+ ".output/*"
40
+ ];
41
+ consola.debug("Looking for:", tempDirs.map(pc.cyan).join(", "));
42
+ const directories = await glob(tempDirs, {
43
+ cwd: path.resolve(root),
44
+ absolute: true,
45
+ onlyDirectories: true,
46
+ deep: 2
47
+ });
48
+ if (directories.length === 0) {
49
+ consola.debug("No generated files found.");
50
+ return;
51
+ }
52
+ consola.debug(
53
+ "Found:",
54
+ directories.map((dir) => pc.cyan(path.relative(root, dir))).join(", ")
4309
55
  );
4310
- if (config.analysis.enabled) {
4311
- await combineAnalysisStats(config);
4312
- config.logger.info(
4313
- `Analysis complete:
4314
- ${pc3.gray("\u2514\u2500")} ${pc3.yellow("stats.html")}`
4315
- );
56
+ for (const directory of directories) {
57
+ await fs.rm(directory, { force: true, recursive: true });
58
+ consola.debug("Deleted " + pc.cyan(path.relative(root, directory)));
4316
59
  }
4317
- return output;
4318
60
  }
4319
- async function rebuild(config, entrypointGroups, existingOutput = {
4320
- steps: [],
4321
- publicAssets: []
4322
- }) {
4323
- const { default: ora } = await import("ora");
4324
- const spinner = ora(`Preparing...`).start();
4325
- const allEntrypoints = await findEntrypoints(config);
4326
- await generateTypesDir(allEntrypoints, config).catch((err) => {
4327
- config.logger.warn("Failed to update .wxt directory:", err);
4328
- if (config.command === "build")
4329
- throw err;
4330
- });
4331
- const newOutput = await buildEntrypoints(entrypointGroups, config, spinner);
4332
- const mergedOutput = {
4333
- steps: [...existingOutput.steps, ...newOutput.steps],
4334
- publicAssets: [...existingOutput.publicAssets, ...newOutput.publicAssets]
4335
- };
4336
- const newManifest = await generateMainfest(
4337
- allEntrypoints,
4338
- mergedOutput,
4339
- config
4340
- );
4341
- const finalOutput = {
4342
- manifest: newManifest,
4343
- ...newOutput
4344
- };
4345
- await writeManifest(newManifest, finalOutput, config);
4346
- spinner.clear().stop();
4347
- return {
4348
- output: {
4349
- manifest: newManifest,
4350
- steps: [...existingOutput.steps, ...finalOutput.steps],
4351
- publicAssets: [
4352
- ...existingOutput.publicAssets,
4353
- ...finalOutput.publicAssets
4354
- ]
4355
- },
4356
- manifest: newManifest
4357
- };
61
+
62
+ // src/core/define-config.ts
63
+ function defineConfig(config) {
64
+ return config;
4358
65
  }
4359
- async function combineAnalysisStats(config) {
4360
- const unixFiles = await glob3(`stats-*.json`, {
4361
- cwd: config.outDir,
4362
- absolute: true
4363
- });
4364
- const absolutePaths = unixFiles.map(unnormalizePath);
4365
- await execaCommand(
4366
- `rollup-plugin-visualizer ${absolutePaths.join(" ")} --template ${config.analysis.template}`,
4367
- { cwd: config.root, stdio: "inherit" }
4368
- );
66
+
67
+ // src/core/define-runner-config.ts
68
+ function defineRunnerConfig(config) {
69
+ return config;
4369
70
  }
4370
71
 
4371
- // src/core/server.ts
4372
- import * as vite6 from "vite";
72
+ // src/core/create-server.ts
73
+ import * as vite from "vite";
4373
74
 
4374
75
  // src/core/runners/wsl.ts
4375
- import { relative as relative5 } from "node:path";
76
+ import { relative } from "node:path";
4376
77
  function createWslRunner() {
4377
78
  return {
4378
79
  async openBrowser(config) {
4379
80
  config.logger.warn(
4380
- `Cannot open browser when using WSL. Load "${relative5(
81
+ `Cannot open browser when using WSL. Load "${relative(
4381
82
  process.cwd(),
4382
83
  config.outDir
4383
84
  )}" as an unpacked extension manually`
@@ -4444,12 +145,12 @@ var WARN_LOG_LEVEL = 40;
4444
145
  var ERROR_LOG_LEVEL = 50;
4445
146
 
4446
147
  // src/core/runners/safari.ts
4447
- import { relative as relative6 } from "node:path";
148
+ import { relative as relative2 } from "node:path";
4448
149
  function createSafariRunner() {
4449
150
  return {
4450
151
  async openBrowser(config) {
4451
152
  config.logger.warn(
4452
- `Cannot Safari using web-ext. Load "${relative6(
153
+ `Cannot Safari using web-ext. Load "${relative2(
4453
154
  process.cwd(),
4454
155
  config.outDir
4455
156
  )}" as an unpacked extension manually`
@@ -4461,12 +162,12 @@ function createSafariRunner() {
4461
162
  }
4462
163
 
4463
164
  // src/core/runners/manual.ts
4464
- import { relative as relative7 } from "node:path";
165
+ import { relative as relative3 } from "node:path";
4465
166
  function createManualRunner() {
4466
167
  return {
4467
168
  async openBrowser(config) {
4468
169
  config.logger.info(
4469
- `Load "${relative7(
170
+ `Load "${relative3(
4470
171
  process.cwd(),
4471
172
  config.outDir
4472
173
  )}" as an unpacked extension manually`
@@ -4494,7 +195,74 @@ async function createExtensionRunner(config) {
4494
195
  return createWebExtRunner();
4495
196
  }
4496
197
 
4497
- // src/core/server.ts
198
+ // src/core/create-server.ts
199
+ import { consola as consola2 } from "consola";
200
+ import { Mutex } from "async-mutex";
201
+ import pc2 from "picocolors";
202
+ import { relative as relative4 } from "node:path";
203
+ async function createServer2(config) {
204
+ const serverInfo = await getServerInfo();
205
+ const getLatestInternalConfig = async () => {
206
+ return getInternalConfig(
207
+ {
208
+ ...config,
209
+ vite: () => serverInfo.viteServerConfig
210
+ },
211
+ "serve"
212
+ );
213
+ };
214
+ let internalConfig = await getLatestInternalConfig();
215
+ const server = await setupServer(serverInfo, internalConfig);
216
+ internalConfig.server = server;
217
+ const fileChangedMutex = new Mutex();
218
+ const changeQueue = [];
219
+ server.ws.on("wxt:background-initialized", () => {
220
+ reloadContentScripts(server.currentOutput.steps, internalConfig, server);
221
+ });
222
+ server.watcher.on("all", async (event, path3, _stats) => {
223
+ if (path3.startsWith(internalConfig.outBaseDir))
224
+ return;
225
+ changeQueue.push([event, path3]);
226
+ await fileChangedMutex.runExclusive(async () => {
227
+ const fileChanges = changeQueue.splice(0, changeQueue.length);
228
+ if (fileChanges.length === 0)
229
+ return;
230
+ const changes = detectDevChanges(fileChanges, server.currentOutput);
231
+ if (changes.type === "no-change")
232
+ return;
233
+ internalConfig.logger.info(
234
+ `Changed: ${Array.from(new Set(fileChanges.map((change) => change[1]))).map((file) => pc2.dim(relative4(internalConfig.root, file))).join(", ")}`
235
+ );
236
+ const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
237
+ return pc2.cyan(
238
+ relative4(internalConfig.outDir, getEntrypointOutputFile(entry, ""))
239
+ );
240
+ }).join(pc2.dim(", "));
241
+ internalConfig = await getLatestInternalConfig();
242
+ internalConfig.server = server;
243
+ const { output: newOutput } = await rebuild(
244
+ internalConfig,
245
+ // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
246
+ changes.rebuildGroups,
247
+ changes.cachedOutput
248
+ );
249
+ server.currentOutput = newOutput;
250
+ switch (changes.type) {
251
+ case "extension-reload":
252
+ server.reloadExtension();
253
+ break;
254
+ case "html-reload":
255
+ reloadHtmlPages(changes.rebuildGroups, server, internalConfig);
256
+ break;
257
+ case "content-script-reload":
258
+ reloadContentScripts(changes.changedSteps, internalConfig, server);
259
+ break;
260
+ }
261
+ consola2.success(`Reloaded: ${rebuiltNames}`);
262
+ });
263
+ });
264
+ return server;
265
+ }
4498
266
  async function getServerInfo() {
4499
267
  const { default: getPort, portNumbers } = await import("get-port");
4500
268
  const port = await getPort({ port: portNumbers(3e3, 3010) });
@@ -4514,20 +282,20 @@ async function getServerInfo() {
4514
282
  }
4515
283
  async function setupServer(serverInfo, config) {
4516
284
  const runner = await createExtensionRunner(config);
4517
- const viteServer = await vite6.createServer(
4518
- vite6.mergeConfig(serverInfo, await config.vite(config.env))
285
+ const viteServer = await vite.createServer(
286
+ vite.mergeConfig(serverInfo, await config.vite(config.env))
4519
287
  );
4520
288
  const start = async () => {
4521
289
  await viteServer.listen(server.port);
4522
290
  config.logger.success(`Started dev server @ ${serverInfo.origin}`);
4523
- server.currentOutput = await buildInternal(config);
291
+ server.currentOutput = await internalBuild(config);
4524
292
  await runner.openBrowser(config);
4525
293
  };
4526
294
  const reloadExtension = () => {
4527
295
  viteServer.ws.send("wxt:reload-extension");
4528
296
  };
4529
- const reloadPage = (path9) => {
4530
- viteServer.ws.send("wxt:reload-page", path9);
297
+ const reloadPage = (path3) => {
298
+ viteServer.ws.send("wxt:reload-page", path3);
4531
299
  };
4532
300
  const reloadContentScript = (contentScript) => {
4533
301
  viteServer.ws.send("wxt:reload-content-script", contentScript);
@@ -4585,133 +353,211 @@ function reloadContentScripts(steps, config, server) {
4585
353
  }
4586
354
  function reloadHtmlPages(groups, server, config) {
4587
355
  groups.flat().forEach((entry) => {
4588
- const path9 = getEntrypointBundlePath(entry, config.outDir, ".html");
4589
- server.reloadPage(path9);
356
+ const path3 = getEntrypointBundlePath(entry, config.outDir, ".html");
357
+ server.reloadPage(path3);
4590
358
  });
4591
359
  }
4592
360
 
4593
- // src/core/clean.ts
4594
- import path8 from "node:path";
4595
- import glob4 from "fast-glob";
4596
- import fs15 from "fs-extra";
4597
- import { consola as consola2 } from "consola";
4598
- import pc4 from "picocolors";
4599
- async function clean(root = process.cwd()) {
4600
- consola2.info("Cleaning Project");
4601
- const tempDirs = [
4602
- "node_modules/.vite",
4603
- "node_modules/.cache",
4604
- "**/.wxt",
4605
- ".output/*"
4606
- ];
4607
- consola2.debug("Looking for:", tempDirs.map(pc4.cyan).join(", "));
4608
- const directories = await glob4(tempDirs, {
4609
- cwd: path8.resolve(root),
4610
- absolute: true,
4611
- onlyDirectories: true,
4612
- deep: 2
4613
- });
4614
- if (directories.length === 0) {
4615
- consola2.debug("No generated files found.");
4616
- return;
4617
- }
4618
- consola2.debug(
4619
- "Found:",
4620
- directories.map((dir) => pc4.cyan(path8.relative(root, dir))).join(", ")
361
+ // src/core/initialize.ts
362
+ import prompts from "prompts";
363
+ import { consola as consola3 } from "consola";
364
+ import { downloadTemplate } from "giget";
365
+ import fs2 from "fs-extra";
366
+ import path2 from "node:path";
367
+ import pc3 from "picocolors";
368
+ async function initialize(options) {
369
+ consola3.info("Initalizing new project");
370
+ const templates = await listTemplates();
371
+ const defaultTemplate = templates.find(
372
+ (template) => template.name === options.template?.toLowerCase().trim()
4621
373
  );
4622
- for (const directory of directories) {
4623
- await fs15.rm(directory, { force: true, recursive: true });
4624
- consola2.debug("Deleted " + pc4.cyan(path8.relative(root, directory)));
374
+ const input = await prompts(
375
+ [
376
+ {
377
+ name: "directory",
378
+ type: () => options.directory == null ? "text" : void 0,
379
+ message: "Project Directory",
380
+ initial: options.directory
381
+ },
382
+ {
383
+ name: "template",
384
+ type: () => defaultTemplate == null ? "select" : void 0,
385
+ message: "Choose a template",
386
+ choices: templates.map((template) => ({
387
+ title: TEMPLATE_COLORS[template.name]?.(template.name) ?? template.name,
388
+ value: template
389
+ }))
390
+ },
391
+ {
392
+ name: "packageManager",
393
+ type: () => options.packageManager == null ? "select" : void 0,
394
+ message: "Package Manager",
395
+ choices: [
396
+ { title: "npm", value: "npm" },
397
+ { title: "pnpm", value: "pnpm" },
398
+ { title: "yarn", value: "yarn" }
399
+ ]
400
+ }
401
+ ],
402
+ {
403
+ onCancel: () => process.exit(1)
404
+ }
405
+ );
406
+ input.directory ??= options.directory;
407
+ input.template ??= defaultTemplate;
408
+ input.packageManager ??= options.packageManager;
409
+ await cloneProject(input);
410
+ const cdPath = path2.relative(process.cwd(), path2.resolve(input.directory));
411
+ console.log();
412
+ consola3.log(
413
+ `\u2728 WXT project created with the ${TEMPLATE_COLORS[input.template.name]?.(input.template.name) ?? input.template.name} template.`
414
+ );
415
+ console.log();
416
+ consola3.log("Next steps:");
417
+ let step = 0;
418
+ if (cdPath !== "")
419
+ consola3.log(` ${++step}.`, pc3.cyan(`cd ${cdPath}`));
420
+ consola3.log(` ${++step}.`, pc3.cyan(`${input.packageManager} install`));
421
+ console.log();
422
+ }
423
+ async function listTemplates() {
424
+ try {
425
+ const res = await fetch(
426
+ "https://api.github.com/repos/wxt-dev/wxt/contents/templates",
427
+ {
428
+ headers: {
429
+ Accept: "application/vnd.github+json",
430
+ "X-GitHub-Api-Version": "2022-11-28"
431
+ }
432
+ }
433
+ );
434
+ if (res.status >= 300)
435
+ throw Error(`Request failed with status ${res.status} ${res.statusText}`);
436
+ const data = await res.json();
437
+ return data.filter((item) => item.type === "dir").map((item) => ({ name: item.name, path: item.path })).sort((l, r) => {
438
+ const lWeight = TEMPLATE_SORT_WEIGHT[l.name] ?? Number.MAX_SAFE_INTEGER;
439
+ const rWeight = TEMPLATE_SORT_WEIGHT[r.name] ?? Number.MAX_SAFE_INTEGER;
440
+ const diff = lWeight - rWeight;
441
+ if (diff !== 0)
442
+ return diff;
443
+ return l.name.localeCompare(r.name);
444
+ });
445
+ } catch (err) {
446
+ throw Error(`Cannot load templates: ${JSON.stringify(err, null, 2)}`);
4625
447
  }
4626
448
  }
4627
-
4628
- // package.json
4629
- var version2 = "0.8.4";
4630
-
4631
- // src/core/utils/defineConfig.ts
4632
- function defineConfig(config) {
4633
- return config;
4634
- }
4635
-
4636
- // src/core/utils/defineRunnerConfig.ts
4637
- function defineRunnerConfig(config) {
4638
- return config;
449
+ async function cloneProject({
450
+ directory,
451
+ template,
452
+ packageManager
453
+ }) {
454
+ const { default: ora } = await import("ora");
455
+ const spinner = ora("Downloading template").start();
456
+ try {
457
+ await downloadTemplate(`gh:wxt-dev/wxt/${template.path}`, {
458
+ dir: directory,
459
+ force: true
460
+ });
461
+ await fs2.move(
462
+ path2.join(directory, "_gitignore"),
463
+ path2.join(directory, ".gitignore")
464
+ ).catch(
465
+ (err) => consola3.warn("Failed to move _gitignore to .gitignore:", err)
466
+ );
467
+ if (packageManager === "pnpm") {
468
+ await fs2.writeFile(
469
+ path2.join(directory, ".npmrc"),
470
+ "shamefully-hoist=true\n"
471
+ );
472
+ }
473
+ spinner.succeed();
474
+ } catch (err) {
475
+ spinner.fail();
476
+ throw Error(`Failed to setup new project: ${JSON.stringify(err, null, 2)}`);
477
+ }
4639
478
  }
479
+ var TEMPLATE_COLORS = {
480
+ vanilla: pc3.blue,
481
+ vue: pc3.green,
482
+ react: pc3.cyan,
483
+ svelte: pc3.red,
484
+ solid: pc3.blue
485
+ };
486
+ var TEMPLATE_SORT_WEIGHT = {
487
+ vanilla: 0,
488
+ vue: 1,
489
+ react: 2
490
+ };
4640
491
 
4641
- // src/index.ts
4642
- async function build2(config) {
492
+ // src/core/prepare.ts
493
+ async function prepare(config) {
4643
494
  const internalConfig = await getInternalConfig(config, "build");
4644
- return await buildInternal(internalConfig);
495
+ internalConfig.logger.info("Generating types...");
496
+ const entrypoints = await findEntrypoints(internalConfig);
497
+ await generateTypesDir(entrypoints, internalConfig);
4645
498
  }
4646
- async function createServer2(config) {
4647
- const serverInfo = await getServerInfo();
4648
- const getLatestInternalConfig = async () => {
4649
- return getInternalConfig(
4650
- {
4651
- ...config,
4652
- vite: () => serverInfo.viteServerConfig
4653
- },
4654
- "serve"
4655
- );
4656
- };
4657
- let internalConfig = await getLatestInternalConfig();
4658
- const server = await setupServer(serverInfo, internalConfig);
4659
- internalConfig.server = server;
4660
- const fileChangedMutex = new Mutex();
4661
- const changeQueue = [];
4662
- server.ws.on("wxt:background-initialized", () => {
4663
- reloadContentScripts(server.currentOutput.steps, internalConfig, server);
499
+
500
+ // src/core/zip.ts
501
+ import zipdir from "zip-dir";
502
+ import { dirname, relative as relative5, resolve } from "node:path";
503
+ import fs3 from "fs-extra";
504
+ import { minimatch } from "minimatch";
505
+ async function zip(config) {
506
+ const internalConfig = await getInternalConfig(config ?? {}, "build");
507
+ const output = await internalBuild(internalConfig);
508
+ const start = Date.now();
509
+ internalConfig.logger.info("Zipping extension...");
510
+ const zipFiles = [];
511
+ const projectName = internalConfig.zip.name ?? kebabCaseAlphanumeric(
512
+ (await getPackageJson(internalConfig))?.name || dirname(process.cwd())
513
+ );
514
+ const applyTemplate = (template) => template.replaceAll("{{name}}", projectName).replaceAll("{{browser}}", internalConfig.browser).replaceAll(
515
+ "{{version}}",
516
+ output.manifest.version_name ?? output.manifest.version
517
+ ).replaceAll("{{manifestVersion}}", `mv${internalConfig.manifestVersion}`);
518
+ await fs3.ensureDir(internalConfig.outBaseDir);
519
+ const outZipFilename = applyTemplate(internalConfig.zip.artifactTemplate);
520
+ const outZipPath = resolve(internalConfig.outBaseDir, outZipFilename);
521
+ await zipdir(internalConfig.outDir, {
522
+ saveTo: outZipPath
4664
523
  });
4665
- server.watcher.on("all", async (event, path9, _stats) => {
4666
- if (path9.startsWith(internalConfig.outBaseDir))
4667
- return;
4668
- changeQueue.push([event, path9]);
4669
- await fileChangedMutex.runExclusive(async () => {
4670
- const fileChanges = changeQueue.splice(0, changeQueue.length);
4671
- if (fileChanges.length === 0)
4672
- return;
4673
- const changes = detectDevChanges(fileChanges, server.currentOutput);
4674
- if (changes.type === "no-change")
4675
- return;
4676
- internalConfig.logger.info(
4677
- `Changed: ${Array.from(new Set(fileChanges.map((change) => change[1]))).map((file) => pc5.dim(relative8(internalConfig.root, file))).join(", ")}`
4678
- );
4679
- const rebuiltNames = changes.rebuildGroups.flat().map((entry) => {
4680
- return pc5.cyan(
4681
- relative8(internalConfig.outDir, getEntrypointOutputFile(entry, ""))
524
+ zipFiles.push(outZipPath);
525
+ if (internalConfig.browser === "firefox") {
526
+ const sourcesZipFilename = applyTemplate(
527
+ internalConfig.zip.sourcesTemplate
528
+ );
529
+ const sourcesZipPath = resolve(
530
+ internalConfig.outBaseDir,
531
+ sourcesZipFilename
532
+ );
533
+ await zipdir(internalConfig.zip.sourcesRoot, {
534
+ saveTo: sourcesZipPath,
535
+ filter(path3) {
536
+ const relativePath = relative5(internalConfig.zip.sourcesRoot, path3);
537
+ const matchedPattern = internalConfig.zip.ignoredSources.find(
538
+ (pattern) => minimatch(relativePath, pattern)
4682
539
  );
4683
- }).join(pc5.dim(", "));
4684
- internalConfig = await getLatestInternalConfig();
4685
- internalConfig.server = server;
4686
- const { output: newOutput } = await rebuild(
4687
- internalConfig,
4688
- // TODO: this excludes new entrypoints, so they're not built until the dev command is restarted
4689
- changes.rebuildGroups,
4690
- changes.cachedOutput
4691
- );
4692
- server.currentOutput = newOutput;
4693
- switch (changes.type) {
4694
- case "extension-reload":
4695
- server.reloadExtension();
4696
- break;
4697
- case "html-reload":
4698
- reloadHtmlPages(changes.rebuildGroups, server, internalConfig);
4699
- break;
4700
- case "content-script-reload":
4701
- reloadContentScripts(changes.changedSteps, internalConfig, server);
4702
- break;
540
+ return matchedPattern == null;
4703
541
  }
4704
- consola3.success(`Reloaded: ${rebuiltNames}`);
4705
542
  });
4706
- });
4707
- return server;
543
+ zipFiles.push(sourcesZipPath);
544
+ }
545
+ await printFileList(
546
+ internalConfig.logger.success,
547
+ `Zipped extension in ${formatDuration(Date.now() - start)}`,
548
+ internalConfig.outBaseDir,
549
+ zipFiles
550
+ );
551
+ return zipFiles;
4708
552
  }
4709
553
  export {
4710
- build2 as build,
554
+ build,
4711
555
  clean,
4712
556
  createServer2 as createServer,
4713
557
  defineConfig,
4714
558
  defineRunnerConfig,
4715
- version2 as version
559
+ initialize,
560
+ prepare,
561
+ version,
562
+ zip
4716
563
  };
4717
- //# sourceMappingURL=index.js.map