koa-validate = function (app) { app.context.checkQuery = function(key,transFn) { return new Validator(this, key, getValue(this.request.query,key,transFn), hasKey(this.request.query, key, transFn),this.request .query); }; app.context.checkParams = function(key) { return new Validator(this, key, this.params[key], key in this.params,this.params); }; app.context.checkHeader = function(key) { return new Validator(this, key, this.header[key], key in this.header,this.header); }; app.context.checkBody = function(key,transFn) { var body = this.request.body; if(!body) { if(!this.errors){ this.errors = ['no body to check!']; } return new Validator(this, null, null,false, null ,false ); } var body = body.fields || body; // koa-body fileds. multipart fields in body.fields return new Validator(this, key,getValue(body,key,transFn), hasKey(body, key, transFn), body); }; app.context.checkFile = function(key , deleteOnCheckFailed) { if('undefined' == typeof this.request.body || 'undefined' == typeof this.request.body.files ) { if(!this.errors){ this.errors = ['no file to check']; } return new Validator(this, null, null,false, null,false ); } deleteOnCheckFailed = ('undefined' == typeof deleteOnCheckFailed?true :false); var files = this.request.body.files; return new FileValidator(this, key ,files&&files[key],!!(files&&files[key]) , this.request.body , deleteOnCheckFailed); }; // return function* (next) { // yield next; // }; }
n/a
function FileValidator(context, key, value, exists, params, deleteOnCheckFailed){ Validator.call(this,context, key, value, exists, params ,true); this.deleteOnCheckFailed = deleteOnCheckFailed; }
n/a
function Validator(context, key, value, exists, params , goOn) { this.params = params; this.context = context; this.key = key; this.value = value; this.exists = exists; this.goOn = (false===goOn?false:true); if(this.value && this instanceof FileValidator && 'goOn' in this.value ){ this.goOn = this.value.goOn; } }
n/a
function FileValidator(context, key, value, exists, params, deleteOnCheckFailed){ Validator.call(this,context, key, value, exists, params ,true); this.deleteOnCheckFailed = deleteOnCheckFailed; }
n/a
function Validator(context, key, value, exists, params , goOn) { this.params = params; this.context = context; this.key = key; this.value = value; this.exists = exists; this.goOn = (false===goOn?false:true); if(this.value && this instanceof FileValidator && 'goOn' in this.value ){ this.goOn = this.value.goOn; } }
n/a
contentTypeMatch = function (reg, tip){ if (this.goOn && (!this.value || !reg.test(this.value.type))) { this.addError(tip || "file "+ (this.value && this.value.name||this.key) + " is bad format."); if(this.deleteOnCheckFailed){ delFileAsync(this.value &&this.value.path); } } return this; }
...
describe('koa-validate' , function(){
// this.timeout(100000);
it("file check ok" , function(done){
var app = appFactory.create(1);
app.router.post('/upload',function*(){
this.checkFile('empty').empty();
// this.checkFile('file1').empty().contentTypeMatch(/^text/);
this.checkFile('file').empty().contentTypeMatch(/^application\//);
yield this.checkFile('file1').empty().move(__dirname+"/temp", function(file , context){
});
this.checkFile('file').notEmpty();
yield this.checkFile('file').notEmpty().copy(__dirname+"/tempdir/" , function(file , context){
});
yield this.checkFile('file').notEmpty().copy(__dirname);
...
function* (dst, afterCopy){ if (this.goOn && this.value ) { var dstFile = dst; if('function' == typeof dst){ if(isGeneratorFunction(dst)){ dstFile = yield dst(this.value,this.key,this.context); }else{ dstFile = dst(this.value,this.key,this.context); } } if(!(yield coFsExists(this.value.path))){ this.addError('upload file not exists'); return; } if(dstFile.length-1 == dstFile.lastIndexOf('/') ||dstFile.length-1 == dstFile.lastIndexOf('\\')||(yield coFsExists(dstFile)) && ( yield coFsIsDir(dstFile))){ dstFile = path.join(dstFile , path.basename(this.value.path)); } yield ensureDir(path.dirname(dstFile)); yield coFsCopy(this.value.path,dstFile); this.value.newPath = dstFile; if('function' == typeof afterCopy){ if(isGeneratorFunction(afterCopy)){ yield afterCopy(this.value,this.key,this.context); }else{ afterCopy(this.value,this.key,this.context); } } } return this; }
...
- **size(min,max,[tip])** - limit the file size.
- **contentTypeMatch(reg,[tip])** - check the file's contentType with regular expression.
- **isImageContentType([tip])** - check the file's contentType if is image content type.
- **fileNameMatch(reg,[tip])** - check the file's name with regular expression.
- **suffixIn(arr,[tip])** - check the suffix of file's if in specified arr. `arr` eg. ['png','jpg']
#### Sanitizers:
File sanitizers are generators,we should use `yield` to execute them. eg. `yield this.checkFile('file').notEmpty().copy('/')`;
- **move(target,[afterMove])** - move upload file to the target location. target can be a `string` or `function` or `function*`.
if target end with '/' or '\\',the target will be deemed as directory.
target function interface:`string function(fileObject,fieldName,context)`.this function will return a string of the target file.
afterMove:it can be a `function` or `function*`.interface:`function(fileObject,fieldName,context)`
- **copy(target,[afterCopy])** - move upload file to the target location. target can be a `string` or `function` or `function*`.
target function interface:`function (fileObject,fieldName,context)` .
afterCopy:it can be a `function` or `function*`.interface:`function(fileObject,fieldName,context)`
- **delete()** - delete upload file.
...
function* (){ if (this.goOn && this.value ) { yield coFsDel(this.value.path); } return this; }
...
this.checkFile('file').notEmpty();
yield this.checkFile('file').notEmpty().copy(__dirname+"/tempdir/" , function(file , context){
});
yield this.checkFile('file').notEmpty().copy(__dirname);
yield this.checkFile('file').notEmpty().copy(function(){return __dirname+"/temp"});
yield (yield this.checkFile('file').notEmpty().fileNameMatch(/^.*.js$/).size(0,10*1024).suffixIn(['js']).
copy(function*(obj){
return __dirname+"/temp";
})).delete();
require('fs').unlinkSync(__dirname+'/temp');
require('fs').unlinkSync(__dirname+'/'+require('path').basename(this.request.body.files.file.path
));
require('fs').unlinkSync(__dirname+'/tempdir/'+require('path').basename(this.request.body.files
.file.path));
// require('fs').unlinkSync(__dirname+'/tempdir');
if(this.errors){
this.body = this.errors;
return;
...
fileNameMatch = function (reg, tip){ if (this.goOn && (!this.value || !reg.test(this.value.name))) { this.addError(tip || "file "+ (this.value && this.value.name||this.key) + " is bad file type."); if(this.deleteOnCheckFailed){ delFileAsync(this.value&&this.value.path); } } return this; }
...
yield this.checkFile('file1').empty().move(__dirname+"/temp", function(file , context){
});
this.checkFile('file').notEmpty();
yield this.checkFile('file').notEmpty().copy(__dirname+"/tempdir/" , function(file , context){
});
yield this.checkFile('file').notEmpty().copy(__dirname);
yield this.checkFile('file').notEmpty().copy(function(){return __dirname+"/temp"});
yield (yield this.checkFile('file').notEmpty().fileNameMatch(/^.*.js$/).
size(0,10*1024).suffixIn(['js']).copy(function*(obj){
return __dirname+"/temp";
})).delete();
require('fs').unlinkSync(__dirname+'/temp');
require('fs').unlinkSync(__dirname+'/'+require('path').basename(this.request.body.files.file.path
));
require('fs').unlinkSync(__dirname+'/tempdir/'+require('path').basename(this.request.body.files
.file.path));
// require('fs').unlinkSync(__dirname+'/tempdir');
if(this.errors){
...
isImageContentType = function (tip){ if (this.goOn && (!this.value || 0!==this.value.type.indexOf('image/'))) { this.addError(tip || "file "+ (this.value && this.value.name||this.key) + " is not a image format."); if(this.deleteOnCheckFailed){ delFileAsync(this.value &&this.value.path); } } return this; }
...
this.checkFile('file0').size(10,10 );
this.checkFile('file').size(1024*100,1024*1024*10 );
this.checkFile('file1').size(1024*100,1024*1024*1024*10 );
this.checkFile('file2').suffixIn(['png']);
this.checkFile('file3').contentTypeMatch(/^image\/.*$/);
this.checkFile('file4').contentTypeMatch(/^image\/.*$/);
this.checkFile('file5').fileNameMatch(/\.png$/);
this.checkFile('file6').isImageContentType("not image content type.
x22;);
if(9 === this.errors.length){
this.body = 'ok';
return ;
}else{
this.body = 'not ok';
...
function* (dst, afterMove){ if (this.goOn && this.value ) { yield this.copy(dst); yield coFsDel(this.value.path); if('function' == typeof afterMove){ if(isGeneratorFunction(afterMove)){ yield afterMove(this.value,this.key,this.context); }else{ afterMove(this.value,this.key,this.context); } } } return this; }
...
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" , function*(file,context){
//resize image
});
if (this.errors) {
this.body = this.errors;
return;
}
});
...
notEmpty = function (tip){ if (this.goOn && (!this.value||this.value.size<=0)) { this.addError(tip || "file "+ this.key + " can not be a empty file."); if(this.deleteOnCheckFailed){ delFileAsync(this.value&&this.value.path); } } return this; }
...
app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
//resize image
});
...
size = function (min, max, tip){ if (this.goOn && (!this.value||this.value.size<min || this.value.size>max)) { this.addError(tip || "file "+(this.value && this.value.name||this.key) + "' length must between "+formatSize(min)+" and "+formatSize (max)+"."); if(this.deleteOnCheckFailed){ delFileAsync(this.value &&this.value.path); } } return this; }
...
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large
').move("/static/icon/" , function*(file,context){
//resize image
});
if (this.errors) {
this.body = this.errors;
return;
}
});
...
suffixIn = function (arr, tip){ if (this.goOn && (!this.value || -1==arr.indexOf(-1==this.value.name.lastIndexOf('.')?"":this.value.name.substring(this.value.name .lastIndexOf('.')+1)))) { this.addError(tip || "file "+ (this.value && this.value.name||this.key) + " is bad file type."); if(this.deleteOnCheckFailed){ delFileAsync(this.value &&this.value.path); } } return this; }
...
yield this.checkFile('file1').empty().move(__dirname+"/temp", function(file , context){
});
this.checkFile('file').notEmpty();
yield this.checkFile('file').notEmpty().copy(__dirname+"/tempdir/" , function(file , context){
});
yield this.checkFile('file').notEmpty().copy(__dirname);
yield this.checkFile('file').notEmpty().copy(function(){return __dirname+"/temp"});
yield (yield this.checkFile('file').notEmpty().fileNameMatch(/^.*.js$/).size(0,10*1024).suffixIn(['js']).copy(function*(obj){
return __dirname+"/temp";
})).delete();
require('fs').unlinkSync(__dirname+'/temp');
require('fs').unlinkSync(__dirname+'/'+require('path').basename(this.request.body.files.file.path
));
require('fs').unlinkSync(__dirname+'/tempdir/'+require('path').basename(this.request.body.files
.file.path));
// require('fs').unlinkSync(__dirname+'/tempdir');
if(this.errors){
...
function Validator(context, key, value, exists, params , goOn) { this.params = params; this.context = context; this.key = key; this.value = value; this.exists = exists; this.goOn = (false===goOn?false:true); if(this.value && this instanceof FileValidator && 'goOn' in this.value ){ this.goOn = this.value.goOn; } }
n/a
addError = function (tip) { this.goOn = false; if(this.value && this instanceof FileValidator ){ this.value.goOn = false; } if (!this.context.errors) { this.context.errors = []; } var e = {}; e[this.key] = tip; this.context.errors.push(e); }
...
if (!this.exists) {
this.goOn = false;
}
return this;
};
Validator.prototype.notEmpty = function(tip) {
if (this.goOn && (null==this.value||'undefined'==typeof(this.value) || ('string' == typeof(this.value
) &&!this.value))) {
this.addError(tip || this.key + " can not be empty.");
}
return this;
};
Validator.prototype.empty = function() {
if (this.goOn) {
if (!this.value) {
this.goOn = false;
...
blacklist = function (s) { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.blacklist(this.value,s); } return this; }
...
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.whitelist(this.value,s);
}
return this;
};
Validator.prototype.blacklist = function(s) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.blacklist(this.value,s);
}
return this;
};
Validator.prototype.encodeURI = function() {
if (this.goOn && !this.hasError()&&this.value) {
this.value = this.params[this.key] = encodeURI(this.value);
}
...
byteLength = function (min, max, charset, tip) { min = min || 0; max = max || Number.MAX_VALUE; charset = charset||'utf8'; this.notEmpty(tip); if (this.goOn) { var bl = Buffer.byteLength(this.value , charset); tip = 'number' != typeof max ? max : tip; if (bl<min || bl>max) { this.addError(tip || this.key + "'s byte lenth great than " + min +" and less than " + max + "." ); } } return this; }
...
};
Validator.prototype.isByteLength = function(min, max,charset,tip) {
min = min || 0;
max = max || Number.MAX_VALUE;
charset = charset||'utf8';
this.notEmpty(tip);
if (this.goOn) {
var bl = Buffer.byteLength(this.value , charset);
tip = 'number' != typeof max ? max : tip;
if (bl<min || bl>max) {
this.addError(tip || this.key + "'s byte lenth great than " + min +" and less than " + max + ".
x22; );
}
}
return this;
};
...
check = function (fn , tip, scope) { if(this.goOn && !this.hasError()&&!fn.call(scope||this,this.value,this.key,this.context)) { this.addError(tip||this.key+" check failed.") } return this; }
n/a
clone = function (key , value) { if (!this.hasError()&&this.value) { this.value = this.params[key] = ('undefined' == typeof value?this.value:value); this.key = key; } return this; }
...
- **whitelist(value)** - remove characters that do not appear in the whitelist.
- **blacklist(value)** - remove characters that appear in the blacklist.
- **encodeURI()** - ref mdn [encodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
)
- **decodeURI([tip])** - ref mdn [decodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI
)
- **encodeURIComponent()** - ref mdn [encodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
/encodeURIComponent)
- **decodeURIComponent([tip])** - ref mdn [decodeURIComponent](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
/Global_Objects/decodeURIComponent)
- **replace(regexp|substr, newSubStr|function)** - the same as [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/
Reference/Global_Objects/String/replace) replace
- **clone(newKey,[newValue])** - clone current value to the new key, if newValue supplied , use it. eg. `this.checkBody('v1
').clone('md5').md5()`; then your can use `this.request.body.md5`.
- **encodeBase64()** - encode current value to base64 string.
- **decodeBase64([inBuffer],[tip])** - decode current base64 to a normal string,if inBuffer is true , the value will be a Buffer
.
- **hash(alg , [encoding])** - hash current value use specified algorithm and encoding(if supplied , default is 'hex').
ref [hash](http://nodejs.org/api/crypto.html#crypto_class_hash)
- **md5()** - md5 current value into hex string.
- **sha1()** - sha1 current value into hex string.
### For json path:
...
contains = function (s, tip) { if (this.goOn && (!isString(this.value) ||!v.contains(this.value,s))) { this.addError(tip || this.key + " is must contain " + s + "."); } return this; }
...
Validator.prototype.le = function(l, tip) {
if (this.goOn && this.value > l) {
this.addError(tip || this.key + " must less than or equal " + l + ".");
}
return this;
};
Validator.prototype.contains = function(s, tip) {
if (this.goOn && (!isString(this.value) ||!v.contains(this.value,s))) {
this.addError(tip || this.key + " is must contain " + s + ".");
}
return this;
};
Validator.prototype.notContains = function(s, tip) {
if (this.goOn && (!isString(this.value) ||v.contains(this.value,s))) {
this.addError(tip || this.key + " is must not contain " + s + ".");
...
decodeBase64 = function (inBuffer , tip) { if (!this.hasError()&&this.value) { try{ if(inBuffer){ this.value = this.params[this.key] = new Buffer(this.value , 'base64'); }else{ this.value = this.params[this.key] = new Buffer(this.value , 'base64').toString(); } }catch(e){ this.addError(tip||"bad base64 format value"); } } return this; }
...
this.checkBody('whitelist').whitelist('ll');
this.checkBody('blacklist').blacklist('ll');
this.checkBody('encodeURI').decodeURI();
this.checkBody('decodeURI').encodeURI();
this.checkBody('encodeURIComponent').decodeURIComponent();
this.checkBody('decodeURIComponent').encodeURIComponent();
this.checkBody('rep').replace(',' ,'');
this.checkBody('base64').clone('base64Buffer').decodeBase64(true
);
this.checkBody('base64').decodeBase64();
this.checkBody('debase64').encodeBase64();
this.checkBody('hash').clone('md5').md5();
this.checkBody('hash').clone('sha1').sha1();
this.checkBody('hash').clone('num1' ,1);
this.checkBody('json').toJson();
//console.log(this.request.body)
...
decodeURI = function (tip) { if (this.goOn && !this.hasError()&&this.value) { try{ this.value = this.params[this.key] = decodeURI(this.value); }catch(e){ this.addError(tip||'bad uri to decode.'); } } return this; }
...
req.post('/decodeURIComponent')
.send({uri:"%"})
.expect(500 , done);
});
it("bad uri decodeURI should not to be ok" , function(done){
var app = appFactory.create(1);
app.router.post('/decodeURI',function*(){
this.checkBody('uri').decodeURI();
if(this.errors) {
this.status=500;
}else{
this.status=200;
}
});
var req = request(app.listen());
...
decodeURIComponent = function (tip) { if (this.goOn && !this.hasError()&&this.value) { try{ this.value = this.params[this.key] = decodeURIComponent(this.value); }catch(e){ this.addError(tip||'bad uri to decode.'); } } return this; }
...
describe('koa-validate' , function(){
it("bad uri decodeURIComponent should not to be ok" , function(done){
var app = appFactory.create(1);
app.router.post('/decodeURIComponent',function*(){
this.checkBody('uri').decodeURIComponent();
if(this.errors) {
this.status=500;
}else{
this.status=200;
}
});
var req = request(app.listen());
...
default = function (d) { if(!this.hasError()&&!this.value){ this.value = this.params[this.key] = d; } return this; }
...
.expect(200)
.expect('ok' , done);
});
it('there sanitizers should be to okay' , function(done){
var url ="http://www.google.com/"
var app = appFactory.create(1);
app.router.post('/sanitizers',function*(){
this.checkBody('default').default('default');
this.checkBody('int_').toInt();
this.checkBody('int_').toInt(null, 10, {min:20});
this.checkBody('int_').toInt(null, 10, {max:20});
this.checkBody('int_').toInt(null, 10, {min:20,max:20});
this.checkBody('octal_').toInt(null, 8);
this.checkBody('octal_').toInt(null, 8, {min:8});
this.checkBody('octal_').toInt(null, 8, {max:8});
...
empty = function () { if (this.goOn) { if (!this.value) { this.goOn = false; } } return this; }
...
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
//resize image
});
if (this.errors) {
this.body = this.errors;
...
encodeBase64 = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = new Buffer(this.value).toString('base64'); } return this; }
...
this.checkBody('encodeURI').decodeURI();
this.checkBody('decodeURI').encodeURI();
this.checkBody('encodeURIComponent').decodeURIComponent();
this.checkBody('decodeURIComponent').encodeURIComponent();
this.checkBody('rep').replace(',' ,'');
this.checkBody('base64').clone('base64Buffer').decodeBase64(true);
this.checkBody('base64').decodeBase64();
this.checkBody('debase64').encodeBase64();
this.checkBody('hash').clone('md5').md5();
this.checkBody('hash').clone('sha1').sha1();
this.checkBody('hash').clone('num1' ,1);
this.checkBody('json').toJson();
//console.log(this.request.body)
if(this.errors){
this.body = this.errors;
...
encodeURI = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = encodeURI(this.value); } return this; }
...
this.checkBody('up').toUp();
this.checkBody('low').toLow();
this.checkBody('escape').escape();
this.checkBody('stripLow').stripLow();
this.checkBody('whitelist').whitelist('ll');
this.checkBody('blacklist').blacklist('ll');
this.checkBody('encodeURI').decodeURI();
this.checkBody('decodeURI').encodeURI();
this.checkBody('encodeURIComponent').decodeURIComponent();
this.checkBody('decodeURIComponent').encodeURIComponent();
this.checkBody('rep').replace(',' ,'');
this.checkBody('base64').clone('base64Buffer').decodeBase64(true);
this.checkBody('base64').decodeBase64();
this.checkBody('debase64').encodeBase64();
this.checkBody('hash').clone('md5').md5();
...
encodeURIComponent = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = encodeURIComponent(this.value); } return this; }
...
this.checkBody('escape').escape();
this.checkBody('stripLow').stripLow();
this.checkBody('whitelist').whitelist('ll');
this.checkBody('blacklist').blacklist('ll');
this.checkBody('encodeURI').decodeURI();
this.checkBody('decodeURI').encodeURI();
this.checkBody('encodeURIComponent').decodeURIComponent();
this.checkBody('decodeURIComponent').encodeURIComponent();
this.checkBody('rep').replace(',' ,'');
this.checkBody('base64').clone('base64Buffer').decodeBase64(true);
this.checkBody('base64').decodeBase64();
this.checkBody('debase64').encodeBase64();
this.checkBody('hash').clone('md5').md5();
this.checkBody('hash').clone('sha1').sha1();
this.checkBody('hash').clone('num1' ,1);
...
ensure = function (assertion, tip, shouldBail) { if (shouldBail) this.goOn = false; if (this.goOn && !assertion) { this.addError(tip || this.key + ' failed an assertion.'); } return this; }
...
this.checkBody('optional').optional().len(1, 100).trim().toInt()
this.checkBody('optionalInt').optional().len(1, 100).trim().toInt()
this.checkBody('name').notEmpty().len(3,20);
this.checkBody('empty').empty();
this.checkBody('notBlank').notBlank();
this.checkBody('match').match(/^abc$/i);
this.checkBody('notMatch').notMatch(/^xyz$/i);
this.checkBody('ensure').ensure(true);
this.checkBody('ensureNot').ensureNot(false);
this.checkBody('integer').isInt();
this.checkBody('integer').isInt(null, {min:12});
this.checkBody('integer').isInt(null, {max:12});
this.checkBody('integer').isInt(null, {min:12,max:12});
this.checkBody('stringInteger').isInt();
this.checkBody('stringInteger').isInt(null, {min:12});
...
ensureNot = function (assertion, tip, shouldBail) { if (shouldBail) this.goOn = false; if (this.goOn && !!assertion) { this.addError(tip || this.key + ' failed an assertion.'); } return this; }
...
this.checkBody('optionalInt').optional().len(1, 100).trim().toInt()
this.checkBody('name').notEmpty().len(3,20);
this.checkBody('empty').empty();
this.checkBody('notBlank').notBlank();
this.checkBody('match').match(/^abc$/i);
this.checkBody('notMatch').notMatch(/^xyz$/i);
this.checkBody('ensure').ensure(true);
this.checkBody('ensureNot').ensureNot(false);
this.checkBody('integer').isInt();
this.checkBody('integer').isInt(null, {min:12});
this.checkBody('integer').isInt(null, {max:12});
this.checkBody('integer').isInt(null, {min:12,max:12});
this.checkBody('stringInteger').isInt();
this.checkBody('stringInteger').isInt(null, {min:12});
this.checkBody('stringInteger').isInt(null, {max:12});
...
eq = function (l, tip) { if (this.goOn && this.value != l) { this.addError(tip || this.key + " is must equal " + l + "."); } return this; }
...
if (this.errors) {
this.body = this.errors;
return;
}
});
//json body,we can check it using [json path](https://github.com/flitbit/json-path)(like xpath)
router.post('/json' , function*(){
this.checkBody('/store/book[0]/price').get(0).eq(8.95);
this.checkBody('#/store/book[0]/category').first().trim().eq('reference');
if (this.errors) {
this.body = this.errors;
return;
}
})
...
escape = function () { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.escape(this.value); } return this; }
...
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.rtrim(this.value,c);
}
return this;
};
Validator.prototype.escape = function() {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.escape(this.value);
}
return this;
};
Validator.prototype.stripLow = function(nl) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.stripLow(this.value, nl);
}
...
exist = function (tip) { if (this.goOn && !this.exists) { this.addError(tip || this.key +" should exists!"); } return this; }
...
return this;
};
Validator.prototype.isLength = function(min, max, tip) {
min = min || 0;
tip = 'number' != typeof max ? max : tip;
max = 'number' == typeof max ? max :-1;
this.exist(tip);
if (this.goOn) {
if(this.value.length<min) {
this.addError(tip || this.key + "'s length must equal or great than " + min+".");
return this;
}
if (-1!=max&&this.value.length>max) {
this.addError(tip || this.key + "'s length must equal or less than " + max + ".");
...
filter = function (cb, scope) { if (this.value&&this.value.length>0) { var vs = [] for(var i = 0 ;i<this.value.length;i++) { if(cb.call(scope||this,this.value[i],i,this.key,this.context)){ vs.push(this.value[i]) } } this.value=vs; } return this; }
...
app.router.post('/json',function*(){
this.checkBody('/', true).notEmpty();
this.checkBody('/store/bicycle/color', true).exist()
this.checkBody('/store/book[0]/price', true).get(0).eq(8.95);
this.checkBody('/store/book[0]/price', true).get(0).isFloat().eq(8.95);
this.checkBody('/store/book[0]/disabled', true).first().notEmpty().toBoolean()
this.checkBody('#/store/book[0]/category', true).first().trim().eq('reference');
this.checkBody('/store/book[*]/price', true).filter(function(v,k,o){
return v>10
}).first().gt(10)
if(this.errors) {
// console.log(this.errors)
this.status=500;
}else{
this.status=200;
...
first = function (index) { return this.get(0); }
...
this.body = this.errors;
return;
}
});
//json body,we can check it using [json path](https://github.com/flitbit/json-path)(like xpath)
router.post('/json' , function*(){
this.checkBody('/store/book[0]/price').get(0).eq(8.95);
this.checkBody('#/store/book[0]/category').first().trim().eq('reference
');
if (this.errors) {
this.body = this.errors;
return;
}
})
app.listen(3000);
...
ge = function (l, tip) { if (this.goOn && this.value < l) { this.addError(tip || this.key + " must great than or equal " + l + "."); } return this; }
...
this.checkBody('stringInteger').isInt(null, {min:12,max:12});
this.checkBody('float_').isFloat();
this.checkBody('in').in([1,2]);
this.checkBody('eq').eq("eq");
this.checkBody('neq').neq("eq");
this.checkBody('number4').gt(3);
this.checkBody('number4').lt(5);
this.checkBody('number4').ge(4);
this.checkBody('number4').le(4);
this.checkBody('number4').ge(3);
this.checkBody('number4').le(5);
this.checkBody('contains').contains("tain");
this.checkBody('notContains').notContains(" ");
this.checkBody('email').isEmail();
this.checkBody('url').isUrl();
...
get = function (index) { if (this.value) { this.value = this.value[index||0] } return this; }
...
//resize image
});
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/users', function * () {
this.checkQuery('department').empty().in(["sale","finance"], "not support this department!
x22;).len(3, 20);
this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow();
this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to old!").toInt();
if (this.errors) {
this.body = this.errors;
return;
}
...
gt = function (l, tip) { if (this.goOn && this.value <= l) { this.addError(tip || this.key + " must great than " + l + "."); } return this; }
...
this.body = this.errors;
return;
}
});
router.get('/users', function * () {
this.checkQuery('department').empty().in(["sale","finance"], "not support this department!
x22;).len(3, 20);
this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow();
this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to
old!").toInt();
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/user/:id', function * () {
this.checkParams('id').toInt(0);
...
hasError = function () { return this.context.errors && this.context.errors.length > 0 ? true : false; }
...
}
return this;
};
//Sanitizers
Validator.prototype.default = function(d) {
if(!this.hasError()&&!this.value){
this.value = this.params[this.key] = d;
}
return this;
};
Validator.prototype.toDate = function() {
this.isDate();
if (this.goOn && !this.hasError()) {
...
hash = function (alg , enc) { if (!this.hasError()&&this.value) { enc = enc ||'hex'; this.value = this.params[this.key] =require('crypto').createHash(alg).update(this.value).digest(enc); } return this; }
...
if (!this.hasError()&&this.value) {
enc = enc ||'hex';
this.value = this.params[this.key] =require('crypto').createHash(alg).update(this.value).digest(enc);
}
return this;
};
Validator.prototype.md5 = function() {
this.hash('md5');
return this;
};
Validator.prototype.sha1 = function() {
this.hash('sha1');
return this;
};
Validator.prototype.clone = function(key , value) {
...
in = function (arr, tip) { if (this.goOn && arr) { for(var i = 0 ; i < arr.length ;i++){ if(this.value == arr[i]){ return this; } } this.addError(tip || this.key + " must be in [" + arr.join(',') + "]."); } return this; }
...
});
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/users', function * () {
this.checkQuery('department').empty().in(["sale","finance
x22;], "not support this department!").len(3, 20);
this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow();
this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to old!").toInt();
if (this.errors) {
this.body = this.errors;
return;
}
});
...
isAfter = function (d, tip) { if (this.goOn && (!isString(this.value) ||!v.isAfter(this.value, d))) { this.addError(tip || this.key + " must after " + d + "."); } return this; }
...
if(this.goOn && ! timeReg.test(this.value)){
this.addError(tip || this.key + " is not a time format.");
}
return this;
};
Validator.prototype.isAfter = function(d, tip) {
if (this.goOn && (!isString(this.value) ||!v.isAfter(this.value, d))) {
this.addError(tip || this.key + " must after " + d + ".");
}
return this;
};
Validator.prototype.isBefore = function(d, tip) {
if (this.goOn && (!isString(this.value) ||!v.isBefore(this.value, d))) {
this.addError(tip || this.key + " must before " + d + ".");
...
isAlpha = function (tip, locale) { if (this.goOn && (!isString(this.value) ||!v.isAlpha(this.value,locale))) { this.addError(tip || this.key + " is not an alpha string."); } return this; }
...
Validator.prototype.isIp = function(tip,version) {
if (this.goOn && (!isString(this.value) ||!v.isIP(this.value,version))) {
this.addError(tip || this.key + " is not ip format.");
}
return this;
};
Validator.prototype.isAlpha = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isAlpha(this.value,locale))) {
this.addError(tip || this.key + " is not an alpha string.");
}
return this;
};
Validator.prototype.isNumeric = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isNumeric(this.value))) {
this.addError(tip || this.key + " is not numeric.");
...
isAlphanumeric = function (tip, locale) { if (this.goOn && (!isString(this.value) ||!v.isAlphanumeric(this.value,locale))) { this.addError(tip || this.key + " is not an aphanumeric string."); } return this; }
...
if (this.goOn && (!isString(this.value) ||!v.isNumeric(this.value))) {
this.addError(tip || this.key + " is not numeric.");
}
return this;
};
Validator.prototype.isAlphanumeric = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isAlphanumeric(this.value,locale
))) {
this.addError(tip || this.key + " is not an aphanumeric string.");
}
return this;
};
Validator.prototype.isBase64 = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isBase64(this.value))) {
this.addError(tip || this.key + " is not a base64 string.");
...
isAscii = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isAscii(this.value))) { this.addError(tip || this.key + " is not a ascii string."); } return this; }
...
Validator.prototype.isMultibyte = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isMultibyte(this.value))) {
this.addError(tip || this.key + " is not a multibyte string.");
}
return this;
};
Validator.prototype.isAscii = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isAscii(this.value))) {
this.addError(tip || this.key + " is not a ascii string.");
}
return this;
};
Validator.prototype.isFullWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isFullWidth(this.value))) {
this.addError(tip || this.key + " is not a full width string.");
...
isBase64 = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isBase64(this.value))) { this.addError(tip || this.key + " is not a base64 string."); } return this; }
...
Validator.prototype.isAlphanumeric = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isAlphanumeric(this.value,locale))) {
this.addError(tip || this.key + " is not an aphanumeric string.");
}
return this;
};
Validator.prototype.isBase64 = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isBase64(this.value))) {
this.addError(tip || this.key + " is not a base64 string.");
}
return this;
};
Validator.prototype.isHexadecimal = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHexadecimal(this.value))) {
this.addError(tip || this.key + " is not a hexa decimal string.");
...
isBefore = function (d, tip) { if (this.goOn && (!isString(this.value) ||!v.isBefore(this.value, d))) { this.addError(tip || this.key + " must before " + d + "."); } return this; }
...
Validator.prototype.isAfter = function(d, tip) {
if (this.goOn && (!isString(this.value) ||!v.isAfter(this.value, d))) {
this.addError(tip || this.key + " must after " + d + ".");
}
return this;
};
Validator.prototype.isBefore = function(d, tip) {
if (this.goOn && (!isString(this.value) ||!v.isBefore(this.value, d))) {
this.addError(tip || this.key + " must before " + d + ".");
}
return this;
};
Validator.prototype.isCreditCard = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isCreditCard(this.value))) {
this.addError(tip || this.key + " is not credit card format.");
...
isByteLength = function (min, max, charset, tip) { min = min || 0; max = max || Number.MAX_VALUE; charset = charset||'utf8'; this.notEmpty(tip); if (this.goOn) { var bl = Buffer.byteLength(this.value , charset); tip = 'number' != typeof max ? max : tip; if (bl<min || bl>max) { this.addError(tip || this.key + "'s byte lenth great than " + min +" and less than " + max + "." ); } } return this; }
...
this.checkBody('color3').isHexColor();
this.checkBody('color4').isHexColor();
this.checkBody('low').isLowercase();
this.checkBody('up').isUppercase();
this.checkBody('div').isDivisibleBy(3);
this.checkBody('n').isNull();
this.checkBody('len').isLength(1,4);
this.checkBody('byteLenght').isByteLength(4,6);
this.checkBody('uuid').isUUID();
this.checkBody('date').isDate();
this.checkBody('time').isTime();
this.checkBody('after').isAfter("2014-08-06");
this.checkBody('before').isBefore("2014-08-08");
this.checkBody('in').isIn();
this.checkBody('credit').isCreditCard();
...
isCreditCard = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isCreditCard(this.value))) { this.addError(tip || this.key + " is not credit card format."); } return this; }
...
Validator.prototype.isBefore = function(d, tip) {
if (this.goOn && (!isString(this.value) ||!v.isBefore(this.value, d))) {
this.addError(tip || this.key + " must before " + d + ".");
}
return this;
};
Validator.prototype.isCreditCard = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isCreditCard(this.value))) {
this.addError(tip || this.key + " is not credit card format.");
}
return this;
};
Validator.prototype.isISBN = function(tip,version) {
if (this.goOn && (!isString(this.value) ||!v.isISBN(this.value,version))) {
this.addError(tip || this.key + " is not a ISBN format.");
...
isCurrency = function (tip, options) { if (this.goOn && (!isString(this.value) ||!v.isCurrency(this.value,options))) { this.addError(tip || this.key + " is not a currency format."); } return this; }
...
Validator.prototype.isSurrogatePair = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isSurrogatePair(this.value))) {
this.addError(tip || this.key + " is not a surrogate pair string.");
}
return this;
};
Validator.prototype.isCurrency = function(tip,options) {
if (this.goOn && (!isString(this.value) ||!v.isCurrency(this.value,options
))) {
this.addError(tip || this.key + " is not a currency format.");
}
return this;
};
Validator.prototype.isDataURI = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isDataURI(this.value))) {
this.addError(tip || this.key + " is not a data uri format.");
...
isDataURI = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isDataURI(this.value))) { this.addError(tip || this.key + " is not a data uri format."); } return this; }
...
Validator.prototype.isCurrency = function(tip,options) {
if (this.goOn && (!isString(this.value) ||!v.isCurrency(this.value,options))) {
this.addError(tip || this.key + " is not a currency format.");
}
return this;
};
Validator.prototype.isDataURI = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isDataURI(this.value))) {
this.addError(tip || this.key + " is not a data uri format.");
}
return this;
};
Validator.prototype.isMobilePhone = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isMobilePhone(this.value,locale))) {
this.addError(tip || this.key + " is not a mobile phone format.");
...
isDate = function (tip) { if (this.goOn && !util.isDate(this.value) && (!isString(this.value) ||!v.isDate(this.value))) { this.addError(tip || this.key + " is not a date format."); } return this; }
...
Validator.prototype.isUUID = function(tip,ver) {
if (this.goOn && (!isString(this.value) ||!v.isUUID(this.value,ver))) {
this.addError(tip || this.key + " is not a UUID format.");
}
return this;
};
Validator.prototype.isDate = function(tip) {
if (this.goOn && !util.isDate(this.value) && (!isString(this.value
) ||!v.isDate(this.value))) {
this.addError(tip || this.key + " is not a date format.");
}
return this;
};
Validator.prototype.isTime = function(tip) {
var timeReg = /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/;
if(this.goOn && ! timeReg.test(this.value)){
...
isDivisibleBy = function (n, tip) { if (this.goOn && (!isString(this.value) ||!v.isDivisibleBy(this.value, n))) { this.addError(tip || this.key + " can not divide by" + n + "."); } return this; }
...
Validator.prototype.isUppercase = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isUppercase(this.value))) {
this.addError(tip || this.key + " is not a upper case string.");
}
return this;
};
Validator.prototype.isDivisibleBy = function(n, tip) {
if (this.goOn && (!isString(this.value) ||!v.isDivisibleBy(this.value, n))) {
this.addError(tip || this.key + " can not divide by" + n + ".");
}
return this;
};
Validator.prototype.isNull = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isNull(this.value))) {
this.addError(tip || this.key + " is not null.");
...
isEmail = function (tip, options) { if (this.goOn && (!isString(this.value) ||!v.isEmail(this.value,options))) { this.addError(tip || this.key + " is not email format."); } return this; }
...
require('koa-validate')(app);
app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
//resize image
...
isFQDN = function (tip, options) { if (this.goOn && (!isString(this.value) ||!v.isFQDN(this.value,options))) { this.addError(tip || this.key + " is not a fully qualified domain name format."); } return this; }
...
Validator.prototype.isISIN = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isISIN(this.value))) {
this.addError(tip || this.key + " is not a ISIN format.");
}
return this;
};
Validator.prototype.isFQDN = function(tip,options) {
if (this.goOn && (!isString(this.value) ||!v.isFQDN(this.value,options))) {
this.addError(tip || this.key + " is not a fully qualified domain name format.");
}
return this;
};
//Sanitizers
...
isFloat = function (tip, options) { if (this.goOn && !v.isFloat(String(this.value), options)) { this.addError(tip || this.key + " is not float."); } return this; }
...
Validator.prototype.isInt = function(tip, options) {
if (this.goOn&& !v.isInt(String(this.value), options)) {
this.addError(tip || this.key + " is not integer.");
}
return this;
};
Validator.prototype.isFloat = function(tip,options) {
if (this.goOn && !v.isFloat(String(this.value), options)) {
this.addError(tip || this.key + " is not float.");
}
return this;
};
Validator.prototype.isLength = function(min, max, tip) {
min = min || 0;
...
isFullWidth = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isFullWidth(this.value))) { this.addError(tip || this.key + " is not a full width string."); } return this; }
...
Validator.prototype.isAscii = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isAscii(this.value))) {
this.addError(tip || this.key + " is not a ascii string.");
}
return this;
};
Validator.prototype.isFullWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isFullWidth(this.value))) {
this.addError(tip || this.key + " is not a full width string.");
}
return this;
};
Validator.prototype.isHalfWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHalfWidth(this.value))) {
this.addError(tip || this.key + " is not a half width string.");
...
isHalfWidth = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isHalfWidth(this.value))) { this.addError(tip || this.key + " is not a half width string."); } return this; }
...
Validator.prototype.isFullWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isFullWidth(this.value))) {
this.addError(tip || this.key + " is not a full width string.");
}
return this;
};
Validator.prototype.isHalfWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHalfWidth(this.value))) {
this.addError(tip || this.key + " is not a half width string.");
}
return this;
};
Validator.prototype.isVariableWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isVariableWidth(this.value))) {
this.addError(tip || this.key + " is not a variable width string.");
...
isHexColor = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isHexColor(this.value))) { this.addError(tip || this.key + " is not hex color format."); } return this; }
...
Validator.prototype.isHexadecimal = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHexadecimal(this.value))) {
this.addError(tip || this.key + " is not a hexa decimal string.");
}
return this;
};
Validator.prototype.isHexColor = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHexColor(this.value))) {
this.addError(tip || this.key + " is not hex color format.");
}
return this;
};
Validator.prototype.isLowercase = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isLowercase(this.value))) {
this.addError(tip || this.key + " is not a lowwer case string");
...
isHexadecimal = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isHexadecimal(this.value))) { this.addError(tip || this.key + " is not a hexa decimal string."); } return this; }
...
Validator.prototype.isBase64 = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isBase64(this.value))) {
this.addError(tip || this.key + " is not a base64 string.");
}
return this;
};
Validator.prototype.isHexadecimal = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHexadecimal(this.value))) {
this.addError(tip || this.key + " is not a hexa decimal string.");
}
return this;
};
Validator.prototype.isHexColor = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHexColor(this.value))) {
this.addError(tip || this.key + " is not hex color format.");
...
isISBN = function (tip, version) { if (this.goOn && (!isString(this.value) ||!v.isISBN(this.value,version))) { this.addError(tip || this.key + " is not a ISBN format."); } return this; }
...
Validator.prototype.isCreditCard = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isCreditCard(this.value))) {
this.addError(tip || this.key + " is not credit card format.");
}
return this;
};
Validator.prototype.isISBN = function(tip,version) {
if (this.goOn && (!isString(this.value) ||!v.isISBN(this.value,version))) {
this.addError(tip || this.key + " is not a ISBN format.");
}
return this;
};
Validator.prototype.isJSON = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isJSON(this.value))) {
this.addError(tip || this.key + " is not a json format.");
...
isISIN = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isISIN(this.value))) { this.addError(tip || this.key + " is not a ISIN format."); } return this; }
...
if (this.goOn && (!isString(this.value) ||!v.isMACAddress(this.value))) {
this.addError(tip || this.key + " is not a MAC address format.");
}
return this;
};
Validator.prototype.isISIN = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isISIN(this.value))) {
this.addError(tip || this.key + " is not a ISIN format.");
}
return this;
};
Validator.prototype.isFQDN = function(tip,options) {
if (this.goOn && (!isString(this.value) ||!v.isFQDN(this.value,options))) {
this.addError(tip || this.key + " is not a fully qualified domain name format.");
...
isISO8601 = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isISO8601(this.value))) { this.addError(tip || this.key + " is not a ISO8601 string format."); } return this; }
...
Validator.prototype.isMobilePhone = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isMobilePhone(this.value,locale))) {
this.addError(tip || this.key + " is not a mobile phone format.");
}
return this;
};
Validator.prototype.isISO8601 = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isISO8601(this.value))) {
this.addError(tip || this.key + " is not a ISO8601 string format.");
}
return this;
};
Validator.prototype.isMACAddress = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isMACAddress(this.value))) {
this.addError(tip || this.key + " is not a MAC address format.");
...
isIn = function (arr, tip) { if (this.goOn && arr) { for(var i = 0 ; i < arr.length ;i++){ if(this.value == arr[i]){ return this; } } this.addError(tip || this.key + " must be in [" + arr.join(',') + "]."); } return this; }
...
this.checkBody('len').isLength(1,4);
this.checkBody('byteLenght').isByteLength(4,6);
this.checkBody('uuid').isUUID();
this.checkBody('date').isDate();
this.checkBody('time').isTime();
this.checkBody('after').isAfter("2014-08-06");
this.checkBody('before').isBefore("2014-08-08");
this.checkBody('in').isIn();
this.checkBody('credit').isCreditCard();
this.checkBody('isbn').isISBN();
this.checkBody('json').isJSON();
this.checkBody('mb').isMultibyte();
this.checkBody('ascii').isAscii();
this.checkBody('fw').isFullWidth();
this.checkBody('hw').isHalfWidth();
...
isInt = function (tip, options) { if (this.goOn&& !v.isInt(String(this.value), options)) { this.addError(tip || this.key + " is not integer."); } return this; }
...
if (this.goOn && !assertion) {
this.addError(tip || this.key + ' failed an assertion.');
}
return this;
};
Validator.prototype.isInt = function(tip, options) {
if (this.goOn&& !v.isInt(String(this.value), options)) {
this.addError(tip || this.key + " is not integer.");
}
return this;
};
Validator.prototype.isFloat = function(tip,options) {
if (this.goOn && !v.isFloat(String(this.value), options)) {
this.addError(tip || this.key + " is not float.");
...
isIp = function (tip, version) { if (this.goOn && (!isString(this.value) ||!v.isIP(this.value,version))) { this.addError(tip || this.key + " is not ip format."); } return this; }
...
this.checkBody('number4').le(4);
this.checkBody('number4').ge(3);
this.checkBody('number4').le(5);
this.checkBody('contains').contains("tain");
this.checkBody('notContains').notContains(" ");
this.checkBody('email').isEmail();
this.checkBody('url').isUrl();
this.checkBody('ip').isIp();
this.checkBody('alpha').isAlpha();
this.checkBody('numeric').isNumeric();
this.checkBody('an').isAlphanumeric();
this.checkBody('base64').isBase64();
this.checkBody('hex').isHexadecimal();
this.checkBody('color1').isHexColor();
this.checkBody('color2').isHexColor();
...
isJSON = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isJSON(this.value))) { this.addError(tip || this.key + " is not a json format."); } return this; }
...
Validator.prototype.isISBN = function(tip,version) {
if (this.goOn && (!isString(this.value) ||!v.isISBN(this.value,version))) {
this.addError(tip || this.key + " is not a ISBN format.");
}
return this;
};
Validator.prototype.isJSON = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isJSON(this.value))) {
this.addError(tip || this.key + " is not a json format.");
}
return this;
};
Validator.prototype.isMultibyte = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isMultibyte(this.value))) {
...
isLength = function (min, max, tip) { min = min || 0; tip = 'number' != typeof max ? max : tip; max = 'number' == typeof max ? max :-1; this.exist(tip); if (this.goOn) { if(this.value.length<min) { this.addError(tip || this.key + "'s length must equal or great than " + min+"."); return this; } if (-1!=max&&this.value.length>max) { this.addError(tip || this.key + "'s length must equal or less than " + max + "."); return this; } } return this; }
...
this.checkBody('color2').isHexColor();
this.checkBody('color3').isHexColor();
this.checkBody('color4').isHexColor();
this.checkBody('low').isLowercase();
this.checkBody('up').isUppercase();
this.checkBody('div').isDivisibleBy(3);
this.checkBody('n').isNull();
this.checkBody('len').isLength(1,4);
this.checkBody('byteLenght').isByteLength(4,6);
this.checkBody('uuid').isUUID();
this.checkBody('date').isDate();
this.checkBody('time').isTime();
this.checkBody('after').isAfter("2014-08-06");
this.checkBody('before').isBefore("2014-08-08");
this.checkBody('in').isIn();
...
isLowercase = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isLowercase(this.value))) { this.addError(tip || this.key + " is not a lowwer case string"); } return this; }
...
Validator.prototype.isHexColor = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHexColor(this.value))) {
this.addError(tip || this.key + " is not hex color format.");
}
return this;
};
Validator.prototype.isLowercase = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isLowercase(this.value))) {
this.addError(tip || this.key + " is not a lowwer case string");
}
return this;
};
Validator.prototype.isUppercase = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isUppercase(this.value))) {
this.addError(tip || this.key + " is not a upper case string.");
...
isMACAddress = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isMACAddress(this.value))) { this.addError(tip || this.key + " is not a MAC address format."); } return this; }
...
Validator.prototype.isISO8601 = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isISO8601(this.value))) {
this.addError(tip || this.key + " is not a ISO8601 string format.");
}
return this;
};
Validator.prototype.isMACAddress = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isMACAddress(this.value))) {
this.addError(tip || this.key + " is not a MAC address format.");
}
return this;
};
Validator.prototype.isISIN = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isISIN(this.value))) {
...
isMobilePhone = function (tip, locale) { if (this.goOn && (!isString(this.value) ||!v.isMobilePhone(this.value,locale))) { this.addError(tip || this.key + " is not a mobile phone format."); } return this; }
...
Validator.prototype.isDataURI = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isDataURI(this.value))) {
this.addError(tip || this.key + " is not a data uri format.");
}
return this;
};
Validator.prototype.isMobilePhone = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isMobilePhone(this.value,locale
))) {
this.addError(tip || this.key + " is not a mobile phone format.");
}
return this;
};
Validator.prototype.isISO8601 = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isISO8601(this.value))) {
this.addError(tip || this.key + " is not a ISO8601 string format.");
...
isMultibyte = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isMultibyte(this.value))) { this.addError(tip || this.key + " is not a multibyte string."); } return this; }
...
if (this.goOn && (!isString(this.value) ||!v.isJSON(this.value))) {
this.addError(tip || this.key + " is not a json format.");
}
return this;
};
Validator.prototype.isMultibyte = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isMultibyte(this.value))) {
this.addError(tip || this.key + " is not a multibyte string.");
}
return this;
};
Validator.prototype.isAscii = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isAscii(this.value))) {
this.addError(tip || this.key + " is not a ascii string.");
...
isNull = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isNull(this.value))) { this.addError(tip || this.key + " is not null."); } return this; }
...
Validator.prototype.isDivisibleBy = function(n, tip) {
if (this.goOn && (!isString(this.value) ||!v.isDivisibleBy(this.value, n))) {
this.addError(tip || this.key + " can not divide by" + n + ".");
}
return this;
};
Validator.prototype.isNull = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isNull(this.value))) {
this.addError(tip || this.key + " is not null.");
}
return this;
};
Validator.prototype.isByteLength = function(min, max,charset,tip) {
min = min || 0;
max = max || Number.MAX_VALUE;
...
isNumeric = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isNumeric(this.value))) { this.addError(tip || this.key + " is not numeric."); } return this; }
...
Validator.prototype.isAlpha = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isAlpha(this.value,locale))) {
this.addError(tip || this.key + " is not an alpha string.");
}
return this;
};
Validator.prototype.isNumeric = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isNumeric(this.value))) {
this.addError(tip || this.key + " is not numeric.");
}
return this;
};
Validator.prototype.isAlphanumeric = function(tip,locale) {
if (this.goOn && (!isString(this.value) ||!v.isAlphanumeric(this.value,locale))) {
...
isSurrogatePair = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isSurrogatePair(this.value))) { this.addError(tip || this.key + " is not a surrogate pair string."); } return this; }
...
Validator.prototype.isVariableWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isVariableWidth(this.value))) {
this.addError(tip || this.key + " is not a variable width string.");
}
return this;
};
Validator.prototype.isSurrogatePair = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isSurrogatePair(this.value))) {
this.addError(tip || this.key + " is not a surrogate pair string.");
}
return this;
};
Validator.prototype.isCurrency = function(tip,options) {
if (this.goOn && (!isString(this.value) ||!v.isCurrency(this.value,options))) {
this.addError(tip || this.key + " is not a currency format.");
...
isTime = function (tip) { var timeReg = /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/; if(this.goOn && ! timeReg.test(this.value)){ this.addError(tip || this.key + " is not a time format."); } return this; }
...
this.checkBody('up').isUppercase();
this.checkBody('div').isDivisibleBy(3);
this.checkBody('n').isNull();
this.checkBody('len').isLength(1,4);
this.checkBody('byteLenght').isByteLength(4,6);
this.checkBody('uuid').isUUID();
this.checkBody('date').isDate();
this.checkBody('time').isTime();
this.checkBody('after').isAfter("2014-08-06");
this.checkBody('before').isBefore("2014-08-08");
this.checkBody('in').isIn();
this.checkBody('credit').isCreditCard();
this.checkBody('isbn').isISBN();
this.checkBody('json').isJSON();
this.checkBody('mb').isMultibyte();
...
isUUID = function (tip, ver) { if (this.goOn && (!isString(this.value) ||!v.isUUID(this.value,ver))) { this.addError(tip || this.key + " is not a UUID format."); } return this; }
...
this.addError(tip || this.key + "'s byte lenth great than " + min +" and less than " + max + ".
x22; );
}
}
return this;
};
Validator.prototype.byteLength = Validator.prototype.isByteLength;
Validator.prototype.isUUID = function(tip,ver) {
if (this.goOn && (!isString(this.value) ||!v.isUUID(this.value,ver))) {
this.addError(tip || this.key + " is not a UUID format.");
}
return this;
};
Validator.prototype.isDate = function(tip) {
if (this.goOn && !util.isDate(this.value) && (!isString(this.value) ||!v.isDate(this.value))) {
this.addError(tip || this.key + " is not a date format.");
...
isUppercase = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isUppercase(this.value))) { this.addError(tip || this.key + " is not a upper case string."); } return this; }
...
Validator.prototype.isLowercase = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isLowercase(this.value))) {
this.addError(tip || this.key + " is not a lowwer case string");
}
return this;
};
Validator.prototype.isUppercase = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isUppercase(this.value))) {
this.addError(tip || this.key + " is not a upper case string.");
}
return this;
};
Validator.prototype.isDivisibleBy = function(n, tip) {
if (this.goOn && (!isString(this.value) ||!v.isDivisibleBy(this.value, n))) {
this.addError(tip || this.key + " can not divide by" + n + ".");
...
isUrl = function (tip, options) { if (this.goOn && (!isString(this.value) ||!v.isURL(this.value,options))) { this.addError(tip || this.key + " is not url format."); } return this; }
...
this.checkBody('number4').ge(4);
this.checkBody('number4').le(4);
this.checkBody('number4').ge(3);
this.checkBody('number4').le(5);
this.checkBody('contains').contains("tain");
this.checkBody('notContains').notContains(" ");
this.checkBody('email').isEmail();
this.checkBody('url').isUrl();
this.checkBody('ip').isIp();
this.checkBody('alpha').isAlpha();
this.checkBody('numeric').isNumeric();
this.checkBody('an').isAlphanumeric();
this.checkBody('base64').isBase64();
this.checkBody('hex').isHexadecimal();
this.checkBody('color1').isHexColor();
...
isVariableWidth = function (tip) { if (this.goOn && (!isString(this.value) ||!v.isVariableWidth(this.value))) { this.addError(tip || this.key + " is not a variable width string."); } return this; }
...
Validator.prototype.isHalfWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isHalfWidth(this.value))) {
this.addError(tip || this.key + " is not a half width string.");
}
return this;
};
Validator.prototype.isVariableWidth = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isVariableWidth(this.value))) {
this.addError(tip || this.key + " is not a variable width string.");
}
return this;
};
Validator.prototype.isSurrogatePair = function(tip) {
if (this.goOn && (!isString(this.value) ||!v.isSurrogatePair(this.value))) {
this.addError(tip || this.key + " is not a surrogate pair string.");
...
le = function (l, tip) { if (this.goOn && this.value > l) { this.addError(tip || this.key + " must less than or equal " + l + "."); } return this; }
...
this.checkBody('float_').isFloat();
this.checkBody('in').in([1,2]);
this.checkBody('eq').eq("eq");
this.checkBody('neq').neq("eq");
this.checkBody('number4').gt(3);
this.checkBody('number4').lt(5);
this.checkBody('number4').ge(4);
this.checkBody('number4').le(4);
this.checkBody('number4').ge(3);
this.checkBody('number4').le(5);
this.checkBody('contains').contains("tain");
this.checkBody('notContains').notContains(" ");
this.checkBody('email').isEmail();
this.checkBody('url').isUrl();
this.checkBody('ip').isIp();
...
len = function (min, max, tip) { min = min || 0; tip = 'number' != typeof max ? max : tip; max = 'number' == typeof max ? max :-1; this.exist(tip); if (this.goOn) { if(this.value.length<min) { this.addError(tip || this.key + "'s length must equal or great than " + min+"."); return this; } if (-1!=max&&this.value.length>max) { this.addError(tip || this.key + "'s length must equal or less than " + max + "."); return this; } } return this; }
...
var router = require('koa-router')();
require('koa-validate')(app);
app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?"
;);
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
...
lt = function (l, tip) { if (this.goOn && this.value >= l) { this.addError(tip || this.key + " must less than " + l + "."); } return this; }
...
this.body = this.errors;
return;
}
});
router.get('/users', function * () {
this.checkQuery('department').empty().in(["sale","finance"], "not support this department!
x22;).len(3, 20);
this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow();
this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to
old!").toInt();
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/user/:id', function * () {
this.checkParams('id').toInt(0);
...
ltrim = function (c) { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.ltrim(this.value,c); } return this; }
...
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.trim(this.value,c);
}
return this;
};
Validator.prototype.ltrim = function(c) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.ltrim(this.value,c);
}
return this;
};
Validator.prototype.rtrim = function(c) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.rtrim(this.value,c);
}
...
match = function (reg, tip) { if (this.goOn && !reg.test(this.value)) { this.addError(tip || this.key + " is bad format."); } return this; }
...
app.router.post('/validate',function*(){
this.checkBody('optional').optional().len(3,20);
this.checkBody('optional').optional().len(1, 100).trim().toInt()
this.checkBody('optionalInt').optional().len(1, 100).trim().toInt()
this.checkBody('name').notEmpty().len(3,20);
this.checkBody('empty').empty();
this.checkBody('notBlank').notBlank();
this.checkBody('match').match(/^abc$/i);
this.checkBody('notMatch').notMatch(/^xyz$/i);
this.checkBody('ensure').ensure(true);
this.checkBody('ensureNot').ensureNot(false);
this.checkBody('integer').isInt();
this.checkBody('integer').isInt(null, {min:12});
this.checkBody('integer').isInt(null, {max:12});
this.checkBody('integer').isInt(null, {min:12,max:12});
...
md5 = function () { this.hash('md5'); return this; }
...
app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
//resize image
});
...
neq = function (l, tip) { if (this.goOn && this.value == l) { this.addError(tip || this.key + " is must not equal " + l + "."); } return this; }
...
this.checkBody('stringInteger').isInt();
this.checkBody('stringInteger').isInt(null, {min:12});
this.checkBody('stringInteger').isInt(null, {max:12});
this.checkBody('stringInteger').isInt(null, {min:12,max:12});
this.checkBody('float_').isFloat();
this.checkBody('in').in([1,2]);
this.checkBody('eq').eq("eq");
this.checkBody('neq').neq("eq");
this.checkBody('number4').gt(3);
this.checkBody('number4').lt(5);
this.checkBody('number4').ge(4);
this.checkBody('number4').le(4);
this.checkBody('number4').ge(3);
this.checkBody('number4').le(5);
this.checkBody('contains').contains("tain");
...
notBlank = function (tip) { if (this.goOn && (null==this.value||'undefined'==typeof(this.value) || ('string' == typeof(this.value) &&(/^\s*$/gi).test(this. value)))) { this.addError(tip || this.key + " can not be blank."); } return this; }
...
var app = appFactory.create(1);
app.router.post('/validate',function*(){
this.checkBody('optional').optional().len(3,20);
this.checkBody('optional').optional().len(1, 100).trim().toInt()
this.checkBody('optionalInt').optional().len(1, 100).trim().toInt()
this.checkBody('name').notEmpty().len(3,20);
this.checkBody('empty').empty();
this.checkBody('notBlank').notBlank();
this.checkBody('match').match(/^abc$/i);
this.checkBody('notMatch').notMatch(/^xyz$/i);
this.checkBody('ensure').ensure(true);
this.checkBody('ensureNot').ensureNot(false);
this.checkBody('integer').isInt();
this.checkBody('integer').isInt(null, {min:12});
this.checkBody('integer').isInt(null, {max:12});
...
notContains = function (s, tip) { if (this.goOn && (!isString(this.value) ||v.contains(this.value,s))) { this.addError(tip || this.key + " is must not contain " + s + "."); } return this; }
...
this.checkBody('number4').gt(3);
this.checkBody('number4').lt(5);
this.checkBody('number4').ge(4);
this.checkBody('number4').le(4);
this.checkBody('number4').ge(3);
this.checkBody('number4').le(5);
this.checkBody('contains').contains("tain");
this.checkBody('notContains').notContains(" ");
this.checkBody('email').isEmail();
this.checkBody('url').isUrl();
this.checkBody('ip').isIp();
this.checkBody('alpha').isAlpha();
this.checkBody('numeric').isNumeric();
this.checkBody('an').isAlphanumeric();
this.checkBody('base64').isBase64();
...
notEmpty = function (tip) { if (this.goOn && (null==this.value||'undefined'==typeof(this.value) || ('string' == typeof(this.value) &&!this.value))) { this.addError(tip || this.key + " can not be empty."); } return this; }
...
app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
//resize image
});
...
notMatch = function (reg, tip) { if (this.goOn && reg.test(this.value)) { this.addError(tip || this.key + ' is bad format.'); } return this; }
...
this.checkBody('optional').optional().len(3,20);
this.checkBody('optional').optional().len(1, 100).trim().toInt()
this.checkBody('optionalInt').optional().len(1, 100).trim().toInt()
this.checkBody('name').notEmpty().len(3,20);
this.checkBody('empty').empty();
this.checkBody('notBlank').notBlank();
this.checkBody('match').match(/^abc$/i);
this.checkBody('notMatch').notMatch(/^xyz$/i);
this.checkBody('ensure').ensure(true);
this.checkBody('ensureNot').ensureNot(false);
this.checkBody('integer').isInt();
this.checkBody('integer').isInt(null, {min:12});
this.checkBody('integer').isInt(null, {max:12});
this.checkBody('integer').isInt(null, {min:12,max:12});
this.checkBody('stringInteger').isInt();
...
optional = function () { if (!this.exists) { this.goOn = false; } return this; }
...
var router = require('koa-router')();
require('koa-validate')(app);
app.use(require('koa-body')({multipart:true , formidable:{keepExtensions:true}}));
app.use(router.routes()).use(router.allowedMethods());
router.post('/signup', function * () {
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?"
;);
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
...
replace = function (a, b) { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = this.value.replace(a,b); } return this; }
...
this.addError(tip||'bad uri to decode.');
}
}
return this;
};
Validator.prototype.replace = function(a,b) {
if (this.goOn && !this.hasError()&&this.value) {
this.value = this.params[this.key] = this.value.replace(a,b);
}
return this;
};
Validator.prototype.encodeBase64 = function() {
if (this.goOn && !this.hasError()&&this.value) {
this.value = this.params[this.key] = new Buffer(this.value).toString('base64');
}
...
rtrim = function (c) { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.rtrim(this.value,c); } return this; }
...
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.ltrim(this.value,c);
}
return this;
};
Validator.prototype.rtrim = function(c) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.rtrim(this.value,c);
}
return this;
};
Validator.prototype.escape = function() {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.escape(this.value);
}
...
sha1 = function () { this.hash('sha1'); return this; }
...
this.checkBody('encodeURIComponent').decodeURIComponent();
this.checkBody('decodeURIComponent').encodeURIComponent();
this.checkBody('rep').replace(',' ,'');
this.checkBody('base64').clone('base64Buffer').decodeBase64(true);
this.checkBody('base64').decodeBase64();
this.checkBody('debase64').encodeBase64();
this.checkBody('hash').clone('md5').md5();
this.checkBody('hash').clone('sha1').sha1();
this.checkBody('hash').clone('num1' ,1);
this.checkBody('json').toJson();
//console.log(this.request.body)
if(this.errors){
this.body = this.errors;
return;
}
...
stripLow = function (nl) { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.stripLow(this.value, nl); } return this; }
...
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.escape(this.value);
}
return this;
};
Validator.prototype.stripLow = function(nl) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.stripLow(this.value, nl);
}
return this;
};
Validator.prototype.whitelist = function(s) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.whitelist(this.value,s);
}
...
toBoolean = function () { if (this.goOn && !this.hasError()) { if('boolean' == typeof(this.value)) { return this; } if('string' == typeof(this.value)){ this.value = this.params[this.key] = v.toBoolean(this.value); } } return this; }
...
Validator.prototype.toUp = Validator.prototype.toUppercase;
Validator.prototype.toBoolean = function() {
if (this.goOn && !this.hasError()) {
if('boolean' == typeof(this.value)) {
return this;
}
if('string' == typeof(this.value)){
this.value = this.params[this.key] = v.toBoolean(this.value);
}
}
return this;
};
Validator.prototype.trim = function(c) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.trim(this.value,c);
...
toDate = function () { this.isDate(); if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.toDate(this.value); } return this; }
...
this.value = this.params[this.key] = d;
}
return this;
};
Validator.prototype.toDate = function() {
this.isDate();
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.toDate(this.value);
}
return this;
};
Validator.prototype.toInt = function(tip, radix, options) {
this.isInt(tip, options);
if (this.goOn && !this.hasError()) {
if('number' == typeof(this.value)) {
...
toFloat = function (tip) { this.isFloat(tip); if (this.goOn && !this.hasError()) { if('number' == typeof(this.value)) { return this; } this.value = this.params[this.key] = v.toFloat(this.value); } return this; }
...
};
Validator.prototype.toFloat = function(tip) {
this.isFloat(tip);
if (this.goOn && !this.hasError()) {
if('number' == typeof(this.value)) {
return this;
}
this.value = this.params[this.key] = v.toFloat(this.value);
}
return this;
};
Validator.prototype.toJson = function(tip) {
if (this.goOn && !this.hasError()) {
try{
if('object' == typeof(this.value)) {
...
toInt = function (tip, radix, options) { this.isInt(tip, options); if (this.goOn && !this.hasError()) { if('number' == typeof(this.value)) { return this; } this.value = this.params[this.key] = v.toInt(this.value, radix); } return this; }
...
//optional() means this param may not in the params.
this.checkBody('name').optional().len(2, 20,"are you kidding me?");
this.checkBody('email').isEmail("your enter a bad email.");
this.checkBody('password').notEmpty().len(3, 20).md5();
//empty() mean this param can be a empty string.
this.checkBody('nick').optional().empty().len(3, 20);
//also we can get the sanitized value
var age = this.checkBody('age').toInt().value;
yield this.checkFile('icon').notEmpty().size(0,300*1024,'file too large').move("/static/icon/" ,
function*(file,context){
//resize image
});
if (this.errors) {
this.body = this.errors;
return;
}
...
toJson = function (tip) { if (this.goOn && !this.hasError()) { try{ if('object' == typeof(this.value)) { return this; } this.value = this.params[this.key] = JSON.parse(this.value); }catch(e){ this.addError(tip||'not json format'); } } return this; }
...
this.checkBody('rep').replace(',' ,'');
this.checkBody('base64').clone('base64Buffer').decodeBase64(true);
this.checkBody('base64').decodeBase64();
this.checkBody('debase64').encodeBase64();
this.checkBody('hash').clone('md5').md5();
this.checkBody('hash').clone('sha1').sha1();
this.checkBody('hash').clone('num1' ,1);
this.checkBody('json').toJson();
//console.log(this.request.body)
if(this.errors){
this.body = this.errors;
return;
}
var body = this.request.body;
if('default' != body.default){
...
toLow = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = this.value.toLowerCase(); } return this; }
...
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/users', function * () {
this.checkQuery('department').empty().in(["sale","finance"], "not support this department!
x22;).len(3, 20);
this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow();
this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to old!").toInt();
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/user/:id', function * () {
...
toLowercase = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = this.value.toLowerCase(); } return this; }
n/a
toUp = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = this.value.toUpperCase(); } return this; }
...
this.checkBody('float_').toFloat();
this.checkBody('bool').toBoolean();
this.checkBody('falseValue').notEmpty('value is empty').toBoolean();
this.checkBody('date').toDate();
this.checkBody('trim').trim();
this.checkBody('ltrim').ltrim();
this.checkBody('rtrim').rtrim();
this.checkBody('up').toUp();
this.checkBody('low').toLow();
this.checkBody('escape').escape();
this.checkBody('stripLow').stripLow();
this.checkBody('whitelist').whitelist('ll');
this.checkBody('blacklist').blacklist('ll');
this.checkBody('encodeURI').decodeURI();
this.checkBody('decodeURI').encodeURI();
...
toUppercase = function () { if (this.goOn && !this.hasError()&&this.value) { this.value = this.params[this.key] = this.value.toUpperCase(); } return this; }
n/a
trim = function (c) { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.trim(this.value,c); } return this; }
...
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/users', function * () {
this.checkQuery('department').empty().in(["sale","finance"], "not support this department!
x22;).len(3, 20);
this.checkQuery('name').empty().len(2,20,"bad name.").trim().toLow
();
this.checkQuery('age').empty().gt(10,"too young!").lt(30,"to old!").toInt();
if (this.errors) {
this.body = this.errors;
return;
}
});
router.get('/user/:id', function * () {
...
type = function (t, tip) { if(this.value){ if('boolean'==t || 'string'==t|| 'number' == t || 'object' == t || 'undefined' ==t){ if(t!=typeof(this.value)) this.addError(tip|| this.key+" is not "+t+""); }else if ('array' == t){ if(!util.isArray(this.value)) this.addError(tip|| this.key+" is not array"); }else if ('date' == t){ if(!util.isDate(this.value)) this.addError(tip|| this.key+" is not date."); }else if ('null' == t){ if(!util.isNull(this.value)) this.addError(tip|| this.key+" is not null."); }else if ('nullorundefined' == t.toLowerCase()){ if(!util.isNullOrUndefined(this.value)) this.addError(tip|| this.key+" is not primitive type."); }else if ('primitive' == t){ if(!util.isPrimitive(this.value)) this.addError(tip|| this.key+" is not primitive type."); }else{ console.warn("not support this type check,type:'"+t+"'") } } return this; }
...
});
describe('koa-validate type' , function(){
it("type check" , function(done){
var app = appFactory.create(1);
app.router.post('/json',function*(){
this.checkBody('/', true).notEmpty();
this.checkBody('/store/book[0]/price', true).get(0).type('number
x27;).type("primitive")
this.checkBody('/store/book[0]/price', true).get(0).type('hello') // should warn
this.checkBody('#/store/book[0]/category', true).first().type('string');
this.checkBody('/store/book[*]/price', true).type('array')
this.checkBody('/store/book[0]/publishDate', true).get(0).toDate().type('date').type('object')
if(this.errors) {
this.status=500;
}else{
...
whitelist = function (s) { if (this.goOn && !this.hasError()) { this.value = this.params[this.key] = v.whitelist(this.value,s); } return this; }
...
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.stripLow(this.value, nl);
}
return this;
};
Validator.prototype.whitelist = function(s) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.whitelist(this.value,s);
}
return this;
};
Validator.prototype.blacklist = function(s) {
if (this.goOn && !this.hasError()) {
this.value = this.params[this.key] = v.blacklist(this.value,s);
}
...