Validaciones con validator.js
This commit is contained in:
parent
a13526f3e7
commit
4f5a5ceee0
|
@ -1,6 +1,6 @@
|
|||
import {module} from './module';
|
||||
import {loopbackValidations} from 'vendor';
|
||||
|
||||
import {validator} from 'vendor';
|
||||
console.log(validator);
|
||||
directive.$inject = ['$interpolate', '$compile', '$window']
|
||||
export function directive(interpolate, compile, $window) {
|
||||
return {
|
||||
|
@ -19,7 +19,6 @@ export function directive(interpolate, compile, $window) {
|
|||
|
||||
let entityName = firstUpper(split[0]);
|
||||
let fieldName = split[1];
|
||||
|
||||
let entity = vnValidations[entityName];
|
||||
|
||||
if(!entity)
|
||||
|
@ -82,257 +81,86 @@ export function directive(interpolate, compile, $window) {
|
|||
|
||||
function isValid(value, conf, messageNode) {
|
||||
let valid = true;
|
||||
let inst = {value: value};
|
||||
let validator = validators[conf.validation];
|
||||
|
||||
if(!validator)
|
||||
return true;
|
||||
|
||||
validator.call(inst, 'value', conf, err);
|
||||
|
||||
function err(kind) {
|
||||
var message, code = conf.code || conf.validation;
|
||||
if (conf.message) {
|
||||
message = conf.message;
|
||||
}
|
||||
if (!message && defaultMessages[conf.validation]) {
|
||||
message = defaultMessages[conf.validation];
|
||||
}
|
||||
if (!message) {
|
||||
message = 'is invalid';
|
||||
}
|
||||
if (kind) {
|
||||
code += '.' + kind;
|
||||
if (message[kind]) {
|
||||
message = message[kind];
|
||||
} else if (defaultMessages.common[kind]) {
|
||||
message = defaultMessages.common[kind];
|
||||
} else {
|
||||
message = 'is invalid';
|
||||
}
|
||||
}
|
||||
messageNode.text(message); // code
|
||||
valid = false;
|
||||
try {
|
||||
nullCheck(value, conf);
|
||||
validator && validator(value, conf);
|
||||
}
|
||||
catch(e) {
|
||||
let message = conf.message ? conf.message : e.message;
|
||||
messageNode.text(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return valid;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
module.directive('vnValidation', directive);
|
||||
|
||||
// Code portion of 'lib/validations.js' from 'loopback-datasource-juggler' package
|
||||
|
||||
/*!
|
||||
* Presence validator
|
||||
*/
|
||||
function validatePresence(attr, conf, err, options) {
|
||||
if (blank(this[attr])) {
|
||||
err();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Absence validator
|
||||
*/
|
||||
function validateAbsence(attr, conf, err, options) {
|
||||
if (!blank(this[attr])) {
|
||||
err();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Length validator
|
||||
*/
|
||||
function validateLength(attr, conf, err, options) {
|
||||
if (nullCheck.call(this, attr, conf, err)) return;
|
||||
|
||||
var len = this[attr].length;
|
||||
if (conf.min && len < conf.min) {
|
||||
err('min');
|
||||
}
|
||||
if (conf.max && len > conf.max) {
|
||||
err('max');
|
||||
}
|
||||
if (conf.is && len !== conf.is) {
|
||||
err('is');
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Numericality validator
|
||||
*/
|
||||
function validateNumericality(attr, conf, err, options) {
|
||||
if (nullCheck.call(this, attr, conf, err)) return;
|
||||
|
||||
if (typeof this[attr] !== 'number' || isNaN(this[attr])) {
|
||||
return err('number');
|
||||
}
|
||||
if (conf.int && this[attr] !== Math.round(this[attr])) {
|
||||
return err('int');
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Inclusion validator
|
||||
*/
|
||||
function validateInclusion(attr, conf, err, options) {
|
||||
if (nullCheck.call(this, attr, conf, err)) return;
|
||||
|
||||
if (!~conf.in.indexOf(this[attr])) {
|
||||
err();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Exclusion validator
|
||||
*/
|
||||
function validateExclusion(attr, conf, err, options) {
|
||||
if (nullCheck.call(this, attr, conf, err)) return;
|
||||
|
||||
if (~conf.in.indexOf(this[attr])) {
|
||||
err();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Format validator
|
||||
*/
|
||||
function validateFormat(attr, conf, err, options) {
|
||||
if (nullCheck.call(this, attr, conf, err)) return;
|
||||
|
||||
if (typeof this[attr] === 'string') {
|
||||
if (!this[attr].match(conf['with'])) {
|
||||
err();
|
||||
}
|
||||
} else {
|
||||
err();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Custom validator
|
||||
*/
|
||||
function validateCustom(attr, conf, err, options, done) {
|
||||
if (typeof options === 'function') {
|
||||
done = options;
|
||||
options = {};
|
||||
}
|
||||
conf.customValidator.call(this, err, done);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Uniqueness validator
|
||||
*/
|
||||
function validateUniqueness(attr, conf, err, options, done) {
|
||||
if (typeof options === 'function') {
|
||||
done = options;
|
||||
options = {};
|
||||
}
|
||||
if (blank(this[attr])) {
|
||||
return process.nextTick(done);
|
||||
}
|
||||
var cond = {where: {}};
|
||||
cond.where[attr] = this[attr];
|
||||
|
||||
if (conf && conf.scopedTo) {
|
||||
conf.scopedTo.forEach(function(k) {
|
||||
var val = this[k];
|
||||
if (val !== undefined)
|
||||
cond.where[k] = this[k];
|
||||
}, this);
|
||||
}
|
||||
|
||||
var idName = this.constructor.definition.idName();
|
||||
var isNewRecord = this.isNewRecord();
|
||||
this.constructor.find(cond, options, function(error, found) {
|
||||
if (error) {
|
||||
err(error);
|
||||
} else if (found.length > 1) {
|
||||
err();
|
||||
} else if (found.length === 1 && idName === attr && isNewRecord) {
|
||||
err();
|
||||
} else if (found.length === 1 && (
|
||||
!this.id || !found[0].id || found[0].id.toString() != this.id.toString()
|
||||
)) {
|
||||
err();
|
||||
}
|
||||
done();
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
var validators = {
|
||||
presence: validatePresence,
|
||||
absence: validateAbsence,
|
||||
length: validateLength,
|
||||
numericality: validateNumericality,
|
||||
inclusion: validateInclusion,
|
||||
exclusion: validateExclusion,
|
||||
format: validateFormat,
|
||||
custom: validateCustom,
|
||||
uniqueness: validateUniqueness,
|
||||
presence: function(value, conf) {
|
||||
console.log(value);
|
||||
if(validator.isEmpty(value))
|
||||
throw new Error(`Value can't be empty`);
|
||||
},
|
||||
length: function(value, conf) {
|
||||
let options = {
|
||||
min: conf.min || conf.is,
|
||||
max: conf.max || conf.is
|
||||
};
|
||||
|
||||
if(!validator.isLength(value, options)) {
|
||||
if(conf.is)
|
||||
throw new Error(`Value shoud be ${conf.is} characters long`);
|
||||
else
|
||||
throw new Error(`Value shoud have a length between ${conf.min} and ${conf.max}`);
|
||||
}
|
||||
},
|
||||
numericality: function(value, conf) {
|
||||
if(conf.int) {
|
||||
if(!validator.isInt(value))
|
||||
throw new Error(`Value shoud be integer`);
|
||||
}
|
||||
else {
|
||||
if(!validator.isNumeric(vlaue))
|
||||
throw new Error(`Value shoud be a number`);
|
||||
}
|
||||
},
|
||||
inclusion: function(value, conf) {
|
||||
if(!validator.isIn(value, conf.in))
|
||||
throw new Error(`Invalid value`);
|
||||
},
|
||||
exclusion: function(value, conf) {
|
||||
if(validator.isIn(value, conf.in))
|
||||
throw new Error(`Invalid value`);
|
||||
},
|
||||
format: function(value, conf) {
|
||||
if(!validator.matches(value, conf.with))
|
||||
throw new Error(`Invalid value`);
|
||||
},
|
||||
custom: function(value, conf) {
|
||||
let valid = true;
|
||||
function err(kind) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
let inst = {attr: value};
|
||||
conf.customValidator.call(inst, err)
|
||||
|
||||
if(!valid)
|
||||
throw new Error(`Invalid value`);
|
||||
},
|
||||
absence: function() {},
|
||||
uniqueness: function() {},
|
||||
};
|
||||
|
||||
var defaultMessages = {
|
||||
presence: 'can\'t be blank',
|
||||
absence: 'can\'t be set',
|
||||
'unknown-property': 'is not defined in the model',
|
||||
length: {
|
||||
min: 'too short',
|
||||
max: 'too long',
|
||||
is: 'length is wrong',
|
||||
},
|
||||
common: {
|
||||
blank: 'is blank',
|
||||
'null': 'is null',
|
||||
},
|
||||
numericality: {
|
||||
'int': 'is not an integer',
|
||||
'number': 'is not a number',
|
||||
},
|
||||
inclusion: 'is not included in the list',
|
||||
exclusion: 'is reserved',
|
||||
uniqueness: 'is not unique',
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if attribute is undefined or null. Calls err function with 'blank' or 'null'.
|
||||
* See defaultMessages. You can affect this behaviour with conf.allowBlank and conf.allowNull.
|
||||
* @param {String} attr Property name of attribute
|
||||
* @param {Object} conf conf object for validator
|
||||
* @param {Function} err
|
||||
* @return {Boolean} returns true if attribute is null or blank
|
||||
*/
|
||||
function nullCheck(attr, conf, err) {
|
||||
// First determine if attribute is defined
|
||||
if (typeof this[attr] === 'undefined') {
|
||||
if (!conf.allowBlank) {
|
||||
err('blank');
|
||||
function nullCheck(value, conf) {
|
||||
if (typeof value === 'undefined') {
|
||||
if (!conf.allowBlank)
|
||||
throw new Error(`Value can't be blank`);
|
||||
} else {
|
||||
if (value === null && !conf.allowNull)
|
||||
throw new Error(`Value can't be null`);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// Now check if attribute is null
|
||||
if (this[attr] === null) {
|
||||
if (!conf.allowNull) {
|
||||
err('null');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Return true when v is undefined, blank array, null or empty string
|
||||
* otherwise returns false
|
||||
*
|
||||
* @param {Mix} v
|
||||
* Returns true if `v` is blank.
|
||||
*/
|
||||
function blank(v) {
|
||||
if (typeof v === 'undefined') return true;
|
||||
if (v instanceof Array && v.length === 0) return true;
|
||||
if (v === null) return true;
|
||||
if (typeof v === 'number' && isNaN(v)) return true;
|
||||
if (typeof v == 'string' && v === '') return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
import * as validatorJs from 'validator';
|
||||
|
||||
export const validator = validatorJs;
|
|
@ -4,3 +4,4 @@ export * from './ui-router';
|
|||
export * from './angular-translate';
|
||||
export * from './material-design-lite';
|
||||
export * from './angular-paging';
|
||||
export * from './validator';
|
|
@ -15,7 +15,8 @@
|
|||
"angular-translate-loader-partial": "^2.13.1",
|
||||
"angular-ui-router": "^1.0.0-beta.3",
|
||||
"material-design-lite": "^1.3.0",
|
||||
"oclazyload": "^0.6.3"
|
||||
"oclazyload": "^0.6.3",
|
||||
"validator": "^6.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "*",
|
||||
|
|
Loading…
Reference in New Issue