1 | import {response, IResponse} from './tools';
|
2 |
|
3 | export interface IAddress {
|
4 | address1?: string;
|
5 | address2?: string;
|
6 | city?: string;
|
7 | state?: string;
|
8 | country?: string;
|
9 | zip?: string;
|
10 | }
|
11 |
|
12 | interface IValidatorItem {
|
13 | key: string;
|
14 | format: string;
|
15 | value: any;
|
16 | }
|
17 |
|
18 | export 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 |
|
42 | if(item.format.indexOf('|') > 0) {
|
43 | const ex = item.format.split('|');
|
44 |
|
45 |
|
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 |
|
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 |
|
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 |
|
187 | isNumber(value: any): IResponse {
|
188 | return this.createResponse(this.validator.isNumeric(value.toString()), 'number');
|
189 | }
|
190 |
|
191 |
|
192 | isFloat(value: any): IResponse {
|
193 | return this.createResponse(this.validator.isFloat(value.toString()), 'float');
|
194 | }
|
195 |
|
196 |
|
197 | isCurrency(value: any): IResponse {
|
198 | return this.createResponse(this.validator.isCurrency(value.toString()), 'currency');
|
199 | }
|
200 |
|
201 |
|
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 |
|
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 |
|
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 |
|
221 | isTime(value: any): IResponse {
|
222 | return this.createResponse(this.validator.matches(value.toString(), /^(\d{1,2}):(\d{2})$/), 'Time');
|
223 | }
|
224 |
|
225 |
|
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 |
|
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 |