Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c3009a48f | |||
| 6c6087249f | |||
| 539d482f71 | |||
| cab97bca1e | |||
| 6020083b89 | |||
| 947b24f1b0 | |||
| 2c5ba64b61 | |||
| faa4fcb718 | |||
| 8e9b67fea2 | |||
| 659bdd46a0 | |||
| edcc411d26 | |||
| e022423bad | |||
| 84e1fd44eb | |||
| b68d1ff828 | |||
| c31a5c30ed | |||
| 5b408c2bc2 | |||
| ca29419db6 | |||
| ab26bdc7c1 | |||
| d270250633 | |||
| d75f64df79 | |||
| 5faa5d7537 | |||
| 177223c625 | |||
| a64ff22917 | |||
| 0bf08329b0 | |||
| e3f00d2797 | |||
| 09de72895e | |||
| c0aa12089e | |||
| 0248f58785 | |||
| 247cd66f74 |
@@ -6,7 +6,9 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: '/' # Location of package manifests
|
||||
directories:
|
||||
- /
|
||||
- packages/*
|
||||
schedule:
|
||||
interval: 'monthly'
|
||||
- package-ecosystem: 'github-actions'
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -40,6 +40,10 @@ const chromeExtensionIds = [
|
||||
'fonflmjnjbkigocpoommgmhljdpljain', // NiceTab - https://github.com/web-dahuyou/NiceTab
|
||||
'fcffekbnfcfdemeekijbbmgmkognnmkd', // Draftly for LinkedIn
|
||||
'nkndldfehcidpejfkokbeghpnlbppdmo', // YouTube Summarized - Summarize any YouTube video
|
||||
'dbichmdlbjdeplpkhcejgkakobjbjalc', // 社媒助手 - https://github.com/iszhouhua/social-media-copilot
|
||||
'opepfpjeogkbgeigkbepobceinnfmjdd', // Dofollow Links for SEO
|
||||
'pdnenlnelpdomajfejgapbdpmjkfpjkp', // ChatGPT Writer: Use AI on Any Site (GPT-4o, Claude, Gemini, and More)
|
||||
'jobnhifpphkgoelnhnopgkdhbdkiadmj', // discord message translator
|
||||
];
|
||||
|
||||
const { data, err, isLoading } = useListExtensionDetails(chromeExtensionIds);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 136 KiB |
+11
-16
@@ -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"
|
||||
@@ -56,10 +56,5 @@
|
||||
"search-insights"
|
||||
]
|
||||
}
|
||||
},
|
||||
"changelog": {
|
||||
"excludeAuthors": [
|
||||
"aaronklinker1@gmail.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:*"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# Changelog
|
||||
|
||||
## v0.2.0
|
||||
|
||||
[⚠️ breaking changes](https://wxt.dev/guide/upgrade-guide/wxt) • [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))
|
||||
@@ -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:*"
|
||||
},
|
||||
|
||||
@@ -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")',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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}"`);
|
||||
|
||||
@@ -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 `<`. 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;
|
||||
|
||||
@@ -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:*"
|
||||
}
|
||||
|
||||
@@ -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:*"
|
||||
}
|
||||
|
||||
@@ -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:*"
|
||||
}
|
||||
|
||||
@@ -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:*"
|
||||
}
|
||||
|
||||
@@ -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,5 +1,30 @@
|
||||
# Changelog
|
||||
|
||||
## v0.19.11
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.19.10...wxt-v0.19.11)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- **zip:** Hooks ([#993](https://github.com/wxt-dev/wxt/pull/993))
|
||||
- **zip:** `wxt zip --sources` and auto sources for opera ([#1014](https://github.com/wxt-dev/wxt/pull/1014))
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- Reverse env files priority ([#1016](https://github.com/wxt-dev/wxt/pull/1016))
|
||||
- #1005 fixed, by updating type-definations to getItem method. ([#1007](https://github.com/wxt-dev/wxt/pull/1007), [#1005](https://github.com/wxt-dev/wxt/issues/1005))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Move some files around ([#996](https://github.com/wxt-dev/wxt/pull/996))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
- Florian Metz ([@Timeraa](http://github.com/Timeraa))
|
||||
- Gurvir Singh ([@baraich](http://github.com/baraich))
|
||||
- Mezannic ([@mezannic](http://github.com/mezannic))
|
||||
- Aaron ([@aklinker1](http://github.com/aklinker1))
|
||||
|
||||
## v0.19.10
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.19.9...wxt-v0.19.10)
|
||||
|
||||
@@ -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",
|
||||
),
|
||||
});
|
||||
|
||||
@@ -14,6 +14,12 @@ const hooks: WxtHooks = {
|
||||
'entrypoints:grouped': vi.fn(),
|
||||
'vite:build:extendConfig': vi.fn(),
|
||||
'vite:devServer:extendConfig': vi.fn(),
|
||||
'zip:start': vi.fn(),
|
||||
'zip:extension:start': vi.fn(),
|
||||
'zip:extension:done': vi.fn(),
|
||||
'zip:sources:start': vi.fn(),
|
||||
'zip:sources:done': vi.fn(),
|
||||
'zip:done': vi.fn(),
|
||||
};
|
||||
|
||||
function expectHooksToBeCalled(
|
||||
@@ -53,6 +59,12 @@ describe('Hooks', () => {
|
||||
'entrypoints:resolved': true,
|
||||
'vite:build:extendConfig': false,
|
||||
'vite:devServer:extendConfig': false,
|
||||
'zip:start': false,
|
||||
'zip:extension:start': false,
|
||||
'zip:extension:done': false,
|
||||
'zip:sources:start': false,
|
||||
'zip:sources:done': false,
|
||||
'zip:done': false,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,6 +86,12 @@ describe('Hooks', () => {
|
||||
'entrypoints:resolved': true,
|
||||
'vite:build:extendConfig': 1,
|
||||
'vite:devServer:extendConfig': false,
|
||||
'zip:start': false,
|
||||
'zip:extension:start': false,
|
||||
'zip:extension:done': false,
|
||||
'zip:sources:start': false,
|
||||
'zip:sources:done': false,
|
||||
'zip:done': false,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -95,6 +113,39 @@ describe('Hooks', () => {
|
||||
'entrypoints:resolved': true,
|
||||
'vite:build:extendConfig': 1,
|
||||
'vite:devServer:extendConfig': false,
|
||||
'zip:start': true,
|
||||
'zip:extension:start': true,
|
||||
'zip:extension:done': true,
|
||||
'zip:sources:start': false,
|
||||
'zip:sources:done': false,
|
||||
'zip:done': true,
|
||||
});
|
||||
});
|
||||
|
||||
it('zip -b firefox should call hooks', async () => {
|
||||
const project = new TestProject();
|
||||
project.addFile('entrypoints/popup.html', '<html></html>');
|
||||
|
||||
await project.zip({ hooks, browser: 'firefox' });
|
||||
|
||||
expectHooksToBeCalled({
|
||||
ready: true,
|
||||
'prepare:types': true,
|
||||
'prepare:publicPaths': true,
|
||||
'build:before': true,
|
||||
'build:done': true,
|
||||
'build:publicAssets': true,
|
||||
'build:manifestGenerated': true,
|
||||
'entrypoints:grouped': true,
|
||||
'entrypoints:resolved': true,
|
||||
'vite:build:extendConfig': 1,
|
||||
'vite:devServer:extendConfig': false,
|
||||
'zip:start': true,
|
||||
'zip:extension:start': true,
|
||||
'zip:extension:done': true,
|
||||
'zip:sources:start': true,
|
||||
'zip:sources:done': true,
|
||||
'zip:done': true,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -122,6 +173,12 @@ describe('Hooks', () => {
|
||||
'entrypoints:resolved': true,
|
||||
'vite:build:extendConfig': 2,
|
||||
'vite:devServer:extendConfig': 1,
|
||||
'zip:start': false,
|
||||
'zip:extension:start': false,
|
||||
'zip:extension:done': false,
|
||||
'zip:sources:start': false,
|
||||
'zip:sources:done': false,
|
||||
'zip:done': false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -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(
|
||||
@@ -178,4 +180,73 @@ describe('Zipping', () => {
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it.each(['firefox', 'opera'])(
|
||||
'should create sources zip for "%s" browser when sourcesZip is undefined',
|
||||
async (browser) => {
|
||||
const project = new TestProject({
|
||||
name: 'test',
|
||||
version: '1.0.0',
|
||||
});
|
||||
project.addFile(
|
||||
'entrypoints/background.ts',
|
||||
'export default defineBackground(() => {});',
|
||||
);
|
||||
const sourcesZip = project.resolvePath('.output/test-1.0.0-sources.zip');
|
||||
|
||||
await project.zip({
|
||||
browser,
|
||||
});
|
||||
|
||||
expect(await project.fileExists(sourcesZip)).toBe(true);
|
||||
},
|
||||
);
|
||||
|
||||
it.each(['firefox', 'chrome'])(
|
||||
'should create sources zip for "%s" when sourcesZip is true',
|
||||
async (browser) => {
|
||||
const project = new TestProject({
|
||||
name: 'test',
|
||||
version: '1.0.0',
|
||||
});
|
||||
project.addFile(
|
||||
'entrypoints/background.ts',
|
||||
'export default defineBackground(() => {});',
|
||||
);
|
||||
const sourcesZip = project.resolvePath('.output/test-1.0.0-sources.zip');
|
||||
|
||||
await project.zip({
|
||||
browser,
|
||||
zip: {
|
||||
zipSources: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists(sourcesZip)).toBe(true);
|
||||
},
|
||||
);
|
||||
|
||||
it.each(['firefox', 'chrome'])(
|
||||
'should not create sources zip for "%s" when sourcesZip is false',
|
||||
async (browser) => {
|
||||
const project = new TestProject({
|
||||
name: 'test',
|
||||
version: '1.0.0',
|
||||
});
|
||||
project.addFile(
|
||||
'entrypoints/background.ts',
|
||||
'export default defineBackground(() => {});',
|
||||
);
|
||||
const sourcesZip = project.resolvePath('.output/test-1.0.0-sources.zip');
|
||||
|
||||
await project.zip({
|
||||
browser,
|
||||
zip: {
|
||||
zipSources: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(await project.fileExists(sourcesZip)).toBe(false);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -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(
|
||||
|
||||
+19
-19
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.19.10",
|
||||
"version": "0.19.11",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -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": {
|
||||
|
||||
@@ -903,5 +903,24 @@ describe('Storage Utils', () => {
|
||||
// @ts-expect-error
|
||||
await storage.getItem('loca:test').catch(() => {});
|
||||
});
|
||||
|
||||
it('should return a nullable type when getItem is called without a fallback', async () => {
|
||||
const res = await storage.getItem<string>('local:test');
|
||||
expectTypeOf(res).toBeNullable();
|
||||
});
|
||||
|
||||
it('should return a non-null type when getItem is called with a fallback', async () => {
|
||||
const res = await storage.getItem('local:test', {
|
||||
fallback: 'test',
|
||||
});
|
||||
expectTypeOf(res).not.toBeNullable();
|
||||
});
|
||||
|
||||
it('should return a non-null type when getItem is called with a fallback and the first type parameter is passed', async () => {
|
||||
const res = await storage.getItem<string>('local:test', {
|
||||
fallback: 'test',
|
||||
});
|
||||
expectTypeOf(res).not.toBeNullable();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -237,7 +237,9 @@ describe('CLI', () => {
|
||||
mockArgv('zip');
|
||||
await importCli();
|
||||
|
||||
expect(zipMock).toBeCalledWith({});
|
||||
expect(zipMock).toBeCalledWith({
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('should respect passing a custom root', async () => {
|
||||
@@ -246,6 +248,7 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
root: 'path/to/root',
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -255,6 +258,7 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
configFile: './path/to/config.ts',
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -264,6 +268,7 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
mode: 'development',
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -273,6 +278,7 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
browser: 'firefox',
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -282,6 +288,7 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
manifestVersion: 2,
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -291,6 +298,7 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
manifestVersion: 3,
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -300,6 +308,40 @@ describe('CLI', () => {
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
debug: true,
|
||||
zip: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass undefined for zipSources when --sources is not passed', async () => {
|
||||
mockArgv('zip');
|
||||
await importCli();
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
zip: {
|
||||
zipSources: undefined,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass true for zipSources when --sources is passed', async () => {
|
||||
mockArgv('zip', '--sources');
|
||||
await importCli();
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
zip: {
|
||||
zipSources: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should pass false for zipSources when --sources=false is passed', async () => {
|
||||
mockArgv('zip', '--sources=false');
|
||||
await importCli();
|
||||
|
||||
expect(zipMock).toBeCalledWith({
|
||||
zip: {
|
||||
zipSources: false,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -95,6 +95,7 @@ cli
|
||||
.option('-b, --browser <browser>', 'specify a browser')
|
||||
.option('--mv3', 'target manifest v3')
|
||||
.option('--mv2', 'target manifest v2')
|
||||
.option('--sources', 'always create sources zip')
|
||||
.action(
|
||||
wrapAction(async (root, flags) => {
|
||||
await zip({
|
||||
@@ -104,6 +105,9 @@ cli
|
||||
manifestVersion: flags.mv3 ? 3 : flags.mv2 ? 2 : undefined,
|
||||
configFile: flags.config,
|
||||
debug: flags.debug,
|
||||
zip: {
|
||||
zipSources: flags.sources,
|
||||
},
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
+8
-13
@@ -1,23 +1,18 @@
|
||||
import { Entrypoint, WxtDirEntry, WxtDirFileEntry } from '../../../types';
|
||||
import { Entrypoint, WxtDirEntry, WxtDirFileEntry } from '../types';
|
||||
import fs from 'fs-extra';
|
||||
import { dirname, relative, resolve } from 'node:path';
|
||||
import {
|
||||
getEntrypointBundlePath,
|
||||
isHtmlEntrypoint,
|
||||
} from '../../utils/entrypoints';
|
||||
import { getEntrypointGlobals, getGlobals } from '../../utils/globals';
|
||||
import { normalizePath } from '../../utils/paths';
|
||||
import { getEntrypointBundlePath, isHtmlEntrypoint } from './utils/entrypoints';
|
||||
import { getEntrypointGlobals, getGlobals } from './utils/globals';
|
||||
import { normalizePath } from './utils/paths';
|
||||
import path from 'node:path';
|
||||
import { Message, parseI18nMessages } from '../../utils/i18n';
|
||||
import { writeFileIfDifferent, getPublicFiles } from '../../utils/fs';
|
||||
import { wxt } from '../../wxt';
|
||||
import { Message, parseI18nMessages } from './utils/i18n';
|
||||
import { writeFileIfDifferent, getPublicFiles } from './utils/fs';
|
||||
import { wxt } from './wxt';
|
||||
|
||||
/**
|
||||
* Generate and write all the files inside the `InternalConfig.typesDir` directory.
|
||||
*/
|
||||
export async function generateTypesDir(
|
||||
entrypoints: Entrypoint[],
|
||||
): Promise<void> {
|
||||
export async function generateWxtDir(entrypoints: Entrypoint[]): Promise<void> {
|
||||
await fs.ensureDir(wxt.config.typesDir);
|
||||
|
||||
const entries: WxtDirEntry[] = [
|
||||
@@ -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))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { InlineConfig } from '../types';
|
||||
import { findEntrypoints, generateTypesDir } from './utils/building';
|
||||
import { findEntrypoints } from './utils/building';
|
||||
import { generateWxtDir } from './generate-wxt-dir';
|
||||
import { registerWxt, wxt } from './wxt';
|
||||
|
||||
export async function prepare(config: InlineConfig) {
|
||||
@@ -7,5 +8,5 @@ export async function prepare(config: InlineConfig) {
|
||||
wxt.logger.info('Generating types...');
|
||||
|
||||
const entrypoints = await findEntrypoints();
|
||||
await generateTypesDir(entrypoints);
|
||||
await generateWxtDir(entrypoints);
|
||||
}
|
||||
|
||||
+12
-9
@@ -14,19 +14,19 @@ import {
|
||||
WxtModuleWithMetadata,
|
||||
ResolvedEslintrc,
|
||||
Eslintrc,
|
||||
} from '../../../types';
|
||||
} from '../types';
|
||||
import path from 'node:path';
|
||||
import { createFsCache } from '../../utils/cache';
|
||||
import { createFsCache } from './utils/cache';
|
||||
import consola, { LogLevels } from 'consola';
|
||||
import defu from 'defu';
|
||||
import { NullablyRequired } from '../types';
|
||||
import { NullablyRequired } from './utils/types';
|
||||
import fs from 'fs-extra';
|
||||
import { normalizePath } from '../paths';
|
||||
import { normalizePath } from './utils/paths';
|
||||
import glob from 'fast-glob';
|
||||
import { builtinModules } from '../../../builtin-modules';
|
||||
import { getEslintVersion } from '../eslint';
|
||||
import { safeStringToNumber } from '../number';
|
||||
import { loadEnv } from '../env';
|
||||
import { builtinModules } from '../builtin-modules';
|
||||
import { getEslintVersion } from './utils/eslint';
|
||||
import { safeStringToNumber } from './utils/number';
|
||||
import { loadEnv } from './utils/env';
|
||||
|
||||
/**
|
||||
* Given an inline config, discover the config file if necessary, merge the results, resolve any
|
||||
@@ -179,7 +179,7 @@ export async function resolveConfig(
|
||||
srcDir,
|
||||
typesDir,
|
||||
wxtDir,
|
||||
zip: resolveZipConfig(root, outBaseDir, mergedConfig),
|
||||
zip: resolveZipConfig(root, browser, outBaseDir, mergedConfig),
|
||||
transformManifest: mergedConfig.transformManifest,
|
||||
analysis: resolveAnalysisConfig(root, mergedConfig),
|
||||
userConfigMetadata: userConfigMetadata ?? {},
|
||||
@@ -258,6 +258,7 @@ async function mergeInlineConfig(
|
||||
|
||||
function resolveZipConfig(
|
||||
root: string,
|
||||
browser: string,
|
||||
outBaseDir: string,
|
||||
mergedConfig: InlineConfig,
|
||||
): NullablyRequired<ResolvedConfig['zip']> {
|
||||
@@ -270,6 +271,8 @@ function resolveZipConfig(
|
||||
includeSources: [],
|
||||
compressionLevel: 9,
|
||||
...mergedConfig.zip,
|
||||
zipSources:
|
||||
mergedConfig.zip?.zipSources ?? ['firefox', 'opera'].includes(browser),
|
||||
exclude: mergedConfig.zip?.exclude ?? [],
|
||||
excludeSources: [
|
||||
'**/node_modules',
|
||||
@@ -1,8 +1,6 @@
|
||||
export * from './build-entrypoints';
|
||||
export * from './detect-dev-changes';
|
||||
export * from './find-entrypoints';
|
||||
export * from './generate-wxt-dir';
|
||||
export * from './resolve-config';
|
||||
export * from './group-entrypoints';
|
||||
export * from './import-entrypoint';
|
||||
export * from './internal-build';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Manifest } from 'wxt/browser';
|
||||
import { BuildOutput, Entrypoint, EntrypointGroup } from '../../../types';
|
||||
import { generateTypesDir } from './generate-wxt-dir';
|
||||
import { generateWxtDir } from '../../generate-wxt-dir';
|
||||
import { buildEntrypoints } from './build-entrypoints';
|
||||
import { generateManifest, writeManifest } from '../../utils/manifest';
|
||||
import { wxt } from '../../wxt';
|
||||
@@ -37,7 +37,7 @@ export async function rebuild(
|
||||
const spinner = ora(`Preparing...`).start();
|
||||
|
||||
// Update types directory with new files and types
|
||||
await generateTypesDir(allEntrypoints).catch((err) => {
|
||||
await generateWxtDir(allEntrypoints).catch((err) => {
|
||||
wxt.logger.warn('Failed to update .wxt directory:', err);
|
||||
// Throw the error if doing a regular build, don't for dev mode.
|
||||
if (wxt.config.command === 'build') throw err;
|
||||
|
||||
@@ -5,6 +5,6 @@ import { config } from 'dotenv';
|
||||
*/
|
||||
export function loadEnv(mode: string) {
|
||||
return config({
|
||||
path: [`.env`, `.env.local`, `.env.${mode}`, `.env.${mode}.local`],
|
||||
path: [`.env.${mode}.local`, `.env.${mode}`, `.env.local`, `.env`],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -293,6 +293,7 @@ export const fakeResolvedConfig = fakeObjectCreator<ResolvedConfig>(() => {
|
||||
downloadedPackagesDir: fakeDir(),
|
||||
downloadPackages: [],
|
||||
compressionLevel: 9,
|
||||
zipSources: false,
|
||||
},
|
||||
transformManifest: () => {},
|
||||
userConfigMetadata: {},
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
WxtHooks,
|
||||
WxtModule,
|
||||
} from '../types';
|
||||
import { resolveConfig } from './utils/building';
|
||||
import { resolveConfig } from './resolve-config';
|
||||
import { createHooks } from 'hookable';
|
||||
import { createWxtPackageManager } from './package-managers';
|
||||
import { createViteBuilder } from './builders/vite';
|
||||
|
||||
@@ -20,6 +20,7 @@ import { normalizePath } from './utils/paths';
|
||||
export async function zip(config?: InlineConfig): Promise<string[]> {
|
||||
await registerWxt('build', config);
|
||||
const output = await internalBuild();
|
||||
await wxt.hooks.callHook('zip:start', wxt);
|
||||
|
||||
const start = Date.now();
|
||||
wxt.logger.info('Zipping extension...');
|
||||
@@ -27,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)
|
||||
@@ -42,17 +45,17 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
|
||||
await fs.ensureDir(wxt.config.outBaseDir);
|
||||
|
||||
// ZIP output directory
|
||||
|
||||
await wxt.hooks.callHook('zip:extension:start', wxt);
|
||||
const outZipFilename = applyTemplate(wxt.config.zip.artifactTemplate);
|
||||
const outZipPath = path.resolve(wxt.config.outBaseDir, outZipFilename);
|
||||
await zipDir(wxt.config.outDir, outZipPath, {
|
||||
exclude: wxt.config.zip.exclude,
|
||||
});
|
||||
zipFiles.push(outZipPath);
|
||||
await wxt.hooks.callHook('zip:extension:done', wxt, outZipPath);
|
||||
|
||||
// ZIP sources for Firefox
|
||||
|
||||
if (wxt.config.browser === 'firefox') {
|
||||
if (wxt.config.zip.zipSources) {
|
||||
await wxt.hooks.callHook('zip:sources:start', wxt);
|
||||
const { overrides, files: downloadedPackages } =
|
||||
await downloadPrivatePackages();
|
||||
const sourcesZipFilename = applyTemplate(wxt.config.zip.sourcesTemplate);
|
||||
@@ -71,6 +74,7 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
|
||||
additionalFiles: downloadedPackages,
|
||||
});
|
||||
zipFiles.push(sourcesZipPath);
|
||||
await wxt.hooks.callHook('zip:sources:done', wxt, sourcesZipPath);
|
||||
}
|
||||
|
||||
await printFileList(
|
||||
@@ -80,8 +84,11 @@ export async function zip(config?: InlineConfig): Promise<string[]> {
|
||||
zipFiles,
|
||||
);
|
||||
|
||||
await wxt.hooks.callHook('zip:done', wxt, zipFiles);
|
||||
|
||||
return zipFiles;
|
||||
}
|
||||
|
||||
async function zipDir(
|
||||
directory: string,
|
||||
outputPath: string,
|
||||
|
||||
@@ -461,7 +461,16 @@ export interface WxtStorage {
|
||||
* @example
|
||||
* await storage.getItem<number>("local:installDate");
|
||||
*/
|
||||
getItem<T>(key: StorageItemKey, opts?: GetItemOptions<T>): Promise<T | null>;
|
||||
getItem<TValue>(
|
||||
key: StorageItemKey,
|
||||
opts: GetItemOptions<TValue> & { fallback: TValue },
|
||||
): Promise<TValue>;
|
||||
|
||||
getItem<TValue>(
|
||||
key: StorageItemKey,
|
||||
opts?: GetItemOptions<TValue>,
|
||||
): Promise<TValue | null>;
|
||||
|
||||
/**
|
||||
* Get multiple items from storage. The return order is guaranteed to be the same as the order
|
||||
* requested.
|
||||
|
||||
@@ -130,6 +130,16 @@ export interface InlineConfig {
|
||||
* @default "{{name}}-{{version}}-{{browser}}.zip"
|
||||
*/
|
||||
artifactTemplate?: string;
|
||||
/**
|
||||
* When zipping the extension, also zip sources.
|
||||
*
|
||||
* - `undefined`: zip sources if the target browser is "firefox" or "opera"
|
||||
* - `true`: always zip sources
|
||||
* - `false`: never zip sources
|
||||
*
|
||||
* @default undefined
|
||||
*/
|
||||
zipSources?: boolean;
|
||||
/**
|
||||
* Configure the filename output when zipping files.
|
||||
*
|
||||
@@ -1164,6 +1174,44 @@ export interface WxtHooks {
|
||||
* @param entrypoints The list of files that will be copied into the output directory
|
||||
*/
|
||||
'build:publicAssets': (wxt: Wxt, files: ResolvedPublicFile[]) => HookResult;
|
||||
/**
|
||||
* Called before the zip process starts.
|
||||
* @param wxt The configured WXT object
|
||||
*/
|
||||
'zip:start': (wxt: Wxt) => HookResult;
|
||||
|
||||
/**
|
||||
* Called before zipping the extension files.
|
||||
* @param wxt The configured WXT object
|
||||
*/
|
||||
'zip:extension:start': (wxt: Wxt) => HookResult;
|
||||
|
||||
/**
|
||||
* Called after zipping the extension files.
|
||||
* @param wxt The configured WXT object
|
||||
* @param zipPath The path to the created extension zip file
|
||||
*/
|
||||
'zip:extension:done': (wxt: Wxt, zipPath: string) => HookResult;
|
||||
|
||||
/**
|
||||
* Called before zipping the source files (for Firefox).
|
||||
* @param wxt The configured WXT object
|
||||
*/
|
||||
'zip:sources:start': (wxt: Wxt) => HookResult;
|
||||
|
||||
/**
|
||||
* Called after zipping the source files (for Firefox).
|
||||
* @param wxt The configured WXT object
|
||||
* @param zipPath The path to the created sources zip file
|
||||
*/
|
||||
'zip:sources:done': (wxt: Wxt, zipPath: string) => HookResult;
|
||||
|
||||
/**
|
||||
* Called after the entire zip process is complete.
|
||||
* @param wxt The configured WXT object
|
||||
* @param zipFiles An array of paths to all created zip files
|
||||
*/
|
||||
'zip:done': (wxt: Wxt, zipFiles: string[]) => HookResult;
|
||||
}
|
||||
|
||||
export interface Wxt {
|
||||
@@ -1247,6 +1295,10 @@ export interface ResolvedConfig {
|
||||
downloadPackages: string[];
|
||||
compressionLevel: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
||||
exclude: string[];
|
||||
/**
|
||||
* If true, when zipping the extension, also zip the sources.
|
||||
*/
|
||||
zipSources: boolean;
|
||||
};
|
||||
/**
|
||||
* @deprecated Use `build:manifestGenerated` hook instead.
|
||||
|
||||
Generated
+1317
-1146
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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',
|
||||
],
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"postinstall": "wxt prepare"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.4",
|
||||
"wxt": "^0.19.1"
|
||||
"typescript": "^5.6.2",
|
||||
"wxt": "^0.19.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
"strict": true,
|
||||
"lib": ["DOM", "WebWorker", "ESNext"],
|
||||
|
||||
/* Linting */
|
||||
"noUnusedLocals": true,
|
||||
|
||||
/* Completeness */
|
||||
"skipLibCheck": true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user