wxt 0.19.15 → 0.19.17
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/builtin-modules/unimport.mjs +2 -2
- package/dist/client/content-scripts/ui/index.mjs +1 -0
- package/dist/core/builders/vite/index.d.ts +1 -1
- package/dist/core/builders/vite/index.mjs +10 -9
- package/dist/core/create-server.mjs +79 -58
- package/dist/core/generate-wxt-dir.mjs +1 -1
- package/dist/core/resolve-config.mjs +11 -4
- package/dist/core/utils/building/detect-dev-changes.d.ts +5 -1
- package/dist/core/utils/building/detect-dev-changes.mjs +5 -0
- package/dist/core/utils/content-scripts.mjs +1 -1
- package/dist/core/utils/manifest.d.ts +2 -2
- package/dist/core/utils/manifest.mjs +21 -20
- package/dist/core/utils/testing/fake-objects.d.ts +384 -0
- package/dist/core/wxt.d.ts +7 -2
- package/dist/core/wxt.mjs +23 -16
- package/dist/modules.d.ts +1 -1
- package/dist/modules.mjs +7 -6
- package/dist/types.d.ts +28 -5
- package/dist/version.mjs +1 -1
- package/package.json +3 -3
|
@@ -7,7 +7,7 @@ export default defineWxtModule({
|
|
|
7
7
|
const options = wxt.config.imports;
|
|
8
8
|
if (options === false) return;
|
|
9
9
|
let unimport;
|
|
10
|
-
wxt.hooks.hook("
|
|
10
|
+
wxt.hooks.hook("config:resolved", () => {
|
|
11
11
|
const addModuleImports = (module) => {
|
|
12
12
|
if (!module.imports) return;
|
|
13
13
|
options.imports ??= [];
|
|
@@ -17,7 +17,7 @@ export default defineWxtModule({
|
|
|
17
17
|
wxt.config.userModules.forEach(addModuleImports);
|
|
18
18
|
});
|
|
19
19
|
wxt.hooks.afterEach((event) => {
|
|
20
|
-
if (event.name === "
|
|
20
|
+
if (event.name === "config:resolved") {
|
|
21
21
|
unimport = createUnimport(options);
|
|
22
22
|
}
|
|
23
23
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ResolvedConfig, WxtBuilder, WxtDevServer, WxtHooks } from '../../../types';
|
|
2
2
|
import { Hookable } from 'hookable';
|
|
3
|
-
export declare function createViteBuilder(wxtConfig: ResolvedConfig, hooks: Hookable<WxtHooks>,
|
|
3
|
+
export declare function createViteBuilder(wxtConfig: ResolvedConfig, hooks: Hookable<WxtHooks>, getWxtDevServer?: () => WxtDevServer | undefined): Promise<WxtBuilder>;
|
|
@@ -9,7 +9,7 @@ import { importEntrypointFile } from "../../utils/building/index.mjs";
|
|
|
9
9
|
import { ViteNodeServer } from "vite-node/server";
|
|
10
10
|
import { ViteNodeRunner } from "vite-node/client";
|
|
11
11
|
import { installSourcemapsSupport } from "vite-node/source-map";
|
|
12
|
-
export async function createViteBuilder(wxtConfig, hooks,
|
|
12
|
+
export async function createViteBuilder(wxtConfig, hooks, getWxtDevServer) {
|
|
13
13
|
const vite = await import("vite");
|
|
14
14
|
const getBaseConfig = async (baseConfigOptions) => {
|
|
15
15
|
const config = await wxtConfig.vite(wxtConfig.env);
|
|
@@ -33,6 +33,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
|
|
|
33
33
|
config.server.watch = {
|
|
34
34
|
ignored: [`${wxtConfig.outBaseDir}/**`, `${wxtConfig.wxtDir}/**`]
|
|
35
35
|
};
|
|
36
|
+
const server = getWxtDevServer?.();
|
|
36
37
|
config.plugins ??= [];
|
|
37
38
|
config.plugins.push(
|
|
38
39
|
wxtPlugins.download(wxtConfig),
|
|
@@ -180,18 +181,18 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
|
|
|
180
181
|
plugins: [wxtPlugins.removeEntrypointMainFunction(wxtConfig, path)]
|
|
181
182
|
};
|
|
182
183
|
const config = vite.mergeConfig(baseConfig, envConfig);
|
|
183
|
-
const
|
|
184
|
-
await
|
|
184
|
+
const server = await vite.createServer(config);
|
|
185
|
+
await server.pluginContainer.buildStart({});
|
|
185
186
|
const node = new ViteNodeServer(
|
|
186
187
|
// @ts-ignore: Some weird type error...
|
|
187
|
-
|
|
188
|
+
server
|
|
188
189
|
);
|
|
189
190
|
installSourcemapsSupport({
|
|
190
191
|
getSourceMap: (source) => node.getSourceMap(source)
|
|
191
192
|
});
|
|
192
193
|
const runner = new ViteNodeRunner({
|
|
193
|
-
root:
|
|
194
|
-
base:
|
|
194
|
+
root: server.config.root,
|
|
195
|
+
base: server.config.base,
|
|
195
196
|
// when having the server and runner in a different context,
|
|
196
197
|
// you will need to handle the communication between them
|
|
197
198
|
// and pass to this function
|
|
@@ -203,7 +204,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
|
|
|
203
204
|
}
|
|
204
205
|
});
|
|
205
206
|
const res = await runner.executeFile(path);
|
|
206
|
-
await
|
|
207
|
+
await server.close();
|
|
207
208
|
return res.default;
|
|
208
209
|
}
|
|
209
210
|
}
|
|
@@ -239,7 +240,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
|
|
|
239
240
|
const finalConfig = vite.mergeConfig(baseConfig, serverConfig);
|
|
240
241
|
await hooks.callHook("vite:devServer:extendConfig", finalConfig);
|
|
241
242
|
const viteServer = await vite.createServer(finalConfig);
|
|
242
|
-
const
|
|
243
|
+
const server = {
|
|
243
244
|
async listen() {
|
|
244
245
|
await viteServer.listen(info.port);
|
|
245
246
|
},
|
|
@@ -259,7 +260,7 @@ export async function createViteBuilder(wxtConfig, hooks, server) {
|
|
|
259
260
|
},
|
|
260
261
|
watcher: viteServer.watcher
|
|
261
262
|
};
|
|
262
|
-
return
|
|
263
|
+
return server;
|
|
263
264
|
}
|
|
264
265
|
};
|
|
265
266
|
}
|
|
@@ -14,66 +14,98 @@ import { createExtensionRunner } from "./runners/index.mjs";
|
|
|
14
14
|
import { Mutex } from "async-mutex";
|
|
15
15
|
import pc from "picocolors";
|
|
16
16
|
import { relative } from "node:path";
|
|
17
|
-
import { registerWxt, wxt } from "./wxt.mjs";
|
|
17
|
+
import { deinitWxtModules, initWxtModules, registerWxt, wxt } from "./wxt.mjs";
|
|
18
18
|
import { unnormalizePath } from "./utils/paths.mjs";
|
|
19
19
|
import {
|
|
20
20
|
getContentScriptJs,
|
|
21
21
|
mapWxtOptionsToRegisteredContentScript
|
|
22
22
|
} from "./utils/content-scripts.mjs";
|
|
23
23
|
export async function createServer(inlineConfig) {
|
|
24
|
-
await registerWxt("serve", inlineConfig
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
await registerWxt("serve", inlineConfig);
|
|
25
|
+
wxt.server = await createServerInternal();
|
|
26
|
+
await wxt.hooks.callHook("server:created", wxt, wxt.server);
|
|
27
|
+
return wxt.server;
|
|
28
|
+
}
|
|
29
|
+
async function createServerInternal() {
|
|
30
|
+
const getServerInfo = () => {
|
|
31
|
+
const { port, hostname } = wxt.config.dev.server;
|
|
32
|
+
return {
|
|
27
33
|
port,
|
|
28
34
|
hostname,
|
|
29
35
|
origin: `http://${hostname}:${port}`
|
|
30
36
|
};
|
|
31
|
-
|
|
32
|
-
...serverInfo,
|
|
33
|
-
get watcher() {
|
|
34
|
-
return builderServer.watcher;
|
|
35
|
-
},
|
|
36
|
-
get ws() {
|
|
37
|
-
return builderServer.ws;
|
|
38
|
-
},
|
|
39
|
-
currentOutput: void 0,
|
|
40
|
-
async start() {
|
|
41
|
-
await builderServer.listen();
|
|
42
|
-
wxt.logger.success(`Started dev server @ ${serverInfo.origin}`);
|
|
43
|
-
await buildAndOpenBrowser();
|
|
44
|
-
},
|
|
45
|
-
async stop() {
|
|
46
|
-
await runner.closeBrowser();
|
|
47
|
-
await builderServer.close();
|
|
48
|
-
},
|
|
49
|
-
async restart() {
|
|
50
|
-
await closeAndRecreateRunner();
|
|
51
|
-
await buildAndOpenBrowser();
|
|
52
|
-
},
|
|
53
|
-
transformHtml(url, html, originalUrl) {
|
|
54
|
-
return builderServer.transformHtml(url, html, originalUrl);
|
|
55
|
-
},
|
|
56
|
-
reloadContentScript(payload) {
|
|
57
|
-
server2.ws.send("wxt:reload-content-script", payload);
|
|
58
|
-
},
|
|
59
|
-
reloadPage(path) {
|
|
60
|
-
server2.ws.send("wxt:reload-page", path);
|
|
61
|
-
},
|
|
62
|
-
reloadExtension() {
|
|
63
|
-
server2.ws.send("wxt:reload-extension");
|
|
64
|
-
},
|
|
65
|
-
async restartBrowser() {
|
|
66
|
-
await closeAndRecreateRunner();
|
|
67
|
-
await runner.openBrowser();
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
return server2;
|
|
71
|
-
});
|
|
72
|
-
const server = wxt.server;
|
|
37
|
+
};
|
|
73
38
|
let [runner, builderServer] = await Promise.all([
|
|
74
39
|
createExtensionRunner(),
|
|
75
|
-
wxt.builder.createServer(
|
|
40
|
+
wxt.builder.createServer(getServerInfo())
|
|
76
41
|
]);
|
|
42
|
+
let wasStopped = false;
|
|
43
|
+
const server = {
|
|
44
|
+
get hostname() {
|
|
45
|
+
return getServerInfo().hostname;
|
|
46
|
+
},
|
|
47
|
+
get port() {
|
|
48
|
+
return getServerInfo().port;
|
|
49
|
+
},
|
|
50
|
+
get origin() {
|
|
51
|
+
return getServerInfo().origin;
|
|
52
|
+
},
|
|
53
|
+
get watcher() {
|
|
54
|
+
return builderServer.watcher;
|
|
55
|
+
},
|
|
56
|
+
get ws() {
|
|
57
|
+
return builderServer.ws;
|
|
58
|
+
},
|
|
59
|
+
currentOutput: void 0,
|
|
60
|
+
async start() {
|
|
61
|
+
if (wasStopped) {
|
|
62
|
+
await wxt.reloadConfig();
|
|
63
|
+
runner = await createExtensionRunner();
|
|
64
|
+
builderServer = await wxt.builder.createServer(getServerInfo());
|
|
65
|
+
await initWxtModules();
|
|
66
|
+
}
|
|
67
|
+
await builderServer.listen();
|
|
68
|
+
wxt.logger.success(`Started dev server @ ${server.origin}`);
|
|
69
|
+
await wxt.hooks.callHook("server:started", wxt, server);
|
|
70
|
+
await buildAndOpenBrowser();
|
|
71
|
+
server.ws.on("wxt:background-initialized", () => {
|
|
72
|
+
if (server.currentOutput == null) return;
|
|
73
|
+
reloadContentScripts(server.currentOutput.steps, server);
|
|
74
|
+
});
|
|
75
|
+
const reloadOnChange = createFileReloader(server);
|
|
76
|
+
server.watcher.on("all", reloadOnChange);
|
|
77
|
+
},
|
|
78
|
+
async stop() {
|
|
79
|
+
wasStopped = true;
|
|
80
|
+
await runner.closeBrowser();
|
|
81
|
+
await builderServer.close();
|
|
82
|
+
await wxt.hooks.callHook("server:closed", wxt, server);
|
|
83
|
+
deinitWxtModules();
|
|
84
|
+
server.currentOutput = void 0;
|
|
85
|
+
},
|
|
86
|
+
async restart() {
|
|
87
|
+
await server.stop();
|
|
88
|
+
await server.start();
|
|
89
|
+
},
|
|
90
|
+
transformHtml(url, html, originalUrl) {
|
|
91
|
+
return builderServer.transformHtml(url, html, originalUrl);
|
|
92
|
+
},
|
|
93
|
+
reloadContentScript(payload) {
|
|
94
|
+
server.ws.send("wxt:reload-content-script", payload);
|
|
95
|
+
},
|
|
96
|
+
reloadPage(path) {
|
|
97
|
+
server.ws.send("wxt:reload-page", path);
|
|
98
|
+
},
|
|
99
|
+
reloadExtension() {
|
|
100
|
+
server.ws.send("wxt:reload-extension");
|
|
101
|
+
},
|
|
102
|
+
async restartBrowser() {
|
|
103
|
+
await runner.closeBrowser();
|
|
104
|
+
await wxt.reloadConfig();
|
|
105
|
+
runner = await createExtensionRunner();
|
|
106
|
+
await runner.openBrowser();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
77
109
|
const buildAndOpenBrowser = async () => {
|
|
78
110
|
server.currentOutput = await internalBuild();
|
|
79
111
|
try {
|
|
@@ -83,17 +115,6 @@ export async function createServer(inlineConfig) {
|
|
|
83
115
|
}
|
|
84
116
|
await runner.openBrowser();
|
|
85
117
|
};
|
|
86
|
-
const closeAndRecreateRunner = async () => {
|
|
87
|
-
await runner.closeBrowser();
|
|
88
|
-
await wxt.reloadConfig();
|
|
89
|
-
runner = await createExtensionRunner();
|
|
90
|
-
};
|
|
91
|
-
server.ws.on("wxt:background-initialized", () => {
|
|
92
|
-
if (server.currentOutput == null) return;
|
|
93
|
-
reloadContentScripts(server.currentOutput.steps, server);
|
|
94
|
-
});
|
|
95
|
-
const reloadOnChange = createFileReloader(server);
|
|
96
|
-
server.watcher.on("all", reloadOnChange);
|
|
97
118
|
return server;
|
|
98
119
|
}
|
|
99
120
|
function createFileReloader(server) {
|
|
@@ -125,7 +125,7 @@ ${commentLines.map((line) => ` * ${line}`.trimEnd()).join("\n")}
|
|
|
125
125
|
message.message
|
|
126
126
|
)
|
|
127
127
|
),
|
|
128
|
-
// Include a final union-based override so TS accepts valid string templates or
|
|
128
|
+
// Include a final union-based override so TS accepts valid string templates or concatenations
|
|
129
129
|
// ie: browser.i18n.getMessage(`some_enum_${enumValue}`)
|
|
130
130
|
renderGetMessageOverload(
|
|
131
131
|
messages.map((message) => `"${message.name}"`).join(" | ")
|
|
@@ -10,6 +10,7 @@ import { builtinModules } from "../builtin-modules/index.mjs";
|
|
|
10
10
|
import { getEslintVersion } from "./utils/eslint.mjs";
|
|
11
11
|
import { safeStringToNumber } from "./utils/number.mjs";
|
|
12
12
|
import { loadEnv } from "./utils/env.mjs";
|
|
13
|
+
import { getPort } from "get-port-please";
|
|
13
14
|
export async function resolveConfig(inlineConfig, command) {
|
|
14
15
|
let userConfig = {};
|
|
15
16
|
let userConfigMetadata;
|
|
@@ -82,14 +83,19 @@ export async function resolveConfig(inlineConfig, command) {
|
|
|
82
83
|
);
|
|
83
84
|
let devServerConfig;
|
|
84
85
|
if (command === "serve") {
|
|
86
|
+
const hostname = mergedConfig.dev?.server?.hostname ?? "localhost";
|
|
85
87
|
let port = mergedConfig.dev?.server?.port;
|
|
86
88
|
if (port == null || !isFinite(port)) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
port = await getPort({
|
|
90
|
+
port: 3e3,
|
|
91
|
+
portRange: [3001, 3010],
|
|
92
|
+
// Passing host required for Mac, unsure of Windows/Linux
|
|
93
|
+
host: hostname
|
|
94
|
+
});
|
|
89
95
|
}
|
|
90
96
|
devServerConfig = {
|
|
91
97
|
port,
|
|
92
|
-
hostname
|
|
98
|
+
hostname,
|
|
93
99
|
watchDebounce: safeStringToNumber(process.env.WXT_WATCH_DEBOUNCE) ?? 800
|
|
94
100
|
};
|
|
95
101
|
}
|
|
@@ -274,9 +280,10 @@ async function getUnimportEslintOptions(wxtDir, options) {
|
|
|
274
280
|
case "auto":
|
|
275
281
|
const version = await getEslintVersion();
|
|
276
282
|
let major = parseInt(version[0]);
|
|
283
|
+
if (isNaN(major)) eslintEnabled = false;
|
|
277
284
|
if (major <= 8) eslintEnabled = 8;
|
|
278
285
|
else if (major >= 9) eslintEnabled = 9;
|
|
279
|
-
else eslintEnabled =
|
|
286
|
+
else eslintEnabled = false;
|
|
280
287
|
break;
|
|
281
288
|
case true:
|
|
282
289
|
eslintEnabled = 8;
|
|
@@ -17,7 +17,11 @@ import { BuildOutput, BuildStepOutput, EntrypointGroup } from '../../../types';
|
|
|
17
17
|
* - Background script is changed
|
|
18
18
|
* - Manifest is different
|
|
19
19
|
* - Restart browser
|
|
20
|
-
* -
|
|
20
|
+
* - web-ext.config.ts (runner config changes)
|
|
21
|
+
* - Full dev server restart
|
|
22
|
+
* - wxt.config.ts (main config file)
|
|
23
|
+
* - modules/* (any file related to WXT modules)
|
|
24
|
+
* - .env (environment variable changed could effect build)
|
|
21
25
|
*/
|
|
22
26
|
export declare function detectDevChanges(changedFiles: string[], currentOutput: BuildOutput): DevModeChange;
|
|
23
27
|
/**
|
|
@@ -7,6 +7,11 @@ export function detectDevChanges(changedFiles, currentOutput) {
|
|
|
7
7
|
(file) => file === wxt.config.userConfigMetadata.configFile
|
|
8
8
|
);
|
|
9
9
|
if (isConfigChange) return { type: "full-restart" };
|
|
10
|
+
const isWxtModuleChange = some(
|
|
11
|
+
changedFiles,
|
|
12
|
+
(file) => file.startsWith(wxt.config.modulesDir)
|
|
13
|
+
);
|
|
14
|
+
if (isWxtModuleChange) return { type: "full-restart" };
|
|
10
15
|
const isRunnerChange = some(
|
|
11
16
|
changedFiles,
|
|
12
17
|
(file) => file === wxt.config.runnerConfig.configFile
|
|
@@ -28,7 +28,7 @@ export function hashContentScriptOptions(options) {
|
|
|
28
28
|
}
|
|
29
29
|
export function mapWxtOptionsToContentScript(options, js, css) {
|
|
30
30
|
return {
|
|
31
|
-
matches: options.matches,
|
|
31
|
+
matches: options.matches ?? [],
|
|
32
32
|
all_frames: options.allFrames,
|
|
33
33
|
match_about_blank: options.matchAboutBlank,
|
|
34
34
|
exclude_globs: options.excludeGlobs,
|
|
@@ -35,10 +35,10 @@ export declare function stripPathFromMatchPattern(pattern: string): string;
|
|
|
35
35
|
/**
|
|
36
36
|
* Converts all MV3 web accessible resources to their MV2 forms. MV3 web accessible resources are
|
|
37
37
|
* generated in this file, and may be defined by the user in their manifest. In both cases, when
|
|
38
|
-
*
|
|
38
|
+
* targeting MV2, automatically convert their definitions down to the basic MV2 array.
|
|
39
39
|
*/
|
|
40
40
|
export declare function convertWebAccessibleResourcesToMv2(manifest: Manifest.WebExtensionManifest): void;
|
|
41
41
|
/**
|
|
42
42
|
* Make sure all resources are in MV3 format. If not, add a wanring
|
|
43
43
|
*/
|
|
44
|
-
export declare function
|
|
44
|
+
export declare function validateMv3WebAccessibleResources(manifest: Manifest.WebExtensionManifest): void;
|
|
@@ -70,10 +70,11 @@ export async function generateManifest(entrypoints, buildOutput) {
|
|
|
70
70
|
if (wxt.config.manifestVersion === 2) {
|
|
71
71
|
convertWebAccessibleResourcesToMv2(manifest);
|
|
72
72
|
convertActionToMv2(manifest);
|
|
73
|
+
convertCspToMv2(manifest);
|
|
73
74
|
moveHostPermissionsToPermissions(manifest);
|
|
74
75
|
}
|
|
75
76
|
if (wxt.config.manifestVersion === 3) {
|
|
76
|
-
|
|
77
|
+
validateMv3WebAccessibleResources(manifest);
|
|
77
78
|
}
|
|
78
79
|
stripKeys(manifest);
|
|
79
80
|
if (manifest.name == null)
|
|
@@ -262,7 +263,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
|
|
|
262
263
|
const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
|
|
263
264
|
if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
|
|
264
265
|
contentScripts.forEach((script) => {
|
|
265
|
-
script.options.matches
|
|
266
|
+
script.options.matches?.forEach((matchPattern) => {
|
|
266
267
|
addHostPermission(manifest, matchPattern);
|
|
267
268
|
});
|
|
268
269
|
});
|
|
@@ -297,7 +298,7 @@ function addEntrypoints(manifest, entrypoints, buildOutput) {
|
|
|
297
298
|
);
|
|
298
299
|
}
|
|
299
300
|
runtimeContentScripts.forEach((script) => {
|
|
300
|
-
script.options.matches
|
|
301
|
+
script.options.matches?.forEach((matchPattern) => {
|
|
301
302
|
addHostPermission(manifest, matchPattern);
|
|
302
303
|
});
|
|
303
304
|
});
|
|
@@ -353,28 +354,20 @@ function addDevModeCsp(manifest) {
|
|
|
353
354
|
addPermission(manifest, permission);
|
|
354
355
|
}
|
|
355
356
|
const extensionPagesCsp = new ContentSecurityPolicy(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
manifest.content_security_policy?.extension_pages ?? "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
|
|
359
|
-
) : manifest.content_security_policy ?? "script-src 'self'; object-src 'self';"
|
|
360
|
-
// default CSP for MV2
|
|
357
|
+
// @ts-expect-error: extension_pages exists, we convert MV2 CSPs to this earlier in the process
|
|
358
|
+
manifest.content_security_policy?.extension_pages ?? (manifest.manifest_version === 3 ? DEFAULT_MV3_EXTENSION_PAGES_CSP : DEFAULT_MV2_CSP)
|
|
361
359
|
);
|
|
362
360
|
const sandboxCsp = new ContentSecurityPolicy(
|
|
363
361
|
// @ts-expect-error: sandbox is not typed
|
|
364
|
-
manifest.content_security_policy?.sandbox ??
|
|
365
|
-
// default sandbox CSP for MV3
|
|
362
|
+
manifest.content_security_policy?.sandbox ?? DEFAULT_MV3_SANDBOX_CSP
|
|
366
363
|
);
|
|
367
|
-
if (wxt.
|
|
364
|
+
if (wxt.config.command === "serve") {
|
|
368
365
|
extensionPagesCsp.add("script-src", allowedCsp);
|
|
369
366
|
sandboxCsp.add("script-src", allowedCsp);
|
|
370
367
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
manifest.content_security_policy.sandbox = sandboxCsp.toString();
|
|
375
|
-
} else {
|
|
376
|
-
manifest.content_security_policy = extensionPagesCsp.toString();
|
|
377
|
-
}
|
|
368
|
+
manifest.content_security_policy ??= {};
|
|
369
|
+
manifest.content_security_policy.extension_pages = extensionPagesCsp.toString();
|
|
370
|
+
manifest.content_security_policy.sandbox = sandboxCsp.toString();
|
|
378
371
|
}
|
|
379
372
|
function addDevModePermissions(manifest) {
|
|
380
373
|
addPermission(manifest, "tabs");
|
|
@@ -400,7 +393,7 @@ export function getContentScriptCssWebAccessibleResources(contentScripts, conten
|
|
|
400
393
|
if (cssFile == null) return;
|
|
401
394
|
resources.push({
|
|
402
395
|
resources: [cssFile],
|
|
403
|
-
matches: script.options.matches
|
|
396
|
+
matches: script.options.matches?.map(
|
|
404
397
|
(matchPattern) => stripPathFromMatchPattern(matchPattern)
|
|
405
398
|
)
|
|
406
399
|
});
|
|
@@ -457,7 +450,12 @@ function convertActionToMv2(manifest) {
|
|
|
457
450
|
return;
|
|
458
451
|
manifest.browser_action = manifest.action;
|
|
459
452
|
}
|
|
460
|
-
|
|
453
|
+
function convertCspToMv2(manifest) {
|
|
454
|
+
if (typeof manifest.content_security_policy === "string" || manifest.content_security_policy?.extension_pages == null)
|
|
455
|
+
return;
|
|
456
|
+
manifest.content_security_policy = manifest.content_security_policy.extension_pages;
|
|
457
|
+
}
|
|
458
|
+
export function validateMv3WebAccessibleResources(manifest) {
|
|
461
459
|
if (manifest.web_accessible_resources == null) return;
|
|
462
460
|
const stringResources = manifest.web_accessible_resources.filter(
|
|
463
461
|
(item) => typeof item === "string"
|
|
@@ -510,3 +508,6 @@ const mv3OnlyKeys = [
|
|
|
510
508
|
"side_panel"
|
|
511
509
|
];
|
|
512
510
|
const firefoxMv3OnlyKeys = ["host_permissions"];
|
|
511
|
+
const DEFAULT_MV3_EXTENSION_PAGES_CSP = "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';";
|
|
512
|
+
const DEFAULT_MV3_SANDBOX_CSP = "sandbox allow-scripts allow-forms allow-popups allow-modals; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';";
|
|
513
|
+
const DEFAULT_MV2_CSP = "script-src 'self'; object-src 'self';";
|