UNPKG

9.29 kBPlain TextView Raw
1import {response, IResponse} from './tools';
2
3export interface IAddress {
4 address1?: string;
5 address2?: string;
6 city?: string;
7 state?: string;
8 country?: string;
9 zip?: string;
10}
11
12interface IValidatorItem {
13 key: string;
14 format: string;
15 value: any;
16}
17
18export class Validator {
19 private validator:any;
20
21 constructor() {
22 this.validator = require('validator');
23 }
24
25 private createResponse(value: any, type: string): IResponse {
26 if(value === true) {
27 return response(true, null, true);
28 } else {
29 return response(false, `is not a valid "${type}"`, value);
30 }
31 }
32
33 validateArray(items: Array<IValidatorItem>): IResponse {
34 try {
35 let success = true;
36 const answer = {};
37
38 for (let i = 0; i < items.length; i++) {
39 const item:IValidatorItem = items[i];
40
41 // if there is "pipe |" as parameter
42 if(item.format.indexOf('|') > 0) {
43 const ex = item.format.split('|');
44
45 // if it's an array so 'value' has to be an array as well
46 if(ex[0].toLowerCase() === 'array') {
47 if (Array.isArray(item.value)) {
48 for (let k=0; k<item.value.length; k++) {
49 const formats = JSON.parse(ex[1]);
50 if ((typeof formats) === 'object') {
51 const keys = Object.keys(formats);
52 for (let j=0; j<keys.length; j++) {
53 const fName = 'is' + formats[keys[j]].charAt(0).toUpperCase() + formats[keys[j]].substr(1, formats[keys[j]].length);
54 const res = this[fName](item.value[k][keys[j]]);
55
56 if (!res.success) {
57 success = false;
58 const _key = `${item.key}[${j}].${keys[j]}`;
59 answer[_key] = response(false, `${_key} does not match expected format "${_key}: ${formats[keys[j]]}"`);
60 }
61 }
62 } else {
63 success = false;
64 answer[item.key] = response(false, `${item.key} does not match expected format "Array[${formats}]"`);
65 }
66 }
67 } else {
68 success = false;
69 answer[item.key] = response(false, `${item.key} does not match expected format "${item.format}"`);
70 }
71
72 } else {
73 const formats = JSON.parse(ex[1]);
74 if ((typeof formats) === 'object') {
75 const keys = Object.keys(formats);
76 for (let j=0; j<keys.length; j++) {
77 const fName = 'is' + formats[keys[j]].charAt(0).toUpperCase() + formats[keys[j]].substr(1, formats[keys[j]].length);
78 const res = this[fName](item.value[keys[j]]);
79
80 if (!res.success) {
81 success = false;
82 const _key = `${item.key}.${keys[j]}`;
83 answer[_key] = response(false, `${_key} does not match expected format "${_key}:${formats[keys[j]]}"`);
84 }
85 }
86 } else {
87 success = false;
88 answer[item.key] = response(false, `${item.key} does not match expected format "${formats}"`);
89 }
90 }
91 } else {
92 const fName = 'is' + item.format.charAt(0).toUpperCase() + item.format.substr(1, item.format.length);
93 if (!this[fName]) {
94 return response(false, `${fName} is not a known validator.`);
95 }
96
97 const res = this[fName](item.value);
98
99 if (!res.success) {
100 success = false;
101 answer[item.key] = response(false, `${item.key} does not match expected format "${item.format}"`);
102 }
103 }
104
105 }
106 if (success) {
107 return response(true, null, true);
108 }
109 return response(false, 'one or more fields do not match expected formats', answer);
110 } catch (error) {
111 console.log('107 tools.validation.validateArray()', error);
112 return response(false, error);
113 }
114 }
115
116 // TODO implement for a third party API to check address
117 private _verifyAddress(address: IAddress): IResponse {
118 const validator = this;
119
120 try {
121 const err = [];
122
123 if (!address.address1) {
124 err.push('address1');
125 }
126 if (!address.zip || !validator.isNumber(address.zip.toString()).success) {
127 err.push('zip code');
128 }
129 if (!address.city) {
130 err.push('city');
131 }
132 if (!address.state) {
133 err.push('state');
134 }
135
136 if(err.length < 1) {
137 return response(true, null, true);
138 }
139
140 return response(false, `is not a valid 'address', field is not a correct format`, err);
141 } catch(error) {
142 console.log(error);
143 return response(false, error);
144 }
145 }
146
147 isArray(value: any): IResponse {
148 return this.createResponse(Array.isArray(value), 'array');
149 }
150
151 isAddress(address: IAddress): IResponse {
152 return this._verifyAddress(address);
153 }
154
155 isEmail(value: any): IResponse {
156 return this.createResponse(this.validator.isEmail(value.toString()), 'email');
157 }
158
159 isString(value: any): IResponse {
160 return this.createResponse(!!(typeof value ==='string'), 'string');
161 }
162
163 // 123-456-7890
164 isSSN(value: any): IResponse {
165 return this.createResponse(this.validator.matches(value.toString(), /^[0-9]{3}\-?[0-9]{2}\-?[0-9]{4}$/), 'SSN');
166 }
167
168 isLast4Digits(value: any): IResponse {
169 return this.createResponse(this.validator.matches(value.toString(), /^\d{4}$/), 'last4Digits');
170 }
171
172 isIDnumber(value: any, state: string): IResponse {
173 const regExSt = {
174 'NY': /^\d{9}$/,
175 'NJ': /^[A-Z]{1}\d{14}$/,
176 'FL': /^[A-Z]{1}\d{13}$/
177 };
178
179 if (Object.keys(regExSt).indexOf(state.toUpperCase()) < 0) {
180 return response(false, `"${state}"" verify rule not found`);
181 }
182
183 return this.createResponse(this.validator.matches(value.toString(), regExSt[state.toUpperCase()]), 'IDnumber');
184 }
185
186 // 49985
187 isNumber(value: any): IResponse {
188 return this.createResponse(this.validator.isNumeric(value.toString()), 'number');
189 }
190
191 // 3.14155986
192 isFloat(value: any): IResponse {
193 return this.createResponse(this.validator.isFloat(value.toString()), 'float');
194 }
195
196 // 20,55
197 isCurrency(value: any): IResponse {
198 return this.createResponse(this.validator.isCurrency(value.toString()), 'currency');
199 }
200
201 // 12/31/1980 or 12-31-1980
202 isBirthDate(value: any): IResponse {
203 return this.createResponse(this.validator.matches(value.toString(), /^(0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])[\/\-]\d{4}$/gm), 'birthDate');
204 }
205
206 isISODate(value: any): IResponse {
207 return this.createResponse(this.validator.isISO8601(value.toString()), 'ISO date');
208 }
209
210 // 2018-12-31
211 isDate(value: any): IResponse {
212 return this.createResponse(this.validator.matches(value.toString(), /^\d{4}[\-](0?[1-9]|1[012])[\-](0?[1-9]|[12][0-9]|3[01])$/), 'date');
213 }
214
215 // 2018-12-31T13:15:00.233Z
216 isDateTime(value: any): IResponse {
217 return this.createResponse(this.validator.matches(value.toString(), /^\d{4}[\-](0?[1-9]|1[012])[\-](0?[1-9]|[12][0-9]|3[01])T(\d{1,2}):(\d{2})(?::(\d{2}))?\.(\d{3})Z$/), 'dateTime');
218 }
219
220 //13:15
221 isTime(value: any): IResponse {
222 return this.createResponse(this.validator.matches(value.toString(), /^(\d{1,2}):(\d{2})$/), 'Time');
223 }
224
225 // 1:04PM
226 is12HourTime(value: any): IResponse {
227 return this.createResponse(this.validator.matches(value.toString().toUpperCase(), /^(\d{1,2}):(\d{2})?(AM|PM)$/), 'Time');
228 }
229
230 // 13:15:00.233Z
231 isISOTime(value: any): IResponse {
232 return this.createResponse(this.validator.matches(value.toString(), /^(\d{1,2}):(\d{2})(?::(\d{2}))?\.(\d{3})Z$/), 'ISO time');
233 }
234
235 isUUID(value: any): IResponse {
236 return this.createResponse(this.validator.isUUID(value.toString()), 'UUID');
237 }
238
239 isPhoneNumber(value: any): IResponse {
240 return this.createResponse(this.validator.matches(value.toString(), /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/i), 'PhoneNumber');
241 }
242
243}
\No newline at end of file