Skip to content

Commit

Permalink
feat: 校验增加关联字段名转换
Browse files Browse the repository at this point in the history
  • Loading branch information
D-xuanmo committed Jul 10, 2023
1 parent 1d248a1 commit bbc412f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@xuanmo/validator",
"version": "0.0.15",
"version": "0.0.16",
"description": "用最少的代码,解决繁琐的事情",
"private": false,
"main": "dist/validator.cjs.js",
Expand Down
12 changes: 12 additions & 0 deletions src/types.ts
Expand Up @@ -115,11 +115,19 @@ export type OmitObjectProperties<T extends object, K extends keyof T> = {
[Key in keyof T as Key extends K ? never : Key]: T[Key]
}

/**
* 当前校验上下文对象
*/
export type ValidateContextType = {
/**
* 当前校验的所有数据
*/
data: Readonly<Array<ValidateDataModelItem>>

/**
* 当前校验数据的 map 结构,与 data 等价
*/
dataKeyMap: Map<string, ValidateDataModelItem>
}

/**
Expand All @@ -137,6 +145,10 @@ export type SingleRuleType<TValue = unknown, TP = RuleParamsType> = {

/**
* 参数枚举
* @example
* [
* { name: 'max' }
* ]
*/
paramsEnum?: Array<{
name: string
Expand Down
3 changes: 3 additions & 0 deletions src/validator/constants.ts
@@ -1,2 +1,5 @@
// 规则参数分隔符
export const RULE_PARAMS_SEPARATOR = ','

// 关联字段分隔符
export const RELATED_FIELD_SEPARATOR = '@'
43 changes: 32 additions & 11 deletions src/validator/index.ts
Expand Up @@ -14,7 +14,7 @@ import {
ValidatorModelType,
ValidatorRuleModel
} from '../types'
import { RULE_PARAMS_SEPARATOR } from './constants'
import { RELATED_FIELD_SEPARATOR, RULE_PARAMS_SEPARATOR } from './constants'

class Validator {
/**
Expand All @@ -23,7 +23,7 @@ class Validator {
private locale: LocaleMessageType['message'] | null = null

/**
* 校验模型
* 校验规则模型
*/
private validateModel: Map<string, ValidatorRuleModel> = new Map()

Expand Down Expand Up @@ -95,15 +95,18 @@ class Validator {
* 格式化错误信息
* @param message 错误信息
* @param fieldName 当前字段
* @param ruleParams 校验规则参数
* @param paramsEnum 参数映射
* @param options
*/
private formatMessage(
message: string,
fieldName: string,
ruleParams?: RuleParamsType,
paramsEnum?: SingleRuleType['paramsEnum']
options?: {
ruleParams?: RuleParamsType,
paramsEnum?: SingleRuleType['paramsEnum'],
context?: ValidateContextType
}
) {
const { ruleParams, paramsEnum, context } = options ?? {}
let formatted = message.replace(/\{#field}/gi, fieldName)

if (Array.isArray(ruleParams)) {
Expand All @@ -116,7 +119,12 @@ class Validator {
}

if (typeof ruleParams === 'string') {
formatted = formatted.replace(/\{[a-z]+}/i, ruleParams)
let replaceValue = ruleParams
if (new RegExp(`^${RELATED_FIELD_SEPARATOR}`).test(ruleParams)) {
const item = context?.dataKeyMap.get(ruleParams.replace(RELATED_FIELD_SEPARATOR, ''))
replaceValue = item?.label || item?.dataKey || ''
}
formatted = formatted.replace(/\{[a-z]+}/i, replaceValue)
}

return formatted
Expand Down Expand Up @@ -210,8 +218,11 @@ class Validator {
errorResult = this.formatMessage(
validateModel.message,
fieldName,
this.formatRuleParams(ruleParams),
validateModel.paramsEnum
{
ruleParams: this.formatRuleParams(ruleParams),
paramsEnum: validateModel.paramsEnum,
context
}
)
break
}
Expand All @@ -235,6 +246,14 @@ class Validator {
return data as Array<ValidateDataModelItem>
}

private convertDataToMap = (data: Array<ValidateDataModelItem>) => {
const dataKeyMap: ValidateContextType['dataKeyMap'] = new Map()
data.forEach((item) => {
dataKeyMap.set(item.dataKey, item)
})
return dataKeyMap
}

/**
* 执行校验
* @param data 校验数据
Expand All @@ -249,6 +268,7 @@ class Validator {
const { checkAll = true } = options ?? {}
const errorResult: Record<string, ValidateErrorType> = {}
const convertedData = this.convertData(data)
const dataKeyMap = this.convertDataToMap(convertedData)
for (let i = 0; i < convertedData.length; i++) {
const item = convertedData[i]
const fieldName = item.dataKey
Expand All @@ -262,14 +282,15 @@ class Validator {
// 如果当前数据存在局部校验规则,则不执行 rules 规则
if (rest.regexp || rest.validator) {
result = await this.scopeValidateHandler(value, rest as ScopeValidateType, {
data: convertedData
data: convertedData,
dataKeyMap
})
} else {
result = await this.validateHandler(
value,
aliasName,
rest,
{ data: convertedData }
{ data: convertedData, dataKeyMap }
)
}
}
Expand Down
12 changes: 7 additions & 5 deletions test/confirmed.test.js
Expand Up @@ -15,23 +15,25 @@ test('confirmed', async () => {
dataKey: 'confirmed2',
value: '123456',
rules: 'confirmed:confirmed1'
},
}
])).resolves.toBe(true)

// 校验未通过
await expect(validator.validate([
{
dataKey: 'confirmed3',
value: '123456'
value: '123456',
label: '密码'
},
{
dataKey: 'confirmed4',
value: '1',
rules: 'confirmed:confirmed3'
},
rules: 'confirmed:@confirmed3',
label: '二次确认密码'
}
])).rejects.toMatchInlineSnapshot(`
{
"confirmed4": "confirmed4与confirmed3不匹配",
"confirmed4": "二次确认密码与密码不匹配",
}
`)
})

0 comments on commit bbc412f

Please sign in to comment.