wxt 0.20.25 → 0.20.27

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.
@@ -44,7 +44,7 @@ const aliasCommandNames = /* @__PURE__ */ new Set();
44
44
  * @param docsUrl URL to the docs for the aliased CLI tool
45
45
  */
46
46
  function createAliasedCommand(base, name, alias, bin, docsUrl) {
47
- const aliasedCommand = base.command(name, `Alias for ${alias} (${docsUrl})`).allowUnknownOptions().action(async () => {
47
+ const aliasedCommand = base.command(`${name} [...args]`, `Alias for ${alias} (${docsUrl})`).allowUnknownOptions().action(async () => {
48
48
  try {
49
49
  await registerWxt("build");
50
50
  await spawn(bin, process.argv.slice(process.argv.indexOf(aliasedCommand.name) + 1), { stdio: "inherit" });
@@ -1,21 +1,12 @@
1
1
  import { unnormalizePath } from "./utils/paths.mjs";
2
- import { getEntrypointBundlePath, isHtmlEntrypoint } from "./utils/entrypoints.mjs";
3
2
  import { deinitWxtModules, initWxtModules, registerWxt, wxt } from "./wxt.mjs";
4
- import { detectDevChanges } from "./utils/building/detect-dev-changes.mjs";
5
- import { findEntrypoints } from "./utils/building/find-entrypoints.mjs";
6
- import { getContentScriptJs, mapWxtOptionsToRegisteredContentScript } from "./utils/content-scripts.mjs";
7
- import { getContentScriptCssFiles, getContentScriptsCssMap } from "./utils/manifest.mjs";
8
- import { rebuild } from "./utils/building/rebuild.mjs";
9
3
  import { internalBuild } from "./utils/building/internal-build.mjs";
10
4
  import "./utils/building/index.mjs";
11
5
  import { createExtensionRunner } from "./runners/index.mjs";
12
6
  import { createKeyboardShortcuts } from "./keyboard-shortcuts.mjs";
13
7
  import { isBabelSyntaxError, logBabelSyntaxError } from "./utils/syntax-errors.mjs";
14
- import { relative } from "node:path";
15
- import { styleText } from "node:util";
16
- import { debounce } from "perfect-debounce";
8
+ import { createFileReloader, reloadContentScripts } from "./utils/create-file-reloader.mjs";
17
9
  import chokidar from "chokidar";
18
- import { Mutex } from "async-mutex";
19
10
  //#region src/core/create-server.ts
20
11
  /**
21
12
  * Creates a dev server and pre-builds all the files that need to exist before
@@ -147,93 +138,6 @@ async function createServerInternal() {
147
138
  return server;
148
139
  }
149
140
  /**
150
- * Returns a function responsible for reloading different parts of the extension
151
- * when a file changes.
152
- */
153
- function createFileReloader(server) {
154
- const fileChangedMutex = new Mutex();
155
- const changeQueue = [];
156
- const cb = async (event, path) => {
157
- changeQueue.push([event, path]);
158
- await fileChangedMutex.runExclusive(async () => {
159
- if (server.currentOutput == null) return;
160
- const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
161
- if (fileChanges.length === 0) return;
162
- await wxt.reloadConfig();
163
- const changes = detectDevChanges(fileChanges, server.currentOutput);
164
- if (changes.type === "no-change") return;
165
- if (changes.type === "full-restart") {
166
- wxt.logger.info("Config changed, restarting server...");
167
- server.restart();
168
- return;
169
- }
170
- if (changes.type === "browser-restart") {
171
- wxt.logger.info("Runner config changed, restarting browser...");
172
- server.restartBrowser();
173
- return;
174
- }
175
- wxt.logger.info(`Changed: ${Array.from(new Set(fileChanges)).map((file) => styleText("dim", relative(wxt.config.root, file))).join(", ")}`);
176
- const allEntrypoints = await findEntrypoints();
177
- try {
178
- const { output: newOutput } = await rebuild(allEntrypoints, changes.rebuildGroups, changes.cachedOutput);
179
- server.currentOutput = newOutput;
180
- switch (changes.type) {
181
- case "extension-reload":
182
- server.reloadExtension();
183
- wxt.logger.success(`Reloaded extension`);
184
- break;
185
- case "html-reload":
186
- const { reloadedNames } = reloadHtmlPages(changes.rebuildGroups, server);
187
- wxt.logger.success(`Reloaded: ${getFilenameList(reloadedNames)}`);
188
- break;
189
- case "content-script-reload":
190
- reloadContentScripts(changes.changedSteps, server);
191
- const rebuiltNames = changes.rebuildGroups.flat().map((entry) => entry.name);
192
- wxt.logger.success(`Reloaded: ${getFilenameList(rebuiltNames)}`);
193
- break;
194
- }
195
- } catch {}
196
- }).catch((error) => {
197
- if (!isBabelSyntaxError(error)) throw error;
198
- logBabelSyntaxError(error);
199
- });
200
- };
201
- return debounce(cb, wxt.config.dev.server.watchDebounce, {
202
- leading: true,
203
- trailing: false
204
- });
205
- }
206
- /**
207
- * From the server, tell the client to reload content scripts from the provided
208
- * build step outputs.
209
- */
210
- function reloadContentScripts(steps, server) {
211
- if (wxt.config.manifestVersion === 3) steps.forEach((step) => {
212
- if (server.currentOutput == null) return;
213
- const entry = step.entrypoints;
214
- if (Array.isArray(entry) || entry.type !== "content-script") return;
215
- const js = getContentScriptJs(wxt.config, entry);
216
- const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
217
- const css = getContentScriptCssFiles([entry], cssMap);
218
- server.reloadContentScript({
219
- registration: entry.options.registration,
220
- contentScript: mapWxtOptionsToRegisteredContentScript(entry.options, js, css)
221
- });
222
- });
223
- else server.reloadExtension();
224
- }
225
- function reloadHtmlPages(groups, server) {
226
- const htmlEntries = groups.flat().filter(isHtmlEntrypoint);
227
- htmlEntries.forEach((entry) => {
228
- const path = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
229
- server.reloadPage(path);
230
- });
231
- return { reloadedNames: htmlEntries.map((entry) => entry.name) };
232
- }
233
- function getFilenameList(names) {
234
- return names.map((name) => styleText("cyan", name)).join(styleText("dim", ", "));
235
- }
236
- /**
237
141
  * Based on the current build output, return a list of files that are:
238
142
  *
239
143
  * 1. Not in node_modules
@@ -0,0 +1,103 @@
1
+ import { getEntrypointBundlePath, isHtmlEntrypoint } from "./entrypoints.mjs";
2
+ import { wxt } from "../wxt.mjs";
3
+ import { detectDevChanges } from "./building/detect-dev-changes.mjs";
4
+ import { findEntrypoints } from "./building/find-entrypoints.mjs";
5
+ import { getContentScriptJs, mapWxtOptionsToRegisteredContentScript } from "./content-scripts.mjs";
6
+ import { getContentScriptCssFiles, getContentScriptsCssMap } from "./manifest.mjs";
7
+ import { rebuild } from "./building/rebuild.mjs";
8
+ import "./building/index.mjs";
9
+ import { isBabelSyntaxError, logBabelSyntaxError } from "./syntax-errors.mjs";
10
+ import { relative } from "node:path";
11
+ import { styleText } from "node:util";
12
+ import { debounce } from "perfect-debounce";
13
+ import { Mutex } from "async-mutex";
14
+ //#region src/core/utils/create-file-reloader.ts
15
+ /**
16
+ * Returns a function responsible for reloading different parts of the extension
17
+ * when a file changes.
18
+ */
19
+ function createFileReloader(server) {
20
+ const fileChangedMutex = new Mutex();
21
+ const changeQueue = [];
22
+ const cb = async (event, path) => {
23
+ changeQueue.push([event, path]);
24
+ await fileChangedMutex.runExclusive(async () => {
25
+ if (server.currentOutput == null) return;
26
+ const fileChanges = changeQueue.splice(0, changeQueue.length).map(([_, file]) => file);
27
+ if (fileChanges.length === 0) return;
28
+ await wxt.reloadConfig();
29
+ const changes = detectDevChanges(fileChanges, server.currentOutput);
30
+ if (changes.type === "no-change") return;
31
+ if (changes.type === "full-restart") {
32
+ wxt.logger.info("Config changed, restarting server...");
33
+ server.restart();
34
+ return;
35
+ }
36
+ if (changes.type === "browser-restart") {
37
+ wxt.logger.info("Runner config changed, restarting browser...");
38
+ server.restartBrowser();
39
+ return;
40
+ }
41
+ wxt.logger.info(`Changed: ${Array.from(new Set(fileChanges)).map((file) => styleText("dim", relative(wxt.config.root, file))).join(", ")}`);
42
+ const allEntrypoints = await findEntrypoints();
43
+ try {
44
+ const { output: newOutput } = await rebuild(allEntrypoints, changes.rebuildGroups, changes.cachedOutput);
45
+ server.currentOutput = newOutput;
46
+ switch (changes.type) {
47
+ case "extension-reload":
48
+ server.reloadExtension();
49
+ wxt.logger.success(`Reloaded extension`);
50
+ break;
51
+ case "html-reload":
52
+ const { reloadedNames } = reloadHtmlPages(changes.rebuildGroups, server);
53
+ wxt.logger.success(`Reloaded: ${getFilenameList(reloadedNames)}`);
54
+ break;
55
+ case "content-script-reload":
56
+ reloadContentScripts(changes.changedSteps, server);
57
+ const rebuiltNames = changes.rebuildGroups.flat().map((entry) => entry.name);
58
+ wxt.logger.success(`Reloaded: ${getFilenameList(rebuiltNames)}`);
59
+ break;
60
+ }
61
+ } catch {}
62
+ }).catch((error) => {
63
+ if (!isBabelSyntaxError(error)) throw error;
64
+ logBabelSyntaxError(error);
65
+ });
66
+ };
67
+ return debounce(cb, wxt.config.dev.server.watchDebounce, {
68
+ leading: true,
69
+ trailing: false
70
+ });
71
+ }
72
+ /**
73
+ * From the server, tell the client to reload content scripts from the provided
74
+ * build step outputs.
75
+ */
76
+ function reloadContentScripts(steps, server) {
77
+ if (wxt.config.manifestVersion === 3) steps.forEach((step) => {
78
+ if (server.currentOutput == null) return;
79
+ const entry = step.entrypoints;
80
+ if (Array.isArray(entry) || entry.type !== "content-script") return;
81
+ const js = getContentScriptJs(wxt.config, entry);
82
+ const cssMap = getContentScriptsCssMap(server.currentOutput, [entry]);
83
+ const css = getContentScriptCssFiles([entry], cssMap);
84
+ server.reloadContentScript({
85
+ registration: entry.options.registration,
86
+ contentScript: mapWxtOptionsToRegisteredContentScript(entry.options, js, css)
87
+ });
88
+ });
89
+ else server.reloadExtension();
90
+ }
91
+ function reloadHtmlPages(groups, server) {
92
+ const htmlEntries = groups.flat().filter(isHtmlEntrypoint);
93
+ htmlEntries.forEach((entry) => {
94
+ const path = getEntrypointBundlePath(entry, wxt.config.outDir, ".html");
95
+ server.reloadPage(path);
96
+ });
97
+ return { reloadedNames: htmlEntries.map((entry) => entry.name) };
98
+ }
99
+ function getFilenameList(names) {
100
+ return names.map((name) => styleText("cyan", name)).join(styleText("dim", ", "));
101
+ }
102
+ //#endregion
103
+ export { createFileReloader, reloadContentScripts };
@@ -1,3 +1,4 @@
1
+ import { wxt } from "../../wxt.mjs";
1
2
  import { printTable } from "./printTable.mjs";
2
3
  import { lstat } from "node:fs/promises";
3
4
  import path from "node:path";
@@ -10,9 +11,14 @@ async function printFileList(log, header, baseDir, files) {
10
11
  const parts = [path.relative(process.cwd(), baseDir) + path.sep, path.relative(baseDir, file)];
11
12
  const prefix = i === files.length - 1 ? " └─" : " ├─";
12
13
  const chunkColor = getChunkColor(file);
13
- const stats = await lstat(file);
14
- totalSize += stats.size;
15
- const size = String(filesize(stats.size));
14
+ let size = "";
15
+ try {
16
+ const stats = await lstat(file);
17
+ totalSize += stats.size;
18
+ size = String(filesize(stats.size));
19
+ } catch (ex) {
20
+ wxt.logger.warn(`Could not get stats of '${file}' error: ${ex}`);
21
+ }
16
22
  return [`${styleText("gray", prefix)} ${styleText("dim", parts[0])}${styleText(chunkColor, parts[1])}`, styleText("dim", size)];
17
23
  }));
18
24
  fileRows.push([`${styleText("cyan", "Σ Total size:")} ${String(filesize(totalSize))}`]);
@@ -56,6 +56,7 @@ async function generateManifest(allEntrypoints, buildOutput) {
56
56
  manifest.version = version;
57
57
  manifest.version_name = wxt.config.browser === "firefox" || versionName === version ? void 0 : versionName;
58
58
  if (wxt.config.browser === "firefox" && !userManifest.browser_specific_settings?.gecko?.data_collection_permissions && !wxt.config.suppressWarnings?.firefoxDataCollection) wxt.logger.warn("Firefox requires `data_collection_permissions` for new extensions from November 3, 2025. Existing extensions are exempt for now.\nFor more details, see: https://extensionworkshop.com/documentation/develop/firefox-builtin-data-consent/\nTo suppress this warning, set `suppressWarnings.firefoxDataCollection` to `true` in your wxt config.\n");
59
+ if (wxt.config.browser === "firefox" && !manifest.browser_specific_settings?.gecko?.id && !wxt.config.suppressWarnings?.firefoxId) wxt.logger.warn("Firefox requires extension ID for MV3 and recommends it for MV2.\nFor more details, see: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings#id");
59
60
  addEntrypoints(manifest, entrypoints, buildOutput);
60
61
  if (wxt.config.browser === "firefox") addDiscoveredThemeIcons(manifest, buildOutput);
61
62
  if (wxt.config.command === "serve") addDevModeCsp(manifest);
@@ -136,10 +137,11 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
136
137
  const options = {};
137
138
  if (popup.options.defaultIcon) options.default_icon = popup.options.defaultIcon;
138
139
  if (popup.options.defaultTitle) options.default_title = popup.options.defaultTitle;
140
+ if (popup.options.defaultState && wxt.config.manifestVersion === 3) options.default_state = popup.options.defaultState;
139
141
  if (popup.options.browserStyle) options.browser_style = popup.options.browserStyle;
140
142
  if (popup.options.defaultArea) options.default_area = popup.options.defaultArea;
141
143
  if (popup.options.themeIcons) options.theme_icons = popup.options.themeIcons;
142
- const actionKey = manifest.manifest_version === 2 ? popup.options.actionType ?? "browser_action" : wxt.config.browser === "firefox" && popup.options.actionType === "page_action" ? "page_action" : "action";
144
+ const actionKey = wxt.config.manifestVersion === 2 ? popup.options.actionType ?? "browser_action" : wxt.config.browser === "firefox" && popup.options.actionType === "page_action" ? "page_action" : "action";
143
145
  manifest[actionKey] = {
144
146
  ...manifest[actionKey],
145
147
  ...options,
@@ -150,7 +152,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
150
152
  if (options) {
151
153
  const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
152
154
  manifest.options_ui = {
153
- open_in_tab: options.options.openInTab ?? false,
155
+ ...wxt.config.browser !== "safari" && { open_in_tab: options.options.openInTab ?? false },
154
156
  browser_style: wxt.config.browser === "firefox" ? options.options.browserStyle : void 0,
155
157
  chrome_style: wxt.config.browser !== "firefox" ? options.options.chromeStyle : void 0,
156
158
  page
@@ -239,9 +241,9 @@ function addDevModeCsp(manifest) {
239
241
  }
240
242
  const permission = `${permissionUrl}*`;
241
243
  const allowedCsp = wxt.server?.origin ?? "http://localhost:*";
242
- if (manifest.manifest_version === 3) addHostPermission(manifest, permission);
244
+ if (wxt.config.manifestVersion === 3) addHostPermission(manifest, permission);
243
245
  else addPermission(manifest, permission);
244
- const extensionPagesCsp = new ContentSecurityPolicy(manifest.content_security_policy?.extension_pages ?? (manifest.manifest_version === 3 ? DEFAULT_MV3_EXTENSION_PAGES_CSP : DEFAULT_MV2_CSP));
246
+ const extensionPagesCsp = new ContentSecurityPolicy(manifest.content_security_policy?.extension_pages ?? (wxt.config.manifestVersion === 3 ? DEFAULT_MV3_EXTENSION_PAGES_CSP : DEFAULT_MV2_CSP));
245
247
  const sandboxCsp = new ContentSecurityPolicy(manifest.content_security_policy?.sandbox ?? DEFAULT_MV3_SANDBOX_CSP);
246
248
  if (wxt.config.command === "serve") {
247
249
  extensionPagesCsp.add("script-src", allowedCsp);
@@ -8,10 +8,8 @@ import picomatch from "picomatch";
8
8
  * matches any of the negative patterns, it will return `false`.
9
9
  *
10
10
  * @example
11
- * ```ts
12
11
  * picomatchMultiple('a.json', ['*.json', '!b.json']); // => true
13
12
  * picomatchMultiple('b.json', ['*.json', '!b.json']); // => false
14
- * ```;
15
13
  */
16
14
  function picomatchMultiple(search, patterns, options) {
17
15
  if (patterns == null) return false;
package/dist/types.d.mts CHANGED
@@ -89,7 +89,7 @@ interface InlineConfig {
89
89
  * 'serve')
90
90
  *
91
91
  * @example
92
- * {{browser}} -mv{{manifestVersion}}
92
+ * '{{browser}}-mv{{manifestVersion}}';
93
93
  *
94
94
  * @default <span v-pre>`"{{browser}}-mv{{manifestVersion}}{{modeSuffix}}"`</span>
95
95
  */
@@ -168,13 +168,11 @@ interface InlineConfig {
168
168
  * Suppress specific warnings during the build process.
169
169
  *
170
170
  * @example
171
- * ```ts
172
171
  * export default defineConfig({
173
172
  * suppressWarnings: {
174
173
  * firefoxDataCollection: true,
175
174
  * },
176
- * })
177
- * ```;
175
+ * });
178
176
  */
179
177
  suppressWarnings?: {
180
178
  /**
@@ -182,6 +180,11 @@ interface InlineConfig {
182
180
  * https://extensionworkshop.com/documentation/develop/firefox-builtin-data-consent
183
181
  */
184
182
  firefoxDataCollection?: boolean;
183
+ /**
184
+ * Suppress warnings when the Firefox extension ID is missing.
185
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings#id
186
+ */
187
+ firefoxId?: boolean;
185
188
  };
186
189
  /**
187
190
  * Configure browser startup. Options set here can be overridden in a
@@ -309,10 +312,10 @@ interface InlineConfig {
309
312
  *
310
313
  * @example
311
314
  * // Correct:
312
- * ['@scope/package-name', 'package-name'][
313
- * // Incorrect, don't include versions!!!
314
- * ('@scope/package-name@1.1.3', 'package-name@^2')
315
- * ];
315
+ * ['@scope/package-name', 'package-name'];
316
+ *
317
+ * // Incorrect, don't include versions!!!
318
+ * ['@scope/package-name@1.1.3', 'package-name@^2'];
316
319
  *
317
320
  * @default [ ]
318
321
  */
@@ -699,6 +702,22 @@ interface BaseContentScriptEntrypointOptions extends BaseScriptEntrypointOptions
699
702
  * @default 'manifest'
700
703
  */
701
704
  registration?: PerBrowserOption<'manifest' | 'runtime'>;
705
+ /**
706
+ * Do not send the `wxt:content-script-started` message via
707
+ * `window.postMessage`.
708
+ *
709
+ * This has been replaced with custom events. The `postMessage` call is kept
710
+ * for backwards compatibility. For some websites the `postMessage` call is
711
+ * undesirable, such as those with poorly written message event listeners.
712
+ *
713
+ * Setting this to `true` opts into the behavior that will become the default
714
+ * in a future version of WXT, where the `postMessage` call is removed
715
+ * entirely.
716
+ *
717
+ * See https://github.com/wxt-dev/wxt/pull/1938 and
718
+ * https://github.com/wxt-dev/wxt/pull/2035 for a detailed discussion.
719
+ */
720
+ noScriptStartedPostMessage?: boolean;
702
721
  }
703
722
  interface MainWorldContentScriptEntrypointOptions extends BaseContentScriptEntrypointOptions {
704
723
  /**
@@ -742,6 +761,12 @@ interface PopupEntrypointOptions extends BaseEntrypointOptions {
742
761
  mv2Key?: PerBrowserOption<'browser_action' | 'page_action'>;
743
762
  defaultIcon?: Record<string, string>;
744
763
  defaultTitle?: PerBrowserOption<string>;
764
+ /**
765
+ * Chrome only. Controls the initial enabled/disabled state of the action.
766
+ *
767
+ * @see https://developer.chrome.com/docs/extensions/reference/api/action#enabled_state
768
+ */
769
+ defaultState?: PerBrowserOption<'enabled' | 'disabled'>;
745
770
  browserStyle?: PerBrowserOption<boolean>;
746
771
  /**
747
772
  * Firefox only. Defines the part of the browser in which the button is
@@ -968,7 +993,7 @@ type UserManifest = { [key in keyof Browser.runtime.ManifestV3 as key extends 'a
968
993
  strict_max_version?: string;
969
994
  };
970
995
  };
971
- permissions?: (Browser.runtime.ManifestPermissions | (string & Record<never, never>))[];
996
+ permissions?: (Browser.runtime.ManifestPermission | (string & Record<never, never>))[];
972
997
  web_accessible_resources?: string[] | Browser.runtime.ManifestV3['web_accessible_resources'];
973
998
  };
974
999
  type UserManifestFn = (env: ConfigEnv) => UserManifest | Promise<UserManifest>;
@@ -1369,6 +1394,7 @@ interface ResolvedConfig$1 {
1369
1394
  /** List of warning identifiers to suppress during the build process. */
1370
1395
  suppressWarnings: {
1371
1396
  firefoxDataCollection?: boolean;
1397
+ firefoxId?: boolean;
1372
1398
  };
1373
1399
  dev: {
1374
1400
  /** Only defined during dev command */server?: {
@@ -169,7 +169,7 @@ var ContentScriptContext = class ContentScriptContext {
169
169
  contentScriptName: this.contentScriptName,
170
170
  messageId: this.id
171
171
  } }));
172
- window.postMessage({
172
+ if (!this.options?.noScriptStartedPostMessage) window.postMessage({
173
173
  type: ContentScriptContext.SCRIPT_STARTED_MESSAGE_TYPE,
174
174
  contentScriptName: this.contentScriptName,
175
175
  messageId: this.id
package/dist/version.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region src/version.ts
2
- const version = "0.20.25";
2
+ const version = "0.20.27";
3
3
  //#endregion
4
4
  export { version };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wxt",
3
3
  "type": "module",
4
- "version": "0.20.25",
4
+ "version": "0.20.27",
5
5
  "description": "⚡ Next-gen Web Extension Framework",
6
6
  "license": "MIT",
7
7
  "scripts": {
@@ -21,10 +21,10 @@
21
21
  "@webext-core/fake-browser": "^1.3.4",
22
22
  "@webext-core/isolated-element": "^1.1.3",
23
23
  "@webext-core/match-patterns": "^1.0.3",
24
- "@wxt-dev/browser": "^0.1.40",
24
+ "@wxt-dev/browser": "^0.2.0",
25
25
  "@wxt-dev/storage": "^1.0.0",
26
26
  "async-mutex": "^0.5.0",
27
- "c12": "^3.3.3",
27
+ "c12": "^3.3.4",
28
28
  "cac": "^6.7.14 || ^7.0.0",
29
29
  "chokidar": "^5.0.0",
30
30
  "ci-info": "^4.4.0",
@@ -32,7 +32,7 @@
32
32
  "defu": "^6.1.4",
33
33
  "dotenv-expand": "^12.0.3",
34
34
  "esbuild": "^0.27.1",
35
- "filesize": "^11.0.15",
35
+ "filesize": "^11.0.17",
36
36
  "get-port-please": "^3.2.0",
37
37
  "giget": "^1.2.3 || ^2.0.0 || ^3.0.0",
38
38
  "hookable": "^6.1.0",
@@ -51,9 +51,9 @@
51
51
  "perfect-debounce": "^2.1.0",
52
52
  "picomatch": "^4.0.3",
53
53
  "prompts": "^2.4.2",
54
- "publish-browser-extension": "^2.3.0 || ^3.0.2 || ^4.0.4",
54
+ "publish-browser-extension": "^2.3.0 || ^3.0.2 || ^4.0.5",
55
55
  "scule": "^1.3.0",
56
- "tinyglobby": "^0.2.15",
56
+ "tinyglobby": "^0.2.16",
57
57
  "unimport": "^3.13.1 || ^4.0.0 || ^5.0.0 || ^6.0.0",
58
58
  "vite": "^5.4.19 || ^6.3.4 || ^7.0.0 || ^8.0.0-0",
59
59
  "vite-node": "^3.2.4 || ^5.0.0 || ^6.0.0",
@@ -71,7 +71,6 @@
71
71
  "@aklinker1/buildc": "^1.1.7",
72
72
  "@faker-js/faker": "^10.3.0",
73
73
  "@types/bun": "^1.3.5",
74
- "@types/fs-extra": "^11.0.4",
75
74
  "@types/lodash.merge": "^4.6.9",
76
75
  "@types/node": "^20.17.6",
77
76
  "@types/normalize-path": "^3.0.2",
@@ -81,11 +80,11 @@
81
80
  "extract-zip": "^2.0.1",
82
81
  "happy-dom": "^20.8.3",
83
82
  "lodash.merge": "^4.6.2",
84
- "oxlint": "^1.51.0",
83
+ "oxlint": "^1.63.0",
85
84
  "publint": "^0.3.18",
86
85
  "tsdown": "^0.21.0",
87
- "typescript": "^5.9.3",
88
- "vitest": "^4.0.18",
86
+ "typescript": "^6.0.3",
87
+ "vitest": "^4.1.5",
89
88
  "vitest-plugin-random-seed": "^1.1.2"
90
89
  },
91
90
  "repository": {