wxt 0.21.0 → 0.21.2
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/README.md +0 -1
- package/bin/wxt-publish-extension.mjs +4 -3
- package/dist/browser.d.mts +7 -6
- package/dist/browser.mjs +6 -5
- package/dist/builtin-modules/favicon-permission.mjs +28 -0
- package/dist/builtin-modules/index.mjs +3 -4
- package/dist/builtin-modules/unimport.mjs +1 -3
- package/dist/cli/cli-utils.mjs +8 -9
- package/dist/cli/commands.mjs +1 -3
- package/dist/cli/index.mjs +1 -3
- package/dist/core/build.d.mts +9 -8
- package/dist/core/build.mjs +10 -11
- package/dist/core/builders/vite/index.mjs +123 -75
- package/dist/core/builders/vite/plugins/bundleAnalysis.mjs +1 -3
- package/dist/core/builders/vite/plugins/cssEntrypoints.mjs +6 -6
- package/dist/core/builders/vite/plugins/defineImportMeta.mjs +3 -4
- package/dist/core/builders/vite/plugins/devHtmlPrerender.mjs +34 -26
- package/dist/core/builders/vite/plugins/devServerGlobals.mjs +3 -3
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +2 -6
- package/dist/core/builders/vite/plugins/extensionApiMock.mjs +13 -8
- package/dist/core/builders/vite/plugins/globals.mjs +1 -3
- package/dist/core/builders/vite/plugins/iifeAnonymous.mjs +1 -2
- package/dist/core/builders/vite/plugins/iifeFooter.mjs +14 -7
- package/dist/core/builders/vite/plugins/index.mjs +17 -19
- package/dist/core/builders/vite/plugins/noopBackground.mjs +14 -9
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.mjs +10 -12
- package/dist/core/builders/vite/plugins/resolveAppConfig.mjs +14 -10
- package/dist/core/builders/vite/plugins/resolveVirtualModules.mjs +15 -13
- package/dist/core/builders/vite/plugins/tsconfigPaths.mjs +1 -2
- package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +22 -17
- package/dist/core/clean.d.mts +3 -14
- package/dist/core/clean.mjs +19 -13
- package/dist/core/create-server.d.mts +6 -5
- package/dist/core/create-server.mjs +21 -117
- package/dist/core/define-config.mjs +1 -2
- package/dist/core/define-web-ext-config.d.mts +3 -6
- package/dist/core/define-web-ext-config.mjs +3 -12
- package/dist/core/generate-wxt-dir.mjs +53 -35
- package/dist/core/index.d.mts +3 -2
- package/dist/core/index.mjs +11 -11
- package/dist/core/initialize.mjs +28 -29
- package/dist/core/keyboard-shortcuts.mjs +4 -8
- package/dist/core/package-managers/bun.mjs +1 -3
- package/dist/core/package-managers/deno.mjs +1 -2
- package/dist/core/package-managers/index.mjs +1 -3
- package/dist/core/package-managers/npm.mjs +3 -5
- package/dist/core/package-managers/pnpm.mjs +1 -3
- package/dist/core/package-managers/yarn.mjs +1 -3
- package/dist/core/prepare.mjs +1 -3
- package/dist/core/resolve-config.mjs +63 -43
- package/dist/core/runners/manual.mjs +2 -6
- package/dist/core/runners/safari.mjs +3 -4
- package/dist/core/runners/web-ext.mjs +8 -11
- package/dist/core/runners/wsl.mjs +3 -4
- package/dist/core/utils/arrays.mjs +4 -11
- package/dist/core/utils/building/build-entrypoints.mjs +10 -11
- package/dist/core/utils/building/detect-dev-changes.mjs +37 -19
- package/dist/core/utils/building/find-entrypoints.mjs +40 -21
- package/dist/core/utils/building/group-entrypoints.mjs +3 -4
- package/dist/core/utils/building/index.mjs +7 -8
- package/dist/core/utils/building/internal-build.mjs +21 -21
- package/dist/core/utils/building/rebuild.mjs +10 -10
- package/dist/core/utils/cache.mjs +6 -8
- package/dist/core/utils/constants.mjs +3 -4
- package/dist/core/utils/content-scripts.mjs +3 -4
- package/dist/core/utils/content-security-policy.mjs +2 -5
- package/dist/core/utils/create-file-reloader.mjs +158 -0
- package/dist/core/utils/entrypoints.d.mts +10 -0
- package/dist/core/utils/entrypoints.mjs +6 -10
- package/dist/core/utils/env.mjs +24 -19
- package/dist/core/utils/environments/browser-environment.mjs +1 -3
- package/dist/core/utils/environments/environment.mjs +1 -2
- package/dist/core/utils/environments/extension-environment.mjs +1 -3
- package/dist/core/utils/environments/index.mjs +3 -4
- package/dist/core/utils/eslint.mjs +1 -2
- package/dist/core/utils/fs.mjs +23 -14
- package/dist/core/utils/globals.mjs +1 -2
- package/dist/core/utils/i18n.mjs +2 -3
- package/dist/core/utils/index.d.mts +2 -0
- package/dist/core/utils/index.mjs +3 -3
- package/dist/core/utils/log/index.mjs +5 -6
- package/dist/core/utils/log/printBuildSummary.mjs +1 -3
- package/dist/core/utils/log/printFileList.mjs +25 -21
- package/dist/core/utils/log/printHeader.mjs +3 -5
- package/dist/core/utils/log/printTable.mjs +1 -2
- package/dist/core/utils/manifest.mjs +39 -46
- package/dist/core/utils/number.mjs +1 -2
- package/dist/core/utils/package.mjs +3 -5
- package/dist/core/utils/paths.d.mts +2 -2
- package/dist/core/utils/paths.mjs +7 -9
- package/dist/core/utils/strings.mjs +4 -7
- package/dist/core/utils/syntax-errors.mjs +3 -5
- package/dist/core/utils/theme-icons.mjs +71 -0
- package/dist/core/utils/time.mjs +1 -13
- package/dist/core/utils/transform.mjs +9 -7
- package/dist/core/utils/validation.mjs +1 -2
- package/dist/core/utils/virtual-modules.mjs +9 -15
- package/dist/core/wxt.mjs +11 -12
- package/dist/core/zip.d.mts +1 -0
- package/dist/core/zip.mjs +25 -20
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +3 -3
- package/dist/modules.d.mts +64 -61
- package/dist/modules.mjs +70 -66
- package/dist/testing/fake-browser.mjs +1 -2
- package/dist/testing/wxt-vitest-plugin.d.mts +4 -2
- package/dist/testing/wxt-vitest-plugin.mjs +5 -7
- package/dist/types.d.mts +636 -450
- package/dist/utils/app-config.d.mts +1 -0
- package/dist/utils/app-config.mjs +3 -3
- package/dist/utils/content-script-context.d.mts +49 -39
- package/dist/utils/content-script-context.mjs +37 -32
- package/dist/utils/content-script-ui/iframe.d.mts +14 -15
- package/dist/utils/content-script-ui/iframe.mjs +1 -3
- package/dist/utils/content-script-ui/integrated.d.mts +8 -7
- package/dist/utils/content-script-ui/integrated.mjs +1 -3
- package/dist/utils/content-script-ui/shadow-root.d.mts +37 -25
- package/dist/utils/content-script-ui/shadow-root.mjs +5 -8
- package/dist/utils/content-script-ui/shared.mjs +1 -3
- package/dist/utils/content-script-ui/types.d.mts +29 -34
- package/dist/utils/content-script-ui/types.mjs +1 -1
- package/dist/utils/define-app-config.d.mts +4 -3
- package/dist/utils/define-app-config.mjs +5 -5
- package/dist/utils/define-background.mjs +1 -2
- package/dist/utils/define-content-script.mjs +1 -2
- package/dist/utils/define-unlisted-script.mjs +1 -2
- package/dist/utils/define-wxt-plugin.mjs +1 -2
- package/dist/utils/inject-script.d.mts +2 -2
- package/dist/utils/inject-script.mjs +4 -5
- package/dist/utils/internal/custom-events.mjs +3 -4
- package/dist/utils/internal/location-watcher.mjs +4 -6
- package/dist/utils/internal/logger.mjs +2 -5
- package/dist/utils/match-patterns.mjs +2 -3
- package/dist/utils/split-shadow-root-css.d.mts +6 -2
- package/dist/utils/split-shadow-root-css.mjs +7 -4
- package/dist/utils/storage.mjs +2 -3
- package/dist/version.mjs +2 -3
- package/dist/virtual/background-entrypoint.mjs +4 -16
- package/dist/virtual/content-script-isolated-world-entrypoint.mjs +2 -7
- package/dist/virtual/content-script-main-world-entrypoint.mjs +2 -7
- package/dist/virtual/mock-browser.d.mts +1 -1
- package/dist/virtual/mock-browser.mjs +2 -4
- package/dist/virtual/reload-html.mjs +3 -10
- package/dist/virtual/unlisted-script-entrypoint.mjs +2 -7
- package/package.json +55 -49
- package/LICENSE +0 -21
- package/dist/core/builders/vite/plugins/download.mjs +0 -25
- package/dist/core/runners/index.mjs +0 -17
- package/dist/core/utils/minimatch-multiple.mjs +0 -28
- package/dist/core/utils/network.mjs +0 -38
- package/dist/core/utils/wsl.mjs +0 -12
- package/dist/testing/index.d.mts +0 -3
- package/dist/testing/index.mjs +0 -4
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { parseHTML } from "linkedom";
|
|
2
|
-
|
|
3
2
|
//#region src/core/utils/environments/browser-environment.ts
|
|
4
3
|
function getBrowserEnvironmentGlobals() {
|
|
5
4
|
const { window, document, global } = parseHTML(`
|
|
@@ -15,6 +14,5 @@ function getBrowserEnvironmentGlobals() {
|
|
|
15
14
|
self: global
|
|
16
15
|
};
|
|
17
16
|
}
|
|
18
|
-
|
|
19
17
|
//#endregion
|
|
20
|
-
export { getBrowserEnvironmentGlobals };
|
|
18
|
+
export { getBrowserEnvironmentGlobals };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createEnvironment } from "./environment.mjs";
|
|
2
2
|
import { getBrowserEnvironmentGlobals } from "./browser-environment.mjs";
|
|
3
3
|
import { fakeBrowser } from "@webext-core/fake-browser";
|
|
4
|
-
|
|
5
4
|
//#region src/core/utils/environments/extension-environment.ts
|
|
6
5
|
function createExtensionEnvironment() {
|
|
7
6
|
return createEnvironment(getExtensionEnvironmentGlobals);
|
|
@@ -13,6 +12,5 @@ function getExtensionEnvironmentGlobals() {
|
|
|
13
12
|
browser: fakeBrowser
|
|
14
13
|
};
|
|
15
14
|
}
|
|
16
|
-
|
|
17
15
|
//#endregion
|
|
18
|
-
export { createExtensionEnvironment, getExtensionEnvironmentGlobals };
|
|
16
|
+
export { createExtensionEnvironment, getExtensionEnvironmentGlobals };
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export { };
|
|
1
|
+
import "./browser-environment.mjs";
|
|
2
|
+
import "./extension-environment.mjs";
|
|
3
|
+
export {};
|
package/dist/core/utils/fs.mjs
CHANGED
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import { unnormalizePath } from "./paths.mjs";
|
|
2
2
|
import { wxt } from "../wxt.mjs";
|
|
3
|
-
import
|
|
4
|
-
import glob from "
|
|
5
|
-
|
|
3
|
+
import { access, readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { glob } from "tinyglobby";
|
|
6
5
|
//#region src/core/utils/fs.ts
|
|
6
|
+
async function pathExists(path) {
|
|
7
|
+
try {
|
|
8
|
+
await access(path);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function readJson(path) {
|
|
15
|
+
return JSON.parse(await readFile(path, "utf-8"));
|
|
16
|
+
}
|
|
7
17
|
/**
|
|
8
|
-
* Only write the contents to a file if it results in a change. This prevents
|
|
9
|
-
* watchers from being triggered, like WXT's dev server or the
|
|
18
|
+
* Only write the contents to a file if it results in a change. This prevents
|
|
19
|
+
* unnecessary file watchers from being triggered, like WXT's dev server or the
|
|
20
|
+
* TS language server in editors.
|
|
10
21
|
*
|
|
11
22
|
* @param file The file to write to.
|
|
12
23
|
* @param newContents The new text content to write.
|
|
13
24
|
*/
|
|
14
25
|
async function writeFileIfDifferent(file, newContents) {
|
|
15
|
-
if (await
|
|
26
|
+
if (await readFile(file, "utf-8").catch(() => void 0) !== newContents) await writeFile(file, newContents);
|
|
16
27
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Get all the files in the project's public directory. Returned paths are relative to the
|
|
19
|
-
* `config.publicDir`.
|
|
20
|
-
*/
|
|
21
28
|
async function getPublicFiles() {
|
|
22
|
-
if (!await
|
|
23
|
-
return (await glob("**/*", {
|
|
29
|
+
if (!await pathExists(wxt.config.publicDir)) return [];
|
|
30
|
+
return (await glob("**/*", {
|
|
31
|
+
cwd: wxt.config.publicDir,
|
|
32
|
+
expandDirectories: false
|
|
33
|
+
})).map(unnormalizePath);
|
|
24
34
|
}
|
|
25
|
-
|
|
26
35
|
//#endregion
|
|
27
|
-
export { getPublicFiles, writeFileIfDifferent };
|
|
36
|
+
export { getPublicFiles, pathExists, readJson, writeFileIfDifferent };
|
package/dist/core/utils/i18n.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const predefinedMessages = {
|
|
3
3
|
"@@extension_id": {
|
|
4
4
|
message: "<browser.runtime.id>",
|
|
5
|
-
description: "The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even
|
|
5
|
+
description: "The extension or app ID; you might use this string to construct URLs for resources inside the extension. Even non-localized extensions can use this message.\nNote: You can't use this message in a manifest file."
|
|
6
6
|
},
|
|
7
7
|
"@@ui_locale": {
|
|
8
8
|
message: "<browser.i18n.getUiLocale()>",
|
|
@@ -39,6 +39,5 @@ function parseI18nMessages(messagesJson) {
|
|
|
39
39
|
...details
|
|
40
40
|
}));
|
|
41
41
|
}
|
|
42
|
-
|
|
43
42
|
//#endregion
|
|
44
|
-
export { parseI18nMessages };
|
|
43
|
+
export { parseI18nMessages };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export {
|
|
1
|
+
import "./paths.mjs";
|
|
2
|
+
import "./entrypoints.mjs";
|
|
3
|
+
export {};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
export { };
|
|
1
|
+
import "./printTable.mjs";
|
|
2
|
+
import "./printFileList.mjs";
|
|
3
|
+
import "./printBuildSummary.mjs";
|
|
4
|
+
import "./printHeader.mjs";
|
|
5
|
+
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { wxt } from "../../wxt.mjs";
|
|
2
2
|
import { printFileList } from "./printFileList.mjs";
|
|
3
3
|
import { resolve } from "path";
|
|
4
|
-
|
|
5
4
|
//#region src/core/utils/log/printBuildSummary.ts
|
|
6
5
|
async function printBuildSummary(log, header, output) {
|
|
7
6
|
const files = [...output.steps.flatMap((step) => step.chunks), ...output.publicAssets].sort((l, r) => {
|
|
@@ -22,6 +21,5 @@ const CHUNK_SORT_WEIGHTS = {
|
|
|
22
21
|
function getChunkSortWeight(filename) {
|
|
23
22
|
return Object.entries(CHUNK_SORT_WEIGHTS).find(([key]) => filename.endsWith(key))?.[1] ?? DEFAULT_SORT_WEIGHT;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
24
|
//#endregion
|
|
27
|
-
export { printBuildSummary };
|
|
25
|
+
export { printBuildSummary };
|
|
@@ -1,39 +1,43 @@
|
|
|
1
|
+
import { wxt } from "../../wxt.mjs";
|
|
1
2
|
import { printTable } from "./printTable.mjs";
|
|
2
|
-
import
|
|
3
|
+
import { lstat } from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
4
|
-
import
|
|
5
|
+
import { styleText } from "node:util";
|
|
5
6
|
import { filesize } from "filesize";
|
|
6
|
-
|
|
7
7
|
//#region src/core/utils/log/printFileList.ts
|
|
8
8
|
async function printFileList(log, header, baseDir, files) {
|
|
9
9
|
let totalSize = 0;
|
|
10
10
|
const fileRows = await Promise.all(files.map(async (file, i) => {
|
|
11
11
|
const parts = [path.relative(process.cwd(), baseDir) + path.sep, path.relative(baseDir, file)];
|
|
12
12
|
const prefix = i === files.length - 1 ? " └─" : " ├─";
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const chunkColor = getChunkColor(file);
|
|
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
|
+
}
|
|
22
|
+
return [`${styleText("gray", prefix)} ${styleText("dim", parts[0])}${styleText(chunkColor, parts[1])}`, styleText("dim", size)];
|
|
18
23
|
}));
|
|
19
|
-
fileRows.push([`${
|
|
24
|
+
fileRows.push([`${styleText("cyan", "Σ Total size:")} ${String(filesize(totalSize))}`]);
|
|
20
25
|
printTable(log, header, fileRows);
|
|
21
26
|
}
|
|
22
|
-
const DEFAULT_COLOR =
|
|
27
|
+
const DEFAULT_COLOR = "blue";
|
|
23
28
|
const CHUNK_COLORS = {
|
|
24
|
-
".js.map":
|
|
25
|
-
".cjs.map":
|
|
26
|
-
".mjs.map":
|
|
27
|
-
".html":
|
|
28
|
-
".css":
|
|
29
|
-
".js":
|
|
30
|
-
".cjs":
|
|
31
|
-
".mjs":
|
|
32
|
-
".zip":
|
|
29
|
+
".js.map": "gray",
|
|
30
|
+
".cjs.map": "gray",
|
|
31
|
+
".mjs.map": "gray",
|
|
32
|
+
".html": "green",
|
|
33
|
+
".css": "magenta",
|
|
34
|
+
".js": "cyan",
|
|
35
|
+
".cjs": "cyan",
|
|
36
|
+
".mjs": "cyan",
|
|
37
|
+
".zip": "yellow"
|
|
33
38
|
};
|
|
34
39
|
function getChunkColor(filename) {
|
|
35
40
|
return Object.entries(CHUNK_COLORS).find(([key]) => filename.endsWith(key))?.[1] ?? DEFAULT_COLOR;
|
|
36
41
|
}
|
|
37
|
-
|
|
38
42
|
//#endregion
|
|
39
|
-
export { printFileList };
|
|
43
|
+
export { printFileList };
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { version } from "../../../version.mjs";
|
|
2
2
|
import { consola as consola$1 } from "consola";
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import { styleText } from "node:util";
|
|
5
4
|
//#region src/core/utils/log/printHeader.ts
|
|
6
5
|
function printHeader() {
|
|
7
|
-
consola$1.log(`\n${
|
|
6
|
+
consola$1.log(`\n${styleText("gray", "WXT")} ${styleText(["bold", "gray"], version)}`);
|
|
8
7
|
}
|
|
9
|
-
|
|
10
8
|
//#endregion
|
|
11
|
-
export { printHeader };
|
|
9
|
+
export { printHeader };
|
|
@@ -5,26 +5,22 @@ import { writeFileIfDifferent } from "./fs.mjs";
|
|
|
5
5
|
import { ContentSecurityPolicy } from "./content-security-policy.mjs";
|
|
6
6
|
import { hashContentScriptOptions, mapWxtOptionsToContentScript } from "./content-scripts.mjs";
|
|
7
7
|
import { getPackageJson } from "./package.mjs";
|
|
8
|
-
import
|
|
8
|
+
import { addDiscoveredThemeIcons } from "./theme-icons.mjs";
|
|
9
|
+
import { mkdir } from "node:fs/promises";
|
|
9
10
|
import { resolve } from "path";
|
|
10
11
|
import defu from "defu";
|
|
11
|
-
|
|
12
12
|
//#region src/core/utils/manifest.ts
|
|
13
|
-
/**
|
|
14
|
-
* Writes the manifest to the output directory and the build output.
|
|
15
|
-
*/
|
|
13
|
+
/** Writes the manifest to the output directory and the build output. */
|
|
16
14
|
async function writeManifest(manifest, output) {
|
|
17
15
|
const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
|
|
18
|
-
await
|
|
16
|
+
await mkdir(wxt.config.outDir, { recursive: true });
|
|
19
17
|
await writeFileIfDifferent(resolve(wxt.config.outDir, "manifest.json"), str);
|
|
20
18
|
output.publicAssets.unshift({
|
|
21
19
|
type: "asset",
|
|
22
20
|
fileName: "manifest.json"
|
|
23
21
|
});
|
|
24
22
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Generates the manifest based on the config and entrypoints.
|
|
27
|
-
*/
|
|
23
|
+
/** Generates the manifest based on the config and entrypoints. */
|
|
28
24
|
async function generateManifest(allEntrypoints, buildOutput) {
|
|
29
25
|
const entrypoints = allEntrypoints.filter((entry) => !entry.skipped);
|
|
30
26
|
const warnings = [];
|
|
@@ -59,7 +55,10 @@ async function generateManifest(allEntrypoints, buildOutput) {
|
|
|
59
55
|
}
|
|
60
56
|
manifest.version = version;
|
|
61
57
|
manifest.version_name = wxt.config.browser === "firefox" || versionName === version ? void 0 : versionName;
|
|
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");
|
|
62
60
|
addEntrypoints(manifest, entrypoints, buildOutput);
|
|
61
|
+
if (wxt.config.browser === "firefox") addDiscoveredThemeIcons(manifest, buildOutput);
|
|
63
62
|
if (wxt.config.command === "serve") addDevModeCsp(manifest);
|
|
64
63
|
if (wxt.config.command === "serve") addDevModePermissions(manifest);
|
|
65
64
|
await wxt.hooks.callHook("build:manifestGenerated", wxt, manifest);
|
|
@@ -79,8 +78,9 @@ async function generateManifest(allEntrypoints, buildOutput) {
|
|
|
79
78
|
};
|
|
80
79
|
}
|
|
81
80
|
/**
|
|
82
|
-
* Removes suffixes from the version, like X.Y.Z-alpha1 (which browsers don't
|
|
83
|
-
* simple version number, like X or X.Y or X.Y.Z, which
|
|
81
|
+
* Removes suffixes from the version, like X.Y.Z-alpha1 (which browsers don't
|
|
82
|
+
* allow), so it's a simple version number, like X or X.Y or X.Y.Z, which
|
|
83
|
+
* browsers allow.
|
|
84
84
|
*/
|
|
85
85
|
function simplifyVersion(versionName) {
|
|
86
86
|
const version = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(versionName)?.[1];
|
|
@@ -137,28 +137,22 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
|
|
|
137
137
|
const options = {};
|
|
138
138
|
if (popup.options.defaultIcon) options.default_icon = popup.options.defaultIcon;
|
|
139
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;
|
|
140
141
|
if (popup.options.browserStyle) options.browser_style = popup.options.browserStyle;
|
|
141
142
|
if (popup.options.defaultArea) options.default_area = popup.options.defaultArea;
|
|
142
143
|
if (popup.options.themeIcons) options.theme_icons = popup.options.themeIcons;
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
const actionKey = wxt.config.manifestVersion === 2 ? popup.options.actionType ?? "browser_action" : wxt.config.browser === "firefox" && popup.options.actionType === "page_action" ? "page_action" : "action";
|
|
145
|
+
manifest[actionKey] = {
|
|
146
|
+
...manifest[actionKey],
|
|
145
147
|
...options,
|
|
146
148
|
default_popup
|
|
147
149
|
};
|
|
148
|
-
else {
|
|
149
|
-
const key = popup.options.mv2Key ?? "browser_action";
|
|
150
|
-
manifest[key] = {
|
|
151
|
-
...manifest[key],
|
|
152
|
-
...options,
|
|
153
|
-
default_popup
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
150
|
}
|
|
157
151
|
if (devtools) manifest.devtools_page = getEntrypointBundlePath(devtools, wxt.config.outDir, ".html");
|
|
158
152
|
if (options) {
|
|
159
153
|
const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
|
|
160
154
|
manifest.options_ui = {
|
|
161
|
-
open_in_tab: options.options.openInTab,
|
|
155
|
+
...wxt.config.browser !== "safari" && { open_in_tab: options.options.openInTab ?? false },
|
|
162
156
|
browser_style: wxt.config.browser === "firefox" ? options.options.browserStyle : void 0,
|
|
163
157
|
chrome_style: wxt.config.browser !== "firefox" ? options.options.chromeStyle : void 0,
|
|
164
158
|
page
|
|
@@ -247,9 +241,9 @@ function addDevModeCsp(manifest) {
|
|
|
247
241
|
}
|
|
248
242
|
const permission = `${permissionUrl}*`;
|
|
249
243
|
const allowedCsp = wxt.server?.origin ?? "http://localhost:*";
|
|
250
|
-
if (
|
|
244
|
+
if (wxt.config.manifestVersion === 3) addHostPermission(manifest, permission);
|
|
251
245
|
else addPermission(manifest, permission);
|
|
252
|
-
const extensionPagesCsp = new ContentSecurityPolicy(manifest.content_security_policy?.extension_pages ?? (
|
|
246
|
+
const extensionPagesCsp = new ContentSecurityPolicy(manifest.content_security_policy?.extension_pages ?? (wxt.config.manifestVersion === 3 ? DEFAULT_MV3_EXTENSION_PAGES_CSP : DEFAULT_MV2_CSP));
|
|
253
247
|
const sandboxCsp = new ContentSecurityPolicy(manifest.content_security_policy?.sandbox ?? DEFAULT_MV3_SANDBOX_CSP);
|
|
254
248
|
if (wxt.config.command === "serve") {
|
|
255
249
|
extensionPagesCsp.add("script-src", allowedCsp);
|
|
@@ -264,8 +258,8 @@ function addDevModePermissions(manifest) {
|
|
|
264
258
|
if (wxt.config.manifestVersion === 3) addPermission(manifest, "scripting");
|
|
265
259
|
}
|
|
266
260
|
/**
|
|
267
|
-
* Returns the bundle paths to CSS files associated with a list of content
|
|
268
|
-
* there is no associated CSS.
|
|
261
|
+
* Returns the bundle paths to CSS files associated with a list of content
|
|
262
|
+
* scripts, or undefined if there is no associated CSS.
|
|
269
263
|
*/
|
|
270
264
|
function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
|
|
271
265
|
const css = [];
|
|
@@ -278,9 +272,9 @@ function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
|
|
|
278
272
|
if (css.length > 0) return css;
|
|
279
273
|
}
|
|
280
274
|
/**
|
|
281
|
-
* Content scripts configured with `cssInjectionMode: "ui"` need to add their
|
|
282
|
-
* accessible resources so they can be fetched as text and
|
|
283
|
-
* added to.
|
|
275
|
+
* Content scripts configured with `cssInjectionMode: "ui"` need to add their
|
|
276
|
+
* CSS files to web accessible resources so they can be fetched as text and
|
|
277
|
+
* added to shadow roots that the UI is added to.
|
|
284
278
|
*/
|
|
285
279
|
function getContentScriptCssWebAccessibleResources(contentScripts, contentScriptCssMap) {
|
|
286
280
|
const resources = [];
|
|
@@ -297,8 +291,8 @@ function getContentScriptCssWebAccessibleResources(contentScripts, contentScript
|
|
|
297
291
|
return resources;
|
|
298
292
|
}
|
|
299
293
|
/**
|
|
300
|
-
* Based on the build output, return a Record of each content script's name to
|
|
301
|
-
* script includes one.
|
|
294
|
+
* Based on the build output, return a Record of each content script's name to
|
|
295
|
+
* it CSS file if the script includes one.
|
|
302
296
|
*/
|
|
303
297
|
function getContentScriptsCssMap(buildOutput, scripts) {
|
|
304
298
|
const map = {};
|
|
@@ -320,8 +314,8 @@ function addHostPermission(manifest, hostPermission) {
|
|
|
320
314
|
manifest.host_permissions.push(hostPermission);
|
|
321
315
|
}
|
|
322
316
|
/**
|
|
323
|
-
* - "<all_urls>"
|
|
324
|
-
* - "
|
|
317
|
+
* - "<all_urls>" → "<all_urls>"
|
|
318
|
+
* - "_://play.google.com/books/_" → "_://play.google.com/_"
|
|
325
319
|
*/
|
|
326
320
|
function stripPathFromMatchPattern(pattern) {
|
|
327
321
|
const protocolSepIndex = pattern.indexOf("://");
|
|
@@ -330,9 +324,10 @@ function stripPathFromMatchPattern(pattern) {
|
|
|
330
324
|
return pattern.substring(0, startOfPath) + "/*";
|
|
331
325
|
}
|
|
332
326
|
/**
|
|
333
|
-
* Converts all MV3 web accessible resources to their MV2 forms. MV3 web
|
|
334
|
-
* generated in this file, and may be defined by the
|
|
335
|
-
*
|
|
327
|
+
* Converts all MV3 web accessible resources to their MV2 forms. MV3 web
|
|
328
|
+
* accessible resources are generated in this file, and may be defined by the
|
|
329
|
+
* user in their manifest. In both cases, when targeting MV2, automatically
|
|
330
|
+
* convert their definitions down to the basic MV2 array.
|
|
336
331
|
*/
|
|
337
332
|
function convertWebAccessibleResourcesToMv2(manifest) {
|
|
338
333
|
if (manifest.web_accessible_resources == null) return;
|
|
@@ -354,29 +349,27 @@ function convertCspToMv2(manifest) {
|
|
|
354
349
|
if (typeof manifest.content_security_policy === "string" || manifest.content_security_policy?.extension_pages == null) return;
|
|
355
350
|
manifest.content_security_policy = manifest.content_security_policy.extension_pages;
|
|
356
351
|
}
|
|
357
|
-
/**
|
|
358
|
-
* Make sure all resources are in MV3 format. If not, add a warning.
|
|
359
|
-
*/
|
|
352
|
+
/** Make sure all resources are in MV3 format. If not, add a warning. */
|
|
360
353
|
function validateMv3WebAccessibleResources(manifest) {
|
|
361
354
|
if (manifest.web_accessible_resources == null) return;
|
|
362
355
|
const stringResources = manifest.web_accessible_resources.filter((item) => typeof item === "string");
|
|
363
356
|
if (stringResources.length > 0) throw Error(`Non-MV3 web_accessible_resources detected: ${JSON.stringify(stringResources)}. When manually defining web_accessible_resources, define them as MV3 objects ({ matches: [...], resources: [...] }), and WXT will automatically convert them to MV2 when necessary.`);
|
|
364
357
|
}
|
|
365
|
-
/**
|
|
366
|
-
* Remove keys from the manifest based on the build target.
|
|
367
|
-
*/
|
|
358
|
+
/** Remove keys from the manifest based on the build target. */
|
|
368
359
|
function stripKeys(manifest) {
|
|
369
360
|
let keysToRemove = [];
|
|
370
361
|
if (wxt.config.manifestVersion === 2) {
|
|
371
362
|
keysToRemove.push(...mv3OnlyKeys);
|
|
372
363
|
if (wxt.config.browser === "firefox") keysToRemove.push(...firefoxMv3OnlyKeys);
|
|
373
|
-
} else
|
|
364
|
+
} else {
|
|
365
|
+
keysToRemove.push(...mv2OnlyKeys);
|
|
366
|
+
if (wxt.config.browser !== "firefox") keysToRemove.push(...chromeMv2OnlyKeys);
|
|
367
|
+
}
|
|
374
368
|
keysToRemove.forEach((key) => {
|
|
375
369
|
delete manifest[key];
|
|
376
370
|
});
|
|
377
371
|
}
|
|
378
372
|
const mv2OnlyKeys = [
|
|
379
|
-
"page_action",
|
|
380
373
|
"browser_action",
|
|
381
374
|
"automation",
|
|
382
375
|
"content_capabilities",
|
|
@@ -400,10 +393,10 @@ const mv3OnlyKeys = [
|
|
|
400
393
|
"optional_host_permissions",
|
|
401
394
|
"side_panel"
|
|
402
395
|
];
|
|
396
|
+
const chromeMv2OnlyKeys = ["page_action"];
|
|
403
397
|
const firefoxMv3OnlyKeys = ["host_permissions"];
|
|
404
398
|
const DEFAULT_MV3_EXTENSION_PAGES_CSP = "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';";
|
|
405
399
|
const DEFAULT_MV3_SANDBOX_CSP = "sandbox allow-scripts allow-forms allow-popups allow-modals; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';";
|
|
406
400
|
const DEFAULT_MV2_CSP = "script-src 'self'; object-src 'self';";
|
|
407
|
-
|
|
408
401
|
//#endregion
|
|
409
|
-
export { generateManifest, getContentScriptCssFiles, getContentScriptsCssMap, writeManifest };
|
|
402
|
+
export { generateManifest, getContentScriptCssFiles, getContentScriptsCssMap, writeManifest };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { wxt } from "../wxt.mjs";
|
|
2
|
-
import
|
|
2
|
+
import { readJson } from "./fs.mjs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
-
|
|
5
4
|
//#region src/core/utils/package.ts
|
|
6
5
|
/**
|
|
7
6
|
* Read the project's package.json.
|
|
@@ -11,12 +10,11 @@ import { resolve } from "node:path";
|
|
|
11
10
|
async function getPackageJson() {
|
|
12
11
|
const file = resolve(wxt.config.root, "package.json");
|
|
13
12
|
try {
|
|
14
|
-
return await
|
|
13
|
+
return await readJson(file);
|
|
15
14
|
} catch (err) {
|
|
16
15
|
wxt.logger.debug(`Failed to read package.json at: ${file}. Returning undefined.`, err);
|
|
17
16
|
return {};
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
|
-
|
|
21
19
|
//#endregion
|
|
22
|
-
export { getPackageJson };
|
|
20
|
+
export { getPackageJson };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/core/utils/paths.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Converts system paths to normalized bundler path.
|
|
4
|
-
*
|
|
3
|
+
* Converts system paths to normalized bundler path. On Windows, this returns
|
|
4
|
+
* paths with `/` instead of `\`.
|
|
5
5
|
*/
|
|
6
6
|
declare function normalizePath(path: string): string;
|
|
7
7
|
//#endregion
|
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import normalize from "normalize-path";
|
|
3
|
-
|
|
4
3
|
//#region src/core/utils/paths.ts
|
|
5
4
|
/**
|
|
6
|
-
* Converts system paths to normalized bundler path.
|
|
7
|
-
*
|
|
5
|
+
* Converts system paths to normalized bundler path. On Windows, this returns
|
|
6
|
+
* paths with `/` instead of `\`.
|
|
8
7
|
*/
|
|
9
8
|
function normalizePath(path) {
|
|
10
9
|
return normalize(path);
|
|
11
10
|
}
|
|
12
11
|
/**
|
|
13
|
-
* Given a normalized path, convert it to the system path style. On Windows,
|
|
12
|
+
* Given a normalized path, convert it to the system path style. On Windows,
|
|
13
|
+
* switch to , otherwise use /.
|
|
14
14
|
*/
|
|
15
15
|
function unnormalizePath(path$1) {
|
|
16
16
|
return path.normalize(path$1);
|
|
17
17
|
}
|
|
18
|
-
const
|
|
18
|
+
const CSS_EXTENSIONS_PATTERN = `+(${[
|
|
19
19
|
"css",
|
|
20
20
|
"scss",
|
|
21
21
|
"sass",
|
|
22
22
|
"less",
|
|
23
23
|
"styl",
|
|
24
24
|
"stylus"
|
|
25
|
-
]
|
|
26
|
-
const CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
|
|
27
|
-
|
|
25
|
+
].join("|")})`;
|
|
28
26
|
//#endregion
|
|
29
|
-
export { CSS_EXTENSIONS_PATTERN, normalizePath, unnormalizePath };
|
|
27
|
+
export { CSS_EXTENSIONS_PATTERN, normalizePath, unnormalizePath };
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { camelCase } from "scule";
|
|
2
|
-
|
|
3
2
|
//#region src/core/utils/strings.ts
|
|
4
3
|
function kebabCaseAlphanumeric(str) {
|
|
5
4
|
return str.toLowerCase().replace(/[^a-z0-9-\s]/g, "").replace(/\s+/g, "-");
|
|
6
5
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Return a safe variable name for a given string.
|
|
9
|
-
*/
|
|
6
|
+
/** Return a safe variable name for a given string. */
|
|
10
7
|
function safeVarName(str) {
|
|
11
8
|
const name = camelCase(kebabCaseAlphanumeric(str));
|
|
12
9
|
if (name.match(/^[a-z]/)) return name;
|
|
13
10
|
return "_" + name;
|
|
14
11
|
}
|
|
15
12
|
/**
|
|
16
|
-
* Converts a string to a valid filename (NOT path), stripping out invalid
|
|
13
|
+
* Converts a string to a valid filename (NOT path), stripping out invalid
|
|
14
|
+
* characters.
|
|
17
15
|
*/
|
|
18
16
|
function safeFilename(str) {
|
|
19
17
|
return kebabCaseAlphanumeric(str);
|
|
20
18
|
}
|
|
21
|
-
|
|
22
19
|
//#endregion
|
|
23
|
-
export { safeFilename, safeVarName };
|
|
20
|
+
export { safeFilename, safeVarName };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { wxt } from "../wxt.mjs";
|
|
2
2
|
import { relative } from "node:path";
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
import { styleText } from "node:util";
|
|
5
4
|
//#region src/core/utils/syntax-errors.ts
|
|
6
5
|
function isBabelSyntaxError(error) {
|
|
7
6
|
return error instanceof SyntaxError && error.code === "BABEL_PARSER_SYNTAX_ERROR";
|
|
@@ -10,9 +9,8 @@ function logBabelSyntaxError(error) {
|
|
|
10
9
|
let filename = relative(wxt.config.root, error.id);
|
|
11
10
|
if (filename.startsWith("..")) filename = error.id;
|
|
12
11
|
let message = error.message.replace(/\(\d+:\d+\)$/, `(${filename}:${error.loc.line}:${error.loc.column + 1})`);
|
|
13
|
-
if (error.frame) message += "\n\n" +
|
|
12
|
+
if (error.frame) message += "\n\n" + styleText("red", error.frame);
|
|
14
13
|
wxt.logger.error(message);
|
|
15
14
|
}
|
|
16
|
-
|
|
17
15
|
//#endregion
|
|
18
|
-
export { isBabelSyntaxError, logBabelSyntaxError };
|
|
16
|
+
export { isBabelSyntaxError, logBabelSyntaxError };
|