wxt 0.18.15 → 0.19.0

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.
Files changed (257) hide show
  1. package/bin/wxt.mjs +1 -1
  2. package/dist/browser/chrome.d.ts +17 -0
  3. package/dist/browser/chrome.mjs +7 -0
  4. package/dist/browser/index.d.ts +18 -0
  5. package/dist/browser/index.mjs +2 -0
  6. package/dist/builtin-modules/index.d.ts +2 -0
  7. package/dist/builtin-modules/index.mjs +2 -0
  8. package/dist/builtin-modules/unimport.d.ts +8 -0
  9. package/dist/builtin-modules/unimport.mjs +99 -0
  10. package/dist/cli/cli-utils.d.ts +25 -0
  11. package/dist/cli/cli-utils.mjs +58 -0
  12. package/dist/cli/commands.d.ts +2 -0
  13. package/dist/cli/commands.mjs +104 -0
  14. package/dist/cli/index.d.ts +1 -0
  15. package/dist/cli/index.mjs +11 -0
  16. package/dist/client/app-config.d.ts +2 -0
  17. package/dist/client/app-config.mjs +4 -0
  18. package/dist/client/content-scripts/content-script-context.d.ts +114 -0
  19. package/dist/client/content-scripts/content-script-context.mjs +169 -0
  20. package/dist/client/content-scripts/custom-events.d.ts +10 -0
  21. package/dist/client/content-scripts/custom-events.mjs +13 -0
  22. package/dist/client/content-scripts/index.d.ts +2 -0
  23. package/dist/client/content-scripts/index.mjs +2 -0
  24. package/dist/client/content-scripts/location-watcher.d.ts +12 -0
  25. package/dist/client/content-scripts/location-watcher.mjs +22 -0
  26. package/dist/client/content-scripts/ui/index.d.ts +23 -0
  27. package/dist/client/content-scripts/ui/index.mjs +188 -0
  28. package/dist/{client.d.ts → client/content-scripts/ui/types.d.ts} +17 -45
  29. package/dist/client/content-scripts/ui/types.mjs +0 -0
  30. package/dist/client/index.d.ts +7 -0
  31. package/dist/client/index.mjs +2 -0
  32. package/dist/core/build.d.ts +15 -0
  33. package/dist/core/build.mjs +6 -0
  34. package/dist/core/builders/vite/index.d.ts +3 -0
  35. package/dist/core/builders/vite/index.mjs +285 -0
  36. package/dist/core/builders/vite/plugins/bundleAnalysis.d.ts +7 -0
  37. package/dist/core/builders/vite/plugins/bundleAnalysis.mjs +15 -0
  38. package/dist/core/builders/vite/plugins/cssEntrypoints.d.ts +13 -0
  39. package/dist/core/builders/vite/plugins/cssEntrypoints.mjs +22 -0
  40. package/dist/core/builders/vite/plugins/defineImportMeta.d.ts +14 -0
  41. package/dist/core/builders/vite/plugins/defineImportMeta.mjs +13 -0
  42. package/dist/core/builders/vite/plugins/devHtmlPrerender.d.ts +7 -0
  43. package/dist/core/builders/vite/plugins/devHtmlPrerender.mjs +140 -0
  44. package/dist/core/builders/vite/plugins/devServerGlobals.d.ts +6 -0
  45. package/dist/core/builders/vite/plugins/devServerGlobals.mjs +15 -0
  46. package/dist/core/builders/vite/plugins/download.d.ts +10 -0
  47. package/dist/core/builders/vite/plugins/download.mjs +14 -0
  48. package/dist/core/builders/vite/plugins/entrypointGroupGlobals.d.ts +6 -0
  49. package/dist/core/builders/vite/plugins/entrypointGroupGlobals.mjs +16 -0
  50. package/dist/core/builders/vite/plugins/extensionApiMock.d.ts +11 -0
  51. package/dist/core/builders/vite/plugins/extensionApiMock.mjs +26 -0
  52. package/dist/core/builders/vite/plugins/globals.d.ts +3 -0
  53. package/dist/core/builders/vite/plugins/globals.mjs +15 -0
  54. package/dist/core/builders/vite/plugins/index.d.ts +17 -0
  55. package/dist/core/builders/vite/plugins/index.mjs +17 -0
  56. package/dist/core/builders/vite/plugins/multipageMove.d.ts +20 -0
  57. package/dist/core/builders/vite/plugins/multipageMove.mjs +59 -0
  58. package/dist/core/builders/vite/plugins/noopBackground.d.ts +6 -0
  59. package/dist/core/builders/vite/plugins/noopBackground.mjs +17 -0
  60. package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.d.ts +6 -0
  61. package/dist/core/builders/vite/plugins/removeEntrypointMainFunction.mjs +12 -0
  62. package/dist/core/builders/vite/plugins/resolveAppConfig.d.ts +6 -0
  63. package/dist/core/builders/vite/plugins/resolveAppConfig.mjs +26 -0
  64. package/dist/core/builders/vite/plugins/resolveExtensionApi.d.ts +10 -0
  65. package/dist/core/builders/vite/plugins/resolveExtensionApi.mjs +15 -0
  66. package/dist/core/builders/vite/plugins/resolveVirtualModules.d.ts +6 -0
  67. package/dist/core/builders/vite/plugins/resolveVirtualModules.mjs +30 -0
  68. package/dist/core/builders/vite/plugins/tsconfigPaths.d.ts +3 -0
  69. package/dist/core/builders/vite/plugins/tsconfigPaths.mjs +12 -0
  70. package/dist/core/builders/vite/plugins/wxtPluginLoader.d.ts +6 -0
  71. package/dist/core/builders/vite/plugins/wxtPluginLoader.mjs +56 -0
  72. package/dist/core/clean.d.ts +21 -0
  73. package/dist/core/clean.mjs +38 -0
  74. package/dist/core/create-server.d.ts +11 -0
  75. package/dist/core/create-server.mjs +206 -0
  76. package/dist/core/define-config.d.ts +2 -0
  77. package/dist/core/define-config.mjs +3 -0
  78. package/dist/core/define-runner-config.d.ts +2 -0
  79. package/dist/core/define-runner-config.mjs +3 -0
  80. package/dist/core/index.d.ts +8 -0
  81. package/dist/core/index.mjs +8 -0
  82. package/dist/core/initialize.d.ts +5 -0
  83. package/dist/core/initialize.mjs +128 -0
  84. package/dist/core/package-managers/bun.d.ts +2 -0
  85. package/dist/core/package-managers/bun.mjs +19 -0
  86. package/dist/core/package-managers/index.d.ts +2 -0
  87. package/dist/core/package-managers/index.mjs +65 -0
  88. package/dist/core/package-managers/npm.d.ts +17 -0
  89. package/dist/core/package-managers/npm.mjs +58 -0
  90. package/dist/core/package-managers/pnpm.d.ts +2 -0
  91. package/dist/core/package-managers/pnpm.mjs +21 -0
  92. package/dist/core/package-managers/types.d.ts +2 -0
  93. package/dist/core/package-managers/types.mjs +0 -0
  94. package/dist/core/package-managers/yarn.d.ts +2 -0
  95. package/dist/core/package-managers/yarn.mjs +31 -0
  96. package/dist/core/prepare.d.ts +2 -0
  97. package/dist/core/prepare.mjs +8 -0
  98. package/dist/core/runners/index.d.ts +2 -0
  99. package/dist/core/runners/index.mjs +12 -0
  100. package/dist/core/runners/manual.d.ts +5 -0
  101. package/dist/core/runners/manual.mjs +16 -0
  102. package/dist/core/runners/safari.d.ts +5 -0
  103. package/dist/core/runners/safari.mjs +16 -0
  104. package/dist/core/runners/web-ext.d.ts +5 -0
  105. package/dist/core/runners/web-ext.mjs +78 -0
  106. package/dist/core/runners/wsl.d.ts +5 -0
  107. package/dist/core/runners/wsl.mjs +16 -0
  108. package/dist/core/utils/arrays.d.ts +13 -0
  109. package/dist/{chunk-BERPNPEZ.js → core/utils/arrays.mjs} +6 -10
  110. package/dist/core/utils/building/build-entrypoints.d.ts +3 -0
  111. package/dist/core/utils/building/build-entrypoints.mjs +47 -0
  112. package/dist/core/utils/building/detect-dev-changes.d.ts +57 -0
  113. package/dist/core/utils/building/detect-dev-changes.mjs +93 -0
  114. package/dist/core/utils/building/find-entrypoints.d.ts +5 -0
  115. package/dist/core/utils/building/find-entrypoints.mjs +385 -0
  116. package/dist/core/utils/building/generate-wxt-dir.d.ts +5 -0
  117. package/dist/core/utils/building/generate-wxt-dir.mjs +192 -0
  118. package/dist/core/utils/building/group-entrypoints.d.ts +8 -0
  119. package/dist/core/utils/building/group-entrypoints.mjs +37 -0
  120. package/dist/core/utils/building/import-entrypoint.d.ts +16 -0
  121. package/dist/core/utils/building/import-entrypoint.mjs +97 -0
  122. package/dist/core/utils/building/index.d.ts +9 -0
  123. package/dist/core/utils/building/index.mjs +9 -0
  124. package/dist/core/utils/building/internal-build.d.ts +12 -0
  125. package/dist/core/utils/building/internal-build.mjs +112 -0
  126. package/dist/core/utils/building/rebuild.d.ts +23 -0
  127. package/dist/core/utils/building/rebuild.mjs +39 -0
  128. package/dist/core/utils/building/resolve-config.d.ts +11 -0
  129. package/dist/core/utils/building/resolve-config.mjs +364 -0
  130. package/dist/core/utils/cache.d.ts +8 -0
  131. package/dist/core/utils/cache.mjs +21 -0
  132. package/dist/core/utils/cli.d.ts +3 -0
  133. package/dist/core/utils/cli.mjs +26 -0
  134. package/dist/core/utils/constants.d.ts +5 -0
  135. package/dist/core/utils/constants.mjs +1 -0
  136. package/dist/core/utils/content-scripts.d.ts +11 -0
  137. package/dist/core/utils/content-scripts.mjs +60 -0
  138. package/dist/core/utils/content-security-policy.d.ts +14 -0
  139. package/dist/core/utils/content-security-policy.mjs +39 -0
  140. package/dist/core/utils/entrypoints.d.ts +25 -0
  141. package/dist/core/utils/entrypoints.mjs +31 -0
  142. package/dist/core/utils/eslint.d.ts +1 -0
  143. package/dist/core/utils/eslint.mjs +11 -0
  144. package/dist/core/utils/fs.d.ts +13 -0
  145. package/dist/core/utils/fs.mjs +15 -0
  146. package/dist/core/utils/globals.d.ts +11 -0
  147. package/dist/core/utils/globals.mjs +53 -0
  148. package/dist/core/utils/i18n.d.ts +11 -0
  149. package/dist/core/utils/i18n.mjs +35 -0
  150. package/dist/core/utils/log/index.d.ts +4 -0
  151. package/dist/core/utils/log/index.mjs +4 -0
  152. package/dist/core/utils/log/printBuildSummary.d.ts +2 -0
  153. package/dist/core/utils/log/printBuildSummary.mjs +32 -0
  154. package/dist/core/utils/log/printFileList.d.ts +1 -0
  155. package/dist/core/utils/log/printFileList.mjs +42 -0
  156. package/dist/core/utils/log/printHeader.d.ts +1 -0
  157. package/dist/core/utils/log/printHeader.mjs +7 -0
  158. package/dist/core/utils/log/printTable.d.ts +1 -0
  159. package/dist/core/utils/log/printTable.mjs +22 -0
  160. package/dist/core/utils/manifest.d.ts +44 -0
  161. package/dist/core/utils/manifest.mjs +512 -0
  162. package/dist/core/utils/network.d.ts +7 -0
  163. package/dist/core/utils/network.mjs +38 -0
  164. package/dist/core/utils/package.d.ts +6 -0
  165. package/dist/core/utils/package.mjs +14 -0
  166. package/dist/core/utils/paths.d.ts +11 -0
  167. package/dist/core/utils/paths.mjs +10 -0
  168. package/dist/core/utils/strings.d.ts +14 -0
  169. package/dist/core/utils/strings.mjs +18 -0
  170. package/dist/core/utils/testing/fake-objects.d.ts +4556 -0
  171. package/dist/core/utils/testing/fake-objects.mjs +322 -0
  172. package/dist/core/utils/time.d.ts +9 -0
  173. package/dist/core/utils/time.mjs +17 -0
  174. package/dist/core/utils/transform.d.ts +9 -0
  175. package/dist/core/utils/transform.mjs +17 -0
  176. package/dist/core/utils/types.d.ts +10 -0
  177. package/dist/core/utils/types.mjs +0 -0
  178. package/dist/core/utils/validation.d.ts +15 -0
  179. package/dist/core/utils/validation.mjs +55 -0
  180. package/dist/core/utils/virtual-modules.d.ts +22 -0
  181. package/dist/core/utils/virtual-modules.mjs +14 -0
  182. package/dist/core/utils/wsl.d.ts +4 -0
  183. package/dist/core/utils/wsl.mjs +4 -0
  184. package/dist/core/wxt.d.ts +19 -0
  185. package/dist/core/wxt.mjs +41 -0
  186. package/dist/core/zip.d.ts +7 -0
  187. package/dist/core/zip.mjs +137 -0
  188. package/dist/index.d.ts +4 -79
  189. package/dist/index.mjs +3 -0
  190. package/dist/modules.d.ts +10 -20
  191. package/dist/{chunk-6XSIWUWF.js → modules.mjs} +7 -16
  192. package/dist/sandbox/define-app-config.d.ts +19 -0
  193. package/dist/sandbox/define-app-config.mjs +3 -0
  194. package/dist/sandbox/define-background.d.ts +3 -0
  195. package/dist/sandbox/define-background.mjs +4 -0
  196. package/dist/sandbox/define-content-script.d.ts +2 -0
  197. package/dist/sandbox/define-content-script.mjs +3 -0
  198. package/dist/sandbox/define-unlisted-script.d.ts +3 -0
  199. package/dist/sandbox/define-unlisted-script.mjs +4 -0
  200. package/dist/sandbox/define-wxt-plugin.d.ts +2 -0
  201. package/dist/sandbox/define-wxt-plugin.mjs +3 -0
  202. package/dist/sandbox/dev-server-websocket.d.ts +21 -0
  203. package/dist/sandbox/dev-server-websocket.mjs +37 -0
  204. package/dist/sandbox/index.d.ts +11 -0
  205. package/dist/sandbox/index.mjs +6 -0
  206. package/dist/sandbox/utils/logger.d.ts +9 -0
  207. package/dist/sandbox/utils/logger.mjs +15 -0
  208. package/dist/storage.d.ts +39 -16
  209. package/dist/{storage.js → storage.mjs} +30 -41
  210. package/dist/testing/fake-browser.d.ts +1 -0
  211. package/dist/testing/fake-browser.mjs +1 -0
  212. package/dist/testing/index.d.ts +5 -0
  213. package/dist/testing/index.mjs +2 -0
  214. package/dist/{testing.d.ts → testing/wxt-vitest-plugin.d.ts} +3 -15
  215. package/dist/testing/wxt-vitest-plugin.mjs +26 -0
  216. package/dist/{index-nWRfwAJi.d.cts → types.d.ts} +150 -264
  217. package/dist/types.mjs +0 -0
  218. package/dist/version.d.ts +1 -0
  219. package/dist/version.mjs +1 -0
  220. package/dist/virtual/{background-entrypoint.js → background-entrypoint.mjs} +31 -40
  221. package/dist/virtual/{content-script-isolated-world-entrypoint.js → content-script-isolated-world-entrypoint.mjs} +9 -13
  222. package/dist/virtual/{content-script-main-world-entrypoint.js → content-script-main-world-entrypoint.mjs} +9 -14
  223. package/dist/virtual/mock-browser.mjs +6 -0
  224. package/dist/virtual/{reload-html.js → reload-html.mjs} +8 -9
  225. package/dist/virtual/{unlisted-script-entrypoint.js → unlisted-script-entrypoint.mjs} +8 -12
  226. package/package.json +47 -57
  227. package/dist/browser.d.ts +0 -18
  228. package/dist/browser.js +0 -6
  229. package/dist/chunk-BM6QYGAW.js +0 -1063
  230. package/dist/chunk-FNTE2L27.js +0 -7
  231. package/dist/chunk-FP7RYLVL.js +0 -3617
  232. package/dist/chunk-KPD5J7PZ.js +0 -1065
  233. package/dist/chunk-QGM4M3NI.js +0 -37
  234. package/dist/chunk-SGKCDMVR.js +0 -38
  235. package/dist/cli.d.ts +0 -2
  236. package/dist/cli.js +0 -4438
  237. package/dist/client.js +0 -424
  238. package/dist/define-app-config-bg54F_lV.d.ts +0 -294
  239. package/dist/execa-4UBDUBJZ.js +0 -7244
  240. package/dist/execa-QLUM2B3W.js +0 -7245
  241. package/dist/index-nWRfwAJi.d.ts +0 -1401
  242. package/dist/index.cjs +0 -14473
  243. package/dist/index.d.cts +0 -81
  244. package/dist/index.js +0 -696
  245. package/dist/modules.cjs +0 -96
  246. package/dist/modules.d.cts +0 -119
  247. package/dist/modules.js +0 -17
  248. package/dist/prompt-25QIVJDC.js +0 -755
  249. package/dist/prompt-7BMKNSWS.js +0 -754
  250. package/dist/sandbox.d.ts +0 -16
  251. package/dist/sandbox.js +0 -36
  252. package/dist/storage.cjs +0 -439
  253. package/dist/storage.d.cts +0 -200
  254. package/dist/testing.cjs +0 -2815
  255. package/dist/testing.d.cts +0 -30
  256. package/dist/testing.js +0 -40
  257. package/dist/virtual/mock-browser.js +0 -6
@@ -0,0 +1,512 @@
1
+ import fs from "fs-extra";
2
+ import { resolve } from "path";
3
+ import { getEntrypointBundlePath } from "./entrypoints.mjs";
4
+ import { ContentSecurityPolicy } from "./content-security-policy.mjs";
5
+ import {
6
+ hashContentScriptOptions,
7
+ mapWxtOptionsToContentScript
8
+ } from "./content-scripts.mjs";
9
+ import { getPackageJson } from "./package.mjs";
10
+ import { normalizePath } from "./paths.mjs";
11
+ import { writeFileIfDifferent } from "./fs.mjs";
12
+ import defu from "defu";
13
+ import { wxt } from "../wxt.mjs";
14
+ export async function writeManifest(manifest, output) {
15
+ const str = wxt.config.mode === "production" ? JSON.stringify(manifest) : JSON.stringify(manifest, null, 2);
16
+ await fs.ensureDir(wxt.config.outDir);
17
+ await writeFileIfDifferent(resolve(wxt.config.outDir, "manifest.json"), str);
18
+ output.publicAssets.unshift({
19
+ type: "asset",
20
+ fileName: "manifest.json"
21
+ });
22
+ }
23
+ export async function generateManifest(entrypoints, buildOutput) {
24
+ const warnings = [];
25
+ const pkg = await getPackageJson();
26
+ let versionName = wxt.config.manifest.version_name ?? wxt.config.manifest.version ?? pkg?.version;
27
+ if (versionName == null) {
28
+ versionName = "0.0.0";
29
+ wxt.logger.warn(
30
+ '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'
31
+ );
32
+ }
33
+ const version = wxt.config.manifest.version ?? simplifyVersion(versionName);
34
+ const baseManifest = {
35
+ manifest_version: wxt.config.manifestVersion,
36
+ name: pkg?.name,
37
+ description: pkg?.description,
38
+ version,
39
+ short_name: pkg?.shortName,
40
+ icons: discoverIcons(buildOutput)
41
+ };
42
+ const userManifest = wxt.config.manifest;
43
+ let manifest = defu(
44
+ userManifest,
45
+ baseManifest
46
+ );
47
+ if (wxt.config.command === "serve" && wxt.config.dev.reloadCommand) {
48
+ if (manifest.commands && Object.keys(manifest.commands).length >= 4) {
49
+ warnings.push([
50
+ "Extension already has 4 registered commands, WXT's reload command is disabled"
51
+ ]);
52
+ } else {
53
+ manifest.commands ??= {};
54
+ manifest.commands["wxt:reload-extension"] = {
55
+ description: "Reload the extension during development",
56
+ suggested_key: {
57
+ default: wxt.config.dev.reloadCommand
58
+ }
59
+ };
60
+ }
61
+ }
62
+ manifest.version = version;
63
+ manifest.version_name = // Firefox doesn't support version_name
64
+ wxt.config.browser === "firefox" || versionName === version ? void 0 : versionName;
65
+ addEntrypoints(manifest, entrypoints, buildOutput);
66
+ if (wxt.config.command === "serve") addDevModeCsp(manifest);
67
+ if (wxt.config.command === "serve") addDevModePermissions(manifest);
68
+ wxt.config.transformManifest?.(manifest);
69
+ await wxt.hooks.callHook("build:manifestGenerated", wxt, manifest);
70
+ if (wxt.config.manifestVersion === 2) {
71
+ convertWebAccessibleResourcesToMv2(manifest);
72
+ convertActionToMv2(manifest);
73
+ moveHostPermissionsToPermissions(manifest);
74
+ }
75
+ if (wxt.config.manifestVersion === 3) {
76
+ validateMv3WebAccessbileResources(manifest);
77
+ }
78
+ stripKeys(manifest);
79
+ if (manifest.name == null)
80
+ throw Error(
81
+ "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"
82
+ );
83
+ if (manifest.version == null) {
84
+ throw Error(
85
+ "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"
86
+ );
87
+ }
88
+ return {
89
+ manifest,
90
+ warnings
91
+ };
92
+ }
93
+ function simplifyVersion(versionName) {
94
+ const version = /^((0|[1-9][0-9]{0,8})([.](0|[1-9][0-9]{0,8})){0,3}).*$/.exec(
95
+ versionName
96
+ )?.[1];
97
+ if (version == null)
98
+ throw Error(
99
+ `Cannot simplify package.json version "${versionName}" to a valid extension version, "X.Y.Z"`
100
+ );
101
+ return version;
102
+ }
103
+ function addEntrypoints(manifest, entrypoints, buildOutput) {
104
+ const entriesByType = entrypoints.reduce((map, entrypoint) => {
105
+ map[entrypoint.type] ??= [];
106
+ map[entrypoint.type]?.push(entrypoint);
107
+ return map;
108
+ }, {});
109
+ const background = entriesByType["background"]?.[0];
110
+ const bookmarks = entriesByType["bookmarks"]?.[0];
111
+ const contentScripts = entriesByType["content-script"];
112
+ const devtools = entriesByType["devtools"]?.[0];
113
+ const history = entriesByType["history"]?.[0];
114
+ const newtab = entriesByType["newtab"]?.[0];
115
+ const options = entriesByType["options"]?.[0];
116
+ const popup = entriesByType["popup"]?.[0];
117
+ const sandboxes = entriesByType["sandbox"];
118
+ const sidepanels = entriesByType["sidepanel"];
119
+ if (background) {
120
+ const script = getEntrypointBundlePath(
121
+ background,
122
+ wxt.config.outDir,
123
+ ".js"
124
+ );
125
+ if (wxt.config.browser === "firefox" && wxt.config.manifestVersion === 3) {
126
+ manifest.background = {
127
+ type: background.options.type,
128
+ scripts: [script]
129
+ };
130
+ } else if (wxt.config.manifestVersion === 3) {
131
+ manifest.background = {
132
+ type: background.options.type,
133
+ service_worker: script
134
+ };
135
+ } else {
136
+ manifest.background = {
137
+ persistent: background.options.persistent,
138
+ scripts: [script]
139
+ };
140
+ }
141
+ }
142
+ if (bookmarks) {
143
+ if (wxt.config.browser === "firefox") {
144
+ wxt.logger.warn(
145
+ "Bookmarks are not supported by Firefox. chrome_url_overrides.bookmarks was not added to the manifest"
146
+ );
147
+ } else {
148
+ manifest.chrome_url_overrides ??= {};
149
+ manifest.chrome_url_overrides.bookmarks = getEntrypointBundlePath(
150
+ bookmarks,
151
+ wxt.config.outDir,
152
+ ".html"
153
+ );
154
+ }
155
+ }
156
+ if (history) {
157
+ if (wxt.config.browser === "firefox") {
158
+ wxt.logger.warn(
159
+ "Bookmarks are not supported by Firefox. chrome_url_overrides.history was not added to the manifest"
160
+ );
161
+ } else {
162
+ manifest.chrome_url_overrides ??= {};
163
+ manifest.chrome_url_overrides.history = getEntrypointBundlePath(
164
+ history,
165
+ wxt.config.outDir,
166
+ ".html"
167
+ );
168
+ }
169
+ }
170
+ if (newtab) {
171
+ manifest.chrome_url_overrides ??= {};
172
+ manifest.chrome_url_overrides.newtab = getEntrypointBundlePath(
173
+ newtab,
174
+ wxt.config.outDir,
175
+ ".html"
176
+ );
177
+ }
178
+ if (popup) {
179
+ const default_popup = getEntrypointBundlePath(
180
+ popup,
181
+ wxt.config.outDir,
182
+ ".html"
183
+ );
184
+ const options2 = {};
185
+ if (popup.options.defaultIcon)
186
+ options2.default_icon = popup.options.defaultIcon;
187
+ if (popup.options.defaultTitle)
188
+ options2.default_title = popup.options.defaultTitle;
189
+ if (popup.options.browserStyle)
190
+ options2.browser_style = popup.options.browserStyle;
191
+ if (manifest.manifest_version === 3) {
192
+ manifest.action = {
193
+ ...manifest.action ?? {},
194
+ ...options2,
195
+ default_popup
196
+ };
197
+ } else {
198
+ const key = popup.options.mv2Key ?? "browser_action";
199
+ manifest[key] = {
200
+ ...manifest[key] ?? {},
201
+ ...options2,
202
+ default_popup
203
+ };
204
+ }
205
+ }
206
+ if (devtools) {
207
+ manifest.devtools_page = getEntrypointBundlePath(
208
+ devtools,
209
+ wxt.config.outDir,
210
+ ".html"
211
+ );
212
+ }
213
+ if (options) {
214
+ const page = getEntrypointBundlePath(options, wxt.config.outDir, ".html");
215
+ manifest.options_ui = {
216
+ open_in_tab: options.options.openInTab,
217
+ browser_style: wxt.config.browser === "firefox" ? options.options.browserStyle : void 0,
218
+ chrome_style: wxt.config.browser !== "firefox" ? options.options.chromeStyle : void 0,
219
+ page
220
+ };
221
+ }
222
+ if (sandboxes?.length) {
223
+ if (wxt.config.browser === "firefox") {
224
+ wxt.logger.warn(
225
+ "Sandboxed pages not supported by Firefox. sandbox.pages was not added to the manifest"
226
+ );
227
+ } else {
228
+ manifest.sandbox = {
229
+ pages: sandboxes.map(
230
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".html")
231
+ )
232
+ };
233
+ }
234
+ }
235
+ if (sidepanels?.length) {
236
+ const defaultSidepanel = sidepanels.find((entry) => entry.name === "sidepanel") ?? sidepanels[0];
237
+ const page = getEntrypointBundlePath(
238
+ defaultSidepanel,
239
+ wxt.config.outDir,
240
+ ".html"
241
+ );
242
+ if (wxt.config.browser === "firefox") {
243
+ manifest.sidebar_action = {
244
+ default_panel: page,
245
+ browser_style: defaultSidepanel.options.browserStyle,
246
+ default_icon: defaultSidepanel.options.defaultIcon,
247
+ default_title: defaultSidepanel.options.defaultTitle,
248
+ open_at_install: defaultSidepanel.options.openAtInstall
249
+ };
250
+ } else if (wxt.config.manifestVersion === 3) {
251
+ manifest.side_panel = {
252
+ default_path: page
253
+ };
254
+ addPermission(manifest, "sidePanel");
255
+ } else {
256
+ wxt.logger.warn(
257
+ "Side panel not supported by Chromium using MV2. side_panel.default_path was not added to the manifest"
258
+ );
259
+ }
260
+ }
261
+ if (contentScripts?.length) {
262
+ const cssMap = getContentScriptsCssMap(buildOutput, contentScripts);
263
+ if (wxt.config.command === "serve" && wxt.config.manifestVersion === 3) {
264
+ contentScripts.forEach((script) => {
265
+ script.options.matches.forEach((matchPattern) => {
266
+ addHostPermission(manifest, matchPattern);
267
+ });
268
+ });
269
+ } else {
270
+ const hashToEntrypointsMap = contentScripts.filter((cs) => cs.options.registration !== "runtime").reduce((map, script) => {
271
+ const hash = hashContentScriptOptions(script.options);
272
+ if (map.has(hash)) map.get(hash)?.push(script);
273
+ else map.set(hash, [script]);
274
+ return map;
275
+ }, /* @__PURE__ */ new Map());
276
+ const manifestContentScripts = Array.from(
277
+ hashToEntrypointsMap.values()
278
+ ).map(
279
+ (scripts) => mapWxtOptionsToContentScript(
280
+ scripts[0].options,
281
+ scripts.map(
282
+ (entry) => getEntrypointBundlePath(entry, wxt.config.outDir, ".js")
283
+ ),
284
+ getContentScriptCssFiles(scripts, cssMap)
285
+ )
286
+ );
287
+ if (manifestContentScripts.length >= 0) {
288
+ manifest.content_scripts ??= [];
289
+ manifest.content_scripts.push(...manifestContentScripts);
290
+ }
291
+ const runtimeContentScripts = contentScripts.filter(
292
+ (cs) => cs.options.registration === "runtime"
293
+ );
294
+ if (runtimeContentScripts.length > 0 && wxt.config.manifestVersion === 2) {
295
+ throw Error(
296
+ 'Cannot use `registration: "runtime"` with MV2 content scripts, it is a MV3-only feature.'
297
+ );
298
+ }
299
+ runtimeContentScripts.forEach((script) => {
300
+ script.options.matches.forEach((matchPattern) => {
301
+ addHostPermission(manifest, matchPattern);
302
+ });
303
+ });
304
+ }
305
+ const contentScriptCssResources = getContentScriptCssWebAccessibleResources(
306
+ contentScripts,
307
+ cssMap
308
+ );
309
+ if (contentScriptCssResources.length > 0) {
310
+ manifest.web_accessible_resources ??= [];
311
+ manifest.web_accessible_resources.push(...contentScriptCssResources);
312
+ }
313
+ }
314
+ }
315
+ function discoverIcons(buildOutput) {
316
+ const icons = [];
317
+ const iconRegex = [
318
+ /^icon-([0-9]+)\.png$/,
319
+ // icon-16.png
320
+ /^icon-([0-9]+)x[0-9]+\.png$/,
321
+ // icon-16x16.png
322
+ /^icon@([0-9]+)w\.png$/,
323
+ // icon@16w.png
324
+ /^icon@([0-9]+)h\.png$/,
325
+ // icon@16h.png
326
+ /^icon@([0-9]+)\.png$/,
327
+ // icon@16.png
328
+ /^icons?[\/\\]([0-9]+)\.png$/,
329
+ // icon/16.png | icons/16.png
330
+ /^icons?[\/\\]([0-9]+)x[0-9]+\.png$/
331
+ // icon/16x16.png | icons/16x16.png
332
+ ];
333
+ buildOutput.publicAssets.forEach((asset) => {
334
+ let size;
335
+ for (const regex of iconRegex) {
336
+ const match = asset.fileName.match(regex);
337
+ if (match?.[1] != null) {
338
+ size = match[1];
339
+ break;
340
+ }
341
+ }
342
+ if (size == null) return;
343
+ icons.push([size, normalizePath(asset.fileName)]);
344
+ });
345
+ return icons.length > 0 ? Object.fromEntries(icons) : void 0;
346
+ }
347
+ function addDevModeCsp(manifest) {
348
+ const permission = `http://${wxt.server?.hostname ?? ""}/*`;
349
+ const allowedCsp = wxt.server?.origin ?? "http://localhost:*";
350
+ if (manifest.manifest_version === 3) {
351
+ addHostPermission(manifest, permission);
352
+ } else {
353
+ addPermission(manifest, permission);
354
+ }
355
+ const extensionPagesCsp = new ContentSecurityPolicy(
356
+ manifest.manifest_version === 3 ? (
357
+ // @ts-expect-error: extension_pages is not typed
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
361
+ );
362
+ const sandboxCsp = new ContentSecurityPolicy(
363
+ // @ts-expect-error: sandbox is not typed
364
+ manifest.content_security_policy?.sandbox ?? "sandbox allow-scripts allow-forms allow-popups allow-modals; script-src 'self' 'unsafe-inline' 'unsafe-eval'; child-src 'self';"
365
+ // default sandbox CSP for MV3
366
+ );
367
+ if (wxt.server) {
368
+ extensionPagesCsp.add("script-src", allowedCsp);
369
+ sandboxCsp.add("script-src", allowedCsp);
370
+ }
371
+ if (manifest.manifest_version === 3) {
372
+ manifest.content_security_policy ??= {};
373
+ manifest.content_security_policy.extension_pages = extensionPagesCsp.toString();
374
+ manifest.content_security_policy.sandbox = sandboxCsp.toString();
375
+ } else {
376
+ manifest.content_security_policy = extensionPagesCsp.toString();
377
+ }
378
+ }
379
+ function addDevModePermissions(manifest) {
380
+ addPermission(manifest, "tabs");
381
+ if (wxt.config.manifestVersion === 3) addPermission(manifest, "scripting");
382
+ }
383
+ export function getContentScriptCssFiles(contentScripts, contentScriptCssMap) {
384
+ const css = [];
385
+ contentScripts.forEach((script) => {
386
+ if (script.options.cssInjectionMode === "manual" || script.options.cssInjectionMode === "ui")
387
+ return;
388
+ const cssFile = contentScriptCssMap[script.name];
389
+ if (cssFile == null) return;
390
+ if (cssFile) css.push(cssFile);
391
+ });
392
+ if (css.length > 0) return css;
393
+ return void 0;
394
+ }
395
+ export function getContentScriptCssWebAccessibleResources(contentScripts, contentScriptCssMap) {
396
+ const resources = [];
397
+ contentScripts.forEach((script) => {
398
+ if (script.options.cssInjectionMode !== "ui") return;
399
+ const cssFile = contentScriptCssMap[script.name];
400
+ if (cssFile == null) return;
401
+ resources.push({
402
+ resources: [cssFile],
403
+ matches: script.options.matches.map(
404
+ (matchPattern) => stripPathFromMatchPattern(matchPattern)
405
+ )
406
+ });
407
+ });
408
+ return resources;
409
+ }
410
+ export function getContentScriptsCssMap(buildOutput, scripts) {
411
+ const map = {};
412
+ const allChunks = buildOutput.steps.flatMap((step) => step.chunks);
413
+ scripts.forEach((script) => {
414
+ const relatedCss = allChunks.find(
415
+ (chunk) => chunk.fileName === `content-scripts/${script.name}.css`
416
+ );
417
+ if (relatedCss != null) map[script.name] = relatedCss.fileName;
418
+ });
419
+ return map;
420
+ }
421
+ function addPermission(manifest, permission) {
422
+ manifest.permissions ??= [];
423
+ if (manifest.permissions.includes(permission)) return;
424
+ manifest.permissions.push(permission);
425
+ }
426
+ function addHostPermission(manifest, hostPermission) {
427
+ manifest.host_permissions ??= [];
428
+ if (manifest.host_permissions.includes(hostPermission)) return;
429
+ manifest.host_permissions.push(hostPermission);
430
+ }
431
+ export function stripPathFromMatchPattern(pattern) {
432
+ const protocolSepIndex = pattern.indexOf("://");
433
+ if (protocolSepIndex === -1) return pattern;
434
+ const startOfPath = pattern.indexOf("/", protocolSepIndex + 3);
435
+ return pattern.substring(0, startOfPath) + "/*";
436
+ }
437
+ export function convertWebAccessibleResourcesToMv2(manifest) {
438
+ if (manifest.web_accessible_resources == null) return;
439
+ manifest.web_accessible_resources = Array.from(
440
+ new Set(
441
+ manifest.web_accessible_resources.flatMap((item) => {
442
+ if (typeof item === "string") return item;
443
+ return item.resources;
444
+ })
445
+ )
446
+ );
447
+ }
448
+ function moveHostPermissionsToPermissions(manifest) {
449
+ if (!manifest.host_permissions?.length) return;
450
+ manifest.host_permissions.forEach(
451
+ (permission) => addPermission(manifest, permission)
452
+ );
453
+ delete manifest.host_permissions;
454
+ }
455
+ function convertActionToMv2(manifest) {
456
+ if (manifest.action == null || manifest.browser_action != null || manifest.page_action != null)
457
+ return;
458
+ manifest.browser_action = manifest.action;
459
+ }
460
+ export function validateMv3WebAccessbileResources(manifest) {
461
+ if (manifest.web_accessible_resources == null) return;
462
+ const stringResources = manifest.web_accessible_resources.filter(
463
+ (item) => typeof item === "string"
464
+ );
465
+ if (stringResources.length > 0) {
466
+ throw Error(
467
+ `Non-MV3 web_accessible_resources detected: ${JSON.stringify(
468
+ stringResources
469
+ )}. When manually defining web_accessible_resources, define them as MV3 objects ({ matches: [...], resources: [...] }), and WXT will automatically convert them to MV2 when necessary.`
470
+ );
471
+ }
472
+ }
473
+ function stripKeys(manifest) {
474
+ let keysToRemove = [];
475
+ if (wxt.config.manifestVersion === 2) {
476
+ keysToRemove.push(...mv3OnlyKeys);
477
+ if (wxt.config.browser === "firefox")
478
+ keysToRemove.push(...firefoxMv3OnlyKeys);
479
+ } else {
480
+ keysToRemove.push(...mv2OnlyKeys);
481
+ }
482
+ keysToRemove.forEach((key) => {
483
+ delete manifest[key];
484
+ });
485
+ }
486
+ const mv2OnlyKeys = [
487
+ "page_action",
488
+ "browser_action",
489
+ "automation",
490
+ "content_capabilities",
491
+ "converted_from_user_script",
492
+ "current_locale",
493
+ "differential_fingerprint",
494
+ "event_rules",
495
+ "file_browser_handlers",
496
+ "file_system_provider_capabilities",
497
+ "input_components",
498
+ "nacl_modules",
499
+ "natively_connectable",
500
+ "offline_enabled",
501
+ "platforms",
502
+ "replacement_web_app",
503
+ "system_indicator",
504
+ "user_scripts"
505
+ ];
506
+ const mv3OnlyKeys = [
507
+ "action",
508
+ "export",
509
+ "optional_host_permissions",
510
+ "side_panel"
511
+ ];
512
+ const firefoxMv3OnlyKeys = ["host_permissions"];
@@ -0,0 +1,7 @@
1
+ import { ResolvedConfig } from '../../types';
2
+ export declare function isOnline(): Promise<boolean>;
3
+ /**
4
+ * Fetches a URL with a simple GET request. Grabs it from cache if it doesn't exist, or throws an
5
+ * error if it can't be resolved via the network or cache.
6
+ */
7
+ export declare function fetchCached(url: string, config: ResolvedConfig): Promise<string>;
@@ -0,0 +1,38 @@
1
+ import dns from "node:dns";
2
+ import { withTimeout } from "./time.mjs";
3
+ function isOffline() {
4
+ const isOffline2 = new Promise((res) => {
5
+ dns.resolve("google.com", (err) => {
6
+ if (err == null) {
7
+ res(false);
8
+ } else {
9
+ res(true);
10
+ }
11
+ });
12
+ });
13
+ return withTimeout(isOffline2, 1e3).catch(() => true);
14
+ }
15
+ export async function isOnline() {
16
+ const offline = await isOffline();
17
+ return !offline;
18
+ }
19
+ export async function fetchCached(url, config) {
20
+ let content = "";
21
+ if (await isOnline()) {
22
+ const res = await fetch(url);
23
+ if (res.status < 300) {
24
+ content = await res.text();
25
+ await config.fsCache.set(url, content);
26
+ } else {
27
+ config.logger.debug(
28
+ `Failed to download "${url}", falling back to cache...`
29
+ );
30
+ }
31
+ }
32
+ if (!content) content = await config.fsCache.get(url) ?? "";
33
+ if (!content)
34
+ throw Error(
35
+ `Offline and "${url}" has not been cached. Try again when online.`
36
+ );
37
+ return content;
38
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Read the project's package.json.
3
+ *
4
+ * TODO: look in root and up directories until it's found
5
+ */
6
+ export declare function getPackageJson(): Promise<Partial<Record<string, any>> | undefined>;
@@ -0,0 +1,14 @@
1
+ import { resolve } from "node:path";
2
+ import fs from "fs-extra";
3
+ import { wxt } from "../wxt.mjs";
4
+ export async function getPackageJson() {
5
+ const file = resolve(wxt.config.root, "package.json");
6
+ try {
7
+ return await fs.readJson(file);
8
+ } catch (err) {
9
+ wxt.logger.debug(
10
+ `Failed to read package.json at: ${file}. Returning undefined.`
11
+ );
12
+ return {};
13
+ }
14
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Converts system paths to normalized bundler path. On windows and unix, this returns paths with /
3
+ * instead of \.
4
+ */
5
+ export declare function normalizePath(path: string): string;
6
+ /**
7
+ * Given a normalized path, convert it to the system path style. On Windows, switch to \, otherwise use /.
8
+ */
9
+ export declare function unnormalizePath(path: string): string;
10
+ export declare const CSS_EXTENSIONS: string[];
11
+ export declare const CSS_EXTENSIONS_PATTERN: string;
@@ -0,0 +1,10 @@
1
+ import systemPath from "node:path";
2
+ import normalize from "normalize-path";
3
+ export function normalizePath(path) {
4
+ return normalize(path);
5
+ }
6
+ export function unnormalizePath(path) {
7
+ return systemPath.normalize(path);
8
+ }
9
+ export const CSS_EXTENSIONS = ["css", "scss", "sass", "less", "styl", "stylus"];
10
+ export const CSS_EXTENSIONS_PATTERN = `+(${CSS_EXTENSIONS.join("|")})`;
@@ -0,0 +1,14 @@
1
+ export declare function kebabCaseAlphanumeric(str: string): string;
2
+ /**
3
+ * Return a safe variable name for a given string.
4
+ */
5
+ export declare function safeVarName(str: string): string;
6
+ /**
7
+ * Removes import statements from the top of a file. Keeps import.meta and inline, async `import()`
8
+ * calls.
9
+ */
10
+ export declare function removeImportStatements(text: string): string;
11
+ /**
12
+ * Removes imports, ensuring that some of WXT's client imports are present, so that entrypoints can be parsed if auto-imports are disabled.
13
+ */
14
+ export declare function removeProjectImportStatements(text: string): string;
@@ -0,0 +1,18 @@
1
+ export function kebabCaseAlphanumeric(str) {
2
+ return str.toLowerCase().replace(/[^a-z0-9-\s]/g, "").replace(/\s+/g, "-");
3
+ }
4
+ export function safeVarName(str) {
5
+ return "_" + kebabCaseAlphanumeric(str.trim()).replace("-", "_");
6
+ }
7
+ export function removeImportStatements(text) {
8
+ return text.replace(
9
+ /(import\s?[\s\S]*?from\s?["'][\s\S]*?["'];?|import\s?["'][\s\S]*?["'];?)/gm,
10
+ ""
11
+ );
12
+ }
13
+ export function removeProjectImportStatements(text) {
14
+ const noImports = removeImportStatements(text);
15
+ return `import { defineUnlistedScript, defineContentScript, defineBackground } from 'wxt/sandbox';
16
+
17
+ ${noImports}`;
18
+ }