Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | 5x 5x 5x 5x 3x 5x 3x 5x 214x 215x 221x 428x 214x 51x 51x 18x 196x 11x 11x 186x 33x 33x 32x 32x 10x 10x 22x 1x 1x 23x 186x 11x 11x 4x 7x 175x 5x 5x 5x | import {
ValidatorRule,
ValidatorMessages,
ValidatorData,
ValidatorContext,
ValidatorRuleMap,
ValidatorMessageGenerator,
ValueMap,
ValidatorRules,
} from '../types';
import { validatorRules as importedValidatorRules } from '../rules';
/**
* Validator rules to be used by validator
*/
let validatorRules = importedValidatorRules;
/**
* Returns current validator rules in use
*/
export const getValidatorRules = (): ValidatorRuleMap => {
return validatorRules;
};
/**
* Adds a custom validator rule to the validator. If the rule is
* already defined, the new rule will override the original.
*
* @param rule new rule to be added
*/
export const addValidatorRule = (key: string, rule: ValidatorRule): void => {
validatorRules = {
...validatorRules,
[key]: rule,
};
};
/**
* Validate a field using the provided rules
*
* @param valueKey key of value to be validated
* @param values values of all fields
* @param targetRules validator rules to use
* @param customMessages custom validator messages
*/
export const validate = (
valueKey: string,
Ivalues: ValueMap = {},
targetRules: {
readonly [name: string]: any;
} = {},
customMessages: ValidatorMessages = {},
): ValidatorData => {
const { required, custom, ...restRules } = targetRules;
// Execute required rule first (if it exists)
if (required) {
const response = validatorRules.required(valueKey, values);
if (response) {
return {
...response,
...('required' in customMessages
? {
message: formatCustomMessage(
customMessages['required'],
valueKey,
values,
),
}
: {}),
};
}
}
// Execute custom validator rule second (if it exists)
if (custom) {
const response = custom(valueKey, values);
// Only return if there is a response to return
if (response) return response;
}
// Execute rest rules
let cachedValidatorData: ValidatorData;
Object.keys(restRules).some(
(ruleKey: keyof Omit<ValidatorRules, 'custom'>) => {
const criteria = targetRules[ruleKey];
if (ruleKey in validatorRules) {
const data: ValidatorData = {
name: ruleKey,
...validatorRules[ruleKey](valueKey, values, criteria),
};
// Break early if danger context is encountered
if (data && data.context === ValidatorContext.Danger) {
cachedValidatorData = data;
return true;
}
// Cache first warning context, don't break because there might be an error later on
if (
data &&
data.context === ValidatorContext.Warning &&
!cachedValidatorData
) {
cachedValidatorData = data;
}
} else {
console.warn(`Rule "${ruleKey}" does not exist.`);
}
// Keep iterating
return false;
},
);
// If we have a cached validatorData, return it
if (cachedValidatorData) {
// Use custom error message if available
const ruleKey = cachedValidatorData.name;
if (ruleKey in customMessages) {
return {
...cachedValidatorData,
message: formatCustomMessage(
customMessages[ruleKey],
valueKey,
values,
targetRules[ruleKey],
),
};
}
return cachedValidatorData;
}
// If we don't have a cached response, assume validator is successful
return {
context: ValidatorContext.Success,
message: undefined,
};
};
const formatCustomMessage = (
customMessage: ValidatorMessageGenerator | string,
valueKey: string,
Ivalues: ValueMap = {},
criteria?: any,
) => {
return customMessage instanceof Function
? ((customMessage as ValidatorMessageGenerator)(
valueKey,
values,
criteria,
) as string)
: (customMessage as string);
};
|