1 | 1 | 'use strict'; |
2 | | |
3 | 1 | var valid = module.exports = {}; |
4 | | |
5 | | |
6 | | // ----- affirmative |
7 | | // --------------------------------------- |
8 | 1 | valid.affirmative = function(str) { |
9 | | |
10 | 27 | var regex = /^(?:1|t(?:rue)?|y(?:es)?|on|ok(?:ay)?)$/; |
11 | | |
12 | 27 | return regex.test(str.toLowerCase()); |
13 | | |
14 | | }; |
15 | | |
16 | | |
17 | | // ----- alphanumeric |
18 | | // --------------------------------------- |
19 | 1 | valid.alphaNumeric = function(str) { |
20 | | |
21 | 17 | var regex = /^[A-Za-z0-9]+$/; |
22 | | |
23 | 17 | return regex.test(str.toLowerCase()); |
24 | | |
25 | | }; |
26 | | |
27 | | |
28 | | // ----- alphabetic |
29 | | // --------------------------------------- |
30 | 1 | valid.alpha = function(str) { |
31 | | |
32 | 19 | var regex = /^[A-Za-z]+$/; |
33 | | |
34 | 19 | return regex.test(str.toLowerCase()); |
35 | | |
36 | | }; |
37 | | |
38 | | |
39 | | // ----- email |
40 | | // --------------------------------------- |
41 | 1 | valid.email = function(str) { |
42 | | |
43 | 11 | var regex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; |
44 | | |
45 | 11 | return regex.test(str.toLowerCase()); |
46 | | |
47 | | }; |
48 | | |
49 | | |
50 | | // ----- negatory |
51 | | // --------------------------------------- |
52 | 1 | valid.negatory = function(str) { |
53 | | |
54 | 21 | var regex = /^(?:1|f(?:alse)?|n(?:o)?|off)$/; |
55 | | |
56 | 21 | return regex.test(str.toLowerCase()); |
57 | | |
58 | | |
59 | | }; |
60 | | |
61 | | |
62 | | // ----- numeric |
63 | | // --------------------------------------- |
64 | 1 | valid.numeric = function(str) { |
65 | | |
66 | 14 | str = str.toLowerCase(); |
67 | | |
68 | 13 | if (str === '') { |
69 | 1 | return false; |
70 | | } |
71 | | |
72 | 12 | return !isNaN(str); // http://stackoverflow.com/a/175787 |
73 | | |
74 | | }; |
75 | | |
76 | | |
77 | | // ----- value |
78 | | // --------------------------------------- |
79 | 1 | valid.value = function(str) { |
80 | | |
81 | 27 | str = str.toLowerCase().replace(',', ''); |
82 | | |
83 | 26 | var numbers = ['0','1','2','3','4','5','6','7','8','9', '-']; |
84 | | |
85 | | // for $100 and #123, etc. |
86 | 26 | if (numbers.indexOf(str[0]) === -1) { |
87 | 12 | str = str.slice(1); |
88 | | } |
89 | | |
90 | | |
91 | 26 | return !isNaN(parseInt(str), 10); |
92 | | |
93 | | }; |
94 | | |
95 | | |
96 | | // ----- url |
97 | | // --------------------------------------- |
98 | 1 | valid.url = function(str) { |
99 | | |
100 | 23 | var regex = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/i; |
101 | | |
102 | 23 | return regex.test(str.toLowerCase()); |
103 | | |
104 | | }; |
105 | | |
106 | | |
107 | | // ----- zip code |
108 | | // -- 1. input must be a string |
109 | | // -- 2. check number |
110 | | // -- 3. perform regex test |
111 | | // --------------------------------------- |
112 | 1 | valid.zipCode = function(str) { |
113 | | |
114 | | // [1] throws here if not a string |
115 | 19 | str = str.toLowerCase(); |
116 | | |
117 | | // [2] every zip code begins with a number, and none are < 00501 |
118 | 18 | var numeric = parseInt(str, 10); |
119 | | |
120 | 18 | if (isNaN(numeric) || numeric < 501) { |
121 | 6 | return false; |
122 | | } |
123 | | |
124 | | // [3] |
125 | 12 | var regex = /^\d{5}(-\d{4})?$/; |
126 | | |
127 | 12 | return regex.test(str); |
128 | | |
129 | | }; |
130 | | |
131 | | |
132 | | // -------------- credit card methods -------------- |
133 | | |
134 | | // ----- credit card check constructor |
135 | | // --------------------------------------- |
136 | 1 | function CreditCard(regex) { |
137 | | |
138 | 11 | return function(str) { |
139 | | |
140 | 62 | return regex.test(str.toLowerCase()); |
141 | | |
142 | | }; |
143 | | |
144 | | } |
145 | | |
146 | | |
147 | | // ----- specific card regexp validation |
148 | | // --------------------------------------- |
149 | 1 | valid.card = { |
150 | | visa: new CreditCard(/^4[0-9]{12}(?:[0-9]{3})?$/), |
151 | | mastercard: new CreditCard(/^5[1-5][0-9]{14}$/), |
152 | | amex: new CreditCard(/^3[47][0-9]{13}$/), |
153 | | carteBlanche: new CreditCard(/^389[0-9]{11}$|^380[0-9]{11}$/), |
154 | | dinersClub: new CreditCard(/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/), |
155 | | discover: new CreditCard(/^65[4-9][0-9]{13}|64[4-9][0-9]{13}|6011[0-9]{12}|(622(?:12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|9[01][0-9]|92[0-5])[0-9]{10})$/), |
156 | | jcb: new CreditCard(/^(?:2131|1800|35\d{3})\d{11}$/), |
157 | | lasercard: new CreditCard(/^(6304|6706|6709|6771)[0-9]{12,15}$/), |
158 | | maestro: new CreditCard(/^(5018|5020|5038|6304|6759|6761|6763|6799)[0-9]{8,19}$/), |
159 | | solo: new CreditCard(/^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}$|^(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}$/), |
160 | | unionpay: new CreditCard(/^(62[0-9]{14,17})$/) |
161 | | }; |
162 | | |
163 | | |
164 | | // ----- generic card validation |
165 | | // -- 1. input must be a string |
166 | | // -- 2. input length must be valid |
167 | | // -- 3. perform check based on number |
168 | | // --------------------------------------- |
169 | 1 | valid.creditCard = valid.card.generic = function(str) { |
170 | | |
171 | | // [1] throws here if not a string |
172 | 60 | str = str.toLowerCase(); |
173 | | |
174 | | // [2] must be valid card length |
175 | 58 | if (str.length < 13 || str.length > 19) { |
176 | 4 | return false; |
177 | | } |
178 | | |
179 | | // [3] method of testing credit cards from |
180 | | // http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.js |
181 | 54 | var testNumber = 0; |
182 | | |
183 | 54 | for (var i = str.length - 1, current, currentInteger = 0, even = false; i>=0; i--) { |
184 | | |
185 | 846 | current = str.charAt(i); |
186 | 846 | currentInteger = parseInt(current, 10); |
187 | | |
188 | 846 | if (even && (currentInteger *= 2) > 9 ) { |
189 | 102 | currentInteger -= 9; |
190 | | } |
191 | | |
192 | 846 | testNumber += currentInteger; |
193 | 846 | even = !even; |
194 | | } |
195 | | |
196 | 54 | return (testNumber % 10) === 0; |
197 | | |
198 | | }; |