Merge branch 'fork/xingyu4j/deps'

This commit is contained in:
金毛88
2026-07-22 09:51:25 +08:00
18 changed files with 4203 additions and 4228 deletions

3
.github/config.yml vendored
View File

@@ -21,12 +21,10 @@ newPRWelcomeComment: |
firstPRMergeComment: >
Thanks for your contribution! 🎉🎉🎉
# Comment to be posted to on first time issues
newIssueWelcomeComment: >
Thanks for opening your first issue! Be sure to follow the issue template and provide every bit of information to help the developers!
# *OPTIONAL* default titles to check against for lack of descriptiveness
# MUST BE ALL LOWERCASE
requestInfoDefaultTitles:
@@ -36,4 +34,3 @@ requestInfoDefaultTitles:
# *Required* Comment to reply with
requestInfoReplyComment: >
Thanks for filing this issue/PR! It would be much appreciated if you could provide us with more information so we can effectively analyze the situation in context.

View File

@@ -19,6 +19,7 @@ export const MOCK_USERS: UserInfo[] = [
realName: 'Vben',
roles: ['super'],
username: 'vben',
homePath: '/dashboard/workspace',
},
{
id: 1,

View File

@@ -80,10 +80,7 @@ export type PromptProps<T = any> = {
component?: Component;
componentProps?: Recordable<any>;
componentSlots?:
| (() => any)
| Recordable<unknown>
| VNode
| VNodeArrayChildren;
(() => any) | Recordable<unknown> | VNode | VNodeArrayChildren;
defaultValue?: T;
modelPropName?: string;
} & Omit<AlertProps, 'beforeClose'>;

View File

@@ -9,7 +9,7 @@ const items = [
];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 16px">
<div class="flex gap-4 flex-col">
<VbenDescriptions
size="small"
bordered

View File

@@ -1,7 +1,9 @@
<script lang="ts" setup>
import type { DescriptionsItemType } from '@vben/common-ui';
import { VbenDescriptions } from '@vben/common-ui';
const items = [
const items: DescriptionsItemType[] = [
{ content: '1', label: 'A' },
{ content: '2span: 2', label: 'B', span: 2 },
{ content: '3', label: 'C' },

View File

@@ -1,7 +1,9 @@
<script lang="ts" setup>
import type { DescriptionsItemType } from '@vben/common-ui';
import { VbenDescriptions } from '@vben/common-ui';
const items = [
const items: DescriptionsItemType[] = [
{ content: 'Vben', label: '用户名' },
{ content: '13800138000', label: '手机号' },
{ content: '中国 · 杭州', label: '居住地' },

View File

@@ -66,10 +66,7 @@ export type PromptProps<T = any> = {
component?: Component;
componentProps?: Recordable<any>;
componentSlots?:
| (() => any)
| Recordable<unknown>
| VNode
| VNodeArrayChildren;
(() => any) | Recordable<unknown> | VNode | VNodeArrayChildren;
defaultValue?: T;
modelPropName?: string;
} & Omit<AlertProps, 'beforeClose'>;

View File

@@ -341,12 +341,7 @@ interface RouteMeta {
* Badge color
*/
badgeVariants?:
| 'default'
| 'destructive'
| 'primary'
| 'success'
| 'warning'
| string;
'default' | 'destructive' | 'primary' | 'success' | 'warning' | string;
/**
* The children of the current route are not displayed in the menu
* @default false

View File

@@ -334,12 +334,7 @@ interface RouteMeta {
* 徽标颜色
*/
badgeVariants?:
| 'default'
| 'destructive'
| 'primary'
| 'success'
| 'warning'
| string;
'default' | 'destructive' | 'primary' | 'success' | 'warning' | string;
/**
* 路由的完整路径作为key默认true
*/

View File

@@ -79,6 +79,7 @@ export default {
'nesting-selector-no-missing-scoping-root': null,
'no-descending-specificity': null,
'no-empty-source': null,
'no-invalid-position-declaration': null,
'order/order': [
[
'dollar-variables',

View File

@@ -104,10 +104,10 @@
"vue-tsc": "catalog:"
},
"engines": {
"node": "^22.18.0 || ^24.0.0",
"node": "^22.18.0 || ^24.12.0",
"pnpm": ">=11.0.0"
},
"packageManager": "pnpm@11.7.0",
"packageManager": "pnpm@11.15.1",
"dependencies": {
"sortablejs": "catalog:"
}

View File

@@ -136,14 +136,23 @@ exports[`defaultPreferences immutability test > should not modify the config obj
},
"widget": {
"fullscreen": true,
"fullscreenButtonPosition": "header",
"globalSearch": true,
"globalSearchButtonPosition": "header",
"languageToggle": true,
"languageToggleButtonPosition": "header",
"lockScreen": true,
"lockScreenButtonPosition": "header",
"logoutButtonPosition": "header",
"notification": true,
"notificationButtonPosition": "header",
"refresh": true,
"refreshButtonPosition": "header",
"sidebarToggle": true,
"themeToggle": true,
"themeToggleButtonPosition": "header",
"timezone": true,
"timezoneButtonPosition": "header",
},
}
`;

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
// oxlint-disable unicorn/no-nested-ternary
import type { FormCommonConfig, FormSchema } from '../types';
import { computed } from 'vue';

View File

@@ -76,7 +76,7 @@ const schema: VbenFormSchema[] = [
数组字段名。假设为 `contacts`,第 1 行子字段 `name` 会被转换成:
```ts
contacts[0].name
contacts[0].name;
```
### `children`
@@ -102,22 +102,22 @@ contacts[0].name
传给数组编辑器的配置:
| 字段 | 说明 |
| --- | --- |
| `addButtonText` | 新增按钮文案 |
| `actionText` | 操作列表头文案 |
| `emptyText` | 空数据文案 |
| `min` | 最少行数,达到后禁用删除 |
| `max` | 最多行数,达到后禁用新增 |
| `showIndex` | 是否显示序号 |
| `createRow` | 新增行时生成默认数据 |
| 字段 | 说明 |
| --------------- | ------------------------ |
| `addButtonText` | 新增按钮文案 |
| `actionText` | 操作列表头文案 |
| `emptyText` | 空数据文案 |
| `min` | 最少行数,达到后禁用删除 |
| `max` | 最多行数,达到后禁用新增 |
| `showIndex` | 是否显示序号 |
| `createRow` | 新增行时生成默认数据 |
## 校验建议
数组父级 `rules` 建议只写数组级规则,例如至少一行:
```ts
rules: z.array(z.any()).min(1, '请至少添加一个联系人')
rules: z.array(z.any()).min(1, '请至少添加一个联系人');
```
每个子字段的必填、长度、格式校验写在 children 自己的 `rules`
@@ -156,20 +156,20 @@ children 里的 `dependencies.triggerFields` 默认是“当前行相对路径
在第 1 行中,`triggerFields: ['role']` 会被转换成:
```ts
contacts[0].role
contacts[0].role;
```
回调多了一个可选 `ctx` 参数:
| 字段 | 说明 |
| --- | --- |
| `ctx.row` | 当前行数据 |
| `ctx.rowIndex` | 当前行索引 |
| `ctx.rowPath` | 当前行路径,例如 `contacts[0]` |
| `ctx.arrayField` | 数组字段名,例如 `contacts` |
| `ctx.fieldName` | 当前真实字段名,例如 `contacts[0].phone` |
| `ctx.originalFieldName` | 原始 child 字段名,例如 `phone` |
| `ctx.rootValues` | 表单完整值 |
| 字段 | 说明 |
| ----------------------- | ---------------------------------------- |
| `ctx.row` | 当前行数据 |
| `ctx.rowIndex` | 当前行索引 |
| `ctx.rowPath` | 当前行路径,例如 `contacts[0]` |
| `ctx.arrayField` | 数组字段名,例如 `contacts` |
| `ctx.fieldName` | 当前真实字段名,例如 `contacts[0].phone` |
| `ctx.originalFieldName` | 原始 child 字段名,例如 `phone` |
| `ctx.rootValues` | 表单完整值 |
如果 child 需要依赖表单根字段,可以使用 `$root.` 前缀:
@@ -185,7 +185,7 @@ dependencies: {
如果想显式写当前行字段,也可以使用 `$row.` 前缀:
```ts
triggerFields: ['$row.role']
triggerFields: ['$row.role'];
```
## valueFormat 用法
@@ -210,19 +210,19 @@ children 里的 `valueFormat` 也会按行执行:
`contacts[0]` 中,`setValue('phone', nextValue)` 会自动写到:
```ts
contacts[0].phone
contacts[0].phone;
```
如果要写根字段,用 `$root.`
```ts
setValue('$root.firstContactPhone', value)
setValue('$root.firstContactPhone', value);
```
如果要显式写当前行字段,用 `$row.`
```ts
setValue('$row.phone', value)
setValue('$row.phone', value);
```
## updateSchema 用法

8097
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -37,70 +37,70 @@ overrides:
vue: 'catalog:'
catalog:
'@ast-grep/napi': ^0.43.0
'@ast-grep/napi': ^0.44.1
'@changesets/changelog-github': ^0.7.0
'@changesets/cli': ^2.31.0
'@changesets/cli': ^2.31.1
'@changesets/git': ^3.0.4
'@clack/prompts': ^1.5.1
'@commitlint/cli': ^21.0.2
'@commitlint/config-conventional': ^21.0.2
'@clack/prompts': ^1.7.0
'@commitlint/cli': ^21.2.1
'@commitlint/config-conventional': ^21.2.0
'@ctrl/tinycolor': ^4.2.0
'@eslint-community/eslint-plugin-eslint-comments': ^4.7.2
'@eslint/js': ^10.0.1
'@faker-js/faker': ^10.4.0
'@iconify/json': ^2.2.487
'@faker-js/faker': ^10.5.0
'@iconify/json': ^2.2.501
'@iconify/tailwind4': ^1.2.3
'@iconify/vue': ^5.0.1
'@intlify/core-base': ^11.4.5
'@intlify/unplugin-vue-i18n': ^11.2.3
'@jspm/generator': ^2.16.1
'@lucide/vue': ^1.18.0
'@intlify/core-base': ^11.4.6
'@intlify/unplugin-vue-i18n': ^11.2.4
'@jspm/generator': ^2.16.3
'@lucide/vue': ^1.25.0
'@manypkg/get-packages': ^3.1.0
'@nolebase/vitepress-plugin-git-changelog': ^2.18.2
'@playwright/test': ^1.61.0
'@playwright/test': ^1.61.1
'@pnpm/workspace.read-manifest': ^1000.3.1
'@stylistic/stylelint-plugin': ^5.2.0
'@stylistic/stylelint-plugin': ^5.2.1
'@tailwindcss/typography': ^0.5.20
'@tailwindcss/vite': ^4.3.1
'@tanstack/vue-query': ^5.101.0
'@tailwindcss/vite': ^4.3.3
'@tanstack/vue-query': ^5.101.2
'@tanstack/vue-store': ^0.11.0
'@tiptap/core': ^3.26.1
'@tiptap/extension-document': ^3.26.1
'@tiptap/extension-highlight': ^3.26.1
'@tiptap/extension-image': ^3.26.1
'@tiptap/extension-link': ^3.26.1
'@tiptap/extension-placeholder': ^3.26.1
'@tiptap/extension-text-align': ^3.26.1
'@tiptap/extension-text-style': ^3.26.1
'@tiptap/extension-underline': ^3.26.1
'@tiptap/pm': ^3.26.1
'@tiptap/starter-kit': ^3.26.1
'@tiptap/vue-3': ^3.26.1
'@tsdown/css': ^0.22.3
'@tiptap/core': ^3.28.0
'@tiptap/extension-document': ^3.28.0
'@tiptap/extension-highlight': ^3.28.0
'@tiptap/extension-image': ^3.28.0
'@tiptap/extension-link': ^3.28.0
'@tiptap/extension-placeholder': ^3.28.0
'@tiptap/extension-text-align': ^3.28.0
'@tiptap/extension-text-style': ^3.28.0
'@tiptap/extension-underline': ^3.28.0
'@tiptap/pm': ^3.28.0
'@tiptap/starter-kit': ^3.28.0
'@tiptap/vue-3': ^3.28.0
'@tsdown/css': ^0.22.9
'@types/archiver': ^8.0.0
'@types/html-minifier-terser': ^7.0.2
'@types/json-bigint': ^1.0.4
'@types/jsonwebtoken': ^9.0.10
'@types/lodash.clonedeep': ^4.5.9
'@types/node': ^25.9.4
'@types/node': ^25.9.5
'@types/nprogress': ^0.2.3
'@types/qrcode': ^1.5.6
'@types/qs': ^6.15.1
'@types/sortablejs': ^1.15.9
'@typescript-eslint/parser': ^8.61.1
'@typescript-eslint/parser': ^8.64.0
'@vee-validate/zod': ^4.15.1
'@vite-pwa/vitepress': ^1.1.0
'@vitejs/plugin-vue': ^6.0.7
'@vitejs/plugin-vue-jsx': ^5.1.5
'@vue/shared': ^3.5.38
'@vitejs/plugin-vue': ^6.0.8
'@vitejs/plugin-vue-jsx': ^5.1.6
'@vue/shared': ^3.5.40
'@vue/test-utils': ^2.4.11
'@vueuse/core': ^14.3.0
'@vueuse/integrations': ^14.3.0
'@vueuse/motion': ^3.0.3
ant-design-vue: ^4.2.6
antdv-next: ^1.3.5
antdv-next: ^1.4.3
archiver: ^8.0.0
axios: ^1.18.0
axios: ^1.18.1
axios-mock-adapter: ^2.1.0
cac: ^7.0.0
chalk: ^5.6.2
@@ -118,50 +118,50 @@ catalog:
defu: ^6.1.7
dotenv: ^17.4.2
echarts: ^6.1.0
element-plus: ^2.14.2
es-toolkit: ^1.47.1
eslint: ^10.5.0
eslint-plugin-better-tailwindcss: ^4.6.0
eslint-plugin-command: ^3.5.2
eslint-plugin-jsonc: ^3.2.0
eslint-plugin-n: ^18.1.0
eslint-plugin-perfectionist: ^5.9.1
element-plus: ^2.14.3
es-toolkit: ^1.49.0
eslint: ^10.7.0
eslint-plugin-better-tailwindcss: ^4.6.1
eslint-plugin-command: ^3.5.3
eslint-plugin-jsonc: ^3.3.0
eslint-plugin-n: ^18.2.2
eslint-plugin-perfectionist: ^5.10.0
eslint-plugin-pnpm: ^1.6.1
eslint-plugin-unused-imports: ^4.4.1
eslint-plugin-vue: ^10.9.2
eslint-plugin-yml: ^3.4.0
execa: ^9.6.1
eslint-plugin-yml: ^3.6.0
execa: ^10.0.0
find-up: ^8.0.0
get-port: ^7.2.0
globals: ^17.6.0
globals: ^17.7.0
h3: ^1.15.11
happy-dom: ^20.10.6
happy-dom: ^20.11.0
html-minifier-terser: ^7.2.0
is-ci: ^4.1.0
json-bigint: ^1.0.0
jsonwebtoken: ^9.0.3
knip: ^6.17.0
lefthook: ^2.1.9
knip: ^6.27.0
lefthook: ^2.1.10
lodash.clonedeep: ^4.5.0
medium-zoom: ^1.1.0
naive-ui: ^2.44.1
nitropack: ^2.13.4
nprogress: ^0.2.0
ora: ^9.4.0
oxfmt: ^0.55.0
oxlint: ^1.70.0
oxlint-tsgolint: ^0.23.0
pinia: ^3.0.4
ora: ^9.4.1
oxfmt: ^0.59.0
oxlint: ^1.74.0
oxlint-tsgolint: ^0.25.0
pinia: ^4.0.2
pinia-plugin-persistedstate: ^4.7.1
pkg-types: ^2.3.1
playwright: ^1.61.0
postcss: ^8.5.15
playwright: ^1.61.1
postcss: ^8.5.20
postcss-html: ^1.8.1
postcss-scss: ^4.0.9
publint: ^0.3.21
qrcode: ^1.5.4
qs: ^6.15.2
reka-ui: ^2.9.10
qs: ^6.15.3
reka-ui: ^2.10.1
resolve.exports: ^2.0.3
rimraf: ^6.1.3
rollup-plugin-visualizer: ^7.0.1
@@ -169,7 +169,7 @@ catalog:
sass-embedded: ^1.100.0
secure-ls: ^2.0.0
sortablejs: ^1.15.7
stylelint: ^17.13.0
stylelint: ^17.14.0
stylelint-config-recess-order: ^7.7.0
stylelint-config-recommended: ^18.0.0
stylelint-config-recommended-scss: ^17.0.1
@@ -178,37 +178,37 @@ catalog:
stylelint-order: ^8.1.1
stylelint-scss: ^7.2.0
tailwind-merge: ^3.6.0
tailwindcss: ^4.3.1
tdesign-vue-next: ^1.20.1
tailwindcss: ^4.3.3
tdesign-vue-next: ^1.20.3
theme-colors: ^0.1.0
tippy.js: ^6.3.7
tsdown: ^0.22.3
turbo: ^2.9.18
tsdown: ^0.22.9
turbo: ^2.10.5
tw-animate-css: ^1.4.0
typescript: ^6.0.3
unplugin-dts: ^1.0.2
unplugin-dts: ^1.0.3
unplugin-element-plus: ^0.11.2
unplugin-vue: ^7.2.0
vee-validate: ^4.15.1
vite: 8.0.10
vite: ^8.1.5
vite-plugin-compression: ^0.5.1
vite-plugin-lazy-import: ^1.0.7
vite-plugin-pwa: ^1.3.0
vite-plugin-vue-devtools: ^8.1.3
vitepress: ^2.0.0-alpha.17
vite-plugin-vue-devtools: ^8.1.5
vitepress: ^2.0.0-alpha.18
vitepress-plugin-group-icons: ^1.7.5
vitest: ^4.1.9
vue: ^3.5.38
vitest: ^4.1.10
vue: ^3.5.40
vue-eslint-parser: ^10.4.1
vue-i18n: ^11.4.5
vue-i18n: ^11.4.6
vue-json-pretty: ^2.6.0
vue-router: ^5.1.0
vue-router: ^5.2.0
vue-tippy: ^6.7.1
vue-tsc: ^3.3.5
vxe-pc-ui: ^4.14.39
vxe-table: ^4.19.14
watermark-js-plus: ^1.6.3
yaml-eslint-parser: ^2.0.0
vue-tsc: ^3.3.7
vxe-pc-ui: ^4.16.15
vxe-table: ^4.20.5
watermark-js-plus: ^1.6.6
yaml-eslint-parser: ^2.1.0
zod: ^3.25.76
zod-defaults: 0.1.3

View File

@@ -1,4 +1,4 @@
import { execaCommand, getPackages } from '@vben/node-utils';
import { execa, getPackages } from '@vben/node-utils';
import { cancel, isCancel, select } from '@clack/prompts';
@@ -46,9 +46,13 @@ export async function run(options: RunOptions) {
process.exit(1);
}
execaCommand(`pnpm --filter=${selectPkg} run ${command}`, {
stdio: 'inherit',
});
try {
await execa('pnpm', [`--filter=${selectPkg}`, 'run', command], {
stdio: 'inherit',
});
} catch (error: any) {
process.exit(error.exitCode || 1);
}
}
/**

View File

@@ -3,7 +3,7 @@ import type { CAC } from 'cac';
import { execSync } from 'node:child_process';
import { availableParallelism, freemem } from 'node:os';
import { execaCommand } from '@vben/node-utils';
import { execa } from '@vben/node-utils';
interface LintCommandOptions {
/**
@@ -29,16 +29,35 @@ const CPU_CORE_THRESHOLD = 4;
*/
const FREE_MEMORY_THRESHOLD = 8 * 1024 ** 3;
/**
* 一条命令:可执行文件名 + 参数数组。
*
* execa v10 移除了 execaCommandexeca(file, args?, options?) 的第一个参数是
* 「可执行文件名」而非整条命令行;且默认不走 shell。因此统一用 [file, args] 数组形式,
* 参数逐个传入、无需 shell 转义,跨平台行为一致(避免把整条字符串误当文件名)。
*/
type Command = [file: string, args: string[]];
/** 执行单条命令。 */
function runCommand([file, args]: Command) {
return execa(file, args, { stdio: 'inherit' });
}
/** 将命令还原为可读字符串,用于失败信息展示。 */
function formatCommand([file, args]: Command) {
return [file, ...args].join(' ');
}
/**
* 串行执行所有命令:一次只运行一个进程。
* 保证一次能看到所有工具的报错(配置低的机器更友好)。
*/
async function runSerial(commands: string[]) {
const failed: string[] = [];
async function runSerial(commands: Command[]) {
const failed: Command[] = [];
for (const command of commands) {
try {
await execaCommand(command, { stdio: 'inherit' });
await runCommand(command);
} catch {
failed.push(command);
}
@@ -46,7 +65,9 @@ async function runSerial(commands: string[]) {
if (failed.length > 0) {
throw new Error(
`Lint failed:\n${failed.map((command) => ` - ${command}`).join('\n')}`,
`Lint failed:\n${failed
.map((command) => ` - ${formatCommand(command)}`)
.join('\n')}`,
);
}
}
@@ -55,10 +76,8 @@ async function runSerial(commands: string[]) {
* 并行执行所有命令:同时启动全部进程。
* 任一进程失败时,强制结束其余仍在运行的进程,避免产生遗漏进程。
*/
async function runParallel(commands: string[]) {
const subprocesses = commands.map((command) =>
execaCommand(command, { stdio: 'inherit' }),
);
async function runParallel(commands: Command[]) {
const subprocesses = commands.map((command) => runCommand(command));
try {
await Promise.all(subprocesses);
@@ -89,29 +108,23 @@ async function runLint({ format, threads }: LintCommandOptions) {
// 用户通过 --threads 显式指定时优先使用其值。
const defaultThreads =
cpuCores > CPU_CORE_THRESHOLD && freemem() > FREE_MEMORY_THRESHOLD ? 4 : 2;
const threadsArg = ` --threads=${threads || defaultThreads}`;
const threadsArg = `--threads=${threads || defaultThreads}`;
if (format) {
await execaCommand(`stylelint "**/*.{vue,css,less,scss}" --cache --fix`, {
stdio: 'inherit',
});
await execaCommand(`oxfmt${threadsArg}`, {
stdio: 'inherit',
});
await execaCommand(`oxlint --fix --type-aware${threadsArg}`, {
stdio: 'inherit',
});
await execaCommand(`eslint . --cache --fix`, {
stdio: 'inherit',
});
await runSerial([
['stylelint', ['**/*.{vue,css,less,scss}', '--cache', '--fix']],
['oxfmt', [threadsArg]],
['oxlint', ['--fix', '--type-aware', threadsArg]],
['eslint', ['.', '--cache', '--fix']],
]);
return;
}
const commands = [
`oxfmt --check${threadsArg}`,
`oxlint --type-aware${threadsArg}`,
`eslint . --cache`,
`stylelint "**/*.{vue,css,less,scss}" --cache`,
const commands: Command[] = [
['oxfmt', ['--check', threadsArg]],
['oxlint', ['--type-aware', threadsArg]],
['eslint', ['.', '--cache']],
['stylelint', ['**/*.{vue,css,less,scss}', '--cache']],
];
// 低配机器CPU 核心数较少)串行执行,避免多进程并发导致瞬时占用飙升;