wxt 0.19.22 → 0.20.0-beta1

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 (103) hide show
  1. package/README.md +6 -0
  2. package/dist/browser.d.ts +28 -0
  3. package/dist/builtin-modules/unimport.d.ts +1 -1
  4. package/dist/builtin-modules/unimport.mjs +36 -12
  5. package/dist/cli/index.mjs +0 -1
  6. package/dist/core/builders/vite/index.mjs +21 -38
  7. package/dist/core/builders/vite/plugins/extensionApiMock.d.ts +1 -6
  8. package/dist/core/builders/vite/plugins/extensionApiMock.mjs +2 -4
  9. package/dist/core/builders/vite/plugins/index.d.ts +0 -1
  10. package/dist/core/builders/vite/plugins/index.mjs +0 -1
  11. package/dist/core/builders/vite/plugins/noopBackground.mjs +1 -1
  12. package/dist/core/create-server.mjs +1 -0
  13. package/dist/core/define-web-ext-config.d.ts +9 -0
  14. package/dist/core/define-web-ext-config.mjs +10 -0
  15. package/dist/core/generate-wxt-dir.mjs +4 -6
  16. package/dist/core/index.d.ts +1 -1
  17. package/dist/core/index.mjs +1 -1
  18. package/dist/core/initialize.mjs +2 -5
  19. package/dist/core/keyboard-shortcuts.mjs +3 -9
  20. package/dist/core/resolve-config.mjs +152 -55
  21. package/dist/core/runners/web-ext.mjs +1 -1
  22. package/dist/core/utils/building/find-entrypoints.mjs +2 -1
  23. package/dist/core/utils/building/index.d.ts +0 -1
  24. package/dist/core/utils/building/index.mjs +0 -1
  25. package/dist/core/utils/building/rebuild.d.ts +1 -2
  26. package/dist/core/utils/content-scripts.d.ts +3 -3
  27. package/dist/core/utils/content-scripts.mjs +2 -0
  28. package/dist/core/utils/eslint.mjs +3 -5
  29. package/dist/core/utils/manifest.d.ts +3 -8
  30. package/dist/core/utils/manifest.mjs +4 -7
  31. package/dist/core/utils/strings.d.ts +0 -4
  32. package/dist/core/utils/strings.mjs +0 -6
  33. package/dist/core/utils/testing/fake-objects.d.ts +3416 -991
  34. package/dist/core/utils/testing/fake-objects.mjs +19 -22
  35. package/dist/core/utils/transform.d.ts +1 -1
  36. package/dist/core/utils/types.d.ts +2 -0
  37. package/dist/core/utils/validation.mjs +2 -2
  38. package/dist/index.d.ts +5 -0
  39. package/dist/modules.d.ts +1 -1
  40. package/dist/testing/index.d.ts +1 -0
  41. package/dist/testing/wxt-vitest-plugin.mjs +3 -5
  42. package/dist/types.d.ts +48 -70
  43. package/dist/utils/app-config.d.ts +2 -0
  44. package/dist/{client/content-scripts → utils}/content-script-context.d.ts +4 -3
  45. package/dist/{client/content-scripts → utils}/content-script-context.mjs +5 -3
  46. package/dist/utils/content-script-ui/iframe.d.ts +32 -0
  47. package/dist/utils/content-script-ui/iframe.mjs +30 -0
  48. package/dist/utils/content-script-ui/integrated.d.ts +34 -0
  49. package/dist/utils/content-script-ui/integrated.mjs +32 -0
  50. package/dist/utils/content-script-ui/shadow-root.d.ts +76 -0
  51. package/dist/utils/content-script-ui/shadow-root.mjs +73 -0
  52. package/dist/utils/content-script-ui/shared.d.ts +5 -0
  53. package/dist/{client/content-scripts/ui/index.mjs → utils/content-script-ui/shared.mjs} +5 -138
  54. package/dist/{client/content-scripts/ui → utils/content-script-ui}/types.d.ts +0 -96
  55. package/dist/{sandbox → utils}/define-app-config.d.ts +3 -2
  56. package/dist/{sandbox → utils}/define-background.d.ts +1 -0
  57. package/dist/{sandbox → utils}/define-content-script.d.ts +1 -0
  58. package/dist/{sandbox → utils}/define-unlisted-script.d.ts +1 -0
  59. package/dist/{sandbox → utils}/define-wxt-plugin.d.ts +1 -0
  60. package/dist/{sandbox → utils/internal}/dev-server-websocket.mjs +1 -1
  61. package/dist/{client/content-scripts → utils/internal}/location-watcher.d.ts +1 -1
  62. package/dist/utils/match-patterns.d.ts +5 -0
  63. package/dist/utils/match-patterns.mjs +1 -0
  64. package/dist/utils/storage.d.ts +5 -0
  65. package/dist/version.mjs +1 -1
  66. package/dist/virtual/background-entrypoint.mjs +1 -1
  67. package/dist/virtual/content-script-isolated-world-entrypoint.mjs +1 -1
  68. package/package.json +108 -71
  69. package/dist/browser/chrome.d.ts +0 -13
  70. package/dist/browser/index.d.ts +0 -26
  71. package/dist/browser/index.mjs +0 -2
  72. package/dist/client/app-config.d.ts +0 -2
  73. package/dist/client/content-scripts/index.d.ts +0 -2
  74. package/dist/client/content-scripts/index.mjs +0 -2
  75. package/dist/client/content-scripts/ui/index.d.ts +0 -23
  76. package/dist/client/index.d.ts +0 -8
  77. package/dist/client/index.mjs +0 -3
  78. package/dist/core/builders/vite/plugins/resolveExtensionApi.d.ts +0 -10
  79. package/dist/core/builders/vite/plugins/resolveExtensionApi.mjs +0 -15
  80. package/dist/core/define-runner-config.d.ts +0 -2
  81. package/dist/core/define-runner-config.mjs +0 -3
  82. package/dist/core/utils/building/import-entrypoint.d.ts +0 -16
  83. package/dist/core/utils/building/import-entrypoint.mjs +0 -100
  84. package/dist/sandbox/index.d.ts +0 -11
  85. package/dist/sandbox/index.mjs +0 -6
  86. package/dist/storage.d.ts +0 -4
  87. /package/dist/{browser/chrome.mjs → browser.mjs} +0 -0
  88. /package/dist/{client → utils}/app-config.mjs +0 -0
  89. /package/dist/{client/content-scripts/ui → utils/content-script-ui}/types.mjs +0 -0
  90. /package/dist/{sandbox → utils}/define-app-config.mjs +0 -0
  91. /package/dist/{sandbox → utils}/define-background.mjs +0 -0
  92. /package/dist/{sandbox → utils}/define-content-script.mjs +0 -0
  93. /package/dist/{sandbox → utils}/define-unlisted-script.mjs +0 -0
  94. /package/dist/{sandbox → utils}/define-wxt-plugin.mjs +0 -0
  95. /package/dist/{client → utils}/inject-script.d.ts +0 -0
  96. /package/dist/{client → utils}/inject-script.mjs +0 -0
  97. /package/dist/{client/content-scripts → utils/internal}/custom-events.d.ts +0 -0
  98. /package/dist/{client/content-scripts → utils/internal}/custom-events.mjs +0 -0
  99. /package/dist/{sandbox → utils/internal}/dev-server-websocket.d.ts +0 -0
  100. /package/dist/{client/content-scripts → utils/internal}/location-watcher.mjs +0 -0
  101. /package/dist/{sandbox/utils → utils/internal}/logger.d.ts +0 -0
  102. /package/dist/{sandbox/utils → utils/internal}/logger.mjs +0 -0
  103. /package/dist/{storage.mjs → utils/storage.mjs} +0 -0
@@ -160,13 +160,11 @@ export const fakeOutputAsset = fakeObjectCreator(() => ({
160
160
  export function fakeOutputFile() {
161
161
  return faker.helpers.arrayElement([fakeOutputAsset(), fakeOutputChunk()]);
162
162
  }
163
- export const fakeManifest = fakeObjectCreator(
164
- () => ({
165
- manifest_version: faker.helpers.arrayElement([2, 3]),
166
- name: faker.string.alphanumeric(),
167
- version: `${faker.number.int()}.${faker.number.int()}.${faker.number.int()}`
168
- })
169
- );
163
+ export const fakeManifest = fakeObjectCreator(() => ({
164
+ manifest_version: faker.helpers.arrayElement([2, 3]),
165
+ name: faker.string.alphanumeric(),
166
+ version: `${faker.number.int()}.${faker.number.int()}.${faker.number.int()}`
167
+ }));
170
168
  export const fakeUserManifest = fakeObjectCreator(() => ({
171
169
  name: faker.string.alphanumeric(),
172
170
  version: `${faker.number.int()}.${faker.number.int()}.${faker.number.int()}`
@@ -193,6 +191,7 @@ export const fakeResolvedConfig = fakeObjectCreator(() => {
193
191
  env: { browser, command, manifestVersion, mode },
194
192
  fsCache: mock(),
195
193
  imports: {
194
+ disabled: faker.datatype.boolean(),
196
195
  eslintrc: {
197
196
  enabled: faker.helpers.arrayElement([false, 8, 9]),
198
197
  filePath: fakeFile(),
@@ -244,12 +243,8 @@ export const fakeResolvedConfig = fakeObjectCreator(() => {
244
243
  compressionLevel: 9,
245
244
  zipSources: false
246
245
  },
247
- transformManifest: () => {
248
- },
249
246
  userConfigMetadata: {},
250
247
  alias: {},
251
- extensionApi: "webextension-polyfill",
252
- entrypointLoader: "vite-node",
253
248
  experimental: {},
254
249
  dev: {
255
250
  reloadCommand: "Alt+R"
@@ -299,17 +294,19 @@ export const fakeBuildStepOutput = fakeObjectCreator(() => ({
299
294
  chunks: fakeArray(fakeOutputChunk),
300
295
  entrypoints: fakeArray(fakeEntrypoint)
301
296
  }));
302
- export const fakeManifestCommand = fakeObjectCreator(() => ({
303
- description: faker.string.sample(),
304
- suggested_key: {
305
- default: `${faker.helpers.arrayElement(["ctrl", "alt"])}+${faker.number.int(
306
- {
307
- min: 0,
308
- max: 9
309
- }
310
- )}`
311
- }
312
- }));
297
+ export const fakeManifestCommand = fakeObjectCreator(
298
+ () => ({
299
+ description: faker.string.sample(),
300
+ suggested_key: {
301
+ default: `${faker.helpers.arrayElement(["ctrl", "alt"])}+${faker.number.int(
302
+ {
303
+ min: 0,
304
+ max: 9
305
+ }
306
+ )}`
307
+ }
308
+ })
309
+ );
313
310
  export const fakeDevServer = fakeObjectCreator(() => ({
314
311
  hostname: "localhost",
315
312
  origin: "http://localhost",
@@ -3,7 +3,7 @@
3
3
  * 1. Removes or clears out `main` function from returned object
4
4
  * 2. Removes any unused functions/variables outside the definition that aren't being called/used
5
5
  * 3. Removes unused imports
6
- * 3. Removes value-less, side-effect only imports (like `import "./styles.css"` or `import "webextension-polyfill"`)
6
+ * 3. Removes value-less, side-effect only imports (like `import "./styles.css"` or `import "polyfill"`)
7
7
  */
8
8
  export declare function removeMainFunctionCode(code: string): {
9
9
  code: string;
@@ -8,3 +8,5 @@
8
8
  export type NullablyRequired<T> = {
9
9
  [K in keyof Required<T>]: T[K];
10
10
  };
11
+ export type ManifestContentScript = NonNullable<chrome.runtime.Manifest['content_scripts']>[number];
12
+ export type ManifestV3WebAccessibleResource = NonNullable<chrome.runtime.ManifestV3['web_accessible_resources']>[number];
@@ -21,10 +21,10 @@ export function validateEntrypoints(entrypoints) {
21
21
  }
22
22
  function validateContentScriptEntrypoint(definition) {
23
23
  const errors = validateBaseEntrypoint(definition);
24
- if (definition.options.matches == null) {
24
+ if (definition.options.registration !== "runtime" && definition.options.matches == null) {
25
25
  errors.push({
26
26
  type: "error",
27
- message: "`matches` is required",
27
+ message: "`matches` is required for manifest registered content scripts",
28
28
  value: definition.options.matches,
29
29
  entrypoint: definition
30
30
  });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,9 @@
1
1
  /**
2
+ * This module contains:
3
+ * - JS APIs used by the CLI to build extensions or start dev mode.
4
+ * - Helper functions for defining project config.
5
+ * - Types for building and extension or configuring WXT.
6
+ *
2
7
  * @module wxt
3
8
  */
4
9
  export * from './core';
package/dist/modules.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Utilities for creating reusable, build-time modules for WXT.
2
+ * Utilities for creating [WXT Modules](https://wxt.dev/guide/essentials/wxt-modules.html).
3
3
  *
4
4
  * @module wxt/modules
5
5
  */
@@ -1,4 +1,5 @@
1
1
  /**
2
+ * Utilities for unit testing WXT extensions.
2
3
  * @module wxt/testing
3
4
  */
4
5
  export * from './fake-browser';
@@ -17,10 +17,8 @@ export async function WxtVitest(inlineConfig) {
17
17
  resolveAppConfig(wxt.config),
18
18
  extensionApiMock(wxt.config)
19
19
  ];
20
- if (wxt.config.imports !== false) {
21
- const unimport = createUnimport(wxt.config.imports);
22
- await unimport.init();
23
- plugins.push(unimportPlugin(unimport));
24
- }
20
+ const unimport = createUnimport(wxt.config.imports);
21
+ await unimport.init();
22
+ plugins.push(unimportPlugin(unimport, !wxt.config.imports.disabled));
25
23
  return plugins;
26
24
  }
package/dist/types.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import type * as vite from 'vite';
2
- import type { Manifest, Scripting } from 'wxt/browser';
3
2
  import { UnimportOptions, Import } from 'unimport';
4
3
  import { LogLevel } from 'consola';
5
- import type { ContentScriptContext } from './client/content-scripts/content-script-context';
4
+ import type { ContentScriptContext } from './utils/content-script-context';
6
5
  import type { PluginVisualizerOptions } from '@aklinker1/rollup-plugin-visualizer';
7
6
  import type { FSWatcher } from 'chokidar';
8
7
  import { ResolvedConfig as C12ResolvedConfig } from 'c12';
9
8
  import { Hookable, NestedHooks } from 'hookable';
10
9
  import type * as Nypm from 'nypm';
10
+ import { ManifestContentScript } from './core/utils/types';
11
11
  export interface InlineConfig {
12
12
  /**
13
13
  * Your project's root directory containing the `package.json` used to fill out the
@@ -37,7 +37,7 @@ export interface InlineConfig {
37
37
  */
38
38
  entrypointsDir?: string;
39
39
  /**
40
- * @default "${config.srcDir}/modules"
40
+ * @default "${config.root}/modules"
41
41
  */
42
42
  modulesDir?: string;
43
43
  /**
@@ -62,8 +62,8 @@ export interface InlineConfig {
62
62
  * - <span v-pre>`{{modeSuffix}}`</span>: A suffix based on the mode ('-dev' for development, '' for production)
63
63
  * - <span v-pre>`{{command}}`</span>: The WXT command being run (e.g., 'build', 'serve')
64
64
  *
65
- * @example "{{browser}}-mv{{manifestVersion}}{{modeSuffix}}"
66
- * @default <span v-pre>`"{{browser}}-mv{{manifestVersion}}"`</span>
65
+ * @example "{{browser}}-mv{{manifestVersion}}"
66
+ * @default <span v-pre>`"{{browser}}-mv{{manifestVersion}}{{modeSuffix}}"`</span>
67
67
  */
68
68
  outDirTemplate?: string;
69
69
  /**
@@ -125,9 +125,13 @@ export interface InlineConfig {
125
125
  */
126
126
  manifest?: UserManifest | Promise<UserManifest> | UserManifestFn;
127
127
  /**
128
- * Custom runner options. Options set here can be overridden in a `web-ext.config.ts` file.
128
+ * Configure browser startup. Options set here can be overridden in a `web-ext.config.ts` file.
129
129
  */
130
- runner?: ExtensionRunnerConfig;
130
+ webExt?: WebExtConfig;
131
+ /**
132
+ * @deprecated Use `webExt` instead. Same option, just renamed.
133
+ */
134
+ runner?: WebExtConfig;
131
135
  zip?: {
132
136
  /**
133
137
  * Configure the filename output when zipping files.
@@ -248,25 +252,6 @@ export interface InlineConfig {
248
252
  */
249
253
  compressionLevel?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
250
254
  };
251
- /**
252
- * @deprecated Use `hooks.build.manifestGenerated` to modify your manifest instead. This option
253
- * will be removed in v1.0
254
- *
255
- * Transform the final manifest before it's written to the file system. Edit the `manifest`
256
- * parameter directly, do not return a new object. Return values are ignored.
257
- *
258
- * @example
259
- * defineConfig({
260
- * // Add a CSS-only content script.
261
- * transformManifest(manifest) {
262
- * manifest.content_scripts.push({
263
- * matches: ["*://google.com/*"],
264
- * css: ["content-scripts/some-example.css"],
265
- * });
266
- * }
267
- * })
268
- */
269
- transformManifest?: (manifest: Manifest.WebExtensionManifest) => void;
270
255
  analysis?: {
271
256
  /**
272
257
  * Explicitly include bundle analysis when running `wxt build`. This can be overridden by the
@@ -324,30 +309,6 @@ export interface InlineConfig {
324
309
  * }
325
310
  */
326
311
  alias?: Record<string, string>;
327
- /**
328
- * Which extension API to use.
329
- *
330
- * - `"webextension-polyfill"`: Use `browser` and types from [`webextension-polyfill`](https://www.npmjs.com/package/webextension-polyfill).
331
- * - `"chrome"`: Use the regular `chrome` (or `browser` for Firefox/Safari) globals provided by the browser. Types provided by [`@types/chrome`](https://www.npmjs.com/package/@types/chrome).
332
- *
333
- * @default "webextension-polyfill"
334
- * @since 0.19.0
335
- */
336
- extensionApi?: 'webextension-polyfill' | 'chrome';
337
- /**
338
- * @deprecated Will be removed in v0.20.0, please migrate to using `vite-node`, the new default.
339
- *
340
- * Method used to import entrypoint files during the build process to extract their options.
341
- *
342
- * - `"vite-node"` (default as of 0.19.0): Uses `vite-node` to import the entrypoints. Automatically includes vite config based on your wxt.config.ts file
343
- * - `"jiti"`: Simplest and fastest, but doesn't allow using any imported variables outside the entrypoint's main function
344
- *
345
- * @see {@link https://wxt.dev/guide/go-further/entrypoint-importers.html|Entrypoint Importers}
346
- *
347
- * @default "vite-node"
348
- * @since 0.19.0
349
- */
350
- entrypointLoader?: 'vite-node' | 'jiti';
351
312
  /**
352
313
  * Experimental settings - use with caution.
353
314
  */
@@ -428,7 +389,7 @@ export interface WxtHooks {
428
389
  'vite:devServer:extendConfig': (config: vite.InlineConfig) => HookResult;
429
390
  }
430
391
  export interface BuildOutput {
431
- manifest: Manifest.WebExtensionManifest;
392
+ manifest: chrome.runtime.Manifest;
432
393
  publicAssets: OutputAsset[];
433
394
  steps: BuildStepOutput[];
434
395
  }
@@ -509,7 +470,7 @@ export interface WxtDevServer extends Omit<WxtBuilderServer, 'listen' | 'close'>
509
470
  }
510
471
  export interface ReloadContentScriptPayload {
511
472
  registration?: BaseContentScriptEntrypointOptions['registration'];
512
- contentScript: Omit<Scripting.RegisteredContentScript, 'id'>;
473
+ contentScript: Omit<chrome.scripting.RegisteredContentScript, 'id'>;
513
474
  }
514
475
  export type TargetBrowser = string;
515
476
  export type TargetManifestVersion = 2 | 3;
@@ -553,37 +514,37 @@ export interface BackgroundEntrypointOptions extends BaseEntrypointOptions {
553
514
  type?: PerBrowserOption<'module'>;
554
515
  }
555
516
  export interface BaseContentScriptEntrypointOptions extends BaseEntrypointOptions {
556
- matches?: PerBrowserOption<Manifest.ContentScript['matches']>;
517
+ matches?: PerBrowserOption<NonNullable<ManifestContentScript['matches']>>;
557
518
  /**
558
519
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
559
520
  * @default "documentIdle"
560
521
  */
561
- runAt?: PerBrowserOption<Manifest.ContentScript['run_at']>;
522
+ runAt?: PerBrowserOption<chrome.scripting.RegisteredContentScript['runAt']>;
562
523
  /**
563
524
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
564
525
  * @default false
565
526
  */
566
- matchAboutBlank?: PerBrowserOption<Manifest.ContentScript['match_about_blank']>;
527
+ matchAboutBlank?: PerBrowserOption<ManifestContentScript['match_about_blank']>;
567
528
  /**
568
529
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
569
530
  * @default []
570
531
  */
571
- excludeMatches?: PerBrowserOption<Manifest.ContentScript['exclude_matches']>;
532
+ excludeMatches?: PerBrowserOption<ManifestContentScript['exclude_matches']>;
572
533
  /**
573
534
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
574
535
  * @default []
575
536
  */
576
- includeGlobs?: PerBrowserOption<Manifest.ContentScript['include_globs']>;
537
+ includeGlobs?: PerBrowserOption<ManifestContentScript['include_globs']>;
577
538
  /**
578
539
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
579
540
  * @default []
580
541
  */
581
- excludeGlobs?: PerBrowserOption<Manifest.ContentScript['exclude_globs']>;
542
+ excludeGlobs?: PerBrowserOption<ManifestContentScript['exclude_globs']>;
582
543
  /**
583
544
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
584
545
  * @default false
585
546
  */
586
- allFrames?: PerBrowserOption<Manifest.ContentScript['all_frames']>;
547
+ allFrames?: PerBrowserOption<ManifestContentScript['all_frames']>;
587
548
  /**
588
549
  * See https://developer.chrome.com/docs/extensions/mv3/content_scripts/
589
550
  * @default false
@@ -717,6 +678,12 @@ export interface SidepanelEntrypoint extends BaseEntrypoint {
717
678
  options: ResolvedPerBrowserOptions<SidepanelEntrypointOptions, 'defaultIcon'>;
718
679
  }
719
680
  export type Entrypoint = GenericEntrypoint | BackgroundEntrypoint | ContentScriptEntrypoint | PopupEntrypoint | OptionsEntrypoint | SidepanelEntrypoint;
681
+ export interface EntrypointInfo {
682
+ name: string;
683
+ /** Absolute path to the entrypoint file. */
684
+ inputPath: string;
685
+ type: Entrypoint['type'];
686
+ }
720
687
  export type EntrypointGroup = Entrypoint | Entrypoint[];
721
688
  export type OnContentScriptStopped = (cb: () => void) => void;
722
689
  export interface IsolatedWorldContentScriptDefinition extends IsolatedWorldContentScriptEntrypointOptions {
@@ -833,9 +800,13 @@ export interface ConfigEnv {
833
800
  }
834
801
  export type WxtCommand = 'build' | 'serve';
835
802
  /**
836
- * Configure how the browser starts up.
803
+ * @deprecated Use `WebExtConfig` instead.
804
+ */
805
+ export type ExtensionRunnerConfig = WebExtConfig;
806
+ /**
807
+ * Options for how [`web-ext`](https://github.com/mozilla/web-ext) starts the browser.
837
808
  */
838
- export interface ExtensionRunnerConfig {
809
+ export interface WebExtConfig {
839
810
  /**
840
811
  * Whether or not to open the browser with the extension installed in dev mode.
841
812
  *
@@ -978,6 +949,7 @@ export interface WxtBuilderServer {
978
949
  * Chokidar file watcher instance.
979
950
  */
980
951
  watcher: FSWatcher;
952
+ on?(event: string, callback: () => void): void;
981
953
  }
982
954
  export interface ServerInfo {
983
955
  /**
@@ -1062,7 +1034,13 @@ export interface WxtHooks {
1062
1034
  * @param wxt The configured WXT object
1063
1035
  * @param manifest The manifest that was generated
1064
1036
  */
1065
- 'build:manifestGenerated': (wxt: Wxt, manifest: Manifest.WebExtensionManifest) => HookResult;
1037
+ 'build:manifestGenerated': (wxt: Wxt, manifest: chrome.runtime.Manifest) => HookResult;
1038
+ /**
1039
+ * Called once the names and paths of all entrypoints have been resolved.
1040
+ * @param wxt The configured WXT object
1041
+ * @param infos List of entrypoints found in the project's `entrypoints` directory
1042
+ */
1043
+ 'entrypoints:found': (wxt: Wxt, infos: EntrypointInfo[]) => HookResult;
1066
1044
  /**
1067
1045
  * Called once all entrypoints have been loaded from the `entrypointsDir`.
1068
1046
  * Use `wxt.builder.importEntrypoint` to load entrypoint options from the
@@ -1202,10 +1180,10 @@ export interface ResolvedConfig {
1202
1180
  manifestVersion: TargetManifestVersion;
1203
1181
  env: ConfigEnv;
1204
1182
  logger: Logger;
1205
- imports: false | WxtResolvedUnimportOptions;
1183
+ imports: WxtResolvedUnimportOptions;
1206
1184
  manifest: UserManifest;
1207
1185
  fsCache: FsCache;
1208
- runnerConfig: C12ResolvedConfig<ExtensionRunnerConfig>;
1186
+ runnerConfig: C12ResolvedConfig<WebExtConfig>;
1209
1187
  zip: {
1210
1188
  name?: string;
1211
1189
  artifactTemplate: string;
@@ -1222,10 +1200,6 @@ export interface ResolvedConfig {
1222
1200
  */
1223
1201
  zipSources: boolean;
1224
1202
  };
1225
- /**
1226
- * @deprecated Use `build:manifestGenerated` hook instead.
1227
- */
1228
- transformManifest?: (manifest: Manifest.WebExtensionManifest) => void;
1229
1203
  analysis: {
1230
1204
  enabled: boolean;
1231
1205
  open: boolean;
@@ -1243,8 +1217,6 @@ export interface ResolvedConfig {
1243
1217
  * Import aliases to absolute paths.
1244
1218
  */
1245
1219
  alias: Record<string, string>;
1246
- extensionApi: 'webextension-polyfill' | 'chrome';
1247
- entrypointLoader: 'vite-node' | 'jiti';
1248
1220
  experimental: {};
1249
1221
  dev: {
1250
1222
  /** Only defined during dev command */
@@ -1340,6 +1312,12 @@ export type WxtUnimportOptions = Partial<UnimportOptions> & {
1340
1312
  eslintrc?: Eslintrc;
1341
1313
  };
1342
1314
  export type WxtResolvedUnimportOptions = Partial<UnimportOptions> & {
1315
+ /**
1316
+ * Set to `true` when the user disabled auto-imports. We still use unimport for the #imports module, but other features should be disabled.
1317
+ *
1318
+ * You don't need to check this value before modifying the auto-import options. Even if `disabled` is `true`, there's no harm in adding imports to the config - they'll just be ignored.
1319
+ */
1320
+ disabled: boolean;
1343
1321
  eslintrc: ResolvedEslintrc;
1344
1322
  };
1345
1323
  /**
@@ -0,0 +1,2 @@
1
+ import type { WxtAppConfig } from '../utils/define-app-config';
2
+ export declare function useAppConfig(): WxtAppConfig;
@@ -1,5 +1,6 @@
1
- import { ContentScriptDefinition } from '../../types';
2
- import { WxtLocationChangeEvent } from './custom-events';
1
+ /** @module wxt/utils/content-script-context */
2
+ import { ContentScriptDefinition } from '../types';
3
+ import { WxtLocationChangeEvent } from './internal/custom-events';
3
4
  /**
4
5
  * Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
5
6
  * Used to detect and stop content script code when the script is invalidated.
@@ -10,7 +11,7 @@ import { WxtLocationChangeEvent } from './custom-events';
10
11
  * To create context for testing, you can use the class's constructor:
11
12
  *
12
13
  * ```ts
13
- * import { ContentScriptContext } from 'wxt/client';
14
+ * import { ContentScriptContext } from 'wxt/utils/content-scripts-context';
14
15
  *
15
16
  * test("storage listener should be removed when context is invalidated", () => {
16
17
  * const ctx = new ContentScriptContext('test');
@@ -1,7 +1,9 @@
1
1
  import { browser } from "wxt/browser";
2
- import { logger } from "../../sandbox/utils/logger.mjs";
3
- import { getUniqueEventName } from "./custom-events.mjs";
4
- import { createLocationWatcher } from "./location-watcher.mjs";
2
+ import { logger } from "../utils/internal/logger.mjs";
3
+ import {
4
+ getUniqueEventName
5
+ } from "./internal/custom-events.mjs";
6
+ import { createLocationWatcher } from "./internal/location-watcher.mjs";
5
7
  export class ContentScriptContext {
6
8
  constructor(contentScriptName, options) {
7
9
  this.contentScriptName = contentScriptName;
@@ -0,0 +1,32 @@
1
+ import { ContentScriptContext } from '../content-script-context';
2
+ import type { ContentScriptUi, ContentScriptUiOptions } from './types';
3
+ /**
4
+ * Create a content script UI using an iframe.
5
+ *
6
+ * @see https://wxt.dev/guide/essentials/content-scripts.html#iframe
7
+ */
8
+ export declare function createIframeUi<TMounted>(ctx: ContentScriptContext, options: IframeContentScriptUiOptions<TMounted>): IframeContentScriptUi<TMounted>;
9
+ export interface IframeContentScriptUi<TMounted> extends ContentScriptUi<TMounted> {
10
+ /**
11
+ * The iframe added to the DOM.
12
+ */
13
+ iframe: HTMLIFrameElement;
14
+ /**
15
+ * A wrapper div that assists in positioning.
16
+ */
17
+ wrapper: HTMLDivElement;
18
+ }
19
+ export type IframeContentScriptUiOptions<TMounted> = ContentScriptUiOptions<TMounted> & {
20
+ /**
21
+ * The path to the HTML page that will be shown in the iframe. This string is passed into
22
+ * `browser.runtime.getURL`.
23
+ */
24
+ page: import('wxt/browser').HtmlPublicPath;
25
+ /**
26
+ * Callback executed when mounting the UI. Use this function to customize the iframe or wrapper
27
+ * element's appearance. It is called every time `ui.mount()` is called.
28
+ *
29
+ * Optionally return a value that can be accessed at `ui.mounted` or in the `onRemove` callback.
30
+ */
31
+ onMount?: (wrapper: HTMLElement, iframe: HTMLIFrameElement) => TMounted;
32
+ };
@@ -0,0 +1,30 @@
1
+ import { browser } from "wxt/browser";
2
+ import { applyPosition, createMountFunctions, mountUi } from "./shared.mjs";
3
+ export function createIframeUi(ctx, options) {
4
+ const wrapper = document.createElement("div");
5
+ wrapper.setAttribute("data-wxt-iframe", "");
6
+ const iframe = document.createElement("iframe");
7
+ iframe.src = browser.runtime.getURL(options.page);
8
+ wrapper.appendChild(iframe);
9
+ let mounted = void 0;
10
+ const mount = () => {
11
+ applyPosition(wrapper, iframe, options);
12
+ mountUi(wrapper, options);
13
+ mounted = options.onMount?.(wrapper, iframe);
14
+ };
15
+ const remove = () => {
16
+ options.onRemove?.(mounted);
17
+ wrapper.remove();
18
+ mounted = void 0;
19
+ };
20
+ const mountFunctions = createMountFunctions({ mount, remove }, options);
21
+ ctx.onInvalidated(remove);
22
+ return {
23
+ get mounted() {
24
+ return mounted;
25
+ },
26
+ iframe,
27
+ wrapper,
28
+ ...mountFunctions
29
+ };
30
+ }
@@ -0,0 +1,34 @@
1
+ /** @module wxt/utils/content-script-ui/integrated */
2
+ import { ContentScriptContext } from '../content-script-context';
3
+ import type { ContentScriptUi, ContentScriptUiOptions } from './types';
4
+ /**
5
+ * Create a content script UI without any isolation.
6
+ *
7
+ * @see https://wxt.dev/guide/essentials/content-scripts.html#integrated
8
+ */
9
+ export declare function createIntegratedUi<TMounted>(ctx: ContentScriptContext, options: IntegratedContentScriptUiOptions<TMounted>): IntegratedContentScriptUi<TMounted>;
10
+ /**
11
+ * Shared types for the different `wxt/utils/content-script-ui/*` modules.
12
+ * @module wxt/utils/content-script-ui/types
13
+ */
14
+ export interface IntegratedContentScriptUi<TMounted> extends ContentScriptUi<TMounted> {
15
+ /**
16
+ * A wrapper div that assists in positioning.
17
+ */
18
+ wrapper: HTMLElement;
19
+ }
20
+ export type IntegratedContentScriptUiOptions<TMounted> = ContentScriptUiOptions<TMounted> & {
21
+ /**
22
+ * Tag used to create the wrapper element.
23
+ *
24
+ * @default "div"
25
+ */
26
+ tag?: string;
27
+ /**
28
+ * Callback executed when mounting the UI. This function should create and append the UI to the
29
+ * `wrapper` element. It is called every time `ui.mount()` is called.
30
+ *
31
+ * Optionally return a value that can be accessed at `ui.mounted` or in the `onRemove` callback.
32
+ */
33
+ onMount: (wrapper: HTMLElement) => TMounted;
34
+ };
@@ -0,0 +1,32 @@
1
+ import { applyPosition, createMountFunctions, mountUi } from "./shared.mjs";
2
+ export function createIntegratedUi(ctx, options) {
3
+ const wrapper = document.createElement(options.tag || "div");
4
+ wrapper.setAttribute("data-wxt-integrated", "");
5
+ let mounted = void 0;
6
+ const mount = () => {
7
+ applyPosition(wrapper, void 0, options);
8
+ mountUi(wrapper, options);
9
+ mounted = options.onMount?.(wrapper);
10
+ };
11
+ const remove = () => {
12
+ options.onRemove?.(mounted);
13
+ wrapper.replaceChildren();
14
+ wrapper.remove();
15
+ mounted = void 0;
16
+ };
17
+ const mountFunctions = createMountFunctions(
18
+ {
19
+ mount,
20
+ remove
21
+ },
22
+ options
23
+ );
24
+ ctx.onInvalidated(remove);
25
+ return {
26
+ get mounted() {
27
+ return mounted;
28
+ },
29
+ wrapper,
30
+ ...mountFunctions
31
+ };
32
+ }
@@ -0,0 +1,76 @@
1
+ import { ContentScriptContext } from '../content-script-context';
2
+ import type { ContentScriptUi, ContentScriptUiOptions } from './types';
3
+ /**
4
+ * Create a content script UI inside a [`ShadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot).
5
+ *
6
+ * > This function is async because it has to load the CSS via a network call.
7
+ *
8
+ * @see https://wxt.dev/guide/essentials/content-scripts.html#shadow-root
9
+ */
10
+ export declare function createShadowRootUi<TMounted>(ctx: ContentScriptContext, options: ShadowRootContentScriptUiOptions<TMounted>): Promise<ShadowRootContentScriptUi<TMounted>>;
11
+ export interface ShadowRootContentScriptUi<TMounted> extends ContentScriptUi<TMounted> {
12
+ /**
13
+ * The `HTMLElement` hosting the shadow root used to isolate the UI's styles. This is the element
14
+ * that get's added to the DOM. This element's style is not isolated from the webpage.
15
+ */
16
+ shadowHost: HTMLElement;
17
+ /**
18
+ * The container element inside the `ShadowRoot` whose styles are isolated. The UI is mounted
19
+ * inside this `HTMLElement`.
20
+ */
21
+ uiContainer: HTMLElement;
22
+ /**
23
+ * The shadow root performing the isolation.
24
+ */
25
+ shadow: ShadowRoot;
26
+ }
27
+ export type ShadowRootContentScriptUiOptions<TMounted> = ContentScriptUiOptions<TMounted> & {
28
+ /**
29
+ * The name of the custom component used to host the ShadowRoot. Must be kebab-case.
30
+ */
31
+ name: string;
32
+ /**
33
+ * Custom CSS text to apply to the UI. If your content script imports/generates CSS and you've
34
+ * set `cssInjectionMode: "ui"`, the imported CSS will be included automatically. You do not need
35
+ * to pass those styles in here. This is for any additional styles not in the imported CSS.
36
+ */
37
+ css?: string;
38
+ /**
39
+ * ShadowRoot's mode.
40
+ *
41
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/mode
42
+ * @default "open"
43
+ */
44
+ mode?: 'open' | 'closed';
45
+ /**
46
+ * When enabled, `event.stopPropagation` will be called on events trying to bubble out of the
47
+ * shadow root.
48
+ *
49
+ * - Set to `true` to stop the propagation of a default set of events,
50
+ * `["keyup", "keydown", "keypress"]`
51
+ * - Set to an array of event names to stop the propagation of a custom list of events
52
+ */
53
+ isolateEvents?: boolean | string[];
54
+ /**
55
+ * By default, WXT adds `all: initial` to the shadow root before the rest of
56
+ * your CSS. This resets any inheritable CSS styles that
57
+ * [normally pierce the Shadow DOM](https://open-wc.org/guides/knowledge/styling/styles-piercing-shadow-dom/).
58
+ *
59
+ * WXT resets everything but:
60
+ * - **`rem` Units**: they continue to scale based off the webpage's HTML `font-size`.
61
+ * - **CSS Variables/Custom Properties**: CSS variables defined outside the shadow root can be accessed inside it.
62
+ * - **`@font-face` Definitions**: Fonts defined outside the shadow root can be used inside it.
63
+ *
64
+ * To disable this behavior and inherit styles from the webpage, set `inheritStyles: true`.
65
+ *
66
+ * @default false
67
+ */
68
+ inheritStyles?: boolean;
69
+ /**
70
+ * Callback executed when mounting the UI. This function should create and append the UI to the
71
+ * `uiContainer` element. It is called every time `ui.mount()` is called.
72
+ *
73
+ * Optionally return a value that can be accessed at `ui.mounted` or in the `onRemove` callback.
74
+ */
75
+ onMount: (uiContainer: HTMLElement, shadow: ShadowRoot, shadowHost: HTMLElement) => TMounted;
76
+ };