wxt 0.20.13 → 0.20.14
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/browser.d.mts +20 -0
- package/dist/browser.mjs +18 -3
- package/dist/builtin-modules/index.mjs +7 -2
- package/dist/builtin-modules/unimport.mjs +69 -75
- package/dist/cli/cli-utils.mjs +52 -50
- package/dist/cli/commands.mjs +77 -103
- package/dist/cli/index.d.mts +1 -0
- package/dist/cli/index.mjs +9 -4
- package/dist/core/{build.d.ts → build.d.mts} +6 -2
- package/dist/core/build.mjs +23 -4
- package/dist/core/builders/vite/index.mjs +292 -343
- package/dist/core/builders/vite/plugins/bundleAnalysis.mjs +11 -12
- package/dist/core/builders/vite/plugins/cssEntrypoints.mjs +27 -20
- package/dist/core/builders/vite/plugins/defineImportMeta.mjs +17 -12
- package/dist/core/builders/vite/plugins/devHtmlPrerender.mjs +104 -136
- package/dist/core/builders/vite/plugins/devServerGlobals.mjs +15 -14
- package/dist/core/builders/vite/plugins/download.mjs +23 -12
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +18 -14
- package/dist/core/builders/vite/plugins/extensionApiMock.mjs +31 -33
- package/dist/core/builders/vite/plugins/globals.mjs +14 -13
- package/dist/core/builders/vite/plugins/iifeFooter.mjs +17 -11
- package/dist/core/builders/vite/plugins/index.mjs +18 -16
- package/dist/core/builders/vite/plugins/noopBackground.mjs +21 -15
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.mjs +25 -23
- package/dist/core/builders/vite/plugins/resolveAppConfig.mjs +25 -23
- package/dist/core/builders/vite/plugins/resolveVirtualModules.mjs +27 -26
- package/dist/core/builders/vite/plugins/tsconfigPaths.mjs +11 -11
- package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +41 -47
- package/dist/core/{clean.d.ts → clean.d.mts} +7 -3
- package/dist/core/clean.mjs +38 -35
- package/dist/core/{create-server.d.ts → create-server.d.mts} +6 -2
- package/dist/core/create-server.mjs +236 -247
- package/dist/core/define-config.d.mts +6 -0
- package/dist/core/define-config.mjs +6 -2
- package/dist/core/define-web-ext-config.d.mts +13 -0
- package/dist/core/define-web-ext-config.mjs +16 -7
- package/dist/core/generate-wxt-dir.mjs +109 -148
- package/dist/core/index.d.mts +8 -0
- package/dist/core/index.mjs +10 -8
- package/dist/core/initialize.d.mts +8 -0
- package/dist/core/initialize.mjs +110 -124
- package/dist/core/keyboard-shortcuts.mjs +30 -28
- package/dist/core/package-managers/bun.mjs +18 -16
- package/dist/core/package-managers/deno.mjs +12 -8
- package/dist/core/package-managers/index.mjs +52 -60
- package/dist/core/package-managers/npm.mjs +51 -52
- package/dist/core/package-managers/pnpm.mjs +21 -18
- package/dist/core/package-managers/yarn.mjs +31 -28
- package/dist/core/prepare.d.mts +6 -0
- package/dist/core/prepare.mjs +12 -7
- package/dist/core/resolve-config.mjs +393 -462
- package/dist/core/runners/index.mjs +11 -6
- package/dist/core/runners/manual.mjs +16 -14
- package/dist/core/runners/safari.mjs +16 -14
- package/dist/core/runners/web-ext.mjs +62 -83
- package/dist/core/runners/wsl.mjs +16 -14
- package/dist/core/utils/arrays.mjs +23 -12
- package/dist/core/utils/building/build-entrypoints.mjs +44 -40
- package/dist/core/utils/building/detect-dev-changes.mjs +84 -105
- package/dist/core/utils/building/find-entrypoints.mjs +275 -359
- package/dist/core/utils/building/group-entrypoints.mjs +42 -35
- package/dist/core/utils/building/index.mjs +8 -6
- package/dist/core/utils/building/internal-build.mjs +87 -102
- package/dist/core/utils/building/rebuild.mjs +50 -30
- package/dist/core/utils/cache.mjs +29 -18
- package/dist/core/utils/constants.mjs +9 -1
- package/dist/core/utils/content-scripts.mjs +56 -54
- package/dist/core/utils/content-security-policy.mjs +36 -39
- package/dist/core/utils/entrypoints.mjs +51 -28
- package/dist/core/utils/env.mjs +22 -17
- package/dist/core/utils/environments/browser-environment.mjs +13 -12
- package/dist/core/utils/environments/environment.mjs +36 -33
- package/dist/core/utils/environments/extension-environment.mjs +15 -10
- package/dist/core/utils/environments/index.mjs +4 -2
- package/dist/core/utils/eslint.mjs +11 -10
- package/dist/core/utils/fs.mjs +23 -11
- package/dist/core/utils/globals.mjs +53 -51
- package/dist/core/utils/i18n.mjs +41 -32
- package/dist/core/utils/log/index.mjs +6 -4
- package/dist/core/utils/log/printBuildSummary.mjs +20 -25
- package/dist/core/utils/log/printFileList.mjs +30 -33
- package/dist/core/utils/log/printHeader.mjs +10 -5
- package/dist/core/utils/log/printTable.mjs +19 -21
- package/dist/core/utils/manifest.mjs +364 -479
- package/dist/core/utils/minimatch-multiple.mjs +26 -15
- package/dist/core/utils/network.mjs +30 -33
- package/dist/core/utils/number.mjs +7 -3
- package/dist/core/utils/package.mjs +20 -13
- package/dist/core/utils/paths.mjs +26 -7
- package/dist/core/utils/strings.mjs +19 -14
- package/dist/core/utils/syntax-errors.mjs +14 -16
- package/dist/core/utils/time.mjs +19 -15
- package/dist/core/utils/transform.mjs +129 -160
- package/dist/core/utils/types.d.mts +6 -0
- package/dist/core/utils/validation.mjs +43 -50
- package/dist/core/utils/virtual-modules.mjs +20 -12
- package/dist/core/utils/wsl.mjs +10 -3
- package/dist/core/wxt.mjs +66 -60
- package/dist/core/{zip.d.ts → zip.d.mts} +6 -2
- package/dist/core/zip.mjs +116 -140
- package/dist/index.d.mts +12 -0
- package/dist/index.mjs +12 -3
- package/dist/{modules.d.ts → modules.d.mts} +14 -16
- package/dist/modules.mjs +181 -51
- package/dist/testing/fake-browser.d.mts +2 -0
- package/dist/testing/fake-browser.mjs +3 -1
- package/dist/testing/index.d.mts +3 -0
- package/dist/testing/index.mjs +4 -2
- package/dist/testing/{wxt-vitest-plugin.d.ts → wxt-vitest-plugin.d.mts} +7 -9
- package/dist/testing/wxt-vitest-plugin.mjs +38 -19
- package/dist/types.d.mts +1453 -0
- package/dist/utils/app-config.d.mts +6 -0
- package/dist/utils/app-config.mjs +8 -2
- package/dist/utils/content-script-context.d.mts +137 -0
- package/dist/utils/content-script-context.mjs +192 -175
- package/dist/utils/content-script-ui/iframe.d.mts +42 -0
- package/dist/utils/content-script-ui/iframe.mjs +42 -27
- package/dist/utils/content-script-ui/integrated.d.mts +37 -0
- package/dist/utils/content-script-ui/integrated.mjs +36 -29
- package/dist/utils/content-script-ui/shadow-root.d.mts +80 -0
- package/dist/utils/content-script-ui/shadow-root.mjs +75 -82
- package/dist/utils/content-script-ui/shared.mjs +117 -150
- package/dist/utils/content-script-ui/types.d.mts +107 -0
- package/dist/utils/content-script-ui/types.mjs +1 -0
- package/dist/utils/{define-app-config.d.ts → define-app-config.d.mts} +5 -3
- package/dist/utils/define-app-config.mjs +22 -2
- package/dist/utils/define-background.d.mts +7 -0
- package/dist/utils/define-background.mjs +7 -3
- package/dist/utils/define-content-script.d.mts +6 -0
- package/dist/utils/define-content-script.mjs +6 -2
- package/dist/utils/define-unlisted-script.d.mts +7 -0
- package/dist/utils/define-unlisted-script.mjs +7 -3
- package/dist/utils/define-wxt-plugin.d.mts +6 -0
- package/dist/utils/define-wxt-plugin.mjs +6 -2
- package/dist/utils/inject-script.d.mts +41 -0
- package/dist/utils/inject-script.mjs +44 -34
- package/dist/utils/internal/custom-events.d.mts +9 -0
- package/dist/utils/internal/custom-events.mjs +18 -10
- package/dist/utils/internal/location-watcher.mjs +23 -20
- package/dist/utils/internal/logger.mjs +15 -12
- package/dist/utils/match-patterns.d.mts +1 -0
- package/dist/utils/match-patterns.mjs +3 -1
- package/dist/utils/{split-shadow-root-css.d.ts → split-shadow-root-css.d.mts} +6 -3
- package/dist/utils/split-shadow-root-css.mjs +16 -7
- package/dist/utils/storage.d.mts +1 -0
- package/dist/utils/storage.mjs +3 -1
- package/dist/version.d.mts +4 -0
- package/dist/version.mjs +5 -1
- package/dist/virtual/background-entrypoint.d.mts +4 -0
- package/dist/virtual/background-entrypoint.mjs +146 -161
- package/dist/virtual/content-script-isolated-world-entrypoint.d.mts +4 -0
- package/dist/virtual/content-script-isolated-world-entrypoint.mjs +26 -27
- package/dist/virtual/content-script-main-world-entrypoint.d.mts +4 -0
- package/dist/virtual/content-script-main-world-entrypoint.mjs +24 -24
- package/dist/virtual/mock-browser.d.mts +6 -0
- package/dist/virtual/mock-browser.mjs +5 -3
- package/dist/virtual/reload-html.d.mts +1 -0
- package/dist/virtual/reload-html.mjs +60 -53
- package/dist/virtual/unlisted-script-entrypoint.d.mts +4 -0
- package/dist/virtual/unlisted-script-entrypoint.mjs +35 -43
- package/package.json +47 -49
- package/dist/browser.d.ts +0 -30
- package/dist/builtin-modules/index.d.ts +0 -2
- package/dist/builtin-modules/unimport.d.ts +0 -5
- package/dist/cli/cli-utils.d.ts +0 -25
- package/dist/cli/commands.d.ts +0 -2
- package/dist/cli/index.d.ts +0 -1
- package/dist/core/builders/vite/index.d.ts +0 -7
- package/dist/core/builders/vite/plugins/bundleAnalysis.d.ts +0 -7
- package/dist/core/builders/vite/plugins/cssEntrypoints.d.ts +0 -13
- package/dist/core/builders/vite/plugins/defineImportMeta.d.ts +0 -14
- package/dist/core/builders/vite/plugins/devHtmlPrerender.d.ts +0 -7
- package/dist/core/builders/vite/plugins/devServerGlobals.d.ts +0 -6
- package/dist/core/builders/vite/plugins/download.d.ts +0 -10
- package/dist/core/builders/vite/plugins/entrypointGroupGlobals.d.ts +0 -6
- package/dist/core/builders/vite/plugins/extensionApiMock.d.ts +0 -6
- package/dist/core/builders/vite/plugins/globals.d.ts +0 -3
- package/dist/core/builders/vite/plugins/iifeFooter.d.ts +0 -8
- package/dist/core/builders/vite/plugins/index.d.ts +0 -16
- package/dist/core/builders/vite/plugins/noopBackground.d.ts +0 -6
- package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.d.ts +0 -6
- package/dist/core/builders/vite/plugins/resolveAppConfig.d.ts +0 -6
- package/dist/core/builders/vite/plugins/resolveVirtualModules.d.ts +0 -6
- package/dist/core/builders/vite/plugins/tsconfigPaths.d.ts +0 -3
- package/dist/core/builders/vite/plugins/wxtPluginLoader.d.ts +0 -6
- package/dist/core/define-config.d.ts +0 -2
- package/dist/core/define-web-ext-config.d.ts +0 -9
- package/dist/core/generate-wxt-dir.d.ts +0 -5
- package/dist/core/index.d.ts +0 -8
- package/dist/core/initialize.d.ts +0 -5
- package/dist/core/keyboard-shortcuts.d.ts +0 -12
- package/dist/core/package-managers/bun.d.ts +0 -2
- package/dist/core/package-managers/deno.d.ts +0 -2
- package/dist/core/package-managers/index.d.ts +0 -2
- package/dist/core/package-managers/npm.d.ts +0 -17
- package/dist/core/package-managers/pnpm.d.ts +0 -2
- package/dist/core/package-managers/types.d.ts +0 -2
- package/dist/core/package-managers/types.mjs +0 -0
- package/dist/core/package-managers/yarn.d.ts +0 -2
- package/dist/core/prepare.d.ts +0 -2
- package/dist/core/resolve-config.d.ts +0 -11
- package/dist/core/runners/index.d.ts +0 -2
- package/dist/core/runners/manual.d.ts +0 -5
- package/dist/core/runners/safari.d.ts +0 -5
- package/dist/core/runners/web-ext.d.ts +0 -5
- package/dist/core/runners/wsl.d.ts +0 -5
- package/dist/core/utils/arrays.d.ts +0 -13
- package/dist/core/utils/building/build-entrypoints.d.ts +0 -3
- package/dist/core/utils/building/detect-dev-changes.d.ts +0 -61
- package/dist/core/utils/building/find-entrypoints.d.ts +0 -5
- package/dist/core/utils/building/group-entrypoints.d.ts +0 -8
- package/dist/core/utils/building/index.d.ts +0 -6
- package/dist/core/utils/building/internal-build.d.ts +0 -12
- package/dist/core/utils/building/rebuild.d.ts +0 -23
- package/dist/core/utils/cache.d.ts +0 -8
- package/dist/core/utils/cli.d.ts +0 -3
- package/dist/core/utils/cli.mjs +0 -26
- package/dist/core/utils/constants.d.ts +0 -5
- package/dist/core/utils/content-scripts.d.ts +0 -12
- package/dist/core/utils/content-security-policy.d.ts +0 -14
- package/dist/core/utils/entrypoints.d.ts +0 -31
- package/dist/core/utils/env.d.ts +0 -5
- package/dist/core/utils/environments/browser-environment.d.ts +0 -3
- package/dist/core/utils/environments/environment.d.ts +0 -8
- package/dist/core/utils/environments/extension-environment.d.ts +0 -6
- package/dist/core/utils/environments/index.d.ts +0 -2
- package/dist/core/utils/eslint.d.ts +0 -1
- package/dist/core/utils/fs.d.ts +0 -13
- package/dist/core/utils/globals.d.ts +0 -11
- package/dist/core/utils/i18n.d.ts +0 -11
- package/dist/core/utils/log/index.d.ts +0 -4
- package/dist/core/utils/log/printBuildSummary.d.ts +0 -2
- package/dist/core/utils/log/printFileList.d.ts +0 -1
- package/dist/core/utils/log/printHeader.d.ts +0 -1
- package/dist/core/utils/log/printTable.d.ts +0 -1
- package/dist/core/utils/manifest.d.ts +0 -40
- package/dist/core/utils/minimatch-multiple.d.ts +0 -15
- package/dist/core/utils/network.d.ts +0 -7
- package/dist/core/utils/number.d.ts +0 -1
- package/dist/core/utils/package.d.ts +0 -6
- package/dist/core/utils/paths.d.ts +0 -11
- package/dist/core/utils/strings.d.ts +0 -14
- package/dist/core/utils/syntax-errors.d.ts +0 -11
- package/dist/core/utils/testing/fake-objects.d.ts +0 -11665
- package/dist/core/utils/testing/fake-objects.mjs +0 -326
- package/dist/core/utils/time.d.ts +0 -9
- package/dist/core/utils/transform.d.ts +0 -11
- package/dist/core/utils/types.d.ts +0 -13
- package/dist/core/utils/types.mjs +0 -0
- package/dist/core/utils/validation.d.ts +0 -15
- package/dist/core/utils/virtual-modules.d.ts +0 -22
- package/dist/core/utils/wsl.d.ts +0 -4
- package/dist/core/wxt.d.ts +0 -24
- package/dist/index.d.ts +0 -11
- package/dist/testing/fake-browser.d.ts +0 -10
- package/dist/testing/index.d.ts +0 -10
- package/dist/types.d.ts +0 -1459
- package/dist/types.mjs +0 -0
- package/dist/utils/app-config.d.ts +0 -2
- package/dist/utils/content-script-context.d.ts +0 -134
- package/dist/utils/content-script-ui/iframe.d.ts +0 -32
- package/dist/utils/content-script-ui/integrated.d.ts +0 -34
- package/dist/utils/content-script-ui/shadow-root.d.ts +0 -76
- package/dist/utils/content-script-ui/shared.d.ts +0 -5
- package/dist/utils/content-script-ui/types.d.ts +0 -104
- package/dist/utils/define-background.d.ts +0 -4
- package/dist/utils/define-content-script.d.ts +0 -3
- package/dist/utils/define-unlisted-script.d.ts +0 -4
- package/dist/utils/define-wxt-plugin.d.ts +0 -3
- package/dist/utils/inject-script.d.ts +0 -36
- package/dist/utils/internal/custom-events.d.ts +0 -10
- package/dist/utils/internal/dev-server-websocket.d.ts +0 -21
- package/dist/utils/internal/dev-server-websocket.mjs +0 -37
- package/dist/utils/internal/location-watcher.d.ts +0 -12
- package/dist/utils/internal/logger.d.ts +0 -9
- package/dist/utils/match-patterns.d.ts +0 -5
- package/dist/utils/storage.d.ts +0 -5
- package/dist/version.d.ts +0 -1
|
@@ -1,522 +1,407 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { resolve } from "path";
|
|
1
|
+
import { normalizePath } from "./paths.mjs";
|
|
3
2
|
import { getEntrypointBundlePath } from "./entrypoints.mjs";
|
|
3
|
+
import { wxt } from "../wxt.mjs";
|
|
4
|
+
import { writeFileIfDifferent } from "./fs.mjs";
|
|
4
5
|
import { ContentSecurityPolicy } from "./content-security-policy.mjs";
|
|
5
|
-
import {
|
|
6
|
-
hashContentScriptOptions,
|
|
7
|
-
mapWxtOptionsToContentScript
|
|
8
|
-
} from "./content-scripts.mjs";
|
|
6
|
+
import { hashContentScriptOptions, mapWxtOptionsToContentScript } from "./content-scripts.mjs";
|
|
9
7
|
import { getPackageJson } from "./package.mjs";
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
8
|
+
import fs from "fs-extra";
|
|
9
|
+
import { resolve } from "path";
|
|
12
10
|
import defu from "defu";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
|
|
12
|
+
//#region src/core/utils/manifest.ts
|
|
13
|
+
/**
|
|
14
|
+
* Writes the manifest to the output directory and the build output.
|
|
15
|
+
*/
|
|
16
|
+
async function writeManifest(manifest, output) {
|
|
17
|
+
const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
|
|
18
|
+
await fs.ensureDir(wxt.config.outDir);
|
|
19
|
+
await writeFileIfDifferent(resolve(wxt.config.outDir, "manifest.json"), str);
|
|
20
|
+
output.publicAssets.unshift({
|
|
21
|
+
type: "asset",
|
|
22
|
+
fileName: "manifest.json"
|
|
23
|
+
});
|
|
22
24
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
convertWebAccessibleResourcesToMv2(manifest);
|
|
79
|
-
convertActionToMv2(manifest);
|
|
80
|
-
convertCspToMv2(manifest);
|
|
81
|
-
moveHostPermissionsToPermissions(manifest);
|
|
82
|
-
}
|
|
83
|
-
if (wxt.config.manifestVersion === 3) {
|
|
84
|
-
validateMv3WebAccessibleResources(manifest);
|
|
85
|
-
}
|
|
86
|
-
stripKeys(manifest);
|
|
87
|
-
if (manifest.name == null)
|
|
88
|
-
throw Error(
|
|
89
|
-
"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"
|
|
90
|
-
);
|
|
91
|
-
if (manifest.version == null) {
|
|
92
|
-
throw Error(
|
|
93
|
-
"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"
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
manifest,
|
|
98
|
-
warnings
|
|
99
|
-
};
|
|
25
|
+
/**
|
|
26
|
+
* Generates the manifest based on the config and entrypoints.
|
|
27
|
+
*/
|
|
28
|
+
async function generateManifest(allEntrypoints, buildOutput) {
|
|
29
|
+
const entrypoints = allEntrypoints.filter((entry) => !entry.skipped);
|
|
30
|
+
const warnings = [];
|
|
31
|
+
const pkg = await getPackageJson();
|
|
32
|
+
let versionName = wxt.config.manifest.version_name ?? wxt.config.manifest.version ?? pkg?.version;
|
|
33
|
+
if (versionName == null) {
|
|
34
|
+
versionName = "0.0.0";
|
|
35
|
+
wxt.logger.warn("Extension version not found, defaulting to \"0.0.0\". Add a version to your `package.json` or `wxt.config.ts` file. For more details, see: https://wxt.dev/guide/key-concepts/manifest.html#version-and-version-name");
|
|
36
|
+
}
|
|
37
|
+
const version = wxt.config.manifest.version ?? simplifyVersion(versionName);
|
|
38
|
+
const baseManifest = {
|
|
39
|
+
manifest_version: wxt.config.manifestVersion,
|
|
40
|
+
name: pkg?.name,
|
|
41
|
+
description: pkg?.description,
|
|
42
|
+
version,
|
|
43
|
+
short_name: pkg?.shortName,
|
|
44
|
+
icons: discoverIcons(buildOutput)
|
|
45
|
+
};
|
|
46
|
+
const userManifest = wxt.config.manifest;
|
|
47
|
+
if (userManifest.manifest_version) {
|
|
48
|
+
delete userManifest.manifest_version;
|
|
49
|
+
wxt.logger.warn("`manifest.manifest_version` config was set, but ignored. To change the target manifest version, use the `manifestVersion` option or the `--mv2`/`--mv3` CLI flags.\nSee https://wxt.dev/guide/essentials/target-different-browsers.html#target-a-manifest-version");
|
|
50
|
+
}
|
|
51
|
+
let manifest = defu(userManifest, baseManifest);
|
|
52
|
+
if (wxt.config.command === "serve" && wxt.config.dev.reloadCommand) if (manifest.commands && Object.values(manifest.commands).filter((command) => command.suggested_key).length >= 4) warnings.push(["Extension already has 4 registered commands with suggested keys, WXT's reload command is disabled"]);
|
|
53
|
+
else {
|
|
54
|
+
manifest.commands ??= {};
|
|
55
|
+
manifest.commands["wxt:reload-extension"] = {
|
|
56
|
+
description: "Reload the extension during development",
|
|
57
|
+
suggested_key: { default: wxt.config.dev.reloadCommand }
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
manifest.version = version;
|
|
61
|
+
manifest.version_name = wxt.config.browser === "firefox" || versionName === version ? void 0 : versionName;
|
|
62
|
+
addEntrypoints(manifest, entrypoints, buildOutput);
|
|
63
|
+
if (wxt.config.command === "serve") addDevModeCsp(manifest);
|
|
64
|
+
if (wxt.config.command === "serve") addDevModePermissions(manifest);
|
|
65
|
+
await wxt.hooks.callHook("build:manifestGenerated", wxt, manifest);
|
|
66
|
+
if (wxt.config.manifestVersion === 2) {
|
|
67
|
+
convertWebAccessibleResourcesToMv2(manifest);
|
|
68
|
+
convertActionToMv2(manifest);
|
|
69
|
+
convertCspToMv2(manifest);
|
|
70
|
+
moveHostPermissionsToPermissions(manifest);
|
|
71
|
+
}
|
|
72
|
+
if (wxt.config.manifestVersion === 3) validateMv3WebAccessibleResources(manifest);
|
|
73
|
+
stripKeys(manifest);
|
|
74
|
+
if (manifest.name == null) throw Error("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");
|
|
75
|
+
if (manifest.version == null) throw Error("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");
|
|
76
|
+
return {
|
|
77
|
+
manifest,
|
|
78
|
+
warnings
|
|
79
|
+
};
|
|
100
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Removes suffixes from the version, like X.Y.Z-alpha1 (which browsers don't allow), so it's a
|
|
83
|
+
* simple version number, like X or X.Y or X.Y.Z, which browsers allow.
|
|
84
|
+
*/
|
|
101
85
|
function simplifyVersion(versionName) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (version == null)
|
|
106
|
-
throw Error(
|
|
107
|
-
`Cannot simplify package.json version "${versionName}" to a valid extension version, "X.Y.Z"`
|
|
108
|
-
);
|
|
109
|
-
return version;
|
|
86
|
+
const version = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(versionName)?.[1];
|
|
87
|
+
if (version == null) throw Error(`Cannot simplify package.json version "${versionName}" to a valid extension version, "X.Y.Z"`);
|
|
88
|
+
return version;
|
|
110
89
|
}
|
|
111
90
|
function addEntrypoints(manifest, entrypoints, buildOutput) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
"Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
|
|
235
|
-
);
|
|
236
|
-
} else {
|
|
237
|
-
manifest.sandbox = {
|
|
238
|
-
pages: sandboxes.map(
|
|
239
|
-
(entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".html")
|
|
240
|
-
)
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
if (sidepanels?.length) {
|
|
245
|
-
const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
|
|
246
|
-
const page = getEntrypointBundlePath(
|
|
247
|
-
defaultSidepanel,
|
|
248
|
-
wxt.config.outDir,
|
|
249
|
-
".html"
|
|
250
|
-
);
|
|
251
|
-
if (wxt.config.browser === "firefox") {
|
|
252
|
-
manifest.sidebar_action = {
|
|
253
|
-
default_panel: page,
|
|
254
|
-
browser_style: defaultSidepanel.options.browserStyle,
|
|
255
|
-
default_icon: defaultSidepanel.options.defaultIcon,
|
|
256
|
-
default_title: defaultSidepanel.options.defaultTitle,
|
|
257
|
-
open_at_install: defaultSidepanel.options.openAtInstall
|
|
258
|
-
};
|
|
259
|
-
} else if (wxt.config.manifestVersion === 3) {
|
|
260
|
-
manifest.side_panel = {
|
|
261
|
-
default_path: page
|
|
262
|
-
};
|
|
263
|
-
addPermission(manifest, "sidePanel");
|
|
264
|
-
} else {
|
|
265
|
-
wxt.logger.warn(
|
|
266
|
-
"Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
if (contentScripts?.length) {
|
|
271
|
-
const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
|
|
272
|
-
if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
|
|
273
|
-
contentScripts.forEach((script) => {
|
|
274
|
-
script.options.matches?.forEach((matchPattern) => {
|
|
275
|
-
addHostPermission(manifest, matchPattern);
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
} else {
|
|
279
|
-
const hashToEntrypointsMap = contentScripts.filter((cs) => cs.options.registration !== "runtime").reduce((map, script) => {
|
|
280
|
-
const hash = hashContentScriptOptions(script.options);
|
|
281
|
-
if (map.has(hash)) map.get(hash)?.push(script);
|
|
282
|
-
else map.set(hash, [script]);
|
|
283
|
-
return map;
|
|
284
|
-
}, /* @__PURE__ */ new Map());
|
|
285
|
-
const manifestContentScripts = Array.from(
|
|
286
|
-
hashToEntrypointsMap.values()
|
|
287
|
-
).map(
|
|
288
|
-
(scripts) => mapWxtOptionsToContentScript(
|
|
289
|
-
scripts[0].options,
|
|
290
|
-
scripts.map(
|
|
291
|
-
(entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")
|
|
292
|
-
),
|
|
293
|
-
getContentScriptCssFiles(scripts, cssMap)
|
|
294
|
-
)
|
|
295
|
-
);
|
|
296
|
-
if (manifestContentScripts.length >= 0) {
|
|
297
|
-
manifest.content_scripts ??= [];
|
|
298
|
-
manifest.content_scripts.push(...manifestContentScripts);
|
|
299
|
-
}
|
|
300
|
-
const runtimeContentScripts = contentScripts.filter(
|
|
301
|
-
(cs) => cs.options.registration === "runtime"
|
|
302
|
-
);
|
|
303
|
-
runtimeContentScripts.forEach((script) => {
|
|
304
|
-
script.options.matches?.forEach((matchPattern) => {
|
|
305
|
-
addHostPermission(manifest, matchPattern);
|
|
306
|
-
});
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
const contentScriptCssResources = getContentScriptCssWebAccessibleResources(
|
|
310
|
-
contentScripts,
|
|
311
|
-
cssMap
|
|
312
|
-
);
|
|
313
|
-
if (contentScriptCssResources.length > 0) {
|
|
314
|
-
manifest.web_accessible_resources ??= [];
|
|
315
|
-
manifest.web_accessible_resources.push(...contentScriptCssResources);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
91
|
+
const entriesByType = entrypoints.reduce((map, entrypoint) => {
|
|
92
|
+
map[entrypoint.type] ??= [];
|
|
93
|
+
map[entrypoint.type]?.push(entrypoint);
|
|
94
|
+
return map;
|
|
95
|
+
}, {});
|
|
96
|
+
const background = entriesByType["background"]?.[0];
|
|
97
|
+
const bookmarks = entriesByType["bookmarks"]?.[0];
|
|
98
|
+
const contentScripts = entriesByType["content-script"];
|
|
99
|
+
const devtools = entriesByType["devtools"]?.[0];
|
|
100
|
+
const history = entriesByType["history"]?.[0];
|
|
101
|
+
const newtab = entriesByType["newtab"]?.[0];
|
|
102
|
+
const options = entriesByType["options"]?.[0];
|
|
103
|
+
const popup = entriesByType["popup"]?.[0];
|
|
104
|
+
const sandboxes = entriesByType["sandbox"];
|
|
105
|
+
const sidepanels = entriesByType["sidepanel"];
|
|
106
|
+
if (background) {
|
|
107
|
+
const script = getEntrypointBundlePath(background, wxt.config.outDir, ".js");
|
|
108
|
+
if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) manifest.background = {
|
|
109
|
+
type: background.options.type,
|
|
110
|
+
scripts: [script]
|
|
111
|
+
};
|
|
112
|
+
else if (wxt.config.manifestVersion === 3) manifest.background = {
|
|
113
|
+
type: background.options.type,
|
|
114
|
+
service_worker: script
|
|
115
|
+
};
|
|
116
|
+
else manifest.background = {
|
|
117
|
+
persistent: background.options.persistent,
|
|
118
|
+
scripts: [script]
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (bookmarks) if (wxt.config.browser === "firefox") wxt.logger.warn("Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest");
|
|
122
|
+
else {
|
|
123
|
+
manifest.chrome_url_overrides ??= {};
|
|
124
|
+
manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(bookmarks, wxt.config.outDir, ".html");
|
|
125
|
+
}
|
|
126
|
+
if (history) if (wxt.config.browser === "firefox") wxt.logger.warn("Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest");
|
|
127
|
+
else {
|
|
128
|
+
manifest.chrome_url_overrides ??= {};
|
|
129
|
+
manifest.chrome_url_overrides.history = getEntrypointBundlePath(history, wxt.config.outDir, ".html");
|
|
130
|
+
}
|
|
131
|
+
if (newtab) {
|
|
132
|
+
manifest.chrome_url_overrides ??= {};
|
|
133
|
+
manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(newtab, wxt.config.outDir, ".html");
|
|
134
|
+
}
|
|
135
|
+
if (popup) {
|
|
136
|
+
const default_popup = getEntrypointBundlePath(popup, wxt.config.outDir, ".html");
|
|
137
|
+
const options = {};
|
|
138
|
+
if (popup.options.defaultIcon) options.default_icon = popup.options.defaultIcon;
|
|
139
|
+
if (popup.options.defaultTitle) options.default_title = popup.options.defaultTitle;
|
|
140
|
+
if (popup.options.browserStyle) options.browser_style = popup.options.browserStyle;
|
|
141
|
+
if (manifest.manifest_version === 3) manifest.action = {
|
|
142
|
+
...manifest.action,
|
|
143
|
+
...options,
|
|
144
|
+
default_popup
|
|
145
|
+
};
|
|
146
|
+
else {
|
|
147
|
+
const key = popup.options.mv2Key ?? "browser_action";
|
|
148
|
+
manifest[key] = {
|
|
149
|
+
...manifest[key],
|
|
150
|
+
...options,
|
|
151
|
+
default_popup
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (devtools) manifest.devtools_page = getEntrypointBundlePath(devtools, wxt.config.outDir, ".html");
|
|
156
|
+
if (options) {
|
|
157
|
+
const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
|
|
158
|
+
manifest.options_ui = {
|
|
159
|
+
open_in_tab: options.options.openInTab,
|
|
160
|
+
browser_style: wxt.config.browser === "firefox" ? options.options.browserStyle : void 0,
|
|
161
|
+
chrome_style: wxt.config.browser !== "firefox" ? options.options.chromeStyle : void 0,
|
|
162
|
+
page
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
if (sandboxes?.length) if (wxt.config.browser === "firefox") wxt.logger.warn("Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest");
|
|
166
|
+
else manifest.sandbox = { pages: sandboxes.map((entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".html")) };
|
|
167
|
+
if (sidepanels?.length) {
|
|
168
|
+
const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
|
|
169
|
+
const page = getEntrypointBundlePath(defaultSidepanel, wxt.config.outDir, ".html");
|
|
170
|
+
if (wxt.config.browser === "firefox") manifest.sidebar_action = {
|
|
171
|
+
default_panel: page,
|
|
172
|
+
browser_style: defaultSidepanel.options.browserStyle,
|
|
173
|
+
default_icon: defaultSidepanel.options.defaultIcon,
|
|
174
|
+
default_title: defaultSidepanel.options.defaultTitle,
|
|
175
|
+
open_at_install: defaultSidepanel.options.openAtInstall
|
|
176
|
+
};
|
|
177
|
+
else if (wxt.config.manifestVersion === 3) {
|
|
178
|
+
manifest.side_panel = { default_path: page };
|
|
179
|
+
addPermission(manifest, "sidePanel");
|
|
180
|
+
} else wxt.logger.warn("Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest");
|
|
181
|
+
}
|
|
182
|
+
if (contentScripts?.length) {
|
|
183
|
+
const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
|
|
184
|
+
if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) contentScripts.forEach((script) => {
|
|
185
|
+
script.options.matches?.forEach((matchPattern) => {
|
|
186
|
+
addHostPermission(manifest, matchPattern);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
else {
|
|
190
|
+
const hashToEntrypointsMap = contentScripts.filter((cs) => cs.options.registration !== "runtime").reduce((map, script) => {
|
|
191
|
+
const hash = hashContentScriptOptions(script.options);
|
|
192
|
+
if (map.has(hash)) map.get(hash)?.push(script);
|
|
193
|
+
else map.set(hash, [script]);
|
|
194
|
+
return map;
|
|
195
|
+
}, /* @__PURE__ */ new Map());
|
|
196
|
+
const manifestContentScripts = Array.from(hashToEntrypointsMap.values()).map((scripts) => mapWxtOptionsToContentScript(scripts[0].options, scripts.map((entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")), getContentScriptCssFiles(scripts, cssMap)));
|
|
197
|
+
if (manifestContentScripts.length >= 0) {
|
|
198
|
+
manifest.content_scripts ??= [];
|
|
199
|
+
manifest.content_scripts.push(...manifestContentScripts);
|
|
200
|
+
}
|
|
201
|
+
contentScripts.filter((cs) => cs.options.registration === "runtime").forEach((script) => {
|
|
202
|
+
script.options.matches?.forEach((matchPattern) => {
|
|
203
|
+
addHostPermission(manifest, matchPattern);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
const contentScriptCssResources = getContentScriptCssWebAccessibleResources(contentScripts, cssMap);
|
|
208
|
+
if (contentScriptCssResources.length > 0) {
|
|
209
|
+
manifest.web_accessible_resources ??= [];
|
|
210
|
+
manifest.web_accessible_resources.push(...contentScriptCssResources);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
318
213
|
}
|
|
319
214
|
function discoverIcons(buildOutput) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
break;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
if (size == null) return;
|
|
347
|
-
icons.push([size, normalizePath(asset.fileName)]);
|
|
348
|
-
});
|
|
349
|
-
return icons.length > 0 ? Object.fromEntries(icons) : void 0;
|
|
215
|
+
const icons = [];
|
|
216
|
+
const iconRegex = [
|
|
217
|
+
/^icon-([0-9]+)\.png$/,
|
|
218
|
+
/^icon-([0-9]+)x[0-9]+\.png$/,
|
|
219
|
+
/^icon@([0-9]+)w\.png$/,
|
|
220
|
+
/^icon@([0-9]+)h\.png$/,
|
|
221
|
+
/^icon@([0-9]+)\.png$/,
|
|
222
|
+
/^icons?[/\\]([0-9]+)\.png$/,
|
|
223
|
+
/^icons?[/\\]([0-9]+)x[0-9]+\.png$/
|
|
224
|
+
];
|
|
225
|
+
buildOutput.publicAssets.forEach((asset) => {
|
|
226
|
+
let size;
|
|
227
|
+
for (const regex of iconRegex) {
|
|
228
|
+
const match = asset.fileName.match(regex);
|
|
229
|
+
if (match?.[1] != null) {
|
|
230
|
+
size = match[1];
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (size == null) return;
|
|
235
|
+
icons.push([size, normalizePath(asset.fileName)]);
|
|
236
|
+
});
|
|
237
|
+
return icons.length > 0 ? Object.fromEntries(icons) : void 0;
|
|
350
238
|
}
|
|
351
239
|
function addDevModeCsp(manifest) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
manifest.content_security_policy?.sandbox ?? DEFAULT_MV3_SANDBOX_CSP
|
|
372
|
-
);
|
|
373
|
-
if (wxt.config.command === "serve") {
|
|
374
|
-
extensionPagesCsp.add("script-src", allowedCsp);
|
|
375
|
-
sandboxCsp.add("script-src", allowedCsp);
|
|
376
|
-
}
|
|
377
|
-
manifest.content_security_policy ??= {};
|
|
378
|
-
manifest.content_security_policy.extension_pages = extensionPagesCsp.toString();
|
|
379
|
-
manifest.content_security_policy.sandbox = sandboxCsp.toString();
|
|
240
|
+
let permissonUrl = wxt.server?.origin;
|
|
241
|
+
if (permissonUrl) {
|
|
242
|
+
const permissionUrlInstance = new URL(permissonUrl);
|
|
243
|
+
permissionUrlInstance.port = "";
|
|
244
|
+
permissonUrl = permissionUrlInstance.toString();
|
|
245
|
+
}
|
|
246
|
+
const permission = `${permissonUrl}*`;
|
|
247
|
+
const allowedCsp = wxt.server?.origin ?? "http://localhost:*";
|
|
248
|
+
if (manifest.manifest_version === 3) addHostPermission(manifest, permission);
|
|
249
|
+
else addPermission(manifest, permission);
|
|
250
|
+
const extensionPagesCsp = new ContentSecurityPolicy(manifest.content_security_policy?.extension_pages ?? (manifest.manifest_version === 3 ? DEFAULT_MV3_EXTENSION_PAGES_CSP : DEFAULT_MV2_CSP));
|
|
251
|
+
const sandboxCsp = new ContentSecurityPolicy(manifest.content_security_policy?.sandbox ?? DEFAULT_MV3_SANDBOX_CSP);
|
|
252
|
+
if (wxt.config.command === "serve") {
|
|
253
|
+
extensionPagesCsp.add("script-src", allowedCsp);
|
|
254
|
+
sandboxCsp.add("script-src", allowedCsp);
|
|
255
|
+
}
|
|
256
|
+
manifest.content_security_policy ??= {};
|
|
257
|
+
manifest.content_security_policy.extension_pages = extensionPagesCsp.toString();
|
|
258
|
+
manifest.content_security_policy.sandbox = sandboxCsp.toString();
|
|
380
259
|
}
|
|
381
260
|
function addDevModePermissions(manifest) {
|
|
382
|
-
|
|
383
|
-
|
|
261
|
+
addPermission(manifest, "tabs");
|
|
262
|
+
if (wxt.config.manifestVersion === 3) addPermission(manifest, "scripting");
|
|
384
263
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
264
|
+
/**
|
|
265
|
+
* Returns the bundle paths to CSS files associated with a list of content scripts, or undefined if
|
|
266
|
+
* there is no associated CSS.
|
|
267
|
+
*/
|
|
268
|
+
function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
|
|
269
|
+
const css = [];
|
|
270
|
+
contentScripts.forEach((script) => {
|
|
271
|
+
if (script.options.cssInjectionMode === "manual" || script.options.cssInjectionMode === "ui") return;
|
|
272
|
+
const cssFile = contentScriptCssMap[script.name];
|
|
273
|
+
if (cssFile == null) return;
|
|
274
|
+
if (cssFile) css.push(cssFile);
|
|
275
|
+
});
|
|
276
|
+
if (css.length > 0) return css;
|
|
396
277
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
278
|
+
/**
|
|
279
|
+
* Content scripts configured with `cssInjectionMode: "ui"` need to add their CSS files to web
|
|
280
|
+
* accessible resources so they can be fetched as text and added to shadow roots that the UI is
|
|
281
|
+
* added to.
|
|
282
|
+
*/
|
|
283
|
+
function getContentScriptCssWebAccessibleResources(contentScripts, contentScriptCssMap) {
|
|
284
|
+
const resources = [];
|
|
285
|
+
contentScripts.forEach((script) => {
|
|
286
|
+
if (script.options.cssInjectionMode !== "ui") return;
|
|
287
|
+
const cssFile = contentScriptCssMap[script.name];
|
|
288
|
+
if (cssFile == null) return;
|
|
289
|
+
resources.push({
|
|
290
|
+
resources: [cssFile],
|
|
291
|
+
use_dynamic_url: true,
|
|
292
|
+
matches: script.options.matches?.map((matchPattern) => stripPathFromMatchPattern(matchPattern)) ?? []
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
return resources;
|
|
412
296
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
297
|
+
/**
|
|
298
|
+
* Based on the build output, return a Record of each content script's name to it CSS file if the
|
|
299
|
+
* script includes one.
|
|
300
|
+
*/
|
|
301
|
+
function getContentScriptsCssMap(buildOutput, scripts) {
|
|
302
|
+
const map = {};
|
|
303
|
+
const allChunks = buildOutput.steps.flatMap((step) => step.chunks);
|
|
304
|
+
scripts.forEach((script) => {
|
|
305
|
+
const relatedCss = allChunks.find((chunk) => chunk.fileName === `content-scripts/${script.name}.css`);
|
|
306
|
+
if (relatedCss != null) map[script.name] = relatedCss.fileName;
|
|
307
|
+
});
|
|
308
|
+
return map;
|
|
423
309
|
}
|
|
424
310
|
function addPermission(manifest, permission) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
311
|
+
manifest.permissions ??= [];
|
|
312
|
+
if (manifest.permissions.includes(permission)) return;
|
|
313
|
+
manifest.permissions.push(permission);
|
|
428
314
|
}
|
|
429
315
|
function addHostPermission(manifest, hostPermission) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
316
|
+
manifest.host_permissions ??= [];
|
|
317
|
+
if (manifest.host_permissions.includes(hostPermission)) return;
|
|
318
|
+
manifest.host_permissions.push(hostPermission);
|
|
433
319
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
320
|
+
/**
|
|
321
|
+
* - "<all_urls>" → "<all_urls>"
|
|
322
|
+
* - "*://play.google.com/books/*" → "*://play.google.com/*"
|
|
323
|
+
*/
|
|
324
|
+
function stripPathFromMatchPattern(pattern) {
|
|
325
|
+
const protocolSepIndex = pattern.indexOf("://");
|
|
326
|
+
if (protocolSepIndex === -1) return pattern;
|
|
327
|
+
const startOfPath = pattern.indexOf("/", protocolSepIndex + 3);
|
|
328
|
+
return pattern.substring(0, startOfPath) + "/*";
|
|
439
329
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
330
|
+
/**
|
|
331
|
+
* Converts all MV3 web accessible resources to their MV2 forms. MV3 web accessible resources are
|
|
332
|
+
* generated in this file, and may be defined by the user in their manifest. In both cases, when
|
|
333
|
+
* targeting MV2, automatically convert their definitions down to the basic MV2 array.
|
|
334
|
+
*/
|
|
335
|
+
function convertWebAccessibleResourcesToMv2(manifest) {
|
|
336
|
+
if (manifest.web_accessible_resources == null) return;
|
|
337
|
+
manifest.web_accessible_resources = Array.from(new Set(manifest.web_accessible_resources.flatMap((item) => {
|
|
338
|
+
if (typeof item === "string") return item;
|
|
339
|
+
return item.resources;
|
|
340
|
+
})));
|
|
450
341
|
}
|
|
451
342
|
function moveHostPermissionsToPermissions(manifest) {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
);
|
|
456
|
-
delete manifest.host_permissions;
|
|
343
|
+
if (!manifest.host_permissions?.length) return;
|
|
344
|
+
manifest.host_permissions.forEach((permission) => addPermission(manifest, permission));
|
|
345
|
+
delete manifest.host_permissions;
|
|
457
346
|
}
|
|
458
347
|
function convertActionToMv2(manifest) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
manifest.browser_action = manifest.action;
|
|
348
|
+
if (manifest.action == null || manifest.browser_action != null || manifest.page_action != null) return;
|
|
349
|
+
manifest.browser_action = manifest.action;
|
|
462
350
|
}
|
|
463
351
|
function convertCspToMv2(manifest) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
manifest.content_security_policy = manifest.content_security_policy.extension_pages;
|
|
352
|
+
if (typeof manifest.content_security_policy === "string" || manifest.content_security_policy?.extension_pages == null) return;
|
|
353
|
+
manifest.content_security_policy = manifest.content_security_policy.extension_pages;
|
|
467
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Make sure all resources are in MV3 format. If not, add a wanring
|
|
357
|
+
*/
|
|
468
358
|
function validateMv3WebAccessibleResources(manifest) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
);
|
|
473
|
-
if (stringResources.length > 0) {
|
|
474
|
-
throw Error(
|
|
475
|
-
`Non-MV3 web_accessible_resources detected: ${JSON.stringify(
|
|
476
|
-
stringResources
|
|
477
|
-
)}. When manually defining web_accessible_resources, define them as MV3 objects ({ matches: [...], resources: [...] }), and WXT will automatically convert them to MV2 when necessary.`
|
|
478
|
-
);
|
|
479
|
-
}
|
|
359
|
+
if (manifest.web_accessible_resources == null) return;
|
|
360
|
+
const stringResources = manifest.web_accessible_resources.filter((item) => typeof item === "string");
|
|
361
|
+
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.`);
|
|
480
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Remove keys from the manifest based on the build target.
|
|
365
|
+
*/
|
|
481
366
|
function stripKeys(manifest) {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
keysToRemove.forEach((key) => {
|
|
491
|
-
delete manifest[key];
|
|
492
|
-
});
|
|
367
|
+
let keysToRemove = [];
|
|
368
|
+
if (wxt.config.manifestVersion === 2) {
|
|
369
|
+
keysToRemove.push(...mv3OnlyKeys);
|
|
370
|
+
if (wxt.config.browser === "firefox") keysToRemove.push(...firefoxMv3OnlyKeys);
|
|
371
|
+
} else keysToRemove.push(...mv2OnlyKeys);
|
|
372
|
+
keysToRemove.forEach((key) => {
|
|
373
|
+
delete manifest[key];
|
|
374
|
+
});
|
|
493
375
|
}
|
|
494
376
|
const mv2OnlyKeys = [
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
377
|
+
"page_action",
|
|
378
|
+
"browser_action",
|
|
379
|
+
"automation",
|
|
380
|
+
"content_capabilities",
|
|
381
|
+
"converted_from_user_script",
|
|
382
|
+
"current_locale",
|
|
383
|
+
"differential_fingerprint",
|
|
384
|
+
"event_rules",
|
|
385
|
+
"file_browser_handlers",
|
|
386
|
+
"file_system_provider_capabilities",
|
|
387
|
+
"nacl_modules",
|
|
388
|
+
"natively_connectable",
|
|
389
|
+
"offline_enabled",
|
|
390
|
+
"platforms",
|
|
391
|
+
"replacement_web_app",
|
|
392
|
+
"system_indicator",
|
|
393
|
+
"user_scripts"
|
|
512
394
|
];
|
|
513
395
|
const mv3OnlyKeys = [
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
396
|
+
"action",
|
|
397
|
+
"export",
|
|
398
|
+
"optional_host_permissions",
|
|
399
|
+
"side_panel"
|
|
518
400
|
];
|
|
519
401
|
const firefoxMv3OnlyKeys = ["host_permissions"];
|
|
520
402
|
const DEFAULT_MV3_EXTENSION_PAGES_CSP = "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';";
|
|
521
403
|
const DEFAULT_MV3_SANDBOX_CSP = "sandbox allow-scripts allow-forms allow-popups allow-modals; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';";
|
|
522
404
|
const DEFAULT_MV2_CSP = "script-src 'self'; object-src 'self';";
|
|
405
|
+
|
|
406
|
+
//#endregion
|
|
407
|
+
export { generateManifest, getContentScriptCssFiles, getContentScriptsCssMap, writeManifest };
|