From f6080a5b623aa09d8fee59ec01c1a2c62ed95e2c Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Fri, 11 Apr 2025 18:00:18 +0530 Subject: [PATCH 1/8] feat: Automatically update .wxt/types/paths.d.ts and web_accessible_resources manifest for favicon --- .../wxt/e2e/tests/typescript-project.test.ts | 60 +++++++++++++++++++ .../wxt/src/builtin-modules/favicon-type.ts | 20 +++++++ packages/wxt/src/builtin-modules/index.ts | 3 +- packages/wxt/src/core/generate-wxt-dir.ts | 3 +- 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 packages/wxt/src/builtin-modules/favicon-type.ts diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index de933ce7d..f590d7b1b 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -1,5 +1,10 @@ import { describe, it, expect } from 'vitest'; import { TestProject } from '../utils'; +import { + fakeBuildOutput, + setFakeWxt, +} from '../../src/core/utils/testing/fake-objects'; +import { generateManifest } from '../../src/core/utils/manifest'; describe('TypeScript Project', () => { it('should generate defined constants correctly', async () => { @@ -396,6 +401,61 @@ describe('TypeScript Project', () => { expect(output).toContain('./example.ts'); }); + it('should include favicon types in browser.runtime.getURL and in manifest web_accessible_resources ', async () => { + const project = new TestProject(); + project.addFile('entrypoints/popup.html', ''); + project.addFile('entrypoints/options.html', ''); + project.addFile('entrypoints/sandbox.html', ''); + + await project.prepare({ + manifest: { + permissions: ['favicon'], + }, + }); + + await project.build({ + manifest: { + permissions: ['favicon'], + }, + }); + + const output = await project.serializeFile('.wxt/types/paths.d.ts'); + const manifestOutput = await project.getOutputManifest(); + + const expectedWebAccessibleResource = [ + { + resources: ['/_favicon/*'], + matches: [], + }, + ]; + + expect(manifestOutput.web_accessible_resources).toEqual( + expectedWebAccessibleResource, + ); + expect(output).toMatchInlineSnapshot(` + ".wxt/types/paths.d.ts + ---------------------------------------- + // Generated by wxt + import "wxt/browser"; + + declare module "wxt/browser" { + export type PublicPath = + | "/_favicon" + | "/options.html" + | "/popup.html" + | "/sandbox.html" + | "/" + | "" + type HtmlPublicPath = Extract + export interface WxtRuntime { + getURL(path: PublicPath): string; + getURL(path: \`\${HtmlPublicPath}\${string}\`): string; + } + } + " + `); + }); + // TODO: Once a module has been published, use it here for testing - local files are never added to the .wxt/wxt.d.ts file it.todo( 'should add modules from NPM to the TS project if they have a configKey', diff --git a/packages/wxt/src/builtin-modules/favicon-type.ts b/packages/wxt/src/builtin-modules/favicon-type.ts new file mode 100644 index 000000000..1b061ef8b --- /dev/null +++ b/packages/wxt/src/builtin-modules/favicon-type.ts @@ -0,0 +1,20 @@ +import { defineWxtModule } from '../modules'; + +export default defineWxtModule({ + name: 'wxt:built-in:favicon-type', + setup(wxt) { + wxt.hooks.hook('prepare:publicPaths', async (wxt, paths) => { + if (wxt.config.manifest.permissions?.includes('favicon')) { + paths.push('_favicon/'); + wxt.hooks.hook('build:manifestGenerated', (_, manifest) => { + const favicon_resource: any = { + resources: ['/_favicon/*'], + matches: [], + }; + manifest.web_accessible_resources ??= []; + manifest.web_accessible_resources?.push(favicon_resource); + }); + } + }); + }, +}); diff --git a/packages/wxt/src/builtin-modules/index.ts b/packages/wxt/src/builtin-modules/index.ts index d958b95b4..fc9bd672d 100644 --- a/packages/wxt/src/builtin-modules/index.ts +++ b/packages/wxt/src/builtin-modules/index.ts @@ -1,4 +1,5 @@ import { WxtModule } from '../types'; import unimport from './unimport'; +import faviconTypes from './favicon-type'; -export const builtinModules: WxtModule[] = [unimport]; +export const builtinModules: WxtModule[] = [unimport, faviconTypes]; diff --git a/packages/wxt/src/core/generate-wxt-dir.ts b/packages/wxt/src/core/generate-wxt-dir.ts index b6871b8c5..8a2a67ab4 100644 --- a/packages/wxt/src/core/generate-wxt-dir.ts +++ b/packages/wxt/src/core/generate-wxt-dir.ts @@ -73,7 +73,6 @@ async function getPathsDeclarationEntry( isHtmlEntrypoint(entry) ? '.html' : '.js', ), ) - .concat(['']) .concat(await getPublicFiles()); await wxt.hooks.callHook('prepare:publicPaths', wxt, paths); @@ -82,6 +81,8 @@ async function getPathsDeclarationEntry( .map(normalizePath) .sort() .map((path) => ` | "/${path}"`) + .concat(` | "/"`) + .concat(` | ""`) .join('\n'); const template = `// Generated by wxt From a698e887819be1f26faf1249f6210fc294bc581d Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Fri, 11 Apr 2025 18:23:30 +0530 Subject: [PATCH 2/8] fix: should augment the types for browser.runtime.getURL test fixed. --- packages/wxt/e2e/tests/typescript-project.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index f590d7b1b..ad4618463 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -53,10 +53,11 @@ describe('TypeScript Project', () => { declare module "wxt/browser" { export type PublicPath = - | "/" | "/options.html" | "/popup.html" | "/sandbox.html" + | "/" + | "" type HtmlPublicPath = Extract export interface WxtRuntime { getURL(path: PublicPath): string; From 918945d685b9c09001d44f5e377c5a4d4493d785 Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Tue, 15 Apr 2025 14:26:36 +0530 Subject: [PATCH 3/8] fix: updating the name of the builtin modules for types related operations. --- packages/wxt/src/builtin-modules/index.ts | 4 ++-- .../wxt/src/builtin-modules/{favicon-type.ts => wxt-types.ts} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename packages/wxt/src/builtin-modules/{favicon-type.ts => wxt-types.ts} (94%) diff --git a/packages/wxt/src/builtin-modules/index.ts b/packages/wxt/src/builtin-modules/index.ts index fc9bd672d..29356b68f 100644 --- a/packages/wxt/src/builtin-modules/index.ts +++ b/packages/wxt/src/builtin-modules/index.ts @@ -1,5 +1,5 @@ import { WxtModule } from '../types'; import unimport from './unimport'; -import faviconTypes from './favicon-type'; +import wxtTypes from './wxt-types'; -export const builtinModules: WxtModule[] = [unimport, faviconTypes]; +export const builtinModules: WxtModule[] = [unimport, wxtTypes]; diff --git a/packages/wxt/src/builtin-modules/favicon-type.ts b/packages/wxt/src/builtin-modules/wxt-types.ts similarity index 94% rename from packages/wxt/src/builtin-modules/favicon-type.ts rename to packages/wxt/src/builtin-modules/wxt-types.ts index 1b061ef8b..ebc0d40b3 100644 --- a/packages/wxt/src/builtin-modules/favicon-type.ts +++ b/packages/wxt/src/builtin-modules/wxt-types.ts @@ -1,7 +1,7 @@ import { defineWxtModule } from '../modules'; export default defineWxtModule({ - name: 'wxt:built-in:favicon-type', + name: 'wxt:built-in:wxt-types', setup(wxt) { wxt.hooks.hook('prepare:publicPaths', async (wxt, paths) => { if (wxt.config.manifest.permissions?.includes('favicon')) { From 7f706a9ba0eeab47bef4bbeea889f82f8ff8a438 Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Thu, 17 Apr 2025 12:21:06 +0530 Subject: [PATCH 4/8] fix: updating file name for specific use-case and reverting generate-wxt-dir.ts file. --- packages/wxt/e2e/tests/typescript-project.test.ts | 6 ++---- .../builtin-modules/{wxt-types.ts => favicon-permission.ts} | 2 +- packages/wxt/src/builtin-modules/index.ts | 4 ++-- packages/wxt/src/core/generate-wxt-dir.ts | 3 +-- 4 files changed, 6 insertions(+), 9 deletions(-) rename packages/wxt/src/builtin-modules/{wxt-types.ts => favicon-permission.ts} (93%) diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index 0ae4c24df..768bd15e3 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -53,11 +53,10 @@ describe('TypeScript Project', () => { declare module "wxt/browser" { export type PublicPath = + | "/" | "/options.html" | "/popup.html" | "/sandbox.html" - | "/" - | "" type HtmlPublicPath = Extract export interface WxtRuntime { getURL(path: PublicPath): string; @@ -441,12 +440,11 @@ describe('TypeScript Project', () => { declare module "wxt/browser" { export type PublicPath = + | "/" | "/_favicon" | "/options.html" | "/popup.html" | "/sandbox.html" - | "/" - | "" type HtmlPublicPath = Extract export interface WxtRuntime { getURL(path: PublicPath): string; diff --git a/packages/wxt/src/builtin-modules/wxt-types.ts b/packages/wxt/src/builtin-modules/favicon-permission.ts similarity index 93% rename from packages/wxt/src/builtin-modules/wxt-types.ts rename to packages/wxt/src/builtin-modules/favicon-permission.ts index ebc0d40b3..97c0d872f 100644 --- a/packages/wxt/src/builtin-modules/wxt-types.ts +++ b/packages/wxt/src/builtin-modules/favicon-permission.ts @@ -1,7 +1,7 @@ import { defineWxtModule } from '../modules'; export default defineWxtModule({ - name: 'wxt:built-in:wxt-types', + name: 'wxt:built-in:favicon-permission', setup(wxt) { wxt.hooks.hook('prepare:publicPaths', async (wxt, paths) => { if (wxt.config.manifest.permissions?.includes('favicon')) { diff --git a/packages/wxt/src/builtin-modules/index.ts b/packages/wxt/src/builtin-modules/index.ts index 29356b68f..6fd4b6759 100644 --- a/packages/wxt/src/builtin-modules/index.ts +++ b/packages/wxt/src/builtin-modules/index.ts @@ -1,5 +1,5 @@ import { WxtModule } from '../types'; import unimport from './unimport'; -import wxtTypes from './wxt-types'; +import faviconPermissions from './favicon-permission'; -export const builtinModules: WxtModule[] = [unimport, wxtTypes]; +export const builtinModules: WxtModule[] = [unimport, faviconPermissions]; diff --git a/packages/wxt/src/core/generate-wxt-dir.ts b/packages/wxt/src/core/generate-wxt-dir.ts index 8a2a67ab4..b6871b8c5 100644 --- a/packages/wxt/src/core/generate-wxt-dir.ts +++ b/packages/wxt/src/core/generate-wxt-dir.ts @@ -73,6 +73,7 @@ async function getPathsDeclarationEntry( isHtmlEntrypoint(entry) ? '.html' : '.js', ), ) + .concat(['']) .concat(await getPublicFiles()); await wxt.hooks.callHook('prepare:publicPaths', wxt, paths); @@ -81,8 +82,6 @@ async function getPathsDeclarationEntry( .map(normalizePath) .sort() .map((path) => ` | "/${path}"`) - .concat(` | "/"`) - .concat(` | ""`) .join('\n'); const template = `// Generated by wxt From 3864cf3d807412129b3455eb4b727fd1df0264c6 Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Thu, 17 Apr 2025 14:28:15 +0530 Subject: [PATCH 5/8] chore: rename --- packages/wxt/src/builtin-modules/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wxt/src/builtin-modules/index.ts b/packages/wxt/src/builtin-modules/index.ts index 6fd4b6759..7f3c032dc 100644 --- a/packages/wxt/src/builtin-modules/index.ts +++ b/packages/wxt/src/builtin-modules/index.ts @@ -1,5 +1,5 @@ import { WxtModule } from '../types'; import unimport from './unimport'; -import faviconPermissions from './favicon-permission'; +import faviconPermission from './favicon-permission'; -export const builtinModules: WxtModule[] = [unimport, faviconPermissions]; +export const builtinModules: WxtModule[] = [unimport, faviconPermission]; From efbc2992bb56b43d3786b98d5cac38ce4959b821 Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Mon, 28 Apr 2025 17:05:22 +0530 Subject: [PATCH 6/8] fix: adding docs and proper type for favicon and updating tests. --- docs/guide/essentials/favicon.md | 63 +++++++++++++++++++ .../wxt/e2e/tests/typescript-project.test.ts | 3 +- .../src/builtin-modules/favicon-permission.ts | 2 +- 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 docs/guide/essentials/favicon.md diff --git a/docs/guide/essentials/favicon.md b/docs/guide/essentials/favicon.md new file mode 100644 index 000000000..89efed2d1 --- /dev/null +++ b/docs/guide/essentials/favicon.md @@ -0,0 +1,63 @@ +# Favicons + +[How to fetch favicons](https://developer.chrome.com/docs/extensions/how-to/ui/favicons) + +## What happens when you add favicons permissions in wxt.config.ts? + +WXT automatically adds value in web_accessible_resources with default and updates the types for favicons + +This is automatically added in manifest.json + +```js +"web_accessible_resources": [ + { + "resources": ["_favicon/*"], + "matches": [], + } + ] + +``` + +## If you want to add custom values in `matches` parameter you can either add by hook or [WXT Modules](https://wxt.dev/guide/essentials/wxt-modules.html#wxt-modules). + +1. Via hook in wxt.config.ts + +```js + +import { defineConfig } from "wxt"; +// See https://wxt.dev/api/config.html +export default defineConfig({ + modules: ["@wxt-dev/module-react"], + hooks: { + "build:manifestGenerated": (_, manifest) => { + const favicon_resource: any = manifest.web_accessible_resources?.find( + (resource: any) => resource.includes("favicon") + ); + favicon_resource.matches?.push(""); + manifest.web_accessible_resources ??= []; + manifest.web_accessible_resources?.push(favicon_resource); + }, + }, +}); + +``` + +2. Via module + +```js + +import { defineWxtModule } from "wxt/modules"; + +export default defineWxtModule({ + setup(wxt) { + wxt.hooks.hook("build:manifestGenerated", (_, manifest) => { + const favicon_resource: any = manifest.web_accessible_resources?.find( + (resource: any) => resource.includes("favicon") + ); + favicon_resource.matches?.push(""); + manifest.web_accessible_resources ??= []; + manifest.web_accessible_resources?.push(favicon_resource); + }); + }, +}); +``` diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index f7ed198bd..0ab4b8a68 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -441,8 +441,9 @@ describe('TypeScript Project', () => { declare module "wxt/browser" { export type PublicPath = + | "" | "/" - | "/_favicon" + | "/_favicon/?\${string}\" | "/options.html" | "/popup.html" | "/sandbox.html" diff --git a/packages/wxt/src/builtin-modules/favicon-permission.ts b/packages/wxt/src/builtin-modules/favicon-permission.ts index 97c0d872f..a9db889fe 100644 --- a/packages/wxt/src/builtin-modules/favicon-permission.ts +++ b/packages/wxt/src/builtin-modules/favicon-permission.ts @@ -5,7 +5,7 @@ export default defineWxtModule({ setup(wxt) { wxt.hooks.hook('prepare:publicPaths', async (wxt, paths) => { if (wxt.config.manifest.permissions?.includes('favicon')) { - paths.push('_favicon/'); + paths.push('_favicon/?${string}'); wxt.hooks.hook('build:manifestGenerated', (_, manifest) => { const favicon_resource: any = { resources: ['/_favicon/*'], From f617b989d968e98d5cdb6a8a8c94ba9b7a0d0531 Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Mon, 28 Apr 2025 17:47:58 +0530 Subject: [PATCH 7/8] chore: updating docs. --- docs/guide/essentials/favicon.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/guide/essentials/favicon.md b/docs/guide/essentials/favicon.md index 89efed2d1..3b509d6f1 100644 --- a/docs/guide/essentials/favicon.md +++ b/docs/guide/essentials/favicon.md @@ -1,10 +1,10 @@ # Favicons -[How to fetch favicons](https://developer.chrome.com/docs/extensions/how-to/ui/favicons) +[Chrome Docs: How to fetch favicons](https://developer.chrome.com/docs/extensions/how-to/ui/favicons) -## What happens when you add favicons permissions in wxt.config.ts? +#### What happens when you add favicons permissions in wxt.config.ts? -WXT automatically adds value in web_accessible_resources with default and updates the types for favicons +WXT automatically adds value in `web_accessible_resources` with default value and updates the types for favicon. This is automatically added in manifest.json @@ -18,7 +18,7 @@ This is automatically added in manifest.json ``` -## If you want to add custom values in `matches` parameter you can either add by hook or [WXT Modules](https://wxt.dev/guide/essentials/wxt-modules.html#wxt-modules). +#### If you want to add custom values in `matches` parameter you can either add by hook or WXT modules. 1. Via hook in wxt.config.ts @@ -42,7 +42,9 @@ export default defineConfig({ ``` -2. Via module +2. Via custom module + +- Follow the guide for [creating modules](https://wxt.dev/guide/essentials/wxt-modules.html#writing-modules) and paste this below code. ```js From a983d273546bc9ca386de508d7fd7deea94ac939 Mon Sep 17 00:00:00 2001 From: nishu-murmu Date: Mon, 28 Apr 2025 17:50:20 +0530 Subject: [PATCH 8/8] chore: removing unused imports. --- packages/wxt/e2e/tests/typescript-project.test.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/wxt/e2e/tests/typescript-project.test.ts b/packages/wxt/e2e/tests/typescript-project.test.ts index 0ab4b8a68..c02449b09 100644 --- a/packages/wxt/e2e/tests/typescript-project.test.ts +++ b/packages/wxt/e2e/tests/typescript-project.test.ts @@ -1,10 +1,5 @@ import { describe, it, expect } from 'vitest'; import { TestProject } from '../utils'; -import { - fakeBuildOutput, - setFakeWxt, -} from '../../src/core/utils/testing/fake-objects'; -import { generateManifest } from '../../src/core/utils/manifest'; describe('TypeScript Project', () => { it('should generate defined constants correctly', async () => {