Skip to content

Commit 6fdd98a

Browse files
authored
Merge pull request #8 from gsmithun4/development
Removed lodash and moments dependency
2 parents 8e4862d + 87a7517 commit 6fdd98a

File tree

5 files changed

+223
-45
lines changed

5 files changed

+223
-45
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ Request field validator for expressjs
4444
$ npm install expressjs-field-validator
4545
```
4646

47-
## Dependencies
48-
- [lodash](https://www.npmjs.com/package/lodash)
49-
- [moment](https://www.npmjs.com/package/moment)
50-
5147
## How To Use
5248

5349
```js
@@ -85,13 +81,23 @@ validator([{param : 'id', location : 'params', isRequired : true}], { mode : 're
8581
|isEmail |`Boolean` |The value is `Email` or not (default `false`)|
8682
|isBoolean |`Boolean` |The value is `Boolean` or not (default `false`)|
8783
|isDate |`Boolean` |The value is `Date` or not (default `false`)|
88-
|format |`String` |Date format. Please reffer https://momentjs.com/docs/ for date formats|
84+
|format |`String` |Date format. (default `YYYY-MM-DD`)|
8985
|mobileNumber |`Object` |Object `{countryCode : '91', isCountryCodeMandatory : true, length: {min : 1, max : 10}}` ,describes characteristics of mobile number, length is the length range of mobile number excluding country code |
9086
|length |`Object` |Object `{min : 1, max : 10}` describes minimum and maximum length|
9187
|includes |`Object[]` |Value must be one of the element in the array|
9288
|excludes |`Object[]` |Value must not be one of the element in the array|
9389
|message |`String` |Error message thrown in case of test fails default : Invalid Field Error|
9490

91+
#### Supported date formats
92+
If `isDate` is true you can pass `format`, Only supported the following
93+
```
94+
YYYY-MM-DD
95+
DD-MM-YYYY'
96+
MM-DD-YYYY'
97+
YYYY/MM/DD'
98+
DD/MM/YYYY'
99+
MM/DD/YYYY'
100+
```
95101
#### Nested Objets
96102
In case of `Object` or `Array`, `isArray` or `isObject` must be true
97103
if json structure is

lib/validator/validator.js

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
"use strict";
22

3-
const _ = require('lodash');
4-
const moment = require('moment');
5-
63
module.exports = (validation = [], response = {}) => {
74
const validator = (() => {
85
const validate = (validation, req) => {
@@ -27,13 +24,13 @@ module.exports = (validation = [], response = {}) => {
2724
}
2825
const checkEmpty = (value) => {
2926
//Checking if value is empty
30-
if (_.isObject(value)) {
27+
if (value instanceof Object) {
3128
//Array or Object
3229
if (!value || JSON.stringify(value).length === 2) {
3330
return true;
3431
}
3532

36-
} else if (isNaN(value) && !_.isBoolean(value) && (!value || value === 'undefined' || value.trim() === '')) {
33+
} else if (isNaN(value) && value !== !!value && (!value || value === 'undefined' || value.trim() === '')) {
3734
//Not Number Not Boolean => String
3835
return true;
3936
}
@@ -68,6 +65,53 @@ module.exports = (validation = [], response = {}) => {
6865
}
6966
}
7067
}
68+
69+
const dateCheck = (dateString, format) => {
70+
if (!dateString || !format) {
71+
return false;
72+
}
73+
let regEx = /^\d{4}\/\d{2}\/\d{2}$/;
74+
let YYYY,MM,DD;
75+
76+
switch (format) {
77+
case 'YYYY-MM-DD':
78+
regEx = /^\d{4}-\d{2}-\d{2}$/;
79+
[YYYY, MM, DD] = dateString.split('-');
80+
break;
81+
case 'DD-MM-YYYY':
82+
regEx = /^\d{2}-\d{2}-\d{4}$/;
83+
[DD, MM, YYYY] = dateString.split('-');
84+
break;
85+
case 'MM-DD-YYYY':
86+
regEx = /^\d{2}-\d{2}-\d{4}$/;
87+
[MM, DD, YYYY] = dateString.split('-');
88+
break;
89+
case 'YYYY/MM/DD':
90+
regEx = /^\d{4}\/\d{2}\/\d{2}$/;
91+
[YYYY, MM, DD] = dateString.split('/');
92+
break;
93+
case 'DD/MM/YYYY':
94+
regEx = /^\d{2}\/\d{2}\/\d{4}$/;
95+
[DD, MM, YYYY] = dateString.split('/');
96+
break;
97+
case 'MM/DD/YYYY':
98+
regEx = /^\d{2}\/\d{2}\/\d{4}$/;
99+
[MM, DD, YYYY] = dateString.split('/');
100+
break;
101+
default:
102+
break;
103+
}
104+
105+
if (!dateString.match(regEx)) { // Invalid format
106+
return false;
107+
}
108+
var d = new Date(`${YYYY}-${MM}-${DD}`);
109+
var dNum = d.getTime();
110+
if(!dNum && dNum !== 0) { // NaN value, Invalid date
111+
return false;
112+
}
113+
return true;
114+
}
71115

72116
try {
73117
const isEmpty = checkEmpty(value);
@@ -100,16 +144,30 @@ module.exports = (validation = [], response = {}) => {
100144
if (isArray && !Array.isArray(value)) {
101145
throw new Error('Must Be An Array');
102146
}
103-
if (isObject && !_.isObject(value) && Array.isArray(value)) {
147+
if (isObject && !(value instanceof Object) && Array.isArray(value)) {
104148
throw new Error('Must Be An Object');
105149
}
106150
if (isDate) {
107-
if (!moment(value, format || 'YYYY-MM-DD', true).isValid()) {
108-
throw new Error(`Must Be A Date With Format ${format || 'YYYY-MM-DD'}`);
151+
const supportedFormats = [
152+
'YYYY-MM-DD',
153+
'DD-MM-YYYY',
154+
'MM-DD-YYYY',
155+
'YYYY/MM/DD',
156+
'DD/MM/YYYY',
157+
'MM/DD/YYYY',
158+
]
159+
const checkFormat = format || 'YYYY-MM-DD';
160+
161+
if (!supportedFormats.includes(checkFormat)) {
162+
throw new Error(`Configured format not supported ${checkFormat}`);
163+
}
164+
165+
if (!dateCheck(value, checkFormat)) {
166+
throw new Error(`Must Be A Date With Format ${checkFormat}`);
109167
}
110168
}
111169
if (isBoolean) {
112-
if (!_.isBoolean(value) && value.toLowerCase() !== "true" && value.toLowerCase() !== "false") {
170+
if (value !== !!value && value.toLowerCase() !== "true" && value.toLowerCase() !== "false") {
113171
throw new Error('Must Be A Boolean');
114172
}
115173
}
@@ -187,7 +245,8 @@ module.exports = (validation = [], response = {}) => {
187245
return errorList;
188246
}
189247
const validateFields = (req, res, next) => {
190-
const error = _.reject(_.flattenDeep(validation.map(validateObj => validate(validateObj, req))), _.isNil);
248+
const isNull = val => val === null
249+
const error = validation.map(validateObj => validate(validateObj, req)).flat(Infinity).filter(obj => obj);
191250
if (error && error.length > 0) {
192251

193252
if (response.mode === 'forward') {

lib/validator/validator.test.js

Lines changed: 127 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,11 +550,11 @@ describe('Test for body params', () => {
550550
})
551551
});
552552

553-
test('Test nested objects Success case - Date test', () => {
553+
test('Test nested objects Success case - Date test Format defauly YYYY-MM-DD', () => {
554554
const req = {
555555
body: {
556556
page: {
557-
sorted: '2012-09-09'
557+
sorted: '2012-09-19'
558558
}
559559
}
560560
}
@@ -573,11 +573,11 @@ describe('Test for body params', () => {
573573
expect(resp.send).toHaveBeenCalledTimes(0)
574574
});
575575

576-
test('Test nested objects Success case - Date test - Format', () => {
576+
test('Test nested objects Success case - Date test - Format DD-MM-YYYY', () => {
577577
const req = {
578578
body: {
579579
page: {
580-
sorted: '09-08-2019'
580+
sorted: '19-08-2019'
581581
}
582582
}
583583
}
@@ -596,6 +596,98 @@ describe('Test for body params', () => {
596596
expect(resp.send).toHaveBeenCalledTimes(0)
597597
});
598598

599+
test('Test nested objects Success case - Date test - Format MM-DD-YYYY', () => {
600+
const req = {
601+
body: {
602+
page: {
603+
sorted: '08-18-2019'
604+
}
605+
}
606+
}
607+
const validation = [
608+
{param : 'page', location : 'body', isObject : true, children : [
609+
{param : 'sorted', location : 'body.page', isRequired : true, isDate: true, format: 'MM-DD-YYYY' },
610+
]}
611+
]
612+
const response = {
613+
mode: 'reject'
614+
}
615+
const validatorfn = validaor(validation, response);
616+
validatorfn(req, resp, next);
617+
expect(next).toHaveBeenCalledTimes(1);
618+
expect(resp.status).toHaveBeenCalledTimes(0);
619+
expect(resp.send).toHaveBeenCalledTimes(0)
620+
});
621+
622+
test('Test nested objects Success case - Date test - Format MM/DD/YYYY', () => {
623+
const req = {
624+
body: {
625+
page: {
626+
sorted: '12/18/2019'
627+
}
628+
}
629+
}
630+
const validation = [
631+
{param : 'page', location : 'body', isObject : true, children : [
632+
{param : 'sorted', location : 'body.page', isRequired : true, isDate: true, format: 'MM/DD/YYYY' },
633+
]}
634+
]
635+
const response = {
636+
mode: 'reject'
637+
}
638+
const validatorfn = validaor(validation, response);
639+
validatorfn(req, resp, next);
640+
expect(next).toHaveBeenCalledTimes(1);
641+
expect(resp.status).toHaveBeenCalledTimes(0);
642+
expect(resp.send).toHaveBeenCalledTimes(0)
643+
});
644+
645+
test('Test nested objects Success case - Date test - Format DD/MM/YYYY', () => {
646+
const req = {
647+
body: {
648+
page: {
649+
sorted: '12/07/2019'
650+
}
651+
}
652+
}
653+
const validation = [
654+
{param : 'page', location : 'body', isObject : true, children : [
655+
{param : 'sorted', location : 'body.page', isRequired : true, isDate: true, format: 'DD/MM/YYYY' },
656+
]}
657+
]
658+
const response = {
659+
mode: 'reject'
660+
}
661+
const validatorfn = validaor(validation, response);
662+
validatorfn(req, resp, next);
663+
expect(next).toHaveBeenCalledTimes(1);
664+
expect(resp.status).toHaveBeenCalledTimes(0);
665+
expect(resp.send).toHaveBeenCalledTimes(0)
666+
});
667+
668+
test('Test nested objects Success case - Date test - Format YYYY/MM/DD', () => {
669+
const req = {
670+
body: {
671+
page: {
672+
sorted: '2901/07/19'
673+
}
674+
}
675+
}
676+
const validation = [
677+
{param : 'page', location : 'body', isObject : true, children : [
678+
{param : 'sorted', location : 'body.page', isRequired : true, isDate: true, format: 'YYYY/MM/DD' },
679+
]}
680+
]
681+
const response = {
682+
mode: 'reject'
683+
}
684+
const validatorfn = validaor(validation, response);
685+
validatorfn(req, resp, next);
686+
expect(next).toHaveBeenCalledTimes(1);
687+
expect(resp.status).toHaveBeenCalledTimes(0);
688+
expect(resp.send).toHaveBeenCalledTimes(0)
689+
});
690+
599691
test('Test nested objects Error case - Date test', () => {
600692
const req = {
601693
body: {
@@ -658,6 +750,37 @@ describe('Test for body params', () => {
658750
})
659751
});
660752

753+
test('Test nested objects Error case - Date test - Invalid Format', () => {
754+
const req = {
755+
body: {
756+
page: {
757+
sorted: '2019-23-02'
758+
}
759+
}
760+
}
761+
const validation = [
762+
{param : 'page', location : 'body', isObject : true, children : [
763+
{param : 'sorted', location : 'body.page', isRequired : true, isDate : true, format: 'YYYY/DD/MM' },
764+
]}
765+
]
766+
const response = {
767+
mode: 'reject'
768+
}
769+
const validatorfn = validaor(validation, response);
770+
validatorfn(req, resp, next);
771+
expect(next).toHaveBeenCalledTimes(0);
772+
expect(resp.status).toHaveBeenCalledTimes(1);
773+
expect(resp.send).toHaveBeenCalledWith({
774+
error: [
775+
{
776+
location: 'body.page',
777+
message: 'Invalid Field Error',
778+
param: 'sorted',
779+
}
780+
]
781+
})
782+
});
783+
661784
test('Test nested objects Success case - Mobile number test', () => {
662785
const req = {
663786
body: {

package-lock.json

Lines changed: 11 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)