Compare commits

...

11 Commits

21 changed files with 407 additions and 90 deletions
+1 -5
View File
@@ -14,11 +14,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 18
cache: pnpm
- uses: ./.github/actions/setup
- run: pnpm tsx scripts/sync-releases.ts ${{ inputs.package }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+1
View File
@@ -20,3 +20,4 @@ templates/*/package-lock.json
docs/api/reference
stats.html
.tool-versions
.cache
+8 -3
View File
@@ -15,7 +15,8 @@
"docs:gen": "typedoc --options docs/typedoc.json",
"docs:dev": "pnpm -s docs:gen && vitepress dev docs",
"docs:build": "pnpm -s docs:gen && vitepress build docs",
"docs:preview": "pnpm -s docs:gen && vitepress preview docs"
"docs:preview": "pnpm -s docs:gen && vitepress preview docs",
"build-deps": "pnpm tsx scripts/build-deps.ts"
},
"devDependencies": {
"@aklinker1/check": "^1.1.1",
@@ -23,8 +24,11 @@
"@vitest/coverage-v8": "^1.0.1",
"changelogen": "^0.5.5",
"consola": "^3.2.3",
"dependency-graph": "^1.0.0",
"execa": "^9.1.0",
"fast-glob": "^3.3.1",
"fs-extra": "^11.1.1",
"hasha": "^6.0.0",
"lint-staged": "^15.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.0",
@@ -33,13 +37,14 @@
"typedoc": "^0.25.4",
"typedoc-plugin-markdown": "4.0.0-next.23",
"typedoc-vitepress-theme": "1.0.0-next.3",
"typescript": "^5.3.2",
"typescript": "^5.4.5",
"vitepress": "^1.2.2",
"vitest": "^1.5.3",
"vitest-mock-extended": "^1.3.1",
"vitest-plugin-random-seed": "^1.0.2",
"vue": "^3.3.10",
"wxt": "workspace:*"
"wxt": "workspace:*",
"yaml": "^2.4.5"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
+9 -9
View File
@@ -4,18 +4,18 @@
"private": true,
"type": "module",
"scripts": {
"dev": "pnpm build:deps && wxt",
"build:deps": "pnpm --filter wxt build",
"build": "pnpm build:deps && wxt build",
"build:all": "pnpm build:deps && run-s -s 'build:all:*'",
"dev": "pnpm -s build-deps && wxt",
"build": "pnpm -s build-deps && wxt build",
"build:all": "pnpm -s build-deps && run-s -s 'build:all:*'",
"build:all:chrome-mv3": "wxt build",
"build:all:chrome-mv2": "wxt build --mv2",
"build:all:firefox-mv3": "wxt build -b firefox --mv3",
"build:all:firefox-mv2": "wxt build -b firefox",
"test": "pnpm build:deps && vitest",
"zip": "pnpm build:deps && wxt zip",
"check": "pnpm build:deps && check",
"postinstall": "pnpm build:deps && wxt prepare"
"test": "pnpm -s build-deps && vitest",
"zip": "pnpm -s build-deps && wxt zip",
"check": "pnpm -s build-deps && check",
"postinstall": "pnpm -s build-deps && wxt prepare",
"build-deps": "pnpm -sw build-deps wxt-demo"
},
"dependencies": {
"react": "^18.2.0",
@@ -25,7 +25,7 @@
"@types/react": "^18.2.34",
"@types/react-dom": "^18.2.14",
"sass": "^1.69.5",
"typescript": "^5.3.2",
"typescript": "^5.4.5",
"wxt": "workspace:*"
}
}
+19 -1
View File
@@ -1,8 +1,26 @@
# Changelog
## v0.18.6
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.5...wxt-v0.18.6)
### 🚀 Enhancements
- **modules:** Add new `addImportPreset` helper function ([#720](https://github.com/wxt-dev/wxt/pull/720))
### 🩹 Fixes
- **types:** Module `options` param is optional, but types did not reflect that ([#719](https://github.com/wxt-dev/wxt/pull/719))
- **modules:** Re-export `WxtModule` type from `wxt/modules` to prevent TS2742 ([#721](https://github.com/wxt-dev/wxt/pull/721))
- **modules:** Add modules to TS project so type augmentation works ([#722](https://github.com/wxt-dev/wxt/pull/722))
### 🏡 Chore
- **dev-deps:** Upgrade typescript to 5.4 ([#718](https://github.com/wxt-dev/wxt/pull/718))
## v0.18.5
[compare changes](https://github.com/wxt-dev/wxt/compare/0.18.4...0.18.5)
[compare changes](https://github.com/wxt-dev/wxt/compare/wxt-v0.18.4...wxt-v0.18.5)
### 🚀 Enhancements
@@ -375,4 +375,9 @@ describe('TypeScript Project', () => {
}"
`);
});
// TODO: Once a module has been published, use it here for testing - local files are never added to the .wxt/wxt.d.ts file
it.todo(
'should add modules from NPM to the TS project if they have a configKey',
);
});
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "wxt",
"type": "module",
"version": "0.18.5",
"version": "0.18.6",
"description": "Next gen framework for developing web extensions",
"repository": {
"type": "git",
@@ -157,6 +157,6 @@
"publint": "^0.2.6",
"tsup": "^8.0.1",
"tsx": "^4.11.2",
"typescript": "^5.3.2"
"typescript": "^5.4.5"
}
}
+47 -1
View File
@@ -1,5 +1,5 @@
import { fakeWxt } from '~/core/utils/testing/fake-objects';
import { addViteConfig } from '../modules';
import { addImportPreset, addViteConfig } from '../modules';
import { describe, it, expect } from 'vitest';
import { createHooks } from 'hookable';
@@ -37,4 +37,50 @@ describe('Module Utilities', () => {
expect(actual).toEqual(expected);
});
});
describe('addImportPreset', () => {
it('should add the import to the config', async () => {
const preset = 'vue';
const wxt = fakeWxt({ hooks: createHooks() });
addImportPreset(wxt, preset);
await wxt.hooks.callHook('ready', wxt);
expect(wxt.config.imports && wxt.config.imports.presets).toContain(
preset,
);
});
it('should not add duplicate presets', async () => {
const preset = 'vue';
const wxt = fakeWxt({
hooks: createHooks(),
config: {
imports: {
presets: ['vue', 'react'],
},
},
});
addImportPreset(wxt, preset);
await wxt.hooks.callHook('ready', wxt);
expect(wxt.config.imports && wxt.config.imports.presets).toHaveLength(2);
});
it("should not enable imports if they've been disabled", async () => {
const preset = 'vue';
const wxt = fakeWxt({
hooks: createHooks(),
config: {
imports: false,
},
});
addImportPreset(wxt, preset);
await wxt.hooks.callHook('ready', wxt);
expect(wxt.config.imports).toBe(false);
});
});
});
@@ -204,6 +204,16 @@ async function writeMainDeclarationFile(references: string[]): Promise<string> {
(ref) =>
`/// <reference types="./${normalizePath(relative(dir, ref))}" />`,
),
// Add references to modules installed from NPM to the TS project so
// their type augmentation can update InlineConfig correctly. Local
// modules defined in <root>/modules are already apart of the project, so
// we don't need to add them.
...wxt.config.modules
.filter(
(module) => module.type === 'node_module' && module.configKey != null,
)
.map((module) => `/// <reference types="${module.id}" />`),
].join('\n') + '\n',
);
return filePath;
@@ -11,6 +11,7 @@ import {
Logger,
WxtCommand,
WxtModule,
WxtModuleWithMetadata,
} from '~/types';
import path from 'node:path';
import { createFsCache } from '~/core/utils/cache';
@@ -380,15 +381,21 @@ export async function mergeBuilderConfig(
export async function resolveWxtModules(
modulesDir: string,
modules: string[] = [],
): Promise<WxtModule<any>[]> {
// Resolve NPM packages
const npmModules = await Promise.all(
): Promise<WxtModuleWithMetadata<any>[]> {
// Resolve node_modules modules
const npmModules = await Promise.all<WxtModuleWithMetadata<any>>(
modules.map(async (moduleId) => {
const mod = await import(/* @vite-ignore */ moduleId);
const mod: { default: WxtModule<any> } = await import(
/* @vite-ignore */ moduleId
);
if (mod.default == null) {
throw Error('Module missing default export: ' + moduleId);
}
return mod.default;
return {
...mod.default,
type: 'node_module',
id: moduleId,
};
}),
);
@@ -397,10 +404,11 @@ export async function resolveWxtModules(
cwd: modulesDir,
onlyFiles: true,
}).catch(() => []);
const localModules = await Promise.all(
const localModules = await Promise.all<WxtModuleWithMetadata<any>>(
localModulePaths.map(async (file) => {
const absolutePath = normalizePath(path.resolve(modulesDir, file));
const { config } = await loadConfig<WxtModule<any>>({
configFile: path.resolve(modulesDir, file),
configFile: absolutePath,
globalRc: false,
rcFile: false,
packageJson: false,
@@ -413,10 +421,12 @@ export async function resolveWxtModules(
);
// Add name based on filename
config.name ??= file;
return config;
return {
...config,
type: 'local',
id: absolutePath,
};
}),
);
// Execute modules
return [...npmModules, ...localModules];
}
+47 -1
View File
@@ -13,6 +13,10 @@ import type {
import * as vite from 'vite';
import glob from 'fast-glob';
import { resolve } from 'node:path';
import type { UnimportOptions } from 'unimport';
// Re-export to prevent TS2742 type errors
export { WxtModule };
export function defineWxtModule<TOptions extends WxtModuleOptions>(
module: WxtModule<TOptions> | WxtModuleSetup<TOptions>,
@@ -123,8 +127,50 @@ export function addViteConfig(
* addWxtPlugin(wxt, "wxt-module-analytics/client-plugin");
* });
*/
export function addWxtPlugin(wxt: Wxt, plugin: string) {
export function addWxtPlugin(wxt: Wxt, plugin: string): void {
wxt.hooks.hook('ready', (wxt) => {
wxt.config.plugins.push(plugin);
});
}
/**
* Add an Unimport preset ([built-in](https://github.com/unjs/unimport?tab=readme-ov-file#built-in-presets),
* [custom](https://github.com/unjs/unimport?tab=readme-ov-file#custom-presets),
* or [auto-scanned](https://github.com/unjs/unimport?tab=readme-ov-file#exports-auto-scan)),
* to the project's list of auto-imported utilities.
*
* Some things to note:
* - This function will only de-duplicate built-in preset names. It will not
* stop you adding duplicate custom or auto-scanned presets.
* - If the project has disabled imports, this function has no effect.
*
* @param wxt The wxt instance provided by the module's setup function.
* @param preset The preset to add to the project.
*
* @example
* export default defineWxtModule((wxt) => {
* // Built-in preset:
* addImportPreset(wxt, "vue");
* // Custom preset:
* addImportPreset(wxt, {
* from: "vue",
* imports: ["ref", "reactive", ...],
* });
* // Auto-scanned preset:
* addImportPreset(wxt, { package: "vue" });
* });
*/
export function addImportPreset(
wxt: Wxt,
preset: UnimportOptions['presets'][0],
): void {
wxt.hooks.hook('ready', (wxt) => {
if (!wxt.config.imports) return;
wxt.config.imports.presets ??= [];
// De-dupelicate built-in named presets
if (wxt.config.imports.presets.includes(preset)) return;
wxt.config.imports.presets.push(preset);
});
}
+8 -2
View File
@@ -1185,7 +1185,7 @@ export interface ResolvedConfig {
reloadCommand: string | false;
};
hooks: NestedHooks<WxtHooks>;
modules: WxtModule<any>[];
modules: WxtModuleWithMetadata<any>[];
/**
* An array of string to import plugins from. These paths should be
* resolvable by vite, and they should `export default defineWxtPlugin(...)`.
@@ -1300,7 +1300,7 @@ export type WxtModuleOptions = Record<string, any>;
export type WxtModuleSetup<TOptions extends WxtModuleOptions> = (
wxt: Wxt,
moduleOptions: TOptions,
moduleOptions?: TOptions,
) => void | Promise<void>;
export interface WxtModule<TOptions extends WxtModuleOptions> {
@@ -1325,6 +1325,12 @@ export interface WxtModule<TOptions extends WxtModuleOptions> {
setup?: WxtModuleSetup<TOptions>;
}
export interface WxtModuleWithMetadata<TOptions extends WxtModuleOptions>
extends WxtModule<TOptions> {
type: 'local' | 'node_module';
id: string;
}
export interface ResolvedPublicFile {
/**
* The absolute path to the file that will be copied to the output directory.
+76 -40
View File
@@ -10,7 +10,7 @@ importers:
devDependencies:
'@aklinker1/check':
specifier: ^1.1.1
version: 1.2.0(typescript@5.3.3)
version: 1.2.0(typescript@5.4.5)
'@types/fs-extra':
specifier: ^11.0.4
version: 11.0.4
@@ -23,12 +23,21 @@ importers:
consola:
specifier: ^3.2.3
version: 3.2.3
dependency-graph:
specifier: ^1.0.0
version: 1.0.0
execa:
specifier: ^9.1.0
version: 9.1.0
fast-glob:
specifier: ^3.3.1
version: 3.3.2
fs-extra:
specifier: ^11.1.1
version: 11.2.0
hasha:
specifier: ^6.0.0
version: 6.0.0
lint-staged:
specifier: ^15.2.0
version: 15.2.2
@@ -46,7 +55,7 @@ importers:
version: 4.11.2
typedoc:
specifier: ^0.25.4
version: 0.25.4(typescript@5.3.3)
version: 0.25.4(typescript@5.4.5)
typedoc-plugin-markdown:
specifier: 4.0.0-next.23
version: 4.0.0-next.23(typedoc@0.25.4)
@@ -54,26 +63,29 @@ importers:
specifier: 1.0.0-next.3
version: 1.0.0-next.3(typedoc-plugin-markdown@4.0.0-next.23)
typescript:
specifier: ^5.3.2
version: 5.3.3
specifier: ^5.4.5
version: 5.4.5
vitepress:
specifier: ^1.2.2
version: 1.2.2(typescript@5.3.3)
version: 1.2.2(typescript@5.4.5)
vitest:
specifier: ^1.5.3
version: 1.5.3
vitest-mock-extended:
specifier: ^1.3.1
version: 1.3.1(typescript@5.3.3)(vitest@1.5.3)
version: 1.3.1(typescript@5.4.5)(vitest@1.5.3)
vitest-plugin-random-seed:
specifier: ^1.0.2
version: 1.0.2(vite@5.2.12)
vue:
specifier: ^3.3.10
version: 3.4.21(typescript@5.3.3)
version: 3.4.21(typescript@5.4.5)
wxt:
specifier: workspace:*
version: link:packages/wxt
yaml:
specifier: ^2.4.5
version: 2.4.5
packages/wxt:
dependencies:
@@ -194,7 +206,7 @@ importers:
devDependencies:
'@aklinker1/check':
specifier: ^1.1.1
version: 1.2.0(typescript@5.3.3)
version: 1.2.0(typescript@5.4.5)
'@faker-js/faker':
specifier: ^8.3.1
version: 8.3.1
@@ -236,13 +248,13 @@ importers:
version: 0.2.7
tsup:
specifier: ^8.0.1
version: 8.0.1(typescript@5.3.3)
version: 8.0.1(typescript@5.4.5)
tsx:
specifier: ^4.11.2
version: 4.11.2
typescript:
specifier: ^5.3.2
version: 5.3.3
specifier: ^5.4.5
version: 5.4.5
packages/wxt-demo:
dependencies:
@@ -263,15 +275,15 @@ importers:
specifier: ^1.69.5
version: 1.69.5
typescript:
specifier: ^5.3.2
version: 5.3.3
specifier: ^5.4.5
version: 5.4.5
wxt:
specifier: workspace:*
version: link:../wxt
packages:
/@aklinker1/check@1.2.0(typescript@5.3.3):
/@aklinker1/check@1.2.0(typescript@5.4.5):
resolution: {integrity: sha512-8GEoPcifx5f7Yx2t1KCGEQyrLOOb2ErP3cG+H1+TwWBYjkT2HV9ZHCLYy0Ws8CET8VeUcKDvLKmn2DW3HBt+FA==}
hasBin: true
peerDependencies:
@@ -280,7 +292,7 @@ packages:
'@antfu/utils': 0.7.7
ci-info: 4.0.0
citty: 0.1.6
typescript: 5.3.3
typescript: 5.4.5
dev: true
/@aklinker1/rollup-plugin-visualizer@5.12.0:
@@ -1526,7 +1538,7 @@ packages:
vue: ^3.2.25
dependencies:
vite: 5.2.12
vue: 3.4.27(typescript@5.3.3)
vue: 3.4.27(typescript@5.4.5)
dev: true
/@vitest/coverage-v8@1.2.2(vitest@1.5.3):
@@ -1685,7 +1697,7 @@ packages:
mitt: 3.0.1
perfect-debounce: 1.0.0
speakingurl: 14.0.1
vue: 3.4.27(typescript@5.3.3)
vue: 3.4.27(typescript@5.4.5)
dev: true
/@vue/devtools-shared@7.2.1:
@@ -1743,7 +1755,7 @@ packages:
dependencies:
'@vue/compiler-ssr': 3.4.21
'@vue/shared': 3.4.21
vue: 3.4.21(typescript@5.3.3)
vue: 3.4.21(typescript@5.4.5)
dev: true
/@vue/server-renderer@3.4.27(vue@3.4.27):
@@ -1753,7 +1765,7 @@ packages:
dependencies:
'@vue/compiler-ssr': 3.4.27
'@vue/shared': 3.4.27
vue: 3.4.27(typescript@5.3.3)
vue: 3.4.27(typescript@5.4.5)
dev: true
/@vue/shared@3.4.21:
@@ -2218,7 +2230,7 @@ packages:
scule: 1.3.0
semver: 7.5.4
std-env: 3.6.0
yaml: 2.3.4
yaml: 2.4.5
dev: true
/check-error@1.0.3:
@@ -2578,6 +2590,11 @@ packages:
/defu@6.1.4:
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
/dependency-graph@1.0.0:
resolution: {integrity: sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==}
engines: {node: '>=4'}
dev: true
/dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
@@ -3338,6 +3355,14 @@ packages:
function-bind: 1.1.1
dev: true
/hasha@6.0.0:
resolution: {integrity: sha512-MLydoyGp9QJcjlhE5lsLHXYpWayjjWqkavzju2ZWD2tYa1CgmML1K1gWAu22BLFa2eZ0OfvJ/DlfoVjaD54U2Q==}
engines: {node: '>=18'}
dependencies:
is-stream: 3.0.0
type-fest: 4.20.0
dev: true
/highlight.js@10.7.3:
resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
dev: false
@@ -4635,7 +4660,7 @@ packages:
optional: true
dependencies:
lilconfig: 2.1.0
yaml: 2.3.4
yaml: 2.4.5
dev: true
/postcss@8.4.38:
@@ -5473,12 +5498,12 @@ packages:
hasBin: true
dev: true
/ts-essentials@9.3.2(typescript@5.3.3):
/ts-essentials@9.3.2(typescript@5.4.5):
resolution: {integrity: sha512-JxKJzuWqH1MmH4ZFHtJzGEhkfN3QvVR3C3w+4BIoWeoY68UVVoA2Np/Bca9z0IPSErVCWhv439aT0We4Dks8kQ==}
peerDependencies:
typescript: '>=4.1.0'
dependencies:
typescript: 5.3.3
typescript: 5.4.5
dev: true
/ts-interface-checker@0.1.13:
@@ -5489,7 +5514,7 @@ packages:
resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==}
dev: false
/tsup@8.0.1(typescript@5.3.3):
/tsup@8.0.1(typescript@5.4.5):
resolution: {integrity: sha512-hvW7gUSG96j53ZTSlT4j/KL0q1Q2l6TqGBFc6/mu/L46IoNWqLLUzLRLP1R8Q7xrJTmkDxxDoojV5uCVs1sVOg==}
engines: {node: '>=18'}
hasBin: true
@@ -5522,7 +5547,7 @@ packages:
source-map: 0.8.0-beta.0
sucrase: 3.32.0
tree-kill: 1.2.2
typescript: 5.3.3
typescript: 5.4.5
transitivePeerDependencies:
- supports-color
- ts-node
@@ -5558,6 +5583,11 @@ packages:
resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==}
engines: {node: '>=14.16'}
/type-fest@4.20.0:
resolution: {integrity: sha512-MBh+PHUHHisjXf4tlx0CFWoMdjx8zCMLJHOjnV1prABYZFHqtFOyauCIK2/7w4oIfwkF8iNhLtnJEfVY2vn3iw==}
engines: {node: '>=16'}
dev: true
/typed-array-length@1.0.4:
resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==}
dependencies:
@@ -5581,7 +5611,7 @@ packages:
peerDependencies:
typedoc: '>=0.25.0'
dependencies:
typedoc: 0.25.4(typescript@5.3.3)
typedoc: 0.25.4(typescript@5.4.5)
dev: true
/typedoc-vitepress-theme@1.0.0-next.3(typedoc-plugin-markdown@4.0.0-next.23):
@@ -5592,7 +5622,7 @@ packages:
typedoc-plugin-markdown: 4.0.0-next.23(typedoc@0.25.4)
dev: true
/typedoc@0.25.4(typescript@5.3.3):
/typedoc@0.25.4(typescript@5.4.5):
resolution: {integrity: sha512-Du9ImmpBCw54bX275yJrxPVnjdIyJO/84co0/L9mwe0R3G4FSR6rQ09AlXVRvZEGMUg09+z/usc8mgygQ1aidA==}
engines: {node: '>= 16'}
hasBin: true
@@ -5603,11 +5633,11 @@ packages:
marked: 4.3.0
minimatch: 9.0.3
shiki: 0.14.5
typescript: 5.3.3
typescript: 5.4.5
dev: true
/typescript@5.3.3:
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
/typescript@5.4.5:
resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
@@ -5815,7 +5845,7 @@ packages:
fsevents: 2.3.3
dev: false
/vitepress@1.2.2(typescript@5.3.3):
/vitepress@1.2.2(typescript@5.4.5):
resolution: {integrity: sha512-uZ3nXR5NY4nYj3RJWCo5jev9qlNZAQo5SUXu1U0QSUx84cUm/o7hCTDVjZ4njVSVui+PsV1oAbdQOg8ygbaf4w==}
hasBin: true
peerDependencies:
@@ -5842,7 +5872,7 @@ packages:
minisearch: 6.3.0
shiki: 1.6.2
vite: 5.2.12
vue: 3.4.27(typescript@5.3.3)
vue: 3.4.27(typescript@5.4.5)
transitivePeerDependencies:
- '@algolia/client-search'
- '@types/node'
@@ -5871,14 +5901,14 @@ packages:
- universal-cookie
dev: true
/vitest-mock-extended@1.3.1(typescript@5.3.3)(vitest@1.5.3):
/vitest-mock-extended@1.3.1(typescript@5.4.5)(vitest@1.5.3):
resolution: {integrity: sha512-OpghYjh4BDuQ/Mzs3lFMQ1QRk9D8/2O9T47MLUA5eLn7K4RWIy+MfIivYOWEyxjTENjsBnzgMihDjyNalN/K0Q==}
peerDependencies:
typescript: 3.x || 4.x || 5.x
vitest: '>=0.31.1'
dependencies:
ts-essentials: 9.3.2(typescript@5.3.3)
typescript: 5.3.3
ts-essentials: 9.3.2(typescript@5.4.5)
typescript: 5.4.5
vitest: 1.5.3
dev: true
@@ -5965,10 +5995,10 @@ packages:
'@vue/composition-api':
optional: true
dependencies:
vue: 3.4.27(typescript@5.3.3)
vue: 3.4.27(typescript@5.4.5)
dev: true
/vue@3.4.21(typescript@5.3.3):
/vue@3.4.21(typescript@5.4.5):
resolution: {integrity: sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==}
peerDependencies:
typescript: '*'
@@ -5981,10 +6011,10 @@ packages:
'@vue/runtime-dom': 3.4.21
'@vue/server-renderer': 3.4.21(vue@3.4.21)
'@vue/shared': 3.4.21
typescript: 5.3.3
typescript: 5.4.5
dev: true
/vue@3.4.27(typescript@5.3.3):
/vue@3.4.27(typescript@5.4.5):
resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==}
peerDependencies:
typescript: '*'
@@ -5997,7 +6027,7 @@ packages:
'@vue/runtime-dom': 3.4.27
'@vue/server-renderer': 3.4.27(vue@3.4.27)
'@vue/shared': 3.4.27
typescript: 5.3.3
typescript: 5.4.5
dev: true
/watchpack@2.4.0:
@@ -6233,6 +6263,12 @@ packages:
engines: {node: '>= 14'}
dev: true
/yaml@2.4.5:
resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==}
engines: {node: '>= 14'}
hasBin: true
dev: true
/yargs-parser@20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
+133
View File
@@ -0,0 +1,133 @@
//
// Build all workspace packages, or only dependencies of a specific package.
// Kind of a simple version of nx/turborepo, but we can keep using PNPM to run
// all commands.
//
// Usage:
// pnpm tsx scripts/build-deps.ts # Builds all packages in repo
// pnpm tsx scripts/build-deps.ts <packageName> # Builds only dependencies of <packageName>
//
import glob from 'fast-glob';
import { DepGraph } from 'dependency-graph';
import fs from 'fs-extra';
import YAML from 'yaml';
import { execa } from 'execa';
import consola from 'consola';
import { hashFile, hash } from 'hasha';
import { resolve } from 'node:path';
// Quick hack to prevent recursive calls to this script. If it's being called
// from another instance of this script, the parent instance is already
// preforming this build, so it can be skipped.
if (process.env.BUILD_DEPS) process.exit(0);
process.env.BUILD_DEPS = 'true';
// Parse args
const packageToBuild = process.argv[2];
if (packageToBuild == null) {
consola.info('Building all packages...');
} else {
consola.info(`Building dependencies of \`${packageToBuild}\``);
}
// Build graph
const workspace: { packages: string[] } = YAML.parse(
await fs.readFile('pnpm-workspace.yaml', 'utf8'),
);
const packageDirs = await glob(workspace.packages, { onlyDirectories: true });
const graph = new DepGraph<Record<string, any>>();
// Add all packages to chart
for (const packageDir of packageDirs) {
try {
const packageJson = await fs.readJson(`${packageDir}/package.json`);
graph.addNode(packageJson.name, { ...packageJson, dir: packageDir });
} catch {
// Package missing package.json, ignore it
}
}
// Add dependencies between packages
graph.entryNodes().forEach((packageName) => {
const packageJson = graph.getNodeData(packageName);
[
...Object.entries<string>(packageJson.dependencies ?? {}),
...Object.entries<string>(packageJson.devDependencies ?? {}),
].forEach(([dep, version]) => {
if (version !== 'workspace:*') return;
graph.addDependency(packageName, dep);
});
});
function printGraph(graph: DepGraph<any>) {
consola.debug('Dependency Graph:');
function printNode(node: string, level = 0) {
consola.debug(`${''.padStart(level * 2, ' ')}- \`${node}\``);
graph.dependenciesOf(node).forEach((dep) => printNode(dep, level + 1));
}
graph.entryNodes().forEach((entry) => printNode(entry));
}
printGraph(graph);
if (packageToBuild) {
// Remove nodes not associated with the package to build
graph.entryNodes().forEach((entry) => {
if (entry !== packageToBuild) graph.removeNode(entry);
});
}
// Get order
const buildOrder = graph.overallOrder().filter(
// Remove packageToBuild if provided
(packageName) => packageName !== packageToBuild,
);
consola.info('Build order:', buildOrder);
// Build dependencies of a package
async function hashDir(dir: string): Promise<string> {
const files = await glob('**/*', {
ignore: [
'**/dist/**',
'**/node_modules/**',
'**/__tests__/**',
'**/e2e/**',
'CHANGELOG.md',
'typedoc.json',
'vitest.*.ts',
],
cwd: dir,
});
const hashes = await Promise.all(
files.sort().map(async (file) => {
const hash = await hashFile(resolve(dir, file), { algorithm: 'md5' });
return `${hash}-${file}`;
}),
);
consola.debug(hashes.join('\n'));
return await hash(hashes.join('\n'), { algorithm: 'md5' });
}
async function buildPackage(packageName: string): Promise<void> {
const packageJson = graph.getNodeData(packageName);
const hash = await hashDir(packageJson.dir);
consola.debug('Directory hash:', hash);
const cacheDir = resolve('.cache', packageJson.dir, hash);
const outputDir = resolve(packageJson.dir, 'dist');
if (await fs.pathExists(cacheDir)) {
await fs.ensureDir(outputDir);
await fs.copy(cacheDir, outputDir);
consola.success(`\`${packageName}\` cached`);
} else {
await execa('pnpm', ['--filter', packageName, 'build'], {
stdio: 'inherit',
});
await fs.ensureDir(cacheDir);
await fs.copy(outputDir, cacheDir);
}
}
try {
for (const packageName of buildOrder) {
await buildPackage(packageName);
}
} catch (err) {
consola.error(err);
process.exit(1);
}
+4 -3
View File
@@ -40,13 +40,14 @@ await execa('pnpm', ['version', bumpType], {
});
const updatedPkgJson = await fs.readJson(pkgJsonPath);
const newVersion: string = updatedPkgJson.version;
const newTag = getPkgTag(pkg, newVersion);
consola.info('Bump:', { currentVersion, bumpType, newVersion });
// Generate changelog
const versionChangelog = await generateMarkDown(commits, {
...config,
from: currentVersion,
to: newVersion,
from: prevTag,
to: newTag,
});
const versionChangelogBody = versionChangelog
.split('\n')
@@ -80,5 +81,5 @@ await execa('git', [
'-m',
`chore(release): ${pkgName} v${newVersion}`,
]);
await execa('git', ['tag', getPkgTag(pkg, newVersion)]);
await execa('git', ['tag', newTag]);
consola.success('Committed version and changelog');
+12 -8
View File
@@ -27,14 +27,18 @@ config.tokens.github = process.env.GITHUB_TOKEN;
// Update releases
for (const release of releases) {
const tag = getPkgTag(pkg, release.version);
const existing = await getGithubReleaseByTag(config, tag);
if (existing.body !== release.body) {
await updateGithubRelease(config, existing.id!, {
tag_name: tag,
name: `${pkgName} v${release.version}`,
body: release.body,
});
try {
const existing = await getGithubReleaseByTag(config, tag);
if (existing.body !== release.body) {
await updateGithubRelease(config, existing.id!, {
tag_name: tag,
name: `${pkgName} v${release.version}`,
body: release.body,
});
}
consola.success(`Synced \`${tag}\``);
} catch (err) {
consola.fail(`\`${tag}\``, err);
}
consola.success(`Synced \`${tag}\``);
}
consola.success('Done');
+1 -1
View File
@@ -22,7 +22,7 @@
"@types/react": "^18.2.46",
"@types/react-dom": "^18.2.18",
"@vitejs/plugin-react": "^4.2.1",
"typescript": "^5.3.3",
"typescript": "^5.4.5",
"wxt": "^0.18.0"
}
}
+1 -1
View File
@@ -18,7 +18,7 @@
"solid-js": "^1.8.7"
},
"devDependencies": {
"typescript": "^5.3.3",
"typescript": "^5.4.5",
"vite-plugin-solid": "^2.8.0",
"wxt": "^0.18.0"
}
+1 -1
View File
@@ -19,7 +19,7 @@
"svelte": "^4.2.8",
"svelte-check": "^3.6.2",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"typescript": "^5.4.5",
"wxt": "^0.18.0"
}
}
+1 -1
View File
@@ -15,7 +15,7 @@
"postinstall": "wxt prepare"
},
"devDependencies": {
"typescript": "^5.3.3",
"typescript": "^5.4.5",
"wxt": "^0.18.0"
}
}
+1 -1
View File
@@ -19,7 +19,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.1",
"typescript": "^5.3.3",
"typescript": "^5.4.5",
"vue-tsc": "^2.0.6",
"wxt": "^0.18.0"
}