Compare commits

...

18 Commits

Author SHA1 Message Date
GitHub Actions 1c3009a48f chore(release): @wxt-dev/i18n v0.2.0
vhs / vhs (push) Waiting to run
2024-10-04 23:12:34 +00:00
Aaron 6c6087249f fix!: Remove invalid options argument (#1048) 2024-10-04 18:07:57 -05:00
Aaron 539d482f71 chore: Remove TS compilerOptions.noUnusedLocals because Oxlint already does it (#1047) 2024-10-04 16:48:35 -05:00
Aaron cab97bca1e perf: Downgrade esbuild so a single version is shared between sub-dependencies (#1045) 2024-10-04 16:48:25 -05:00
Florian Metz 6020083b89 perf: Replace execa with nano-spawn for smaller package size (#1042) 2024-10-04 16:38:06 -05:00
GitHub Actions 947b24f1b0 chore(release): @wxt-dev/i18n v0.1.1
vhs / vhs (push) Waiting to run
2024-10-04 18:24:18 +00:00
windmillcode0 2c5ba64b61 fix: Friendly error messages for null and undefined values inside message files (#1041)
Co-authored-by: windmillcode0 <michaelodumosu57@gmail.com>
2024-10-04 13:19:35 -05:00
Aaron faa4fcb718 chore: Upgrade all non-major dependencies (#1040) 2024-10-03 18:47:16 -05:00
dependabot[bot] 8e9b67fea2 chore(deps): bump execa from 9.3.1 to 9.4.0 (#1031)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 18:24:43 -05:00
dependabot[bot] 659bdd46a0 chore(deps): bump linkedom from 0.18.4 to 0.18.5 (#1034)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 13:25:47 -05:00
dependabot[bot] edcc411d26 chore(deps-dev): bump changelogen from 0.5.5 to 0.5.7 (#1019)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 13:25:11 -05:00
dependabot[bot] e022423bad chore(deps): bump @vitejs/plugin-vue from 5.1.1 to 5.1.4 (#1020)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 13:13:24 -05:00
dependabot[bot] 84e1fd44eb chore(deps): bump esbuild from 0.23.0 to 0.24.0 (#1018)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 13:13:00 -05:00
dependabot[bot] b68d1ff828 chore(deps): bump magicast from 0.3.4 to 0.3.5 (#1017)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 13:11:46 -05:00
dependabot[bot] c31a5c30ed chore(deps): bump stefanzweifel/git-auto-commit-action from 4 to 5 (#1022)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-03 13:10:26 -05:00
Aaron 5b408c2bc2 chore: Update dependabot configuration 2024-10-03 13:09:01 -05:00
mezannic ca29419db6 chore: remove email from changelog (#1027) 2024-10-03 13:04:33 -05:00
Aaron ab26bdc7c1 fix: Use directory name when zip.name and package.json#name are not provided (#1028) 2024-10-03 12:26:36 -05:00
43 changed files with 1576 additions and 1342 deletions
+3 -1
View File
@@ -6,7 +6,9 @@
version: 2
updates:
- package-ecosystem: npm
directory: '/' # Location of package manifests
directories:
- /
- packages/*
schedule:
interval: 'monthly'
- package-ecosystem: 'github-actions'
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- uses: charmbracelet/vhs-action@v2.1.0
with:
path: 'docs/tapes/init-demo.tape'
- uses: stefanzweifel/git-auto-commit-action@v4
- uses: stefanzweifel/git-auto-commit-action@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
+4 -3
View File
@@ -1,6 +1,6 @@
import { resolve, join } from 'node:path';
import { resolve } from 'node:path';
import consola from 'consola';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
const cliDir = resolve('packages/wxt/src/cli/commands');
const cliDirGlob = resolve(cliDir, '**');
@@ -37,7 +37,8 @@ export default {
};
async function getHelp(command: string): Promise<string> {
const res = await execaCommand(command + ' --help', {
const args = command.split(' ');
const res = await spawn(args[0], [...args.slice(1), '--help'], {
cwd: 'packages/wxt',
});
return res.stdout;
+11 -11
View File
@@ -4,7 +4,7 @@
"engines": {
"node": ">=18.20.3"
},
"packageManager": "pnpm@9.6.0",
"packageManager": "pnpm@9.12.0",
"scripts": {
"check": "check && pnpm -r --sequential run check",
"test": "pnpm -r --sequential run test run",
@@ -17,18 +17,18 @@
"docs:preview": "pnpm -s docs:gen && vitepress preview docs"
},
"devDependencies": {
"@aklinker1/buildc": "^1.1.1",
"@aklinker1/buildc": "^1.1.4",
"@aklinker1/check": "^1.4.5",
"@types/fs-extra": "^11.0.4",
"@vitest/coverage-v8": "^2.0.4",
"changelogen": "^0.5.5",
"@vitest/coverage-v8": "^2.1.2",
"changelogen": "^0.5.7",
"consola": "^3.2.3",
"dependency-graph": "^1.0.0",
"execa": "^9.3.1",
"fast-glob": "^3.3.2",
"fs-extra": "^11.2.0",
"hasha": "^6.0.0",
"lint-staged": "^15.2.7",
"lint-staged": "^15.2.10",
"nano-spawn": "^0.1.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.3",
"simple-git-hooks": "^2.11.1",
@@ -36,12 +36,12 @@
"typedoc": "^0.25.4",
"typedoc-plugin-markdown": "4.0.0-next.23",
"typedoc-vitepress-theme": "1.0.0-next.3",
"typescript": "^5.5.4",
"vitepress": "^1.3.1",
"vitest-mock-extended": "^2.0.0",
"vue": "^3.4.34",
"typescript": "^5.6.2",
"vitepress": "^1.3.4",
"vitest-mock-extended": "^2.0.2",
"vue": "^3.5.11",
"wxt": "workspace:*",
"yaml": "^2.5.0"
"yaml": "^2.5.1"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
+3 -3
View File
@@ -46,9 +46,9 @@
},
"devDependencies": {
"@aklinker1/check": "^1.4.5",
"oxlint": "^0.9.1",
"publint": "^0.2.9",
"typescript": "^5.5.4",
"oxlint": "^0.9.9",
"publint": "^0.2.11",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"wxt": "workspace:*"
},
+35
View File
@@ -0,0 +1,35 @@
# Changelog
## v0.2.0
[⚠️ breaking changes](https://wxt.dev/guide/upgrade-guide/wxt) &bull; [compare changes](https://github.com/wxt-dev/wxt/compare/i18n-v0.1.1...i18n-v0.2.0)
### 🩹 Fixes
- ⚠️ Remove invalid options argument ([#1048](https://github.com/wxt-dev/wxt/pull/1048))
#### ⚠️ Breaking Changes
- ⚠️ Remove invalid options argument ([#1048](https://github.com/wxt-dev/wxt/pull/1048))
### ❤️ Contributors
- Aaron ([@aklinker1](http://github.com/aklinker1))
## v0.1.1
[compare changes](https://github.com/wxt-dev/wxt/compare/i18n-v0.1.0...i18n-v0.1.1)
### 🩹 Fixes
- Friendly error messages for `null` and `undefined` values inside message files ([#1041](https://github.com/wxt-dev/wxt/pull/1041))
### 🏡 Chore
- Add `oxlint` for linting ([#947](https://github.com/wxt-dev/wxt/pull/947))
- Upgrade all non-major dependencies ([#1040](https://github.com/wxt-dev/wxt/pull/1040))
### ❤️ Contributors
- Windmillcode0 <shieldmousetower734@gmail.com>
- Aaron ([@aklinker1](http://github.com/aklinker1))
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@wxt-dev/i18n",
"description": "Type-safe wrapper around browser.i18n.getMessage with additional features",
"version": "0.1.0",
"version": "0.2.0",
"type": "module",
"repository": {
"type": "git",
@@ -40,12 +40,12 @@
"devDependencies": {
"@aklinker1/check": "^1.4.5",
"@types/chrome": "^0.0.268",
"@types/node": "^20.14.2",
"oxlint": "^0.9.1",
"publint": "^0.2.8",
"typescript": "^5.4.5",
"@types/node": "^20.16.10",
"oxlint": "^0.9.9",
"publint": "^0.2.11",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"vitest": "^1.6.0",
"vitest": "^2.0.0",
"vitest-plugin-random-seed": "^1.1.0",
"wxt": "workspace:*"
},
+13
View File
@@ -161,4 +161,17 @@ describe('Built Tools', () => {
);
expect(mockWriteFile).toBeCalledWith('output.d.ts', expectedDts, 'utf8');
});
it('should throw an error if messages file contains null or undefined', async () => {
const invalidFileContent = stringifyYAML({
simple: 'example',
invalidField: null,
});
mockReadFile.mockResolvedValue(invalidFileContent);
await expect(parseMessagesFile('invalid.yml')).rejects.toThrowError(
'Messages file should not contain `null` (found at "invalidField")',
);
});
});
+3 -19
View File
@@ -1,6 +1,5 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createI18n } from '../index';
import { GetMessageOptions } from '../types';
const getMessageMock = vi.fn();
@@ -28,7 +27,7 @@ describe('createI18n', () => {
expect(actual).toBe(expectedValue);
expect(getMessageMock).toBeCalledTimes(1);
expect(getMessageMock).toBeCalledWith(expectedKey, undefined);
expect(getMessageMock).toBeCalledWith(expectedKey);
});
it.each([
@@ -55,28 +54,13 @@ describe('createI18n', () => {
expect(actual).toBe(expected);
expect(getMessageMock).toBeCalledTimes(1);
expect(getMessageMock).toBeCalledWith(key, [String(count)], undefined);
expect(getMessageMock).toBeCalledWith(key, [String(count)]);
},
);
it('should allow overriding the plural substitutions', () => {
const i18n = createI18n();
i18n.t('key', 3, ['custom']);
expect(getMessageMock).toBeCalledWith('key', ['custom'], undefined);
});
it('should pass options into browser.i18n.getMessage', () => {
const i18n = createI18n();
const options: GetMessageOptions = {
escapeLt: true,
};
i18n.t('key', options);
i18n.t('key', [''], options);
i18n.t('key', 1, options);
i18n.t('key', 1, [''], options);
getMessageMock.mock.calls.forEach((call) => {
expect(call.pop()).toEqual(options);
});
expect(getMessageMock).toBeCalledWith('key', ['custom']);
});
});
+1 -12
View File
@@ -22,13 +22,9 @@ describe('I18n Types', () => {
describe('t', () => {
it('should allow passing any combination of arguments', () => {
i18n.t('any');
i18n.t('any', { escapeLt: true });
i18n.t('any', ['one']);
i18n.t('any', ['one'], { escapeLt: true });
i18n.t('any', ['one', 'two']);
i18n.t('any', ['one', 'two'], { escapeLt: true });
i18n.t('any', n, ['one', 'two']);
i18n.t('any', n, ['one', 'two'], { escapeLt: true });
});
});
});
@@ -46,7 +42,6 @@ describe('I18n Types', () => {
describe('t', () => {
it('should only allow passing valid combinations of arguments', () => {
i18n.t('simple');
i18n.t('simple', { escapeLt: true });
// @ts-expect-error
i18n.t('simple', []);
// @ts-expect-error
@@ -55,7 +50,6 @@ describe('I18n Types', () => {
i18n.t('simple', n);
i18n.t('simpleSub1', ['one']);
i18n.t('simpleSub1', ['one'], { escapeLt: true });
// @ts-expect-error
i18n.t('simpleSub1');
// @ts-expect-error
@@ -66,7 +60,6 @@ describe('I18n Types', () => {
i18n.t('simpleSub1', n);
i18n.t('simpleSub2', ['one', 'two']);
i18n.t('simpleSub2', ['one', 'two'], { escapeLt: true });
// @ts-expect-error
i18n.t('simpleSub2');
// @ts-expect-error
@@ -77,7 +70,6 @@ describe('I18n Types', () => {
i18n.t('simpleSub2', n);
i18n.t('plural', n);
i18n.t('plural', n, { escapeLt: true });
// @ts-expect-error
i18n.t('plural');
// @ts-expect-error
@@ -88,10 +80,8 @@ describe('I18n Types', () => {
i18n.t('plural', n, ['sub']);
i18n.t('pluralSub1', n);
i18n.t('pluralSub1', n, { escapeLt: true });
i18n.t('pluralSub1', n, undefined, { escapeLt: true });
i18n.t('pluralSub1', n, undefined);
i18n.t('pluralSub1', n, ['one']);
i18n.t('pluralSub1', n, ['one'], { escapeLt: true });
// @ts-expect-error
i18n.t('pluralSub1');
// @ts-expect-error
@@ -102,7 +92,6 @@ describe('I18n Types', () => {
i18n.t('pluralSub1', n, ['one', 'two']);
i18n.t('pluralSub2', n, ['one', 'two']);
i18n.t('pluralSub2', n, ['one', 'two'], { escapeLt: true });
// @ts-expect-error
i18n.t('pluralSub2');
// @ts-expect-error
+5
View File
@@ -166,6 +166,11 @@ function _parseMessagesObject(
];
}
case 'object':
if ([null, undefined].includes(object)) {
throw new Error(
`Messages file should not contain \`${object}\` (found at "${path.join('.')}")`,
);
}
if (Array.isArray(object))
return object.flatMap((item, i) =>
_parseMessagesObject(path.concat(String(i)), item, depth + 1),
+2 -15
View File
@@ -6,7 +6,6 @@ import {
DefaultI18nStructure,
I18n,
Substitution,
GetMessageOptions,
} from './types';
export function createI18n<
@@ -16,7 +15,6 @@ export function createI18n<
// Resolve args
let sub: Substitution[] | undefined;
let count: number | undefined;
let options: GetMessageOptions | undefined;
args.forEach((arg, i) => {
if (arg == null) {
// ignore nullish args
@@ -24,8 +22,6 @@ export function createI18n<
count = arg;
} else if (Array.isArray(arg)) {
sub = arg;
} else if (typeof arg === 'object') {
options = arg;
} else {
throw Error(
`Unknown argument at index ${i}. Must be a number for pluralization, substitution array, or options object.`,
@@ -43,18 +39,9 @@ export function createI18n<
if (sub?.length) {
// Convert all substitutions to strings
const stringSubs = sub?.map((sub) => String(sub));
message = chrome.i18n.getMessage(
key.replaceAll('.', '_'),
stringSubs,
// @ts-ignore - @types/chrome doesn't type the options object, but it's there
options,
);
message = chrome.i18n.getMessage(key.replaceAll('.', '_'), stringSubs);
} else {
message = chrome.i18n.getMessage(
key.replaceAll('.', '_'),
// @ts-ignore - @types/chrome doesn't type the options object, but it's there
options,
);
message = chrome.i18n.getMessage(key.replaceAll('.', '_'));
}
if (!message) {
console.warn(`[i18n] Message not found: "${key}"`);
-14
View File
@@ -29,7 +29,6 @@ export type TFunction<T extends I18nStructure> = {
<K extends keyof T>(
// prettier-ignore
key: K & { [P in keyof T]: T[P] extends { plural: false; substitutions: 0 } ? P : never; }[keyof T],
options?: GetMessageOptions,
): string;
// Non-plural with substitutions
@@ -39,7 +38,6 @@ export type TFunction<T extends I18nStructure> = {
substitutions: T[K] extends I18nFeatures
? SubstitutionTuple<T[K]['substitutions']>
: never,
options?: GetMessageOptions,
): string;
// Plural with 1 substitution
@@ -48,7 +46,6 @@ export type TFunction<T extends I18nStructure> = {
key: K & { [P in keyof T]: T[P] extends { plural: true; substitutions: 1 } ? P : never; }[keyof T],
n: number,
substitutions?: SubstitutionTuple<1>,
options?: GetMessageOptions,
): string;
// Plural without substitutions
@@ -56,7 +53,6 @@ export type TFunction<T extends I18nStructure> = {
// prettier-ignore
key: K & { [P in keyof T]: T[P] extends { plural: true; substitutions: 0 | 1 } ? P : never; }[keyof T],
n: number,
options?: GetMessageOptions,
): string;
// Plural with substitutions
@@ -67,7 +63,6 @@ export type TFunction<T extends I18nStructure> = {
substitutions: T[K] extends I18nFeatures
? SubstitutionTuple<T[K]['substitutions']>
: never,
options?: GetMessageOptions,
): string;
};
@@ -77,13 +72,4 @@ export interface I18n<T extends DefaultI18nStructure> {
export type Substitution = string | number;
export interface GetMessageOptions {
/**
* Escape `<` in translation to `&lt;`. This applies only to the message itself, not to the placeholders. Developers might want to use this if the translation is used in an HTML context. Closure Templates used with Closure Compiler generate this automatically.
*
* See https://developer.chrome.com/docs/extensions/reference/api/i18n#type-getMessage-options
*/
escapeLt?: boolean;
}
type SubstitutionCount = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
+4 -4
View File
@@ -47,16 +47,16 @@
"wxt": ">=0.18.6"
},
"dependencies": {
"@vitejs/plugin-react": "^4.3.1"
"@vitejs/plugin-react": "^4.3.2"
},
"devDependencies": {
"@aklinker1/check": "^1.4.5",
"@types/react": "^18.3.3",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"publint": "^0.2.9",
"publint": "^0.2.11",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.5.4",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"wxt": "workspace:*"
}
+3 -3
View File
@@ -51,9 +51,9 @@
},
"devDependencies": {
"@aklinker1/check": "^1.4.5",
"publint": "^0.2.9",
"solid-js": "^1.8.19",
"typescript": "^5.5.4",
"publint": "^0.2.11",
"solid-js": "^1.9.1",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"wxt": "workspace:*"
}
+3 -3
View File
@@ -45,12 +45,12 @@
"wxt": ">=0.18.6"
},
"dependencies": {
"@sveltejs/vite-plugin-svelte": "^3.1.1"
"@sveltejs/vite-plugin-svelte": "^3.1.2"
},
"devDependencies": {
"@aklinker1/check": "^1.4.5",
"publint": "^0.2.9",
"typescript": "^5.5.4",
"publint": "^0.2.11",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"wxt": "workspace:*"
}
+3 -3
View File
@@ -45,12 +45,12 @@
"wxt": ">=0.18.6"
},
"dependencies": {
"@vitejs/plugin-vue": "^5.1.1"
"@vitejs/plugin-vue": "^5.1.4"
},
"devDependencies": {
"@aklinker1/check": "^1.4.5",
"publint": "^0.2.9",
"typescript": "^5.5.4",
"publint": "^0.2.11",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"wxt": "workspace:*"
}
+4 -4
View File
@@ -23,12 +23,12 @@
},
"devDependencies": {
"@types/chrome": "^0.0.269",
"@types/react": "^18.3.3",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@wxt-dev/auto-icons": "workspace:*",
"sass": "^1.77.8",
"typescript": "^5.5.4",
"vitest": "^2.0.4",
"sass": "^1.79.4",
"typescript": "^5.6.2",
"vitest": "^2.1.2",
"vitest-plugin-random-seed": "^1.1.0",
"wxt": "workspace:*"
},
+1 -1
View File
@@ -22,7 +22,7 @@
- Florian Metz ([@Timeraa](http://github.com/Timeraa))
- Gurvir Singh ([@baraich](http://github.com/baraich))
- Mezannic <mezannic@gmail.com>
- Mezannic ([@mezannic](http://github.com/mezannic))
- Aaron ([@aklinker1](http://github.com/aklinker1))
## v0.19.10
+6 -4
View File
@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { TestProject } from '../utils';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
describe('Auto Imports', () => {
describe('imports: { ... }', () => {
@@ -180,7 +180,7 @@ describe('Auto Imports', () => {
await project.prepare({
imports: { eslintrc: { enabled: version } },
});
return await execaCommand('pnpm eslint entrypoints/background.js', {
return await spawn('pnpm', ['eslint', 'entrypoints/background.js'], {
cwd: project.root,
});
}
@@ -205,7 +205,8 @@ describe('Auto Imports', () => {
);
await expect(runEslint(project, 9)).rejects.toMatchObject({
message: expect.stringContaining(
exitCode: 1,
stdout: expect.stringContaining(
"'defineBackground' is not defined",
),
});
@@ -253,7 +254,8 @@ describe('Auto Imports', () => {
);
await expect(runEslint(project, 8)).rejects.toMatchObject({
message: expect.stringContaining(
exitCode: 1,
stdout: expect.stringContaining(
"'defineBackground' is not defined",
),
});
+19 -11
View File
@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { TestProject, WXT_PACKAGE_DIR } from '../utils';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
import glob from 'fast-glob';
import { mkdir, writeJson } from 'fs-extra';
@@ -8,11 +8,15 @@ describe('Init command', () => {
it('should download and create a template', async () => {
const project = new TestProject();
await execaCommand(`pnpm -s wxt init ${project.root} -t vue --pm npm`, {
env: { ...process.env, CI: 'true' },
stdio: 'ignore',
cwd: WXT_PACKAGE_DIR,
});
await spawn(
'pnpm',
['-s', 'wxt', 'init', project.root, '-t', 'vue', '--pm', 'npm'],
{
env: { CI: 'true' },
stdio: 'ignore',
cwd: WXT_PACKAGE_DIR,
},
);
const files = await glob('**/*', {
cwd: project.root,
onlyFiles: true,
@@ -51,11 +55,15 @@ describe('Init command', () => {
await writeJson(project.resolvePath('package.json'), {});
await expect(() =>
execaCommand(`pnpm -s wxt init ${project.root} -t vue --pm npm`, {
env: { ...process.env, CI: 'true' },
stdio: 'ignore',
cwd: WXT_PACKAGE_DIR,
}),
spawn(
'pnpm',
['-s', 'wxt', 'init', project.root, '-t', 'vue', '--pm', 'npm'],
{
env: { CI: 'true' },
stdio: 'ignore',
cwd: WXT_PACKAGE_DIR,
},
),
).rejects.toThrowError('Command failed with exit code 1:');
});
});
@@ -0,0 +1,40 @@
import { test, expect } from 'vitest';
import spawn from 'nano-spawn';
import {
NpmListDependency,
NpmListProject,
} from '../../src/core/package-managers/npm';
// Tests to ensure the total size of the WXT module is as small as possible
// https://pkg-size.dev/wxt
test('Only one version of esbuild should be installed (each version is ~20mb of node_modules)', async () => {
const { stdout } = await spawn('pnpm', [
'why',
'esbuild',
'--prod',
'--json',
]);
const projects: NpmListProject[] = JSON.parse(stdout);
const esbuildVersions = new Set<string>();
iterateDependencies(projects, (name, meta) => {
if (name === 'esbuild') esbuildVersions.add(meta.version);
});
expect([...esbuildVersions]).toHaveLength(1);
});
function iterateDependencies(
projects: NpmListProject[],
cb: (name: string, meta: NpmListDependency) => void,
) {
const recurse = (dependencies: Record<string, NpmListDependency>) => {
Object.entries(dependencies).forEach(([name, meta]) => {
cb(name, meta);
if (meta.dependencies) recurse(meta.dependencies);
});
};
projects.forEach((project) => {
if (project.dependencies) recurse(project.dependencies);
});
}
+7 -5
View File
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
import { TestProject } from '../utils';
import extract from 'extract-zip';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
import { readFile, writeFile } from 'fs-extra';
process.env.WXT_PNPM_IGNORE_WORKSPACE = 'true';
@@ -41,13 +41,15 @@ describe('Zipping', () => {
// Build zipped extension
await expect(
execaCommand('pnpm i --ignore-workspace --frozen-lockfile false', {
spawn('pnpm', ['i', '--ignore-workspace', '--frozen-lockfile', 'false'], {
cwd: unzipDir,
}),
).resolves.toMatchObject({ exitCode: 0 });
).resolves.not.toHaveProperty('exitCode');
await expect(
execaCommand('pnpm wxt build -b firefox', { cwd: unzipDir }),
).resolves.toMatchObject({ exitCode: 0 });
spawn('pnpm', ['wxt', 'build', '-b', 'firefox'], {
cwd: unzipDir,
}),
).resolves.not.toHaveProperty('exitCode');
await expect(project.fileExists(unzipDir, '.output')).resolves.toBe(true);
expect(
+2 -2
View File
@@ -1,7 +1,7 @@
import { dirname, relative, resolve } from 'path';
import fs, { mkdir } from 'fs-extra';
import glob from 'fast-glob';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
import {
InlineConfig,
UserConfig,
@@ -119,7 +119,7 @@ export class TestProject {
await fs.writeFile(filePath, content ?? '', 'utf-8');
}
await execaCommand('pnpm --ignore-workspace i --ignore-scripts', {
await spawn('pnpm', ['--ignore-workspace', 'i', '--ignore-scripts'], {
cwd: this.root,
});
await mkdir(resolve(this.root, 'public'), { recursive: true }).catch(
+18 -18
View File
@@ -88,7 +88,7 @@
"@webext-core/isolated-element": "^1.1.2",
"@webext-core/match-patterns": "^1.0.3",
"async-mutex": "^0.5.0",
"c12": "^1.11.1",
"c12": "^1.11.2",
"cac": "^6.7.14",
"chokidar": "^3.6.0",
"ci-info": "^4.0.0",
@@ -96,10 +96,9 @@
"defu": "^6.1.4",
"dequal": "^2.0.3",
"dotenv": "^16.4.5",
"esbuild": "^0.23.0",
"execa": "^9.3.1",
"esbuild": "^0.21.5",
"fast-glob": "^3.3.2",
"filesize": "^10.1.4",
"filesize": "^10.1.6",
"fs-extra": "^11.2.0",
"get-port": "^7.1.0",
"giget": "^1.2.3",
@@ -108,23 +107,24 @@
"jiti": "^1.21.6",
"json5": "^2.2.3",
"jszip": "^3.10.1",
"linkedom": "^0.18.4",
"magicast": "^0.3.4",
"linkedom": "^0.18.5",
"magicast": "^0.3.5",
"minimatch": "^10.0.1",
"nano-spawn": "^0.1.0",
"natural-compare": "^1.4.0",
"normalize-path": "^3.0.0",
"nypm": "^0.3.9",
"ohash": "^1.1.3",
"nypm": "^0.3.12",
"ohash": "^1.1.4",
"open": "^10.1.0",
"ora": "^8.1.0",
"perfect-debounce": "^1.0.0",
"picocolors": "^1.0.1",
"picocolors": "^1.1.0",
"prompts": "^2.4.2",
"publish-browser-extension": "^2.1.3",
"publish-browser-extension": "^2.2.2",
"scule": "^1.3.0",
"unimport": "^3.11.1",
"vite": "^5.3.5",
"vite-node": "^2.0.4",
"unimport": "^3.13.1",
"vite": "^5.4.8",
"vite-node": "^2.1.2",
"web-ext-run": "^0.2.1",
"webextension-polyfill": "^0.12.0"
},
@@ -134,19 +134,19 @@
"@types/fs-extra": "^11.0.4",
"@types/lodash.merge": "^4.6.9",
"@types/natural-compare": "^1.4.3",
"@types/node": "^20.14.12",
"@types/node": "^20.16.10",
"@types/normalize-path": "^3.0.2",
"@types/prompts": "^2.4.9",
"extract-zip": "^2.0.1",
"happy-dom": "^14.12.3",
"lodash.merge": "^4.6.2",
"oxlint": "^0.9.1",
"oxlint": "^0.9.9",
"p-map": "^7.0.2",
"publint": "^0.2.9",
"publint": "^0.2.11",
"tsx": "4.15.7",
"typescript": "^5.5.4",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"vitest": "^2.0.4",
"vitest": "^2.1.2",
"vitest-plugin-random-seed": "^1.1.0"
},
"peerDependenciesMeta": {
+10 -6
View File
@@ -11,13 +11,17 @@ export type AugmentedBrowser = Omit<Browser, 'runtime' | 'i18n'> & {
i18n: WxtI18n & Omit<Browser['i18n'], 'getMessage'>;
};
export interface WxtRuntime {
// Overriden per-project
}
/**
* This interface is empty because it is generated per-project when running `wxt prepare`. See:
* - `.wxt/types/paths.d.ts`
*/
export interface WxtRuntime {}
export interface WxtI18n {
// Overriden per-project
}
/**
* This interface is empty because it is generated per-project when running `wxt prepare`. See:
* - `.wxt/types/i18n.d.ts`
*/
export interface WxtI18n {}
export const browser: AugmentedBrowser = originalBrowser;
+2 -2
View File
@@ -5,6 +5,7 @@ import { printHeader } from '../core/utils/log';
import { formatDuration } from '../core/utils/time';
import { ValidationError } from '../core/utils/validation';
import { registerWxt } from '../core/wxt';
import spawn from 'nano-spawn';
/**
* Wrap an action handler to add a timer, error handling, and maybe enable debug mode.
@@ -87,8 +88,7 @@ export function createAliasedCommand(
const args = process.argv.slice(
process.argv.indexOf(aliasedCommand.name) + 1,
);
const { execa } = await import('execa');
await execa(bin, args, {
await spawn(bin, args, {
stdio: 'inherit',
});
} catch {
@@ -1,7 +1,7 @@
import { beforeAll, describe, expect, it } from 'vitest';
import path from 'node:path';
import { npm } from '../npm';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
import { exists } from 'fs-extra';
describe('NPM Package Management Utils', () => {
@@ -9,7 +9,7 @@ describe('NPM Package Management Utils', () => {
const cwd = path.resolve(__dirname, 'fixtures/simple-npm-project');
beforeAll(async () => {
// NPM needs the modules installed for 'npm ls' to work
await execaCommand('npm i', { cwd });
await spawn('npm', ['i'], { cwd });
}, 60e3);
it('should list direct dependencies', async () => {
@@ -1,7 +1,7 @@
import { beforeAll, describe, expect, it } from 'vitest';
import path from 'node:path';
import { pnpm } from '../pnpm';
import { execaCommand } from 'execa';
import spawn from 'nano-spawn';
process.env.WXT_PNPM_IGNORE_WORKSPACE = 'true';
@@ -10,7 +10,7 @@ describe('PNPM Package Management Utils', () => {
const cwd = path.resolve(__dirname, 'fixtures/simple-pnpm-project');
beforeAll(async () => {
// PNPM needs the modules installed, or 'pnpm ls' will return a blank list.
await execaCommand('pnpm i --ignore-workspace', { cwd });
await spawn('pnpm', ['i', '--ignore-workspace'], { cwd });
});
it('should list direct dependencies', async () => {
@@ -1,5 +1,6 @@
import { dedupeDependencies, npm } from './npm';
import { WxtPackageManagerImpl } from './types';
import spawn from 'nano-spawn';
export const bun: WxtPackageManagerImpl = {
overridesKey: 'overrides', // But also supports "resolutions"
@@ -11,8 +12,7 @@ export const bun: WxtPackageManagerImpl = {
if (options?.all) {
args.push('--all');
}
const { execa } = await import('execa');
const res = await execa('bun', args, { cwd: options?.cwd });
const res = await spawn('bun', args, { cwd: options?.cwd });
return dedupeDependencies(
res.stdout
.split('\n')
@@ -2,13 +2,13 @@ import { Dependency } from '../../types';
import { WxtPackageManagerImpl } from './types';
import path from 'node:path';
import { ensureDir } from 'fs-extra';
import spawn from 'nano-spawn';
export const npm: WxtPackageManagerImpl = {
overridesKey: 'overrides',
async downloadDependency(id, downloadDir) {
await ensureDir(downloadDir);
const { execa } = await import('execa');
const res = await execa('npm', ['pack', id, '--json'], {
const res = await spawn('npm', ['pack', id, '--json'], {
cwd: downloadDir,
});
const packed: PackedDependency[] = JSON.parse(res.stdout);
@@ -19,8 +19,7 @@ export const npm: WxtPackageManagerImpl = {
if (options?.all) {
args.push('--depth', 'Infinity');
}
const { execa } = await import('execa');
const res = await execa('npm', args, { cwd: options?.cwd });
const res = await spawn('npm', args, { cwd: options?.cwd });
const project: NpmListProject = JSON.parse(res.stdout);
return flattenNpmListOutput([project]);
@@ -1,5 +1,6 @@
import { NpmListProject, flattenNpmListOutput, npm } from './npm';
import { WxtPackageManagerImpl } from './types';
import spawn from 'nano-spawn';
export const pnpm: WxtPackageManagerImpl = {
overridesKey: 'resolutions', // "pnpm.overrides" has a higher priority, but I don't want to deal with nesting
@@ -19,8 +20,7 @@ export const pnpm: WxtPackageManagerImpl = {
) {
args.push('--ignore-workspace');
}
const { execa } = await import('execa');
const res = await execa('pnpm', args, { cwd: options?.cwd });
const res = await spawn('pnpm', args, { cwd: options?.cwd });
const projects: NpmListProject[] = JSON.parse(res.stdout);
return flattenNpmListOutput(projects);
@@ -1,6 +1,7 @@
import { Dependency } from '../../types';
import { WxtPackageManagerImpl } from './types';
import { dedupeDependencies, npm } from './npm';
import spawn from 'nano-spawn';
export const yarn: WxtPackageManagerImpl = {
overridesKey: 'resolutions',
@@ -12,8 +13,7 @@ export const yarn: WxtPackageManagerImpl = {
if (options?.all) {
args.push('--depth', 'Infinity');
}
const { execa } = await import('execa');
const res = await execa('yarn', args, { cwd: options?.cwd });
const res = await spawn('yarn', args, { cwd: options?.cwd });
const tree = res.stdout
.split('\n')
.map<JsonLine>((line) => JSON.parse(line))
+3 -1
View File
@@ -28,7 +28,9 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
const projectName =
wxt.config.zip.name ??
safeFilename((await getPackageJson())?.name || path.dirname(process.cwd()));
safeFilename(
(await getPackageJson())?.name || path.basename(process.cwd()),
);
const applyTemplate = (template: string): string =>
template
.replaceAll('{{name}}', projectName)
+1317 -1146
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -5,7 +5,7 @@ import {
generateMarkDown,
parseChangelogMarkdown,
} from 'changelogen';
import { execa } from 'execa';
import spawn from 'nano-spawn';
import { getPkgTag, grabPackageDetails, listCommitsInDir } from './git';
import { consola } from 'consola';
import fs from 'fs-extra';
@@ -36,7 +36,7 @@ if (currentVersion.startsWith('0.')) {
bumpType = 'patch';
}
}
await execa('pnpm', ['version', bumpType], {
await spawn('pnpm', ['version', bumpType], {
cwd: pkgDir,
});
const updatedPkgJson = await fs.readJson(pkgJsonPath);
@@ -82,11 +82,11 @@ await fs.writeFile(changelogPath, newChangelog, 'utf8');
consola.success('Updated changelog');
// Commit changes
await execa('git', ['add', pkgJsonPath, changelogPath]);
await execa('git', [
await spawn('git', ['add', pkgJsonPath, changelogPath]);
await spawn('git', [
'commit',
'-m',
`chore(release): ${pkgName} v${newVersion}`,
]);
await execa('git', ['tag', newTag]);
await spawn('git', ['tag', newTag]);
consola.success('Committed version and changelog');
+8 -1
View File
@@ -1,4 +1,11 @@
// https://github.com/antfu-collective/taze?tab=readme-ov-file#config-file
export default {
exclude: ['typedoc', 'typedoc-plugin-markdown', 'typedoc-vitepress-theme'],
exclude: [
// Very touchy, don't change:
'typedoc',
'typedoc-plugin-markdown',
'typedoc-vitepress-theme',
// Manually manage version so a single version is used:
'esbuild',
],
};
+4 -4
View File
@@ -19,10 +19,10 @@
"react-dom": "^18.3.1"
},
"devDependencies": {
"@types/react": "^18.3.3",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@wxt-dev/module-react": "^1.1.0",
"typescript": "^5.5.4",
"wxt": "^0.19.1"
"@wxt-dev/module-react": "^1.1.1",
"typescript": "^5.6.2",
"wxt": "^0.19.11"
}
}
+4 -4
View File
@@ -15,11 +15,11 @@
"postinstall": "wxt prepare"
},
"dependencies": {
"solid-js": "^1.8.19"
"solid-js": "^1.9.1"
},
"devDependencies": {
"@wxt-dev/module-solid": "^1.1.1",
"typescript": "^5.5.4",
"wxt": "^0.19.1"
"@wxt-dev/module-solid": "^1.1.2",
"typescript": "^5.6.2",
"wxt": "^0.19.11"
}
}
+6 -6
View File
@@ -16,11 +16,11 @@
},
"devDependencies": {
"@tsconfig/svelte": "^5.0.4",
"@wxt-dev/module-svelte": "^1.0.0",
"svelte": "^4.2.18",
"svelte-check": "^3.8.4",
"tslib": "^2.6.3",
"typescript": "^5.5.4",
"wxt": "^0.19.1"
"@wxt-dev/module-svelte": "^1.0.1",
"svelte": "^4.2.19",
"svelte-check": "^3.8.6",
"tslib": "^2.7.0",
"typescript": "^5.6.2",
"wxt": "^0.19.11"
}
}
+2 -2
View File
@@ -15,7 +15,7 @@
"postinstall": "wxt prepare"
},
"devDependencies": {
"typescript": "^5.5.4",
"wxt": "^0.19.1"
"typescript": "^5.6.2",
"wxt": "^0.19.11"
}
}
+5 -5
View File
@@ -15,12 +15,12 @@
"postinstall": "wxt prepare"
},
"dependencies": {
"vue": "^3.4.34"
"vue": "^3.5.11"
},
"devDependencies": {
"@wxt-dev/module-vue": "^1.0.0",
"typescript": "^5.5.4",
"vue-tsc": "^2.0.29",
"wxt": "^0.19.1"
"@wxt-dev/module-vue": "^1.0.1",
"typescript": "^5.6.2",
"vue-tsc": "^2.1.6",
"wxt": "^0.19.11"
}
}
-3
View File
@@ -11,9 +11,6 @@
"strict": true,
"lib": ["DOM", "WebWorker", "ESNext"],
/* Linting */
"noUnusedLocals": true,
/* Completeness */
"skipLibCheck": true
}