Skip to content

Commit cfff8d1

Browse files
committed
Merge remote-tracking branch 'upstream/main' into content-script-optional
2 parents 3459b5b + 09b5a19 commit cfff8d1

29 files changed

Lines changed: 254 additions & 129 deletions

File tree

bun.lock

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cspell.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ words:
7878
- Noto
7979
- ntvs
8080
- nypm
81+
- obug
8182
- ohash
8283
- oklab
8384
- oxlint

docs/guide/essentials/config/manifest.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,23 @@ export default defineConfig({
200200
});
201201
```
202202

203+
:::warning
204+
205+
Different browsers support different permissions. You are responsible for passing only the permissions required for each browser:
206+
207+
```ts
208+
export default defineConfig({
209+
manifest: ({ browser }) => ({
210+
permissions:
211+
browser === 'chrome'
212+
? ['storage', 'favicon', 'declarativeNetRequest']
213+
: ['storage', 'webRequest'],
214+
}),
215+
});
216+
```
217+
218+
:::
219+
203220
## Host Permissions
204221

205222
> [Chrome docs](https://developer.chrome.com/docs/extensions/develop/concepts/declare-permissions#host-permissions)

docs/guide/essentials/wxt-modules.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,35 @@ console.log(config.myModule);
137137

138138
This is very useful when [generating runtime code](#generate-runtime-module).
139139

140+
#### Logging
141+
142+
There are two "correct" ways to add console logs to your modules:
143+
144+
1. Use `wxt.logger` for info, warnings, and errors
145+
2. Install [`obug`](https://www.npmjs.com/package/obug) for debug messages
146+
147+
```ts
148+
import { defineWxtModule } from 'wxt/modules';
149+
import { createDebug } from 'obug';
150+
151+
const debug = createDebug('my-module');
152+
153+
export default defineWxtModule({
154+
setup(wxt) {
155+
wxt.logger.info('Module loaded');
156+
debug('Debug details');
157+
},
158+
});
159+
```
160+
161+
`wxt.logger` is great for formatted, pretty messages that match the rest of WXT's logs.
162+
163+
`obug` makes it easy for devs to enable and filter debug logs when necessary:
164+
165+
```sh
166+
DEBUG=my-module wxt dev
167+
```
168+
140169
#### Add custom entrypoint options
141170

142171
Modules can add custom options to entrypoints by augmenting the entrypoint options types. This allows you to add custom configuration that can be accessed during the build process.

packages/i18n/src/__tests__/types.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,16 @@ describe('I18n Types', () => {
3535
});
3636

3737
describe('With type-safety', () => {
38-
const i18n = createI18n<{
38+
type MyStructure = {
3939
simple: { plural: false; substitutions: 0 };
4040
simpleSub1: { plural: false; substitutions: 1 };
4141
simpleSub2: { plural: false; substitutions: 2 };
4242
plural: { plural: true; substitutions: 0 };
4343
pluralSub1: { plural: true; substitutions: 1 };
4444
pluralSub2: { plural: true; substitutions: 2 };
45-
}>();
45+
};
46+
47+
const i18n = createI18n<MyStructure>();
4648

4749
describe('t', () => {
4850
it('should only allow passing valid combinations of arguments', () => {

packages/i18n/src/index.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
/** @module @wxt-dev/i18n */
2-
import {
3-
I18nStructure,
4-
DefaultI18nStructure,
5-
I18n,
6-
Substitution,
7-
} from './types';
2+
import { I18nStructure, I18n, Substitution, UntypedI18n } from './types';
83
import { browser } from '@wxt-dev/browser';
94

10-
export function createI18n<
11-
T extends I18nStructure = DefaultI18nStructure,
12-
>(): I18n<T> {
13-
const t = (key: string, ...args: any[]) => {
5+
export function createI18n(): UntypedI18n;
6+
export function createI18n<T extends I18nStructure>(): I18n<T>;
7+
export function createI18n(): UntypedI18n {
8+
const t: UntypedI18n['t'] = (key: string, ...args: unknown[]) => {
149
// Resolve args
1510
let sub: Substitution[] | undefined;
1611
let count: number | undefined;
@@ -64,5 +59,5 @@ export function createI18n<
6459
}
6560
};
6661

67-
return { t } as I18n<T>;
62+
return { t };
6863
}

packages/i18n/src/types.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@ export interface I18nFeatures {
33
substitutions: SubstitutionCount;
44
}
55

6-
export type I18nStructure = {
7-
[K: string]: I18nFeatures;
8-
};
6+
export interface UntypedI18n {
7+
t: UntypedTFunction;
8+
}
99

10-
export type DefaultI18nStructure = {
11-
[K: string]: any;
10+
export type UntypedTFunction = {
11+
(key: string): string;
12+
(key: string, substitutions: Substitution[]): string;
13+
(key: string, n: number): string;
14+
(key: string, n: number, substitutions: Substitution[]): string;
1215
};
1316

17+
export type I18nStructure = Record<string, I18nFeatures>;
18+
19+
export interface I18n<T extends I18nStructure> {
20+
t: TFunction<T>;
21+
}
22+
1423
// prettier-ignore
1524
export type SubstitutionTuple<T extends SubstitutionCount> =
1625
T extends 1 ? [$1: Substitution]
@@ -66,10 +75,6 @@ export type TFunction<T extends I18nStructure> = {
6675
): string;
6776
};
6877

69-
export interface I18n<T extends DefaultI18nStructure> {
70-
t: TFunction<T>;
71-
}
72-
7378
export type Substitution = string | number;
7479

7580
type SubstitutionCount = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;

packages/runner/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,8 @@
4646
},
4747
"files": [
4848
"dist"
49-
]
49+
],
50+
"dependencies": {
51+
"obug": "^2.1.1"
52+
}
5053
}

packages/runner/src/__tests__/options.test.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('Options', () => {
2525
describe('extensionDir', () => {
2626
it('should default to the current working directory', async () => {
2727
const actual = await resolveRunOptions({});
28+
2829
expect(actual).toMatchObject<Partial<ResolvedRunOptions>>({
2930
extensionDir: process.cwd(),
3031
});
@@ -34,40 +35,50 @@ describe('Options', () => {
3435
const actual = await resolveRunOptions({
3536
extensionDir: './path/to/extension',
3637
});
38+
3739
expect(actual).toMatchObject<Partial<ResolvedRunOptions>>({
3840
extensionDir: resolve(process.cwd(), './path/to/extension'),
3941
});
4042
});
43+
44+
it('should use absolute paths as-is', async () => {
45+
const actual = await resolveRunOptions({
46+
extensionDir: '/abs/path/to/extension2',
47+
});
48+
49+
expect(actual).toMatchObject<Partial<ResolvedRunOptions>>({
50+
extensionDir: resolve('/abs/path/to/extension2'),
51+
});
52+
});
4153
});
4254

4355
describe('target', () => {
4456
it('should be "chrome" by default', async () => {
45-
const actual = await resolveRunOptions({
46-
extensionDir: 'path/to/extension',
47-
});
57+
const actual = await resolveRunOptions({});
58+
4859
expect(actual).toMatchObject<Partial<ResolvedRunOptions>>({
4960
target: 'chrome',
5061
});
5162
});
5263

5364
it('should be what is passed in', async () => {
5465
const actual = await resolveRunOptions({
55-
extensionDir: 'path/to/extension',
5666
target: 'custom',
5767
browserBinaries: {
5868
custom: '/path/to/custom/browser',
5969
},
6070
});
71+
6172
expect(actual).toMatchObject<Partial<ResolvedRunOptions>>({
6273
target: 'custom',
6374
});
6475
});
6576

6677
it('should throw an error if the target binary could not be found', async () => {
6778
const actual = resolveRunOptions({
68-
extensionDir: 'path/to/extension',
6979
target: 'custom',
7080
});
81+
7182
await expect(actual).rejects.toThrow('Could not find "custom" binary.');
7283
});
7384
});
@@ -83,7 +94,6 @@ describe('Options', () => {
8394
? 'C:\\path\\to\\custom\\browser.exe'
8495
: path;
8596
const actual = await resolveRunOptions({
86-
extensionDir: 'path/to/extension',
8797
target: 'custom',
8898
browserBinaries: {
8999
custom: path,
@@ -98,9 +108,11 @@ describe('Options', () => {
98108
describe('chromiumArgs', () => {
99109
it('should log a warning when --user-data-dir is passed in', async () => {
100110
const warnSpy = vi.spyOn(console, 'warn');
111+
101112
await resolveRunOptions({
102113
chromiumArgs: ['--user-data-dir=some/custom/path'],
103114
});
115+
104116
expect(warnSpy).toBeCalledTimes(1);
105117
expect(warnSpy).toHaveBeenCalledWith(
106118
expect.stringContaining(
@@ -111,9 +123,11 @@ describe('Options', () => {
111123

112124
it('should log a warning when --remote-debugging-port is passed in', async () => {
113125
const warnSpy = vi.spyOn(console, 'warn');
126+
114127
await resolveRunOptions({
115128
chromiumArgs: ['--remote-debugging-port=9222'],
116129
});
130+
117131
expect(warnSpy).toBeCalledTimes(1);
118132
expect(warnSpy).toHaveBeenCalledWith(
119133
expect.stringContaining(
@@ -126,6 +140,7 @@ describe('Options', () => {
126140
const actual = await resolveRunOptions({
127141
chromiumArgs: ['--window-size=1920,1080'],
128142
});
143+
129144
expect(actual.chromiumArgs).toEqual([
130145
// Defaults
131146
'--disable-features=Translate,OptimizationHints,MediaRouter,DialMediaRouteProvider,CalculateNativeWinOcclusion,InterestFeedContentSuggestions,CertificateTransparencyComponentUpdater,AutofillServerCommunication,PrivacySandboxSettings4',
@@ -161,9 +176,11 @@ describe('Options', () => {
161176
describe('firefoxArgs', () => {
162177
it('should log a warning when --profile is passed in', async () => {
163178
const warnSpy = vi.spyOn(console, 'warn');
179+
164180
await resolveRunOptions({
165181
firefoxArgs: ['--profile=some/custom/path'],
166182
});
183+
167184
expect(warnSpy).toBeCalledTimes(1);
168185
expect(warnSpy).toHaveBeenCalledWith(
169186
expect.stringContaining('Custom Firefox --profile argument ignored'),
@@ -172,9 +189,11 @@ describe('Options', () => {
172189

173190
it('should log a warning when --remote-debugging-port is passed in', async () => {
174191
const warnSpy = vi.spyOn(console, 'warn');
192+
175193
await resolveRunOptions({
176194
firefoxArgs: ['--remote-debugging-port=9222'],
177195
});
196+
178197
expect(warnSpy).toBeCalledTimes(1);
179198
expect(warnSpy).toHaveBeenCalledWith(
180199
expect.stringContaining(
@@ -187,6 +206,7 @@ describe('Options', () => {
187206
const actual = await resolveRunOptions({
188207
firefoxArgs: ['--window-size=1920,1080'],
189208
});
209+
190210
expect(actual.firefoxArgs).toEqual([
191211
// Defaults
192212
'--new-instance',

packages/runner/src/bidi.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { openWebSocket } from './web-socket';
2-
import { debug } from './debug';
2+
import { runnerDebug } from './debug';
33

4-
const debugBidi = debug.scoped('bidi');
4+
const debug = runnerDebug.extend('bidi');
55

66
export interface BidiConnection extends Disposable {
77
send<T>(method: string, params: any, timeout?: number): Promise<T>;
@@ -12,18 +12,18 @@ export async function createBidiConnection(
1212
baseUrl: string,
1313
): Promise<BidiConnection> {
1414
const url = new URL('/session', baseUrl);
15-
debugBidi('Connecting to BiDi server @', url.href);
15+
debug('Connecting to BiDi server @', url.href);
1616

1717
const webSocket = await openWebSocket(url.href);
18-
debugBidi('Connected');
18+
debug('Connected');
1919

2020
let requestId = 0;
2121

2222
return {
2323
send(method, params, timeout = 10e3) {
2424
const id = ++requestId;
2525
const command = { id, method, params };
26-
debugBidi('Sending command:', command);
26+
debug('Sending command:', command);
2727

2828
return new Promise((resolve, reject) => {
2929
const cleanup = () => {
@@ -43,7 +43,7 @@ export async function createBidiConnection(
4343
const onMessage = (event: MessageEvent) => {
4444
const data = JSON.parse(event.data);
4545
if (data.id === id) {
46-
debugBidi('Received response:', data);
46+
debug('Received response:', data);
4747
cleanup();
4848
if (data.type === 'success') resolve(data.result);
4949
else reject(Error(data.message, { cause: data }));
@@ -62,14 +62,14 @@ export async function createBidiConnection(
6262
},
6363

6464
close() {
65-
debugBidi('Closing connection...');
65+
debug('Closing connection...');
6666
webSocket.close();
67-
debugBidi('Closed connection');
67+
debug('Closed connection');
6868
},
6969
[Symbol.dispose]() {
70-
debugBidi('Disposing connection...');
70+
debug('Disposing connection...');
7171
webSocket.close();
72-
debugBidi('Disposed connection');
72+
debug('Disposed connection');
7373
},
7474
};
7575
}

0 commit comments

Comments
 (0)