all files / src/ rules.ts

97.73% Statements 43/44
91.67% Branches 11/12
100% Functions 8/8
97.67% Lines 42/43
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                                                                 16×         16×     16×       16×   33×         33×       33× 45×     45×         45×   52×   52×   52× 25× 25×     20×         52×   52× 19× 19×   19×         33×                              
import {originRulesAnalyse, RealRules} from "./origin-rules-analyse";
import {ValidatorCollection, Validator} from "./build-in-validators";
import {ParamType} from "./enum-type";
 
interface RuleResult {
    fields: {
        [propName: string]: {
            message: string,
            invalid: boolean
        }
    },
    valid: boolean
}
 
interface RuleFunction extends Function {
    (data: Object): RuleResult,
 
    register?: (methodName: string, fn: Function) => void
}
 
interface OriginConfig {
    [propName: string]: string
}
 
interface ValidationInfo {
    labels?: {
        [propName: string]: string
    },
    message: {
        [propName: string]: string
    }
}
 
export {RuleResult, RuleFunction};
 
export function rules(config: OriginConfig, info?: ValidationInfo): RuleFunction {
    let realRules = originRulesAnalyse(config),
        newValidators = ValidatorCollection.create(),
        ruleFn = getRuleFunction(realRules, newValidators, info);
 
 
    ruleFn.register = (methodName: string, fn: Function) => {
        newValidators[methodName] = fn;
    };
 
    return ruleFn;
}
 
function getRuleFunction(realRules: RealRules, newValidators: Validator, info?: ValidationInfo): RuleFunction {
 
    return (data: Object) => {
 
        let ruleResult: RuleResult = {
            fields: {},
            valid: true
        };
 
        if ('*' in realRules) {
            addWildCardRule(realRules, data);
        }
 
 
        for (let fieldName in realRules) {
            let filedItem = realRules[fieldName],
                dataItem = data[fieldName];
 
            ruleResult.fields[fieldName] = {
                message: '',
                invalid: false
            };
 
            let resultItem = ruleResult.fields[fieldName];
 
            for (let ruleItem of filedItem) {
 
                let params: any[];
 
                if (ruleItem.params) {
                    params = ruleItem.params.map((param) => {
                        if (param.type === ParamType.PROPERTY) {
                            let field = param.value.replace(/^\s*\{\{|\}\}\s*$/g, '');
                            return data[field];
                        }
                        else {
                            return param.value;
                        }
                    });
                }
 
                resultItem.invalid = !newValidators[ruleItem.method](...[dataItem].concat(params));
 
                if (resultItem.invalid) {
                    ruleResult.valid = false;
                    if (info !== undefined) {
                        resultItem.message = getMessage(info, fieldName, ruleItem.method)
                    }
                    break;
                }
            }
        }
 
        return ruleResult;
    }
}
 
function addWildCardRule(realRules: RealRules, data: Object) {
    let wildCardRules = realRules['*'];
    delete realRules['*'];
 
    for (let fieldName in data) {
        Eif (realRules[fieldName] === undefined) {
            realRules[fieldName] = wildCardRules;
        }
        else {
            realRules[fieldName] = realRules[fieldName].concat(wildCardRules);
        }
    }
}
 
function getMessage(info: ValidationInfo, fieldName: string, method: string): string {
    let message = info.message[fieldName][method].replace(/{{([^}]+)}}/g, function ($0, $1) {
        return info.labels[$1];
    });
 
    return message;
}