-
Notifications
You must be signed in to change notification settings - Fork 8.5k
chore: 升级 zod 依赖版本至 4.1.13,已处理AI提示 #7052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- 移除对zod-defaults依赖项的依赖。 - 优化表单字段必填校验逻辑,改用 Zod schema 的 safeParse 方法替代 isOptional 判断。 - 将表单验证逻辑从使用Zod内部类型名改为使用公开的def.type属性,并更新相关辅助函数命名以更清晰地反映其功能。 - 重构 Zod 模式辅助函数以简化类型定义并增强默认值提取逻辑。 - 将表单验证规则类型从 ZodTypeAny 更改为 ZodType 以提升类型精确度。 - 重构表单初始化逻辑,移除直接处理 Zod 模式的默认值提取,改由专用辅助函数处理。 - 升级 zod 依赖版本至 4.1.13 并移除已弃用的 zod-defaults 包。 - 升级 zod 依赖版本并移除 zod-defaults 包。
- Zod schema 是普通对象,不应被 Vue 响应式系统处理。
- 移除对 @vee-validate/zod 依赖包的引用 - 移除对 vee-validate/zod 的类型转换依赖,直接返回原始校验规则。 - 将 forEach 替换为 map 以正确返回表单形状数组。 - 升级 vee-validate 到 5.0.0-beta.0 版本并移除其 zod 集成依赖。
|
📝 WalkthroughWalkthroughThe PR refactors form validation across the codebase by wrapping Zod schemas with Vue's Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes The changes span 40+ files with a mix of homogeneous repetitive patterns ( Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (4)
apps/web-antd/src/views/_core/authentication/code-login.vue (1)
48-52: Same verification needed for theerrorparameter.This has the same concern as the phoneNumber validation above - verify that Zod 4's
errorparameter accepts string values directly.apps/web-ele/src/views/_core/authentication/forget-password.vue (1)
5-5: Same changes as web-tdesign variant.This file shows identical changes to the web-tdesign forget-password.vue file. Please refer to the review comments on that file regarding
markRawusage and verification of theerrorparameter.Also applies to: 23-28
apps/web-naive/src/views/_core/authentication/forget-password.vue (1)
5-5: Same changes as other variants.This file shows identical changes to the web-tdesign and web-ele forget-password.vue files. Please refer to the review comments on the web-tdesign file regarding
markRawusage and verification of theerrorparameter.Also applies to: 23-28
apps/web-antd/src/views/_core/authentication/forget-password.vue (1)
5-5: Same changes as other variants.This file shows identical changes to the other forget-password.vue variants. Please refer to the review comments on the web-tdesign file regarding
markRawusage and verification of theerrorparameter.Also applies to: 23-28
🧹 Nitpick comments (2)
playground/src/views/examples/form/custom.vue (1)
70-74: Consider explicit boolean conversion for the regex validation.The
.match()method returnsRegExpMatchArray | null, which relies on truthy/falsy conversion within the refine predicate. For better clarity and type safety, explicitly convert to boolean.🔎 Proposed refactor with explicit boolean conversion
.refine( - (v) => v[1]?.match(/^1[3-9]\d{9}$/), + (v) => !!v[1]?.match(/^1[3-9]\d{9}$/), // 使用全角空格占位,将错误提示文字挤到手机号码输入框的下面 { error: ' 号码格式不正确' }, ),apps/web-naive/src/views/_core/authentication/register.vue (1)
83-87: Optional refactor: Simplify boolean refinement.The
!!valuedouble negation is redundant sincevalueis already a boolean. Consider simplifying:🔎 Proposed simplification
rules: markRaw( z .boolean() - .refine((value) => !!value, { error: $t('authentication.agreeTip') }), + .refine((value) => value === true, { error: $t('authentication.agreeTip') }), ),
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (41)
apps/web-antd/src/views/_core/authentication/code-login.vueapps/web-antd/src/views/_core/authentication/forget-password.vueapps/web-antd/src/views/_core/authentication/login.vueapps/web-antd/src/views/_core/authentication/register.vueapps/web-antd/src/views/_core/profile/password-setting.vueapps/web-ele/src/views/_core/authentication/code-login.vueapps/web-ele/src/views/_core/authentication/forget-password.vueapps/web-ele/src/views/_core/authentication/login.vueapps/web-ele/src/views/_core/authentication/register.vueapps/web-ele/src/views/_core/profile/password-setting.vueapps/web-naive/src/views/_core/authentication/code-login.vueapps/web-naive/src/views/_core/authentication/forget-password.vueapps/web-naive/src/views/_core/authentication/login.vueapps/web-naive/src/views/_core/authentication/register.vueapps/web-naive/src/views/_core/profile/password-setting.vueapps/web-tdesign/src/views/_core/authentication/code-login.vueapps/web-tdesign/src/views/_core/authentication/forget-password.vueapps/web-tdesign/src/views/_core/authentication/login.vueapps/web-tdesign/src/views/_core/authentication/register.vueapps/web-tdesign/src/views/_core/profile/password-setting.vuedocs/src/components/common-ui/vben-form.mddocs/src/demos/vben-form/rules/index.vuepackages/@core/ui-kit/form-ui/package.jsonpackages/@core/ui-kit/form-ui/src/form-render/form-field.vuepackages/@core/ui-kit/form-ui/src/form-render/form.vuepackages/@core/ui-kit/form-ui/src/form-render/helper.tspackages/@core/ui-kit/form-ui/src/types.tspackages/@core/ui-kit/form-ui/src/use-form-context.tspackages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vuepackages/effects/layouts/src/widgets/lock-screen/lock-screen.vueplayground/src/views/_core/authentication/code-login.vueplayground/src/views/_core/authentication/forget-password.vueplayground/src/views/_core/authentication/login.vueplayground/src/views/_core/authentication/register.vueplayground/src/views/_core/profile/password-setting.vueplayground/src/views/examples/form/basic.vueplayground/src/views/examples/form/custom.vueplayground/src/views/examples/form/rules.vueplayground/src/views/system/dept/data.tsplayground/src/views/system/menu/modules/form.vuepnpm-workspace.yaml
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-02-23T04:21:24.691Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5587
File: playground/src/views/examples/loading/index.vue:15-18
Timestamp: 2025-02-23T04:21:24.691Z
Learning: Chinese text in the description of the loading component example (`playground/src/views/examples/loading/index.vue`) is intentionally kept without i18n support.
Applied to files:
packages/effects/layouts/src/widgets/lock-screen/lock-screen.vue
📚 Learning: 2024-11-05T10:34:13.846Z
Learnt from: ArthurDarkstone
Repo: vbenjs/vue-vben-admin PR: 4807
File: docs/src/components/common-ui/vben-vxe-table.md:65-84
Timestamp: 2024-11-05T10:34:13.846Z
Learning: In `docs/src/components/common-ui/vben-vxe-table.md`, the code examples are provided within markdown scripts for documentation and do not require import statements or explicit type annotations.
Applied to files:
playground/src/views/_core/authentication/code-login.vueplayground/src/views/examples/form/rules.vueplayground/src/views/system/dept/data.tsdocs/src/demos/vben-form/rules/index.vueplayground/src/views/system/menu/modules/form.vue
📚 Learning: 2024-12-04T04:41:30.161Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:31-31
Timestamp: 2024-12-04T04:41:30.161Z
Learning: 在 Vben Admin 项目的 `Page` 组件中,`extra` 内容仅通过 slots 提供,没有对应的 prop 属性。
Applied to files:
playground/src/views/examples/form/rules.vue
📚 Learning: 2024-12-09T04:41:58.914Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5075
File: packages/effects/common-ui/src/components/api-select/api-select.vue:61-62
Timestamp: 2024-12-09T04:41:58.914Z
Learning: 在文件 `packages/effects/common-ui/src/components/api-select/api-select.vue` 的组件 `ApiSelect` 中,`childrenField` 的默认值设置为空字符串是有意的,因为并非所有组件都使用树形数据。
Applied to files:
playground/src/views/examples/form/rules.vuedocs/src/demos/vben-form/rules/index.vueplayground/src/views/system/menu/modules/form.vue
📚 Learning: 2025-01-15T04:29:13.944Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5397
File: playground/src/bootstrap.ts:23-30
Timestamp: 2025-01-15T04:29:13.944Z
Learning: In the Vue-Vben-Admin project, commented code in bootstrap.ts showing modal and drawer configuration examples should be preserved as reference documentation, even after moving to CSS variables for z-index management.
Applied to files:
apps/web-tdesign/src/views/_core/authentication/code-login.vue
🧬 Code graph analysis (3)
playground/src/views/system/dept/data.ts (1)
packages/locales/src/index.ts (1)
$t(13-13)
packages/@core/ui-kit/form-ui/src/form-render/helper.ts (1)
packages/@core/base/shared/src/utils/inference.ts (2)
isString(161-161)isObject(160-160)
packages/@core/ui-kit/form-ui/src/use-form-context.ts (1)
packages/@core/ui-kit/form-ui/src/form-render/helper.ts (1)
getCustomDefaultValue_byZodSchema(57-106)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Test (windows-latest)
- GitHub Check: Check (windows-latest)
- GitHub Check: post-update (windows-latest)
- GitHub Check: post-update (ubuntu-latest)
- GitHub Check: Check (windows-latest)
- GitHub Check: Test (windows-latest)
- GitHub Check: post-update (windows-latest)
🔇 Additional comments (67)
apps/web-antd/src/views/_core/profile/password-setting.vue (1)
4-4: LGTM! Zod 4 migration applied correctly.The changes correctly implement the Zod 4 upgrade:
markRaw wrapper (lines 42-49): Prevents Vue's reactivity system from tracking the Zod schema, which improves performance by avoiding unnecessary deep reactive conversions on complex Zod internal structures.
Error key migration (lines 45, 47): The switch from
messagetoerroraligns with Zod 4's unified error customization API, replacing the fragmentedmessage/required_errorpattern from Zod 3.Both changes follow the documented Zod 4 patterns and the PR's stated objectives for performance optimization and API modernization.
Also applies to: 42-49
apps/web-ele/src/views/_core/profile/password-setting.vue (1)
4-4: LGTM! Consistent with the Antd variant.The changes are identical to the
web-antdvariant and correctly implement the Zod 4 migration withmarkRawwrapper and unifiederrorparameter.Also applies to: 42-49
apps/web-naive/src/views/_core/profile/password-setting.vue (1)
4-4: LGTM! Consistent with other UI variants.The changes correctly implement the Zod 4 migration pattern with
markRawwrapper and unifiederrorparameter, consistent with the Antd and Element variants.Also applies to: 42-49
apps/web-tdesign/src/views/_core/profile/password-setting.vue (1)
4-4: LGTM! Consistent with other UI variants.The changes correctly implement the Zod 4 migration pattern with
markRawwrapper and unifiederrorparameter, maintaining consistency across all four UI framework adapters.Also applies to: 42-49
apps/web-antd/src/views/_core/authentication/code-login.vue (2)
5-5: LGTM! Correct import for performance optimization.Adding
markRawis the right approach for preventing Vue's reactivity system from wrapping Zod schemas, which improves performance.
24-31: No issue found. Zod 4's error parameter accepts string values directly, as demonstrated throughout the official documentation. The code correctly uses{ error: $t('authentication.mobileTip') }and{ error: $t('authentication.mobileErrortip') }, which aligns with Zod 4's unified error API.apps/web-tdesign/src/views/_core/authentication/forget-password.vue (2)
5-5: Good addition of markRaw import.The import aligns with the PR's performance optimization goal to prevent Vue's reactivity system from tracking Zod schema objects.
23-28: No changes needed. Zod 4 accepts plain strings for the error parameter in validation methods, as shown in the official documentation examples. In Zod 4, the error parameter unifies what were previously separate message and errorMap parameters, allowing both string and function approaches interchangeably. The code correctly uses direct strings like{ error: $t('authentication.emailTip') }for localized error messages.packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue (2)
4-4: LGTM: Import addition for performance optimization.The addition of
markRawto the Vue imports is correct and necessary for wrapping Zod schemas to prevent unnecessary reactivity tracking.
46-50: Code pattern is correct for Zod 4.The
markRawwrapping prevents Vue reactivity overhead on Zod schemas. The error parameter correctly uses direct string assignment ({ error: $t(...) }), which is the standard Zod 4 syntax for simple error messages. Function syntax is only needed when accessing validation issue details.playground/src/views/examples/form/basic.vue (2)
4-4: LGTM! Appropriate import for performance optimization.Adding
markRawto prevent Vue's reactivity system from tracking Zod schemas is a good performance optimization, as validation schemas don't need reactivity.
237-239: No issues found. Zod 4's.refine()method correctly accepts theerrorparameter with a direct string value, as shown in the official documentation with examples like.refine((val) => val.length > 8, { error: "Too short!" }). In Zod 4, the parameter was renamed frommessagetoerror, and while the message parameter is still supported, it is deprecated. The code in the file uses the correct modern Zod 4 syntax.playground/src/views/_core/profile/password-setting.vue (1)
42-49: Excellent use ofmarkRawfor performance optimization.The
markRawwrapper prevents Vue's reactivity system from tracking Zod schema objects, which aligns perfectly with the PR objectives. The error parameter syntax is also correct; Zod 4 accepts string values directly in the error parameter.apps/web-tdesign/src/views/_core/authentication/code-login.vue (2)
5-5: Good addition ofmarkRawimport for performance optimization.The
markRawimport is correctly used to wrap Zod schemas (lines 24 and 48), preventing Vue's reactivity system from tracking these validation objects unnecessarily, which improves performance.
24-31: No changes needed. Zod 4 supports plain strings for the error parameter, as shown in official documentation examples likez.string().min(5, { error: "Too short!" }). The error param optionally accepts a function, but string values are also valid. The code's use of{ error: $t('authentication.mobileTip') }follows the correct and documented pattern.playground/src/views/system/menu/modules/form.vue (4)
8-8: LGTM!Good addition of
markRawimport. Wrapping Zod schemas withmarkRawis the correct approach to prevent Vue's reactivity system from tracking these objects, improving performance.
53-75: LGTM!Proper use of
markRawwrapping and Zod 4's unifiederrorparameter. The async refinement correctly validates uniqueness by returningfalsewhen the name already exists.
138-168: LGTM!Well-structured validation chain with proper Zod 4 syntax. The path validation correctly enforces format constraints and uniqueness.
268-268: LGTM!Good use of Zod 4's standalone
z.url()schema with unified error customization.playground/src/views/_core/authentication/forget-password.vue (2)
4-4: Good performance optimization with markRaw.Wrapping the Zod schema with
markRaw()is the correct approach to prevent Vue's reactivity system from tracking the immutable Zod object, which improves performance.Also applies to: 22-27
25-26: No action required—validation syntax is correct for Zod 4.In Zod 4, the
errorparameter unified what were separatemessage(string) anderrorMap(function) parameters in v3. Themessageparameter is still supported but deprecated. Both.min()and.email()methods support the{ error: string }syntax, making the current implementation correct.apps/web-antd/src/views/_core/authentication/register.vue (4)
5-5: Good addition of markRaw import.Importing
markRawis appropriate for wrapping Zod schemas to prevent Vue's reactivity system from unnecessarily tracking these objects, which improves performance.
23-25: Excellent use of markRaw for performance optimization.The consistent wrapping of Zod schemas with
markRaw()correctly prevents Vue's reactivity system from tracking the internal structure of Zod validation objects. This is a proper implementation of the performance optimization mentioned in the PR objectives.Also applies to: 40-42, 52-59, 83-87
49-61: Dynamic password confirmation validation looks correct.The implementation correctly uses the
dependenciespattern to dynamically validate that the confirmation password matches the main password field. ThetriggerFieldsconfiguration ensures re-validation when the password changes, which provides proper user feedback.
23-25: No issues found. The validation rules correctly use{ error: string }format, which is supported in Zod 4.1.13 alongside the function format.playground/src/views/examples/form/rules.vue (5)
2-2: LGTM! Good performance optimization.Importing
markRawfrom Vue to wrap Zod schemas is the correct approach to prevent Vue's reactivity system from deeply tracking validation schemas, which improves performance.
54-54: LGTM! Correct Zod 4 default value handling.The combination of
.default()and.optional()is valid in Zod 4, where defaults are now applied even inside optional fields, as documented in the library specifications.
155-155: LGTM! Correct checkbox validation logic.The
.refine((value) => value)correctly validates that the checkbox must be checked (true) before the form can be submitted. The markRaw wrapping is appropriate.
201-219: LGTM! Correct async validation implementation.The async validation logic is correctly implemented:
- Checks minimum length first (
.min(3))- Then performs async username existence check via
.refine()- Correctly returns
!existsto validate that the username is available- The 1-second delay properly simulates an API call
The markRaw wrapping is appropriate for the entire schema.
63-63: > Likely an incorrect or invalid review comment.apps/web-ele/src/views/_core/authentication/register.vue (5)
5-5: LGTM! Appropriate import for performance optimization.Adding
markRawto the imports is correct. This enables wrapping Zod schemas to prevent Vue's reactivity system from tracking them, which improves performance as validation schemas don't need reactivity.
23-25: LGTM! Correct migration to Zod 4 API.The migration from
message:toerror:aligns with Zod 4's unified error customization API, and wrapping withmarkRawprevents unnecessary reactivity tracking.
40-42: LGTM! Consistent with Zod 4 migration.The password field validation follows the same correct pattern as the username field, using the unified
errorparameter andmarkRawwrapper.
83-87: LGTM! Correct boolean validation with Zod 4.The checkbox validation properly uses Zod 4's unified
errorparameter with.refine()and is appropriately wrapped withmarkRawfor performance optimization.
52-59: The Zod 4 API migration is correct and the dynamic markRaw pattern is appropriate.The code correctly uses Zod 4's unified
errorparameter in both.min()and.refine(). The dynamic schema creation withindependencies.rules()is necessary because the validation logic closes over the currentpasswordvalue. UsingmarkRaw()here is the correct optimization, as it prevents Vue from tracking Zod schemas, which are immutable objects that don't need reactivity. This pattern aligns with the rest of the codebase (lines 23, 40, 83).apps/web-ele/src/views/_core/authentication/code-login.vue (3)
5-5: LGTM! Correct import for performance optimization.Adding
markRawto the imports is necessary for wrapping Zod schemas to prevent Vue's reactivity system from tracking their internal properties, which improves performance.
48-52: LGTM! Same pattern as phoneNumber validation.The code validation follows the same pattern as the phoneNumber field with
markRawwrapper anderrorparameter. The same verification request from the previous comment applies here.
24-31: Implementation correctly uses Zod 4 error parameter syntax.In Zod 4, the separate
message(string) anderrorMap(function) parameters from v3 have been unified as theerrorparameter, which optionally accepts a function but also accepts string values directly. The pattern{ error: "string value" }is standard usage for both.min()and other validators. The code correctly uses{ error: $t('...') }where the translation function returns a string, following the documented Zod 4 pattern. No changes needed.playground/src/views/_core/authentication/code-login.vue (2)
5-5: Good addition ofmarkRawimport.Adding
markRawto the imports is appropriate for wrapping Zod schemas to prevent Vue's reactivity system from tracking them, which improves performance.
44-51: Error parameter syntax in Zod 4 is correct and requires no changes.Zod 4 explicitly supports passing a string directly to the error parameter:
z.string().min(5, { error: "Too short!" }). The error param optionally accepts a function, meaning both syntaxes are valid. In Zod v3, there were separate params for message (a string) and errorMap (a function). These have been unified in Zod 4 as error.The code pattern
{ error: $t('...') }used in the validation schemas at lines 44-51 and 87-91 is correct and fully supported by Zod 4.1.13. ThemarkRaw()wrapper is also appropriate for preventing Vue reactivity tracking on the validation schema.Likely an incorrect or invalid review comment.
playground/src/views/examples/form/custom.vue (2)
64-75: LGTM! Successful migration to Zod 4 with markRaw optimization.The migration correctly wraps the Zod schema with
markRaw()to prevent Vue reactivity tracking, which improves performance as noted in the PR objectives. The use of the unified{ error: '...' }parameter in refinements aligns with Zod 4's new error customization API.
67-67: No action needed. The.length(2, 'message')syntax is valid in Zod 4. Zod functions and schema methods accept custom errors both as bare strings and within error objects, with both.length(7, 'String must be exactly 7 characters')and the object format being supported. The message parameter is still supported but deprecated, meaning bare strings remain a valid option for constraint methods.apps/web-tdesign/src/views/_core/authentication/register.vue (2)
5-5: LGTM: Import addition for performance optimization.The
markRawimport is correctly added to support wrapping Zod schemas, preventing Vue's reactivity system from unnecessarily tracking schema objects.
23-25: Zod 4 migration correctly implemented with proper error API usage and Vue optimization.All validation schemas have been properly updated to Zod 4's unified error parameter:
- Migrated from separate message/errorMap parameters to the unified error parameter, as specified in Zod 4
- Wrapped with markRaw() to prevent Vue's reactive conversion overhead on schema objects
- Dynamic validation for confirm password correctly returns a new wrapped schema based on runtime values
- Boolean refinement for policy agreement properly enforces required checkbox validation
vee-validate v5 beta provides first-class Zod support without requiring the @vee-validate/zod companion package, aligning with the dependency removal.
Runtime verification is recommended given the major version upgrades (Zod to 4.1.13, vee-validate to 5.0.0-beta.0).
apps/web-naive/src/views/_core/authentication/code-login.vue (3)
5-5: LGTM: markRaw import added for schema optimization.The addition of
markRawaligns with the performance optimization strategy to prevent Vue's reactivity system from tracking static Zod schemas.
48-52: LGTM: Code field validation correctly updated for Zod v4.The validation rule follows the same correct pattern as the phoneNumber field, using the unified
errorparameter andmarkRawwrapping.
24-31: Correctly migrated to Zod v4 with proper error handling and performance optimization.The
errorparameter replaces the deprecatedmessageparameter in Zod v4, which is correctly implemented across all validation rules. UsingmarkRaw()prevents Vue's reactivity system from tracking the schema, avoiding performance overhead when dealing with static validation objects. The phone number validation logic (minimum 1 character + 11-digit regex) is correctly structured, and this pattern is consistently applied throughout the authentication views.apps/web-naive/src/views/_core/authentication/register.vue (3)
5-5: LGTM: Performance optimization import.Adding
markRawimport is correct and necessary to prevent Vue from tracking Zod schema objects, which improves performance as intended by this PR.
52-60: LGTM: Confirm password validation logic is correct.The dynamic validation using
dependencies.rulescorrectly implements password confirmation logic. ThemarkRawwrapper is properly placed around the returned schema, andtriggerFields: ['password']ensures re-validation when the password field changes.
23-25: No changes needed. Zod 4 accepts both string values and functions for theerrorparameter—the code at lines 23-25 and others (40-42, 52-59, 83-87) is correct as written.Likely an incorrect or invalid review comment.
packages/effects/layouts/src/widgets/lock-screen/lock-screen.vue (1)
2-2: LGTM! Zod v4 migration correctly applied.The changes correctly implement Zod v4's unified error parameter and use
markRawto prevent Vue from making the schema reactive, which improves performance.Also applies to: 54-56
docs/src/components/common-ui/vben-form.md (1)
546-570: LGTM! Documentation correctly demonstrates Zod v4 usage patterns.The documentation examples are updated consistently with:
markRawwrapping to prevent Vue reactivityerrorparameter instead ofmessage(Zod v4 unified error customization)- Various validation patterns (basic, optional, union, refine)
This provides clear guidance for developers migrating to Zod v4.
playground/src/views/system/dept/data.ts (1)
7-7: LGTM! Zod v4 validation rules correctly implemented.The form validation rules are properly migrated:
markRawwrapping prevents unnecessary Vue reactivity overheaderrorkey replacesmessageper Zod v4 API- Internationalized error messages preserved
- Validation logic (min/max length) remains unchanged
Also applies to: 22-37, 75-82
packages/@core/ui-kit/form-ui/package.json (1)
48-48: LGTM! Dependency cleanup aligns with Zod v4 and vee-validate v5.The removal of
@vee-validate/zodandzod-defaultsis correct:
- vee-validate v5 provides direct Zod integration
- Zod v4 has improved default value handling (
.default()and.prefault()methods)- Simpler dependency tree reduces maintenance burden
docs/src/demos/vben-form/rules/index.vue (1)
2-2: LGTM! Demo correctly illustrates Zod v4 validation patterns.The form validation demo is properly updated:
markRawwrapping applied consistentlyerrorparameter used instead ofmessage(Zod v4 API)- Email validation uses object syntax:
.email({ error: '...' })- Default values with optional chaining preserved
Also applies to: 53-53, 62-62, 74-74
playground/src/views/_core/authentication/register.vue (1)
5-5: LGTM! Authentication form validation correctly migrated to Zod v4.All validation rules are properly updated:
- Static rules wrapped with
markRawand useerrorkey- Dynamic rules (in
dependencies.rules) also returnmarkRaw-wrapped schemas- Custom validation with
.refine()useserrorparameter correctly- Validation logic and control flow preserved
Also applies to: 23-25, 40-42, 52-59, 83-87
packages/@core/ui-kit/form-ui/src/types.ts (1)
2-2: LGTM! Type refinement from ZodTypeAny to ZodType improves type safety.The change from
ZodTypeAnytoZodTypeprovides:
- More specific type constraints for form validation rules
- Better type inference in TypeScript
- Alignment with Zod v4's improved type system
This is a beneficial refinement that enhances type safety across the form infrastructure.
Also applies to: 54-54, 75-75
pnpm-workspace.yaml (2)
173-173: Test vee-validate 5.0.0-beta.0 thoroughly before production use.While vee-validate v5 brings built-in support for Zod and other Standard Schema libraries, verify that:
- Critical form validation flows work correctly with your Zod schemas
- You're prepared for potential breaking changes in future beta releases, as this is pre-release software
194-194: Zod v4.1.13 migration is complete across the codebase. All schema definitions consistently use the v4error:syntax instead of v3'smessage:, with no deprecated patterns remaining.apps/web-naive/src/views/_core/authentication/login.vue (1)
41-94: LGTM! Zod v4 migration correctly applied.The changes correctly implement Zod v4's unified error customization using the
errorparameter, replacing the deprecatedmessagekey. Wrapping schemas withmarkRawprevents Vue's reactivity system from deeply tracking Zod objects, which is a good performance optimization for validation rules.The pattern is consistently applied across all fields:
selectAccount: String validation with default and optional chainingusernameandpassword: Required string validationscaptcha: Boolean refinement with custom error messageNote: This same pattern is correctly applied across all login views (web-naive, web-ele, web-antd, web-tdesign, playground).
packages/@core/ui-kit/form-ui/src/form-render/form-field.vue (2)
135-157: Simplified fieldRules logic looks good.The removal of
toTypedSchemaand the simplified rules handling aligns with the migration away from@vee-validate/zod. The logic correctly:
- Returns
nullwhen the field is not visible- Handles string-based rules
- Unwraps optional schemas when required
- Preserves the original schema when optional
108-133: Clarify whether internal Zod API access is acceptable for this use case.In Zod v4, the ._def property moved to ._zod.def, so the code's use of
zodSchema._zod.def.innerTypefollows the correct v4 pattern. However, this internal structure is subject to change and not comprehensively documented—it's considered relevant to library authors but not part of the stable public API. Unlike ZodOptional which has a public.unwrap()method, ZodDefault has no documented public method for accessing its inner type, making this implementation fragile to future Zod updates.packages/@core/ui-kit/form-ui/src/form-render/form.vue (1)
62-91: LGTM! Clean refactor with improved type safety.The refactored
shapescomputation is much clearer and properly leverages the new Zod helper functions:
getDefaultValue_byZodSchemafor extracting defaults from schemasgetBaseRules_byZodSchemafor unwrapping schema layerssafeParse(undefined).successfor determining optionalityThe explicit handling of string vs. ZodType rules improves type safety and makes the code more maintainable. The logic correctly:
- Preserves explicit
defaultValuefrom schema- Extracts defaults from Zod schemas when available
- Determines required state based on schema validation
- Stores base rules for validation
packages/@core/ui-kit/form-ui/src/use-form-context.ts (1)
45-63: LGTM! Simplified default value generation.The refactored
generateInitialValuesfunction is much cleaner and properly delegates to thegetCustomDefaultValue_byZodSchemahelper. The logic correctly:
- Prioritizes explicit
defaultValuefrom schema definitions- Falls back to Zod schema-based defaults for non-string rules
- Only sets values when defaults are defined (undefined check)
The change from
Reflect.has(item, 'defaultValue')to'defaultValue' in itemis acceptable for this use case, though note that theinoperator checks the prototype chain whileReflect.hasdoes not. Since these are plain schema objects, this difference should not cause issues.The removal of complex Zod object merging logic in favor of the dedicated helper function significantly improves maintainability.
packages/@core/ui-kit/form-ui/src/form-render/helper.ts (3)
1-11: Imports look good.The updated imports properly reflect the Zod 4 types needed for the refactored helper functions.
89-98: The.shapeproperty is a documented public API in Zod 4 and is the correct way to access object properties. The official Zod migration guide explicitly shows accessing.shapedirectly: "use z.object(A.shape)". While Zod 4 moved the internal._defproperty to._zod.def, this is an internal change and doesn't affect user-facing APIs. The code correctly accesses the shape property and requires no changes.Likely an incorrect or invalid review comment.
64-101: String format detection incomplete for Zod 4 standalone schemasIn Zod 4, standalone schema methods like z.uuid() are now separate top-level schemas rather than string refinements. The code's comment on line 64 claims it covers
z.email()via atype === 'string'check, but Zod 4 implements these as separate schema classes ($ZodEmail, $ZodUUID, etc.) with their own type discriminators. This means the switch statement will not catch these standalone formats.Additionally, the
._defproperty is now moved to._zod.def, and while lines 72, 75, 93 correctly use this pattern, the type checking logic needs enhancement to detect all string-based schemas (both z.string() and standalone formats like z.email(), z.uuid(), z.ipv4()).
| rules: markRaw( | ||
| z.string().min(1, { error: $t('authentication.passwordTip') }), | ||
| ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enforce minimum password length of at least 8 characters.
The password validation currently accepts passwords as short as 1 character (z.string().min(1, ...)), which is insufficient for security. NIST SP 800-63-3 guidelines require a minimum of 8 characters for standard passwords. While the component includes a password strength indicator, this provides UI feedback only and cannot substitute for proper validation. Ensure server-side validation enforces at least 8 characters minimum (preferably 12+ per OWASP standards).
🤖 Prompt for AI Agents
In apps/web-naive/src/views/_core/authentication/register.vue around lines 40 to
42, the password schema currently uses z.string().min(1, ...) which allows
1-character passwords; update the validation to require a minimum of 8
characters by changing the schema minimum to 8 (or higher if desired) and adjust
the translated error key/message accordingly; also ensure the same minimum
requirement is enforced server-side to match client validation.
| // For ZodDefault, there's no public unwrap method. | ||
| // Accessing _def.innerType is necessary but relies on Zod 4 internals. | ||
| // ⚠️ This assumes Zod v4.x. Update if migrating to a future major version. | ||
| if (schema instanceof ZodDefault) { | ||
| return getBaseRules_byZodSchema(schema._zod.def.innerType as ZodType); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n packages/@core/ui-kit/form-ui/src/form-render/helper.ts | head -40Repository: vbenjs/vue-vben-admin
Length of output: 1473
🏁 Script executed:
# Check for Zod version in package.json
rg '"zod"' package.json -A2 -B2Repository: vbenjs/vue-vben-admin
Length of output: 47
🏁 Script executed:
# Look for other usages of ZodDefault and _def or _zod patterns
rg -n 'schema\._(?:zod\.def|def)' --type=tsRepository: vbenjs/vue-vben-admin
Length of output: 401
🌐 Web query:
Zod 4.1.13 ZodDefault schema inner type property access
💡 Result:
Short answer: use the ZodDefault unwrap() helper (or its internals) to get the inner schema.
Examples (Zod v4.1.x):
-
Preferred: call .unwrap()
const s = z.string().default("x");
const inner = s.unwrap(); // ZodString
console.log(inner.parse("y")); -
Internals (not recommended but available): s._zod.def.innerType or s._def.innerType (works in 4.1.x builds).
const innerViaDef = (s as any)._zod.def.innerType;
console.log(innerViaDef._def.type);
References: Zod internals and ZodDefault implementation showing .unwrap() and ._zod.def.innerType. [1][2]
Sources
[1] Zod core internals docs.
[2] Zod v4 classic schemas implementation (ZodDefault).
Use public .unwrap() API instead of relying on internal properties.
The comment states ZodDefault has "no public unwrap method," but ZodDefault does provide a .unwrap() method. While schema._zod.def.innerType works in Zod 4.1.13, the code should use the public API:
if (schema instanceof ZodDefault) {
return getBaseRules_byZodSchema(schema.unwrap() as ZodType);
}This eliminates reliance on internal properties and removes the version-specific dependency comment. Apply the same fix to lines 46 and 60.
🤖 Prompt for AI Agents
In packages/@core/ui-kit/form-ui/src/form-render/helper.ts around lines 22-27
(and also apply the same change at lines ~46 and ~60), replace usages of the
internal _zod.def.innerType access with the public unwrap() API: call
schema.unwrap() and pass that (cast to ZodType if needed) into
getBaseRules_byZodSchema, and remove the comment about assuming Zod v4 internals
since relying on the public .unwrap() eliminates that dependency.
| if (schema instanceof ZodDefault) { | ||
| return schema._zod.def.defaultValue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Same _zod.def access issue.
Line 46 has the same problematic pattern: schema._zod.def.defaultValue. This should likely be schema._def.defaultValue() or similar, depending on the actual Zod 4 API.
🤖 Prompt for AI Agents
In packages/@core/ui-kit/form-ui/src/form-render/helper.ts around lines 45 to
47, replace the unsafe access to the internal _zod.def.defaultValue with the
correct Zod v4 internal shape by using schema._def.defaultValue and invoking it
if it's a function; specifically, read schema._def.defaultValue, if typeof that
is 'function' call it to get the default, otherwise return it directly, avoiding
use of schema._zod.def.
| if (schema instanceof ZodDefault || schema instanceof ZodOptional) { | ||
| return getCustomDefaultValue_byZodSchema( | ||
| schema._zod.def.innerType as ZodType, | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: _zod.def access pattern repeated.
Line 60 continues the same problematic _zod.def.innerType pattern identified earlier. This will cause the same runtime failures.
🤖 Prompt for AI Agents
In packages/@core/ui-kit/form-ui/src/form-render/helper.ts around lines 58 to
62, the code is again accessing the private _zod.def.innerType which causes
runtime failures; replace that access with the correct public/internal Zod def
property (use schema._def.innerType) and cast to ZodType as needed, i.e., obtain
the inner type from schema._def.innerType for both ZodDefault and ZodOptional
before passing it to getCustomDefaultValue_byZodSchema.
| case 'intersection': { | ||
| // 对于交集类型,从schema 提取默认值 | ||
| const leftDefaultValue = getCustomDefaultValue_byZodSchema( | ||
| (schema as ZodIntersection)._zod.def.left as ZodType, | ||
| ); | ||
| const rightDefaultValue = getCustomDefaultValue_byZodSchema( | ||
| (schema as ZodIntersection)._zod.def.right as ZodType, | ||
| ); | ||
|
|
||
| // 如果左右两边都能提取默认值,合并它们 | ||
| if (isObject(leftDefaultValue) && isObject(rightDefaultValue)) { | ||
| return { ...leftDefaultValue, ...rightDefaultValue }; | ||
| } | ||
|
|
||
| // 否则优先使用左边的默认值 | ||
| return leftDefaultValue ?? rightDefaultValue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: _zod.def pattern in intersection handling.
Lines 72 and 75 access _zod.def.left and _zod.def.right for intersection types. This continues the same incorrect property access pattern that will cause runtime failures.
🤖 Prompt for AI Agents
packages/@core/ui-kit/form-ui/src/form-render/helper.ts lines 69-85: the code
incorrectly accesses internal intersection schema fields via (schema as
ZodIntersection)._zod.def.left/right which will crash at runtime; change the
access to the correct Zod internals (use (schema as ZodIntersection)._def.left
and (schema as ZodIntersection)._def.right) and cast those to ZodType before
passing to getCustomDefaultValue_byZodSchema, keeping the existing merge logic
unchanged.
| rules: markRaw( | ||
| z | ||
| .string() | ||
| .min(2, { | ||
| error: $t('ui.formRules.minLength', [$t('system.menu.path'), 2]), | ||
| }) | ||
| .max(100, { | ||
| error: $t('ui.formRules.maxLength', [$t('system.menu.path'), 100]), | ||
| }) | ||
| .refine( | ||
| (value: string) => { | ||
| return value.startsWith('/'); | ||
| }, | ||
| { | ||
| error: $t('ui.formRules.startWith', [$t('system.menu.path'), '/']), | ||
| }, | ||
| ) | ||
| .refine( | ||
| async (value: string) => { | ||
| return await isMenuPathExists(value, formData.value?.id); | ||
| }, | ||
| { error: $t('system.menu.activePathMustExist') }, | ||
| ) | ||
| .optional(), | ||
| ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error messages reference wrong field label.
The error messages on lines 186, 189, and 196 use $t('system.menu.path'), but this field is activePath with label $t('system.menu.activePath'). This appears to be a copy-paste oversight that could confuse users when validation fails.
🔎 Proposed fix
rules: markRaw(
z
.string()
.min(2, {
- error: $t('ui.formRules.minLength', [$t('system.menu.path'), 2]),
+ error: $t('ui.formRules.minLength', [$t('system.menu.activePath'), 2]),
})
.max(100, {
- error: $t('ui.formRules.maxLength', [$t('system.menu.path'), 100]),
+ error: $t('ui.formRules.maxLength', [$t('system.menu.activePath'), 100]),
})
.refine(
(value: string) => {
return value.startsWith('/');
},
{
- error: $t('ui.formRules.startWith', [$t('system.menu.path'), '/']),
+ error: $t('ui.formRules.startWith', [$t('system.menu.activePath'), '/']),
},
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| rules: markRaw( | |
| z | |
| .string() | |
| .min(2, { | |
| error: $t('ui.formRules.minLength', [$t('system.menu.path'), 2]), | |
| }) | |
| .max(100, { | |
| error: $t('ui.formRules.maxLength', [$t('system.menu.path'), 100]), | |
| }) | |
| .refine( | |
| (value: string) => { | |
| return value.startsWith('/'); | |
| }, | |
| { | |
| error: $t('ui.formRules.startWith', [$t('system.menu.path'), '/']), | |
| }, | |
| ) | |
| .refine( | |
| async (value: string) => { | |
| return await isMenuPathExists(value, formData.value?.id); | |
| }, | |
| { error: $t('system.menu.activePathMustExist') }, | |
| ) | |
| .optional(), | |
| ), | |
| rules: markRaw( | |
| z | |
| .string() | |
| .min(2, { | |
| error: $t('ui.formRules.minLength', [$t('system.menu.activePath'), 2]), | |
| }) | |
| .max(100, { | |
| error: $t('ui.formRules.maxLength', [$t('system.menu.activePath'), 100]), | |
| }) | |
| .refine( | |
| (value: string) => { | |
| return value.startsWith('/'); | |
| }, | |
| { | |
| error: $t('ui.formRules.startWith', [$t('system.menu.activePath'), '/']), | |
| }, | |
| ) | |
| .refine( | |
| async (value: string) => { | |
| return await isMenuPathExists(value, formData.value?.id); | |
| }, | |
| { error: $t('system.menu.activePathMustExist') }, | |
| ) | |
| .optional(), | |
| ), |
🤖 Prompt for AI Agents
In playground/src/views/system/menu/modules/form.vue around lines 182 to 206,
the validation error messages reference the wrong label key
($t('system.menu.path')) for the activePath field; replace those occurrences
(lines ~186, ~189, ~196) with $t('system.menu.activePath') so the
min/max/startWith messages use the correct field label while leaving the
isMenuPathExists error key unchanged.
|
这个有点破坏性更新,有兼容的方法么 |
|
主要是zod的v4版本升级改动极大,并且4.0 和之后的小版本间也有些版本兼容。之所以做这次zod相关的升级是因为现在前后端都用TS了,后端bun用到的hono,drizzle等都和zod v4绑定了。为了保持前后端引用包的一致性,建议还是对vben做zod v4的升级。顺便提一句,AI提出的这些issue,基本都是它自己在v4和v4小版本间混乱了的原因造成的。 |
|
我的意思是 如果原项目用V3的zod 升级V4需要改动很多 |
Description
Type of change
Please delete options that are not relevant.
Checklist
pnpm run docs:devcommand.pnpm test.feat:,fix:,perf:,docs:, orchore:.Summary by CodeRabbit
Refactor
Chores
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.