Skip to content
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

feat: x-validator支持传入函数 && 解决x-validator 并不能按照预期禁用的问题 #4216

Open
wants to merge 3 commits into
base: formily_next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/json-schema/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './schema'
export * from './types'
export * from './compiler'
16 changes: 15 additions & 1 deletion packages/json-schema/src/shared.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { isFn, each, isPlainObj, isArr, toArr, FormPath } from '@formily/shared'
import {
isFn,
each,
isPlainObj,
isArr,
toArr,
FormPath,
isObj,
} from '@formily/shared'
import { isObservable, untracked } from '@formily/reactive'
import { Schema } from './schema'
import { ISchema } from './types'
import { registerMergeRules } from '@formily/validator'

const REVA_ACTIONS_KEY = Symbol.for('__REVA_ACTIONS')

Expand Down Expand Up @@ -106,6 +115,11 @@ export const traverseSchema = (
['x-validator'],
schema['x-compile-omitted']?.includes('x-validator')
)
// 避免 Array 类型的 x-validator 被注册
// 多key校验规则才注册到rules中,否则不注册
if (isObj(schema['x-validator']) && !schema['x-validator']['message']) {
registerMergeRules(schema['x-validator'] as Record<string, any>)
}
}
const seenObjects = []
const root = schema
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export * from './compare'
export * from './checkers'
export * from './clone'
export * from './isEmpty'
export * from './isFalse'
export * from './case'
export * from './string'
export * from './global'
Expand Down
6 changes: 6 additions & 0 deletions packages/shared/src/isFalse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @description 判断 value 是否为 false
*/
export const isFalse = (value: any) => {
return value === false
}
22 changes: 18 additions & 4 deletions packages/validator/src/parser.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isArr, isBool, isFn, isStr } from '@formily/shared'
import { isArr, isBool, isFn, isStr, isFalse } from '@formily/shared'
import { shallowCompile } from '@formily/json-schema'
import {
ValidatorDescription,
ValidatorFunction,
Expand All @@ -12,6 +13,14 @@ import { getValidateRules, getValidateLocale } from './registry'
import { render } from './template'

const getRuleMessage = (rule: IValidatorRules, type: string) => {
if (isFn(rule.message)) {
return rule.message
}
// message 支持字符串形式的函数
if (isStr(rule.message)) {
let message = rule.message ? shallowCompile(rule.message) : rule.message
return message
}
if (rule.format) {
return rule.message || getValidateLocale(rule.format)
}
Expand Down Expand Up @@ -48,12 +57,14 @@ export const parseValidatorRules = (
): ValidatorParsedFunction[] => {
const getRulesKeys = (): string[] => {
const keys = []
if ('required' in rules) {
if ('required' in rules && !isFalse(rules.required)) {
keys.push('required')
}
for (let key in rules) {
if (key === 'required' || key === 'validator') continue
keys.push(key)
if (!isFalse(rules[key])) {
keys.push(key)
}
}
if ('validator' in rules) {
keys.push('validator')
Expand All @@ -68,8 +79,11 @@ export const parseValidatorRules = (
}
}
const createValidate =
(callback: ValidatorFunction, message: string) =>
(callback: ValidatorFunction, message: string | Function) =>
async (value: any, context: any) => {
if (isFn(message)) {
message = message(value, context) as string
}
const context_ = getContext(context, value)
try {
const results = await callback(
Expand Down
27 changes: 23 additions & 4 deletions packages/validator/src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
IRegistryLocales,
IRegistryRules,
} from './types'
import { shallowCompile } from '@formily/json-schema'

const getIn = FormPath.getIn

Expand All @@ -38,7 +39,10 @@ const registry = {
language: getBrowserlanguage(),
},
formats: {},
rules: {},
rules: {
global: {},
merge: {},
},
template: null,
}

Expand Down Expand Up @@ -92,17 +96,32 @@ export const getValidateRules = <T>(
key?: T
): T extends string
? ValidatorFunction
: { [key: string]: ValidatorFunction } =>
key ? registry.rules[key as any] : registry.rules
: { [key: string]: ValidatorFunction } => {
let rules = {
...registry.rules['global'],
...registry.rules['merge'],
}
return key ? rules[key as any] : rules
}

export const registerValidateLocale = (locale: IRegistryLocales) => {
registry.locales.messages = deepmerge(registry.locales.messages, locale)
}

export const registerValidateRules = (rules: IRegistryRules) => {
each(rules, (rule, key) => {
rule = shallowCompile(rule)
if (isFn(rule)) {
registry.rules.global[key] = rule
}
})
}

export const registerMergeRules = (rules: IRegistryRules) => {
each(rules, (rule, key) => {
rule = shallowCompile(rule)
if (isFn(rule)) {
registry.rules[key] = rule
registry.rules.merge[key] = rule
}
})
}
Expand Down
Loading