wxt 0.20.7 → 0.20.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core/zip.mjs CHANGED
@@ -2,7 +2,6 @@ import path from "node:path";
2
2
  import fs from "fs-extra";
3
3
  import { safeFilename } from "./utils/strings.mjs";
4
4
  import { getPackageJson } from "./utils/package.mjs";
5
- import { minimatch } from "minimatch";
6
5
  import { formatDuration } from "./utils/time.mjs";
7
6
  import { printFileList } from "./utils/log/printFileList.mjs";
8
7
  import { findEntrypoints, internalBuild } from "./utils/building/index.mjs";
@@ -10,6 +9,7 @@ import { registerWxt, wxt } from "./wxt.mjs";
10
9
  import JSZip from "jszip";
11
10
  import glob from "fast-glob";
12
11
  import { normalizePath } from "./utils/paths.mjs";
12
+ import { minimatchMultiple } from "./utils/minimatch-multiple.mjs";
13
13
  export async function zip(config) {
14
14
  await registerWxt("build", config);
15
15
  const output = await internalBuild();
@@ -78,7 +78,7 @@ async function zipDir(directory, outputPath, options) {
78
78
  ignore: ["**/node_modules"],
79
79
  onlyFiles: true
80
80
  })).filter((relativePath) => {
81
- return options?.include?.some((pattern) => minimatch(relativePath, pattern)) || !options?.exclude?.some((pattern) => minimatch(relativePath, pattern));
81
+ return minimatchMultiple(relativePath, options?.include) || !minimatchMultiple(relativePath, options?.exclude);
82
82
  });
83
83
  const filesToZip = [
84
84
  ...files,
@@ -1,2 +1,2 @@
1
- import type { WxtAppConfig } from '../utils/define-app-config';
1
+ import type { WxtAppConfig } from './define-app-config';
2
2
  export declare function useAppConfig(): WxtAppConfig;
@@ -72,25 +72,35 @@ export declare class ContentScriptContext implements AbortController {
72
72
  block<T>(): Promise<T>;
73
73
  /**
74
74
  * Wrapper around `window.setInterval` that automatically clears the interval when invalidated.
75
+ *
76
+ * Intervals can be cleared by calling the normal `clearInterval` function.
75
77
  */
76
78
  setInterval(handler: () => void, timeout?: number): number;
77
79
  /**
78
80
  * Wrapper around `window.setTimeout` that automatically clears the interval when invalidated.
81
+ *
82
+ * Timeouts can be cleared by calling the normal `setTimeout` function.
79
83
  */
80
84
  setTimeout(handler: () => void, timeout?: number): number;
81
85
  /**
82
86
  * Wrapper around `window.requestAnimationFrame` that automatically cancels the request when
83
87
  * invalidated.
88
+ *
89
+ * Callbacks can be canceled by calling the normal `cancelAnimationFrame` function.
84
90
  */
85
91
  requestAnimationFrame(callback: FrameRequestCallback): number;
86
92
  /**
87
93
  * Wrapper around `window.requestIdleCallback` that automatically cancels the request when
88
94
  * invalidated.
95
+ *
96
+ * Callbacks can be canceled by calling the normal `cancelIdleCallback` function.
89
97
  */
90
98
  requestIdleCallback(callback: IdleRequestCallback, options?: IdleRequestOptions): number;
91
99
  /**
92
100
  * Call `target.addEventListener` and remove the event listener when the context is invalidated.
93
101
  *
102
+ * Listeners can be canceled by calling the normal `removeEventListener` function.
103
+ *
94
104
  * Includes additional events useful for content scripts:
95
105
  *
96
106
  * - `"wxt:locationchange"` - Triggered when HTML5 history mode is used to change URL. Content
@@ -106,7 +116,7 @@ export declare class ContentScriptContext implements AbortController {
106
116
  * });
107
117
  */
108
118
  addEventListener<TType extends keyof WxtWindowEventMap>(target: Window, type: TType, handler: (event: WxtWindowEventMap[TType]) => void, options?: AddEventListenerOptions): void;
109
- addEventListener<TType extends keyof DocumentEventMap>(target: Document, type: keyof DocumentEventMap, handler: (event: DocumentEventMap[TType]) => void, options?: AddEventListenerOptions): void;
119
+ addEventListener<TType extends keyof DocumentEventMap>(target: Document, type: TType, handler: (event: DocumentEventMap[TType]) => void, options?: AddEventListenerOptions): void;
110
120
  addEventListener<TTarget extends EventTarget>(target: TTarget, ...params: Parameters<TTarget['addEventListener']>): void;
111
121
  /**
112
122
  * @internal
@@ -72,6 +72,8 @@ export class ContentScriptContext {
72
72
  }
73
73
  /**
74
74
  * Wrapper around `window.setInterval` that automatically clears the interval when invalidated.
75
+ *
76
+ * Intervals can be cleared by calling the normal `clearInterval` function.
75
77
  */
76
78
  setInterval(handler, timeout) {
77
79
  const id = setInterval(() => {
@@ -82,6 +84,8 @@ export class ContentScriptContext {
82
84
  }
83
85
  /**
84
86
  * Wrapper around `window.setTimeout` that automatically clears the interval when invalidated.
87
+ *
88
+ * Timeouts can be cleared by calling the normal `setTimeout` function.
85
89
  */
86
90
  setTimeout(handler, timeout) {
87
91
  const id = setTimeout(() => {
@@ -93,6 +97,8 @@ export class ContentScriptContext {
93
97
  /**
94
98
  * Wrapper around `window.requestAnimationFrame` that automatically cancels the request when
95
99
  * invalidated.
100
+ *
101
+ * Callbacks can be canceled by calling the normal `cancelAnimationFrame` function.
96
102
  */
97
103
  requestAnimationFrame(callback) {
98
104
  const id = requestAnimationFrame((...args) => {
@@ -104,6 +110,8 @@ export class ContentScriptContext {
104
110
  /**
105
111
  * Wrapper around `window.requestIdleCallback` that automatically cancels the request when
106
112
  * invalidated.
113
+ *
114
+ * Callbacks can be canceled by calling the normal `cancelIdleCallback` function.
107
115
  */
108
116
  requestIdleCallback(callback, options) {
109
117
  const id = requestIdleCallback((...args) => {
@@ -1,3 +1,4 @@
1
+ /** @module wxt/utils/split-shadow-root-css */
1
2
  /**
2
3
  * Given a CSS string that will be loaded into a shadow root, split it into two parts:
3
4
  * - `documentCss`: CSS that needs to be applied to the document (like `@property`)
package/dist/version.mjs CHANGED
@@ -1 +1 @@
1
- export const version = "0.20.7";
1
+ export const version = "0.20.9";
@@ -88,10 +88,22 @@ async function reloadManifestContentScriptMv3(contentScript) {
88
88
  const existing = registered.find((cs) => cs.id === id);
89
89
  if (existing) {
90
90
  logger.debug("Updating content script", existing);
91
- await browser.scripting.updateContentScripts([{ ...contentScript, id }]);
91
+ await browser.scripting.updateContentScripts([
92
+ {
93
+ ...contentScript,
94
+ id,
95
+ css: contentScript.css ?? []
96
+ }
97
+ ]);
92
98
  } else {
93
99
  logger.debug("Registering new content script...");
94
- await browser.scripting.registerContentScripts([{ ...contentScript, id }]);
100
+ await browser.scripting.registerContentScripts([
101
+ {
102
+ ...contentScript,
103
+ id,
104
+ css: contentScript.css ?? []
105
+ }
106
+ ]);
95
107
  }
96
108
  await reloadTabsForContentScript(contentScript);
97
109
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "wxt",
3
3
  "type": "module",
4
- "version": "0.20.7",
4
+ "version": "0.20.9",
5
5
  "description": "⚡ Next-gen Web Extension Framework",
6
6
  "license": "MIT",
7
7
  "dependencies": {
@@ -18,12 +18,12 @@
18
18
  "ci-info": "^4.2.0",
19
19
  "consola": "^3.4.2",
20
20
  "defu": "^6.1.4",
21
- "dotenv": "^16.5.0",
21
+ "dotenv": "^17.2.2",
22
22
  "dotenv-expand": "^12.0.2",
23
23
  "esbuild": "^0.25.0",
24
24
  "fast-glob": "^3.3.3",
25
25
  "filesize": "^10.1.6",
26
- "fs-extra": "^11.3.0",
26
+ "fs-extra": "^11.3.1",
27
27
  "get-port-please": "^3.1.2",
28
28
  "giget": "^1.2.3 || ^2.0.0",
29
29
  "hookable": "^5.5.3",
@@ -34,7 +34,7 @@
34
34
  "linkedom": "^0.18.10",
35
35
  "magicast": "^0.3.5",
36
36
  "minimatch": "^10.0.1",
37
- "nano-spawn": "^0.2.0",
37
+ "nano-spawn": "^1.0.2",
38
38
  "normalize-path": "^3.0.0",
39
39
  "nypm": "^0.6.0",
40
40
  "ohash": "^2.0.11",
@@ -46,27 +46,27 @@
46
46
  "publish-browser-extension": "^2.3.0 || ^3.0.0",
47
47
  "scule": "^1.3.0",
48
48
  "unimport": "^3.13.1 || ^4.0.0 || ^5.0.0",
49
- "vite": "^5.4.19 || ^6.3.4",
49
+ "vite": "^5.4.19 || ^6.3.4 || ^7.0.0",
50
50
  "vite-node": "^2.1.4 || ^3.1.2",
51
51
  "web-ext-run": "^0.2.3",
52
- "@wxt-dev/browser": "^0.0.326"
52
+ "@wxt-dev/browser": "^0.1.4"
53
53
  },
54
54
  "devDependencies": {
55
- "@aklinker1/check": "2.0.0",
56
- "@faker-js/faker": "^9.7.0",
55
+ "@aklinker1/check": "^2.1.0",
56
+ "@faker-js/faker": "^10.0.0",
57
57
  "@types/fs-extra": "^11.0.4",
58
58
  "@types/lodash.merge": "^4.6.9",
59
59
  "@types/node": "^20.17.6",
60
60
  "@types/normalize-path": "^3.0.2",
61
61
  "@types/prompts": "^2.4.9",
62
62
  "extract-zip": "^2.0.1",
63
- "happy-dom": "^17.4.6",
63
+ "happy-dom": "^18.0.1",
64
64
  "lodash.merge": "^4.6.2",
65
- "oxlint": "^0.16.8",
65
+ "oxlint": "^1.14.0",
66
66
  "publint": "^0.3.12",
67
- "typescript": "^5.8.3",
68
- "unbuild": "^3.5.0",
69
- "vitest": "^3.1.2",
67
+ "typescript": "^5.9.2",
68
+ "unbuild": "^3.6.1",
69
+ "vitest": "^3.2.4",
70
70
  "vitest-plugin-random-seed": "^1.1.1"
71
71
  },
72
72
  "peerDependenciesMeta": {},
@@ -187,7 +187,7 @@
187
187
  "check:default": "check",
188
188
  "check:tsc-virtual": "tsc --noEmit -p src/virtual",
189
189
  "test": "buildc --deps-only -- vitest",
190
- "test:coverage": "pnpm test -- run --coverage",
190
+ "test:coverage": "pnpm test run --coverage",
191
191
  "sync-releases": "pnpx changelogen@latest gh release"
192
192
  }
193
193
  }
@@ -1,20 +0,0 @@
1
- import type * as vite from 'vite';
2
- import { Entrypoint, ResolvedConfig } from '../../../../types';
3
- /**
4
- * Ensures the HTML files output by a multipage build are in the correct location. This does two
5
- * things:
6
- *
7
- * 1. Moves the HMTL files to their final location at `<outDir>/<entrypoint.name>.html`.
8
- * 2. Updates the bundle so it summarizes the files correctly in the returned build output.
9
- *
10
- * Assets (JS and CSS) are output to the `<outDir>/assets` directory, and don't need to be modified.
11
- * HTML files access them via absolute URLs, so we don't need to update any import paths in the HTML
12
- * files either.
13
- *
14
- * THIS PLUGIN SHOULD ONLY BE APPLIED TO MULTIPAGE BUILDS. It should not be added to every build.
15
- */
16
- export declare function multipageMove(entrypoints: Entrypoint[], config: ResolvedConfig): vite.Plugin;
17
- /**
18
- * Recursively remove all directories that are empty/
19
- */
20
- export declare function removeEmptyDirs(dir: string): Promise<void>;
@@ -1,59 +0,0 @@
1
- import { dirname, extname, resolve, join } from "node:path";
2
- import { getEntrypointBundlePath } from "../../../utils/entrypoints.mjs";
3
- import fs, { ensureDir } from "fs-extra";
4
- import { normalizePath } from "../../../utils/paths.mjs";
5
- export function multipageMove(entrypoints, config) {
6
- return {
7
- name: "wxt:multipage-move",
8
- async writeBundle(_, bundle) {
9
- for (const oldBundlePath in bundle) {
10
- const entrypoint = entrypoints.find(
11
- (entry) => !!normalizePath(entry.inputPath).endsWith(oldBundlePath)
12
- );
13
- if (entrypoint == null) {
14
- config.logger.debug(
15
- `No entrypoint found for ${oldBundlePath}, leaving in chunks directory`
16
- );
17
- continue;
18
- }
19
- const newBundlePath = getEntrypointBundlePath(
20
- entrypoint,
21
- config.outDir,
22
- extname(oldBundlePath)
23
- );
24
- if (newBundlePath === oldBundlePath) {
25
- config.logger.debug(
26
- "HTML file is already in the correct location",
27
- oldBundlePath
28
- );
29
- continue;
30
- }
31
- const oldAbsPath = resolve(config.outDir, oldBundlePath);
32
- const newAbsPath = resolve(config.outDir, newBundlePath);
33
- await ensureDir(dirname(newAbsPath));
34
- await fs.move(oldAbsPath, newAbsPath, { overwrite: true });
35
- const renamedChunk = {
36
- ...bundle[oldBundlePath],
37
- fileName: newBundlePath
38
- };
39
- delete bundle[oldBundlePath];
40
- bundle[newBundlePath] = renamedChunk;
41
- }
42
- removeEmptyDirs(config.outDir);
43
- }
44
- };
45
- }
46
- export async function removeEmptyDirs(dir) {
47
- const files = await fs.readdir(dir);
48
- for (const file of files) {
49
- const filePath = join(dir, file);
50
- const stats = await fs.stat(filePath);
51
- if (stats.isDirectory()) {
52
- await removeEmptyDirs(filePath);
53
- }
54
- }
55
- try {
56
- await fs.rmdir(dir);
57
- } catch {
58
- }
59
- }