think_validtion
Version:
Validtion Util for Koatty and ThinkORM.
881 lines • 28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.IsHash = exports.IsUrl = exports.IsPhoneNumber = exports.IsIP = exports.IsEmail = exports.Length = exports.Max = exports.Min = exports.IsDate = exports.IsNotIn = exports.IsIn = exports.Contains = exports.NotEquals = exports.Equals = exports.IsNotEmpty = exports.IsPlateNumber = exports.IsMobile = exports.IsZipCode = exports.IsIdNumber = exports.IsCnName = exports.IsDefined = exports.Expose = exports.setExpose = exports.ValidatorFuncs = exports.FunctionValidator = exports.ClassValidator = void 0;
const tslib_1 = require("tslib");
/**
* @ author: richen
* @ copyright: Copyright (c) - <richenlin(at)gmail.com>
* @ license: MIT
* @ version: 2020-05-10 10:45:21
*/
const think_lib_1 = tslib_1.__importDefault(require("think_lib"));
const lib_1 = require("./lib");
const class_validator_1 = require("class-validator");
class ValidateClass {
constructor() {
}
/**
*
*
* @static
* @returns
* @memberof ValidateUtil
*/
static getInstance() {
return this.instance || (this.instance = new ValidateClass());
}
/**
* validated data vs dto class
*
* @param {*} Clazz
* @param {*} data
* @param {boolean} [convert=false] auto convert paramers type
* @returns {Promise<any>}
* @memberof ValidateClass
*/
async valid(Clazz, data, convert = false) {
let obj = {};
if (data instanceof Clazz) {
obj = data;
}
else {
obj = lib_1.plainToClass(Clazz, data, convert);
}
let errors = [];
if (convert) {
errors = await class_validator_1.validate(obj);
}
else {
errors = await class_validator_1.validate(obj, { skipMissingProperties: true });
}
if (errors.length > 0) {
const err = new Error(Object.values(errors[0].constraints)[0]);
err.code = 400;
err.status = 400;
throw err;
}
return obj;
}
}
/**
* ClassValidator for manual
*/
exports.ClassValidator = ValidateClass.getInstance();
/**
* Validator Functions
*/
exports.FunctionValidator = {
/**
* Checks if value matches ("===") the comparison.
*/
Equals: (value, comparison) => {
return class_validator_1.equals(value, comparison);
},
/**
* Checks if value does not match ("!==") the comparison.
*/
NotEquals: (value, comparison) => {
return class_validator_1.notEquals(value, comparison);
},
/**
* Checks if the string contains the seed. If given value is not a string, then it returns false.
*/
Contains: (value, seed) => {
return class_validator_1.contains(value, seed);
},
/**
* Checks if given value is in a array of allowed values.
*/
IsIn: (value, possibleValues) => {
return class_validator_1.isIn(value, possibleValues);
},
/**
* Checks if given value not in a array of allowed values.
*/
IsNotIn: (value, possibleValues) => {
return class_validator_1.isNotIn(value, possibleValues);
},
/**
* Checks if a given value is a real date.
*/
IsDate: (value) => {
return class_validator_1.isDate(value);
},
/**
* Checks if the first number is greater than or equal to the second.
*/
Min: (num, min) => {
return think_lib_1.default.toNumber(num) >= min;
},
/**
* Checks if the first number is less than or equal to the second.
*/
Max: (num, max) => {
return think_lib_1.default.toNumber(num) <= max;
},
/**
* Checks if the string's length falls in a range. Note: this function takes into account surrogate pairs. If given value is not a string, then it returns false.
*/
Length: (value, min, max) => {
return class_validator_1.length(value, min, max);
},
/**
* Checks if the string is an email. If given value is not a string, then it returns false.
*/
IsEmail: (value, options) => {
return class_validator_1.isEmail(value, options);
},
/**
* Checks if the string is an IP (version 4 or 6). If given value is not a string, then it returns false.
*/
IsIP: (value, version) => {
return class_validator_1.isIP(value, version);
},
/**
* Checks if the string is a valid phone number.
* @param value — the potential phone number string to test
* @param region 2 characters uppercase country code (e.g. DE, US, CH). If users must enter the intl. prefix (e.g. +41), then you may pass "ZZ" or null as region. See [google-libphonenumber, metadata.js:countryCodeToRegionCodeMap on github]{@link https://github.com/ruimarinho/google-libphonenumber/blob/1e46138878cff479aafe2ce62175c6c49cb58720/src/metadata.js#L33}
*/
IsPhoneNumber: (value, region) => {
return class_validator_1.isPhoneNumber(value, region);
},
/**
* Checks if the string is an url. If given value is not a string, then it returns false.
*/
IsUrl: (value, options) => {
return class_validator_1.isURL(value, options);
},
/**
* check if the string is a hash of type algorithm. Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
*/
IsHash: (value, algorithm) => {
return class_validator_1.isHash(value, algorithm);
},
/**
* Checks if value is a chinese name.
*/
IsCnName: (value) => {
if (!think_lib_1.default.isString(value)) {
return false;
}
return lib_1.cnname(value);
},
/**
* Checks if value is a idcard number.
*/
IsIdNumber: (value) => {
if (!think_lib_1.default.isString(value)) {
return false;
}
return lib_1.idnumber(value);
},
/**
* Checks if value is a zipcode.
*/
IsZipCode: (value) => {
if (!think_lib_1.default.isString(value)) {
return false;
}
return lib_1.zipcode(value);
},
/**
* Checks if value is a mobile phone number.
*/
IsMobile: (value) => {
if (!think_lib_1.default.isString(value)) {
return false;
}
return lib_1.mobile(value);
},
/**
* Checks if value is a platenumber.
*/
IsPlateNumber: (value) => {
if (!think_lib_1.default.isString(value)) {
return false;
}
return lib_1.platenumber(value);
},
/**
* Checks value is not empty, undefined, null, '', NaN, [], {} and any empty string(including spaces, tabs, formfeeds, etc.), returns false
*/
IsNotEmpty: (value) => {
return !think_lib_1.default.isEmpty(value);
}
};
/**
* Use functions or built-in rules for validation.
*
* @export
* @param {string} name
* @param {*} value
* @param {string} type
* @param {(ValidRules | ValidRules[] | Function)} rule
* @param {string} [message]
* @param {boolean} [checkType=true]
* @returns
*/
function ValidatorFuncs(name, value, type, rule, message, checkType = true) {
// check type
if (checkType && !lib_1.checkParamsType(value, type)) {
const err = new Error(`TypeError: invalid arguments '${name}'.`);
err.code = 400;
err.status = 400;
throw err;
}
if (think_lib_1.default.isFunction(rule)) {
if (!rule(value)) {
const err = new Error(message || `ValidatorError: invalid arguments[${name}].`);
err.code = 400;
err.status = 400;
throw err;
}
return value;
}
else {
const funcs = rule;
if (think_lib_1.default.isString(rule)) {
funcs.push(rule);
}
if (funcs.some((it) => exports.FunctionValidator[it] && !exports.FunctionValidator[it](value))) {
const err = new Error(message || `ValidatorError: invalid arguments[${name}].`);
err.code = 400;
err.status = 400;
throw err;
}
}
return value;
}
exports.ValidatorFuncs = ValidatorFuncs;
/**
* append to the target class method to validated parameter.
*
* @export
* @param {*} target
* @param {string} propertyKey
*/
// export function validParamter(target: any, propertyKey: string, metaDataTypes: any[]) {
// const vaildMetaDatas = recursiveGetMetadata(PARAM_RULE_KEY, target, propertyKey);
// defineNewProperty(target, propertyKey, function (props: any[]) {
// //convert type
// props = props.map((v, k) => {
// if (helper.isString(metaDataTypes[k])) {
// v = convertParamsType(v, metaDataTypes[k]);
// //@Valid()
// if (vaildMetaDatas[k] && vaildMetaDatas[k].type && vaildMetaDatas[k].rule) {
// ValidatorFuncs(`${k}`, v, vaildMetaDatas[k].type, vaildMetaDatas[k].rule, vaildMetaDatas[k].message);
// }
// } else if (helper.isClass(metaDataTypes[k])) {
// v = plainToClass(metaDataTypes[k], v, true);
// }
// return v;
// });
// return props;
// });
// }
/**
* Set property as included in the process of transformation.
*
* @export
* @param {Object} object
* @param {(string | symbol)} propertyName
*/
function setExpose(object, propertyName) {
const types = Reflect.getMetadata("design:type", object, propertyName);
if (types) {
const originMap = lib_1.getOriginMetadata(lib_1.PARAM_TYPE_KEY, object);
originMap.set(propertyName, types.name);
}
}
exports.setExpose = setExpose;
/**
* Marks property as included in the process of transformation.
*
* @export
* @returns {PropertyDecorator}
*/
function Expose() {
return function (object, propertyName) {
const types = Reflect.getMetadata("design:type", object, propertyName);
if (types) {
const originMap = lib_1.getOriginMetadata(lib_1.PARAM_TYPE_KEY, object);
originMap.set(propertyName, types.name);
}
};
}
exports.Expose = Expose;
/**
* Identifies that the field needs to be defined
*
* @export
* @returns {PropertyDecorator}
*/
function IsDefined() {
return function (object, propertyName) {
setExpose(object, propertyName);
};
}
exports.IsDefined = IsDefined;
/**
* Checks if value is a chinese name.
*
* @export
* @param {string} property
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsCnName(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "IsCnName",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return lib_1.cnname(value);
},
defaultMessage(args) {
return "invalid parameter ($property).";
}
}
});
};
}
exports.IsCnName = IsCnName;
/**
* Checks if value is a idcard number(chinese).
*
* @export
* @param {string} property
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsIdNumber(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "IsIdNumber",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return lib_1.idnumber(value);
},
defaultMessage(args) {
return "invalid parameter ($property).";
}
}
});
};
}
exports.IsIdNumber = IsIdNumber;
/**
* Checks if value is a zipcode(chinese).
*
* @export
* @param {string} property
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsZipCode(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "IsZipCode",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return lib_1.zipcode(value);
},
defaultMessage(args) {
return "invalid parameter ($property).";
}
}
});
};
}
exports.IsZipCode = IsZipCode;
/**
* Checks if value is a mobile phone number(chinese).
*
* @export
* @param {string} property
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsMobile(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "IsMobile",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return lib_1.mobile(value);
},
defaultMessage(args) {
return "invalid parameter ($property).";
}
}
});
};
}
exports.IsMobile = IsMobile;
/**
* Checks if value is a plate number(chinese).
*
* @export
* @param {string} property
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsPlateNumber(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "IsPlateNumber",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return lib_1.platenumber(value);
},
defaultMessage(args) {
return "invalid parameter ($property).";
}
}
});
};
}
exports.IsPlateNumber = IsPlateNumber;
/**
* Checks value is not empty, undefined, null, '', NaN, [], {} and any empty string(including spaces, tabs, formfeeds, etc.), returns false.
*
* @export
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsNotEmpty(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "IsNotEmpty",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return !think_lib_1.default.isEmpty(value);
},
defaultMessage(args) {
return "invalid parameter ($property).";
}
}
});
};
}
exports.IsNotEmpty = IsNotEmpty;
/**
* Checks if value matches ("===") the comparison.
*
* @export
* @param {*} comparison
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function Equals(comparison, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vEquals",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.equals(value, comparison);
},
defaultMessage(args) {
return `invalid parameter, ($property) must be equals ${comparison}.`;
}
}
});
};
}
exports.Equals = Equals;
/**
* Checks if value does not match ("!==") the comparison.
*
* @export
* @param {*} comparison
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function NotEquals(comparison, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vNotEquals",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.notEquals(value, comparison);
},
defaultMessage(args) {
return `invalid parameter, ($property) must be not equals ${comparison}.`;
}
}
});
};
}
exports.NotEquals = NotEquals;
/**
* Checks if the string contains the seed.
*
* @export
* @param {string} seed
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function Contains(seed, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vContains",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.contains(value, seed);
// return typeof value === "string" && (value.indexOf(seed) > -1);
},
defaultMessage(args) {
return `invalid parameter, ($property) must be contains ${seed}.`;
}
}
});
};
}
exports.Contains = Contains;
/**
* Checks if given value is in a array of allowed values.
*
* @export
* @param {any[]} possibleValues
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsIn(possibleValues, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsIn",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isIn(value, possibleValues);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsIn = IsIn;
/**
* Checks if given value not in a array of allowed values.
*
* @export
* @param {any[]} possibleValues
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsNotIn(possibleValues, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsNotIn",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isNotIn(value, possibleValues);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsNotIn = IsNotIn;
/**
* Checks if a given value is a real date.
*
* @export
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsDate(validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsDate",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isDate(value);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsDate = IsDate;
/**
* Checks if the first number is greater than or equal to the min value.
*
* @export
* @param {number} min
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function Min(min, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vMin",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return think_lib_1.default.toNumber(value) >= min;
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.Min = Min;
/**
* Checks if the first number is less than or equal to the max value.
*
* @export
* @param {number} max
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function Max(max, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vMax",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return think_lib_1.default.toNumber(value) <= max;
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.Max = Max;
/**
* Checks if the string's length falls in a range. Note: this function takes into account surrogate pairs. If given value is not a string, then it returns false.
*
* @export
* @param {number} min
* @param {number} [max]
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function Length(min, max, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vLength",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.length(value, min, max);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.Length = Length;
/**
* Checks if the string is an email. If given value is not a string, then it returns false.
*
* @export
* @param {IsEmailOptions} [options]
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsEmail(options, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsEmail",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isEmail(value);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsEmail = IsEmail;
/**
* Checks if the string is an IP (version 4 or 6). If given value is not a string, then it returns false.
*
* @export
* @param {number} [version]
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsIP(version, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsIP",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isIP(value, version);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsIP = IsIP;
/**
* Checks if the string is a valid phone number.
*
* @export
* @param {string} {string} region 2 characters uppercase country code (e.g. DE, US, CH).
* If users must enter the intl. prefix (e.g. +41), then you may pass "ZZ" or null as region.
* See [google-libphonenumber, metadata.js:countryCodeToRegionCodeMap on github]{@link https://github.com/ruimarinho/google-libphonenumber/blob/1e46138878cff479aafe2ce62175c6c49cb58720/src/metadata.js#L33}
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsPhoneNumber(region, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsPhoneNumber",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isPhoneNumber(value, region);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsPhoneNumber = IsPhoneNumber;
/**
* Checks if the string is an url.
*
* @export
* @param {IsURLOptions} [options]
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsUrl(options, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsUrl",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isURL(value, options);
},
defaultMessage(args) {
return `invalid parameter ($property).`;
}
}
});
};
}
exports.IsUrl = IsUrl;
/**
* check if the string is a hash of type algorithm. Algorithm is one of ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
*
* @export
* @param {HashAlgorithm} algorithm
* @param {ValidationOptions} [validationOptions]
* @returns {PropertyDecorator}
*/
function IsHash(algorithm, validationOptions) {
return function (object, propertyName) {
setExpose(object, propertyName);
class_validator_1.registerDecorator({
name: "vIsHash",
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value, args) {
return class_validator_1.isHash(value, algorithm);
},
defaultMessage(args) {
return `invalid parameter, ($property) must be is an ${algorithm} Hash string.`;
}
}
});
};
}
exports.IsHash = IsHash;
//# sourceMappingURL=util.js.map