Skip to content

Commit

Permalink
feat(yup): 添加 validatePlus, validatePlusSync 方法
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Aug 13, 2020
1 parent 50a1c42 commit 8dbc288
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/react/__snapshots__/useValidator.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Object {
"password2": "123456",
"phoneNumber": "13907199856",
},
"error": undefined,
"valid": true,
}
`;
Expand Down
24 changes: 6 additions & 18 deletions src/react/useValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export type UseValidatorSchema<T> = (
export interface UseValidatorResult<T> {
data: T
valid: boolean
error?: _yup.ValidationError
error?: _yup.ValidationError | undefined
}

export function useValidator<T>(
Expand Down Expand Up @@ -69,23 +69,11 @@ export function useValidator<T>(
return _yup.object(schemaOrObjectDefinitions as any)
}, _schemaDeps)
const result = useMemo((): UseValidatorResult<T> => {
try {
// yup 不能保证验证顺序,但通常顺序又是很重要的,因此对于 object 特殊处理
if (yupSchema.type === 'object') {
;(yupSchema as _yup.ObjectSchema).validateInOrderSync(data)
} else {
yupSchema.validateSync(data, validateOptions)
}
return {
data: data,
valid: true,
}
} catch (error) {
return {
data: data,
valid: false,
error: error,
}
const r = yupSchema.validatePlusSync(data, validateOptions)
return {
data: r.data,
valid: !r.error,
error: r.error,
}
}, [..._dataDeps, yupSchema])
return result
Expand Down
58 changes: 58 additions & 0 deletions src/validator/__snapshots__/yup.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,61 @@ exports[`yup validateInOrder 正常: 密码有误 1`] = `[ValidationError: 密
exports[`yup validateInOrderSync 正常: 姓名必填 1`] = `[ValidationError: 姓名必填]`;

exports[`yup validateInOrderSync 正常: 密码有误 1`] = `[ValidationError: 密码必须大于或等于100]`;

exports[`yup validatePlus 正常 1`] = `
Object {
"data": Object {
"name": "",
"pass": 99,
},
"error": [ValidationError: 姓名必填],
}
`;

exports[`yup validatePlus 正常 2`] = `
Object {
"data": Object {
"name": "",
"pass": 99,
},
"error": [ValidationError: 密码必须大于或等于100],
}
`;

exports[`yup validatePlus 正常 3`] = `
Object {
"data": Object {
"name": "8",
"pass": 101,
},
}
`;

exports[`yup validatePlusSync 正常 1`] = `
Object {
"data": Object {
"name": "",
"pass": 99,
},
"error": [ValidationError: 姓名必填],
}
`;

exports[`yup validatePlusSync 正常 2`] = `
Object {
"data": Object {
"name": "",
"pass": 99,
},
"error": [ValidationError: 密码必须大于或等于100],
}
`;

exports[`yup validatePlusSync 正常 3`] = `
Object {
"data": Object {
"name": "8",
"pass": 101,
},
}
`;
50 changes: 50 additions & 0 deletions src/validator/yup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,54 @@ describe('yup', () => {
pass: 101,
})
})

test('validatePlus 正常', async () => {
const rule = yup.object({
name: yup.string().label('姓名').required(),
pass: yup.number().label('密码').required().min(100),
})
expect(
await rule.validatePlus({
name: '',
pass: 99,
}),
).toMatchSnapshot()
expect(
await rule.validatePlus({
pass: 99,
name: '',
}),
).toMatchSnapshot()
expect(
await rule.validatePlus({
name: '8',
pass: 101,
}),
).toMatchSnapshot()
})

test('validatePlusSync 正常', async () => {
const rule = yup.object({
name: yup.string().label('姓名').required(),
pass: yup.number().label('密码').required().min(100),
})
expect(
rule.validatePlusSync({
name: '',
pass: 99,
}),
).toMatchSnapshot()
expect(
rule.validatePlusSync({
pass: 99,
name: '',
}),
).toMatchSnapshot()
expect(
rule.validatePlusSync({
name: '8',
pass: 101,
}),
).toMatchSnapshot()
})
})
26 changes: 26 additions & 0 deletions src/validator/yup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,32 @@ yup.addMethod(yup.object, 'validateInOrderSync', function (
return this.cast(data)
})

// 实现 validatePlus 方法
yup.addMethod(yup.mixed, 'validatePlus', function (data: any, options: any) {
return (this.type === 'object'
? (this as yup.ObjectSchema).validateInOrder(data, options)
: this.validate(data, options)
)
.then(data => ({ data }))
.catch(error => ({ error, data })) as any
})

// 实现 validatePlusSync 方法
yup.addMethod(yup.mixed, 'validatePlusSync', function (
data: any,
options: any,
) {
try {
const _data =
this.type === 'object'
? (this as yup.ObjectSchema).validateInOrderSync(data, options)
: this.validateSync(data, options)
return { data: _data } as any
} catch (error) {
return { error, data } as any
}
})

// 设置中文为默认语言
yup.setLocale(zhCN)

Expand Down
22 changes: 22 additions & 0 deletions src/validator/yupTypes/mixed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,28 @@ declare module 'yup/es' {

validateSync(value: T, options?: SchemaValidateOptions): T

/**
* 验证增强,包括:对象顺序验证、返回结果包含错误信息。
*/
validatePlus(
value: T,
options?: SchemaValidateOptions,
): Promise<{
error?: ValidationError
data: T
}>

/**
* 验证增强,包括:对象顺序验证、返回结果包含错误信息。
*/
validatePlusSync(
value: T,
options?: SchemaValidateOptions,
): {
error?: ValidationError
data: T
}

/** @类型不友好 */
validateAt(
path: string,
Expand Down

0 comments on commit 8dbc288

Please sign in to comment.