@impelsys/validatorjs 3.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +27 -0
- package/CONTRIBUTE.md +34 -0
- package/LICENSE +20 -0
- package/README.md +607 -0
- package/dist/lang/ar.js +66 -0
- package/dist/lang/az.js +104 -0
- package/dist/lang/be.js +105 -0
- package/dist/lang/bg.js +105 -0
- package/dist/lang/bs.js +106 -0
- package/dist/lang/ca.js +40 -0
- package/dist/lang/cs.js +107 -0
- package/dist/lang/cy.js +106 -0
- package/dist/lang/da.js +51 -0
- package/dist/lang/de.js +46 -0
- package/dist/lang/el.js +43 -0
- package/dist/lang/en.js +54 -0
- package/dist/lang/es.js +40 -0
- package/dist/lang/et.js +106 -0
- package/dist/lang/eu.js +106 -0
- package/dist/lang/fa.js +42 -0
- package/dist/lang/fi.js +51 -0
- package/dist/lang/fr.js +40 -0
- package/dist/lang/hr.js +106 -0
- package/dist/lang/hu.js +106 -0
- package/dist/lang/id.js +51 -0
- package/dist/lang/it.js +41 -0
- package/dist/lang/ja.js +54 -0
- package/dist/lang/ka.js +106 -0
- package/dist/lang/ko.js +106 -0
- package/dist/lang/lt.js +106 -0
- package/dist/lang/lv.js +106 -0
- package/dist/lang/mk.js +106 -0
- package/dist/lang/mn.js +106 -0
- package/dist/lang/ms.js +106 -0
- package/dist/lang/nb_NO.js +42 -0
- package/dist/lang/nl.js +51 -0
- package/dist/lang/pl.js +42 -0
- package/dist/lang/pt.js +110 -0
- package/dist/lang/pt_BR.js +105 -0
- package/dist/lang/ro.js +51 -0
- package/dist/lang/ru.js +40 -0
- package/dist/lang/se.js +106 -0
- package/dist/lang/sl.js +106 -0
- package/dist/lang/sq.js +106 -0
- package/dist/lang/sr.js +106 -0
- package/dist/lang/sv.js +105 -0
- package/dist/lang/tr.js +51 -0
- package/dist/lang/ua.js +40 -0
- package/dist/lang/uk.js +106 -0
- package/dist/lang/vi.js +42 -0
- package/dist/lang/zh.js +42 -0
- package/dist/lang/zh_TW.js +42 -0
- package/dist/validator.js +2183 -0
- package/package.json +78 -0
- package/src/async.js +81 -0
- package/src/attributes.js +199 -0
- package/src/errors.js +77 -0
- package/src/lang/ar.js +63 -0
- package/src/lang/az.js +101 -0
- package/src/lang/be.js +102 -0
- package/src/lang/bg.js +102 -0
- package/src/lang/bs.js +103 -0
- package/src/lang/ca.js +37 -0
- package/src/lang/cs.js +104 -0
- package/src/lang/cy.js +103 -0
- package/src/lang/da.js +48 -0
- package/src/lang/de.js +43 -0
- package/src/lang/el.js +40 -0
- package/src/lang/en.js +51 -0
- package/src/lang/es.js +37 -0
- package/src/lang/et.js +103 -0
- package/src/lang/eu.js +103 -0
- package/src/lang/fa.js +39 -0
- package/src/lang/fi.js +48 -0
- package/src/lang/fr.js +37 -0
- package/src/lang/hr.js +103 -0
- package/src/lang/hu.js +103 -0
- package/src/lang/id.js +48 -0
- package/src/lang/it.js +38 -0
- package/src/lang/ja.js +51 -0
- package/src/lang/ka.js +103 -0
- package/src/lang/ko.js +103 -0
- package/src/lang/lt.js +103 -0
- package/src/lang/lv.js +103 -0
- package/src/lang/mk.js +103 -0
- package/src/lang/mn.js +103 -0
- package/src/lang/ms.js +103 -0
- package/src/lang/nb_NO.js +39 -0
- package/src/lang/nl.js +48 -0
- package/src/lang/pl.js +39 -0
- package/src/lang/pt.js +107 -0
- package/src/lang/pt_BR.js +102 -0
- package/src/lang/ro.js +48 -0
- package/src/lang/ru.js +37 -0
- package/src/lang/se.js +47 -0
- package/src/lang/sl.js +103 -0
- package/src/lang/sq.js +103 -0
- package/src/lang/sr.js +103 -0
- package/src/lang/sv.js +102 -0
- package/src/lang/tr.js +48 -0
- package/src/lang/ua.js +37 -0
- package/src/lang/uk.js +103 -0
- package/src/lang/vi.js +39 -0
- package/src/lang/zh.js +39 -0
- package/src/lang/zh_TW.js +39 -0
- package/src/lang.js +78 -0
- package/src/messages.js +152 -0
- package/src/rules.js +864 -0
- package/src/validator.js +662 -0
package/src/validator.js
ADDED
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
var Rules = require('./rules');
|
|
2
|
+
var Lang = require('./lang');
|
|
3
|
+
var Errors = require('./errors');
|
|
4
|
+
var Attributes = require('./attributes');
|
|
5
|
+
var AsyncResolvers = require('./async');
|
|
6
|
+
|
|
7
|
+
var Validator = function (input, rules, customMessages) {
|
|
8
|
+
var lang = Validator.getDefaultLang();
|
|
9
|
+
this.input = input || {};
|
|
10
|
+
|
|
11
|
+
this.messages = Lang._make(lang);
|
|
12
|
+
this.messages._setCustom(customMessages);
|
|
13
|
+
this.setAttributeFormatter(Validator.prototype.attributeFormatter);
|
|
14
|
+
|
|
15
|
+
this.errors = new Errors();
|
|
16
|
+
this.errorCount = 0;
|
|
17
|
+
|
|
18
|
+
this.hasAsync = false;
|
|
19
|
+
this.rules = this._parseRules(rules);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Validator.prototype = {
|
|
23
|
+
|
|
24
|
+
constructor: Validator,
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Default language
|
|
28
|
+
*
|
|
29
|
+
* @type {string}
|
|
30
|
+
*/
|
|
31
|
+
lang: 'en',
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Numeric based rules
|
|
35
|
+
*
|
|
36
|
+
* @type {array}
|
|
37
|
+
*/
|
|
38
|
+
numericRules: ['integer', 'numeric'],
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Attribute formatter.
|
|
42
|
+
*
|
|
43
|
+
* @type {function}
|
|
44
|
+
*/
|
|
45
|
+
attributeFormatter: Attributes.formatter,
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Run validator
|
|
49
|
+
*
|
|
50
|
+
* @return {boolean} Whether it passes; true = passes, false = fails
|
|
51
|
+
*/
|
|
52
|
+
check: function () {
|
|
53
|
+
var self = this;
|
|
54
|
+
|
|
55
|
+
for (var attribute in this.rules) {
|
|
56
|
+
var attributeRules = this.rules[attribute];
|
|
57
|
+
var inputValue = this._objectPath(this.input, attribute);
|
|
58
|
+
|
|
59
|
+
if (this._hasRule(attribute, ['sometimes']) && !this._suppliedWithData(attribute)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (var i = 0, len = attributeRules.length, rule, ruleOptions, rulePassed; i < len; i++) {
|
|
64
|
+
ruleOptions = attributeRules[i];
|
|
65
|
+
rule = this.getRule(ruleOptions.name);
|
|
66
|
+
|
|
67
|
+
if (!this._isValidatable(rule, inputValue)) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
rulePassed = rule.validate(inputValue, ruleOptions.value, attribute);
|
|
72
|
+
if (!rulePassed) {
|
|
73
|
+
this._addFailure(rule);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (this._shouldStopValidating(attribute, rulePassed)) {
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return this.errorCount === 0;
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Run async validator
|
|
87
|
+
*
|
|
88
|
+
* @param {function} passes
|
|
89
|
+
* @param {function} fails
|
|
90
|
+
* @return {void}
|
|
91
|
+
*/
|
|
92
|
+
checkAsync: function (passes, fails) {
|
|
93
|
+
var _this = this;
|
|
94
|
+
passes = passes || function () {};
|
|
95
|
+
fails = fails || function () {};
|
|
96
|
+
|
|
97
|
+
var failsOne = function (rule, message) {
|
|
98
|
+
_this._addFailure(rule, message);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
var resolvedAll = function (allPassed) {
|
|
102
|
+
if (allPassed) {
|
|
103
|
+
passes();
|
|
104
|
+
} else {
|
|
105
|
+
fails();
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
var asyncResolvers = new AsyncResolvers(failsOne, resolvedAll);
|
|
110
|
+
|
|
111
|
+
var validateRule = function (inputValue, ruleOptions, attribute, rule) {
|
|
112
|
+
return function () {
|
|
113
|
+
var resolverIndex = asyncResolvers.add(rule);
|
|
114
|
+
rule.validate(inputValue, ruleOptions.value, attribute, function () {
|
|
115
|
+
asyncResolvers.resolve(resolverIndex);
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
for (var attribute in this.rules) {
|
|
121
|
+
var attributeRules = this.rules[attribute];
|
|
122
|
+
var inputValue = this._objectPath(this.input, attribute);
|
|
123
|
+
|
|
124
|
+
if (this._hasRule(attribute, ['sometimes']) && !this._suppliedWithData(attribute)) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
for (var i = 0, len = attributeRules.length, rule, ruleOptions; i < len; i++) {
|
|
129
|
+
ruleOptions = attributeRules[i];
|
|
130
|
+
|
|
131
|
+
rule = this.getRule(ruleOptions.name);
|
|
132
|
+
|
|
133
|
+
if (!this._isValidatable(rule, inputValue)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
validateRule(inputValue, ruleOptions, attribute, rule)();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
asyncResolvers.enableFiring();
|
|
142
|
+
asyncResolvers.fire();
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Add failure and error message for given rule
|
|
147
|
+
*
|
|
148
|
+
* @param {Rule} rule
|
|
149
|
+
*/
|
|
150
|
+
_addFailure: function (rule) {
|
|
151
|
+
var msg = this.messages.render(rule);
|
|
152
|
+
this.errors.add(rule.attribute, msg);
|
|
153
|
+
this.errorCount++;
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Flatten nested object, normalizing { foo: { bar: 1 } } into: { 'foo.bar': 1 }
|
|
158
|
+
*
|
|
159
|
+
* @param {object} nested object
|
|
160
|
+
* @return {object} flattened object
|
|
161
|
+
*/
|
|
162
|
+
_flattenObject: function (obj) {
|
|
163
|
+
var flattened = {};
|
|
164
|
+
|
|
165
|
+
function recurse(current, property) {
|
|
166
|
+
if (!property && Object.getOwnPropertyNames(current).length === 0) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (Object(current) !== current || Array.isArray(current)) {
|
|
170
|
+
flattened[property] = current;
|
|
171
|
+
} else {
|
|
172
|
+
var isEmpty = true;
|
|
173
|
+
for (var p in current) {
|
|
174
|
+
isEmpty = false;
|
|
175
|
+
recurse(current[p], property ? property + '.' + p : p);
|
|
176
|
+
}
|
|
177
|
+
if (isEmpty) {
|
|
178
|
+
flattened[property] = {};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (obj) {
|
|
183
|
+
recurse(obj);
|
|
184
|
+
}
|
|
185
|
+
return flattened;
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Extract value from nested object using string path with dot notation
|
|
190
|
+
*
|
|
191
|
+
* @param {object} object to search in
|
|
192
|
+
* @param {string} path inside object
|
|
193
|
+
* @return {any|void} value under the path
|
|
194
|
+
*/
|
|
195
|
+
_objectPath: function (obj, path) {
|
|
196
|
+
if (Object.prototype.hasOwnProperty.call(obj, path)) {
|
|
197
|
+
return obj[path];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
var keys = path.replace(/\[(\w+)\]/g, '.$1').replace(/^\./, '').split('.');
|
|
201
|
+
var copy = {};
|
|
202
|
+
for (var attr in obj) {
|
|
203
|
+
if (Object.prototype.hasOwnProperty.call(obj, attr)) {
|
|
204
|
+
copy[attr] = obj[attr];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
for (var i = 0, l = keys.length; i < l; i++) {
|
|
209
|
+
if (typeof copy === 'object' && copy !== null && Object.hasOwnProperty.call(copy, keys[i])) {
|
|
210
|
+
copy = copy[keys[i]];
|
|
211
|
+
} else {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return copy;
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Parse rules, normalizing format into: { attribute: [{ name: 'age', value: 3 }] }
|
|
220
|
+
*
|
|
221
|
+
* @param {object} rules
|
|
222
|
+
* @return {object}
|
|
223
|
+
*/
|
|
224
|
+
_parseRules: function (rules) {
|
|
225
|
+
|
|
226
|
+
var parsedRules = {};
|
|
227
|
+
rules = this._flattenObject(rules);
|
|
228
|
+
|
|
229
|
+
for (var attribute in rules) {
|
|
230
|
+
|
|
231
|
+
var rulesArray = rules[attribute];
|
|
232
|
+
|
|
233
|
+
this._parseRulesCheck(attribute, rulesArray, parsedRules);
|
|
234
|
+
}
|
|
235
|
+
return parsedRules;
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
_parseRulesCheck: function (attribute, rulesArray, parsedRules, wildCardValues) {
|
|
241
|
+
if (attribute.indexOf('*') > -1) {
|
|
242
|
+
this._parsedRulesRecurse(attribute, rulesArray, parsedRules, wildCardValues);
|
|
243
|
+
} else {
|
|
244
|
+
this._parseRulesDefault(attribute, rulesArray, parsedRules, wildCardValues);
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
_parsedRulesRecurse: function (attribute, rulesArray, parsedRules, wildCardValues) {
|
|
249
|
+
var parentPath = attribute.substr(0, attribute.indexOf('*') - 1);
|
|
250
|
+
var propertyValue = this._objectPath(this.input, parentPath);
|
|
251
|
+
|
|
252
|
+
if (propertyValue) {
|
|
253
|
+
for (var propertyNumber = 0; propertyNumber < propertyValue.length; propertyNumber++) {
|
|
254
|
+
var workingValues = wildCardValues ? wildCardValues.slice() : [];
|
|
255
|
+
workingValues.push(propertyNumber);
|
|
256
|
+
this._parseRulesCheck(attribute.replace('*', propertyNumber), rulesArray, parsedRules, workingValues);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
_parseRulesDefault: function (attribute, rulesArray, parsedRules, wildCardValues) {
|
|
262
|
+
var attributeRules = [];
|
|
263
|
+
|
|
264
|
+
if (rulesArray instanceof Array) {
|
|
265
|
+
rulesArray = this._prepareRulesArray(rulesArray);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (typeof rulesArray === 'string') {
|
|
269
|
+
rulesArray = rulesArray.split('|');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
for (var i = 0, len = rulesArray.length, rule; i < len; i++) {
|
|
273
|
+
rule = typeof rulesArray[i] === 'string' ? this._extractRuleAndRuleValue(rulesArray[i]) : rulesArray[i];
|
|
274
|
+
if (rule.value) {
|
|
275
|
+
rule.value = this._replaceWildCards(rule.value, wildCardValues);
|
|
276
|
+
this._replaceWildCardsMessages(wildCardValues);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (Rules.isAsync(rule.name)) {
|
|
280
|
+
this.hasAsync = true;
|
|
281
|
+
}
|
|
282
|
+
attributeRules.push(rule);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
parsedRules[attribute] = attributeRules;
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
_replaceWildCards: function (path, nums) {
|
|
289
|
+
|
|
290
|
+
if (!nums) {
|
|
291
|
+
return path;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
var path2 = path;
|
|
295
|
+
nums.forEach(function (value) {
|
|
296
|
+
if(Array.isArray(path2)){
|
|
297
|
+
path2 = path2[0];
|
|
298
|
+
}
|
|
299
|
+
const pos = path2.indexOf('*');
|
|
300
|
+
if (pos === -1) {
|
|
301
|
+
return path2;
|
|
302
|
+
}
|
|
303
|
+
path2 = path2.substr(0, pos) + value + path2.substr(pos + 1);
|
|
304
|
+
});
|
|
305
|
+
if(Array.isArray(path)){
|
|
306
|
+
path[0] = path2;
|
|
307
|
+
path2 = path;
|
|
308
|
+
}
|
|
309
|
+
return path2;
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
_replaceWildCardsMessages: function (nums) {
|
|
313
|
+
var customMessages = this.messages.customMessages;
|
|
314
|
+
var self = this;
|
|
315
|
+
Object.keys(customMessages).forEach(function (key) {
|
|
316
|
+
if (nums) {
|
|
317
|
+
var newKey = self._replaceWildCards(key, nums);
|
|
318
|
+
customMessages[newKey] = customMessages[key];
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
this.messages._setCustom(customMessages);
|
|
323
|
+
},
|
|
324
|
+
/**
|
|
325
|
+
* Prepare rules if it comes in Array. Check for objects. Need for type validation.
|
|
326
|
+
*
|
|
327
|
+
* @param {array} rulesArray
|
|
328
|
+
* @return {array}
|
|
329
|
+
*/
|
|
330
|
+
_prepareRulesArray: function (rulesArray) {
|
|
331
|
+
var rules = [];
|
|
332
|
+
|
|
333
|
+
for (var i = 0, len = rulesArray.length; i < len; i++) {
|
|
334
|
+
if (typeof rulesArray[i] === 'object') {
|
|
335
|
+
for (var rule in rulesArray[i]) {
|
|
336
|
+
rules.push({
|
|
337
|
+
name: rule,
|
|
338
|
+
value: rulesArray[i][rule]
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
} else {
|
|
342
|
+
rules.push(rulesArray[i]);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return rules;
|
|
347
|
+
},
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Determines if the attribute is supplied with the original data object.
|
|
351
|
+
*
|
|
352
|
+
* @param {array} attribute
|
|
353
|
+
* @return {boolean}
|
|
354
|
+
*/
|
|
355
|
+
_suppliedWithData: function (attribute) {
|
|
356
|
+
return this.input.hasOwnProperty(attribute);
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Extract a rule and a value from a ruleString (i.e. min:3), rule = min, value = 3
|
|
361
|
+
*
|
|
362
|
+
* @param {string} ruleString min:3
|
|
363
|
+
* @return {object} object containing the name of the rule and value
|
|
364
|
+
*/
|
|
365
|
+
_extractRuleAndRuleValue: function (ruleString) {
|
|
366
|
+
var rule = {},
|
|
367
|
+
ruleArray;
|
|
368
|
+
|
|
369
|
+
rule.name = ruleString;
|
|
370
|
+
|
|
371
|
+
if (ruleString.indexOf(':') >= 0) {
|
|
372
|
+
ruleArray = ruleString.split(':');
|
|
373
|
+
rule.name = ruleArray[0];
|
|
374
|
+
rule.value = ruleArray.slice(1).join(':');
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return rule;
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Determine if attribute has any of the given rules
|
|
382
|
+
*
|
|
383
|
+
* @param {string} attribute
|
|
384
|
+
* @param {array} findRules
|
|
385
|
+
* @return {boolean}
|
|
386
|
+
*/
|
|
387
|
+
_hasRule: function (attribute, findRules) {
|
|
388
|
+
var rules = this.rules[attribute] || [];
|
|
389
|
+
for (var i = 0, len = rules.length; i < len; i++) {
|
|
390
|
+
if (findRules.indexOf(rules[i].name) > -1) {
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return false;
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Determine if attribute has any numeric-based rules.
|
|
399
|
+
*
|
|
400
|
+
* @param {string} attribute
|
|
401
|
+
* @return {Boolean}
|
|
402
|
+
*/
|
|
403
|
+
_hasNumericRule: function (attribute) {
|
|
404
|
+
return this._hasRule(attribute, this.numericRules);
|
|
405
|
+
},
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Determine if rule is validatable
|
|
409
|
+
*
|
|
410
|
+
* @param {Rule} rule
|
|
411
|
+
* @param {mixed} value
|
|
412
|
+
* @return {boolean}
|
|
413
|
+
*/
|
|
414
|
+
_isValidatable: function (rule, value) {
|
|
415
|
+
if (Array.isArray(value)) {
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
if (Rules.isImplicit(rule.name)) {
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return this.getRule('required').validate(value);
|
|
423
|
+
},
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Determine if we should stop validating.
|
|
427
|
+
*
|
|
428
|
+
* @param {string} attribute
|
|
429
|
+
* @param {boolean} rulePassed
|
|
430
|
+
* @return {boolean}
|
|
431
|
+
*/
|
|
432
|
+
_shouldStopValidating: function (attribute, rulePassed) {
|
|
433
|
+
|
|
434
|
+
var stopOnAttributes = this.stopOnAttributes;
|
|
435
|
+
if (typeof stopOnAttributes === 'undefined' || stopOnAttributes === false || rulePassed === true) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (stopOnAttributes instanceof Array) {
|
|
440
|
+
return stopOnAttributes.indexOf(attribute) > -1;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return true;
|
|
444
|
+
},
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Set custom attribute names.
|
|
448
|
+
*
|
|
449
|
+
* @param {object} attributes
|
|
450
|
+
* @return {void}
|
|
451
|
+
*/
|
|
452
|
+
setAttributeNames: function (attributes) {
|
|
453
|
+
this.messages._setAttributeNames(attributes);
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Set the attribute formatter.
|
|
458
|
+
*
|
|
459
|
+
* @param {fuction} func
|
|
460
|
+
* @return {void}
|
|
461
|
+
*/
|
|
462
|
+
setAttributeFormatter: function (func) {
|
|
463
|
+
this.messages._setAttributeFormatter(func);
|
|
464
|
+
},
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Get validation rule
|
|
468
|
+
*
|
|
469
|
+
* @param {string} name
|
|
470
|
+
* @return {Rule}
|
|
471
|
+
*/
|
|
472
|
+
getRule: function (name) {
|
|
473
|
+
return Rules.make(name, this);
|
|
474
|
+
},
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Stop on first error.
|
|
478
|
+
*
|
|
479
|
+
* @param {boolean|array} An array of attributes or boolean true/false for all attributes.
|
|
480
|
+
* @return {void}
|
|
481
|
+
*/
|
|
482
|
+
stopOnError: function (attributes) {
|
|
483
|
+
this.stopOnAttributes = attributes;
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Determine if validation passes
|
|
488
|
+
*
|
|
489
|
+
* @param {function} passes
|
|
490
|
+
* @return {boolean|undefined}
|
|
491
|
+
*/
|
|
492
|
+
passes: function (passes) {
|
|
493
|
+
var async = this._checkAsync('passes', passes);
|
|
494
|
+
if (async) {
|
|
495
|
+
return this.checkAsync(passes);
|
|
496
|
+
}
|
|
497
|
+
return this.check();
|
|
498
|
+
},
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Determine if validation fails
|
|
502
|
+
*
|
|
503
|
+
* @param {function} fails
|
|
504
|
+
* @return {boolean|undefined}
|
|
505
|
+
*/
|
|
506
|
+
fails: function (fails) {
|
|
507
|
+
var async = this._checkAsync('fails', fails);
|
|
508
|
+
if (async) {
|
|
509
|
+
return this.checkAsync(function () {}, fails);
|
|
510
|
+
}
|
|
511
|
+
return !this.check();
|
|
512
|
+
},
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Check if validation should be called asynchronously
|
|
516
|
+
*
|
|
517
|
+
* @param {string} funcName Name of the caller
|
|
518
|
+
* @param {function} callback
|
|
519
|
+
* @return {boolean}
|
|
520
|
+
*/
|
|
521
|
+
_checkAsync: function (funcName, callback) {
|
|
522
|
+
var hasCallback = typeof callback === 'function';
|
|
523
|
+
if (this.hasAsync && !hasCallback) {
|
|
524
|
+
throw funcName + ' expects a callback when async rules are being tested.';
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return this.hasAsync || hasCallback;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Set messages for language
|
|
534
|
+
*
|
|
535
|
+
* @param {string} lang
|
|
536
|
+
* @param {object} messages
|
|
537
|
+
* @return {this}
|
|
538
|
+
*/
|
|
539
|
+
Validator.setMessages = function (lang, messages) {
|
|
540
|
+
Lang._set(lang, messages);
|
|
541
|
+
return this;
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* Get messages for given language
|
|
546
|
+
*
|
|
547
|
+
* @param {string} lang
|
|
548
|
+
* @return {Messages}
|
|
549
|
+
*/
|
|
550
|
+
Validator.getMessages = function (lang) {
|
|
551
|
+
return Lang._get(lang);
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Set default language to use
|
|
556
|
+
*
|
|
557
|
+
* @param {string} lang
|
|
558
|
+
* @return {void}
|
|
559
|
+
*/
|
|
560
|
+
Validator.useLang = function (lang) {
|
|
561
|
+
this.prototype.lang = lang;
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Get default language
|
|
566
|
+
*
|
|
567
|
+
* @return {string}
|
|
568
|
+
*/
|
|
569
|
+
Validator.getDefaultLang = function () {
|
|
570
|
+
return this.prototype.lang;
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Set the attribute formatter.
|
|
575
|
+
*
|
|
576
|
+
* @param {fuction} func
|
|
577
|
+
* @return {void}
|
|
578
|
+
*/
|
|
579
|
+
Validator.setAttributeFormatter = function (func) {
|
|
580
|
+
this.prototype.attributeFormatter = func;
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Stop on first error.
|
|
585
|
+
*
|
|
586
|
+
* @param {boolean|array} An array of attributes or boolean true/false for all attributes.
|
|
587
|
+
* @return {void}
|
|
588
|
+
*/
|
|
589
|
+
Validator.stopOnError = function (attributes) {
|
|
590
|
+
this.prototype.stopOnAttributes = attributes;
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Register custom validation rule
|
|
595
|
+
*
|
|
596
|
+
* @param {string} name
|
|
597
|
+
* @param {function} fn
|
|
598
|
+
* @param {string} message
|
|
599
|
+
* @return {void}
|
|
600
|
+
*/
|
|
601
|
+
Validator.register = function (name, fn, message, fnReplacement) {
|
|
602
|
+
var lang = Validator.getDefaultLang();
|
|
603
|
+
Rules.register(name, fn);
|
|
604
|
+
Lang._setRuleMessage(lang, name, message);
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Register custom validation rule
|
|
609
|
+
*
|
|
610
|
+
* @param {string} name
|
|
611
|
+
* @param {function} fn
|
|
612
|
+
* @param {string} message
|
|
613
|
+
* @param {function} fnReplacement
|
|
614
|
+
* @return {void}
|
|
615
|
+
*/
|
|
616
|
+
Validator.registerImplicit = function (name, fn, message, fnReplacement) {
|
|
617
|
+
var lang = Validator.getDefaultLang();
|
|
618
|
+
Rules.registerImplicit(name, fn);
|
|
619
|
+
Lang._setRuleMessage(lang, name, message);
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Register asynchronous validation rule
|
|
624
|
+
*
|
|
625
|
+
* @param {string} name
|
|
626
|
+
* @param {function} fn
|
|
627
|
+
* @param {string} message
|
|
628
|
+
* @return {void}
|
|
629
|
+
*/
|
|
630
|
+
Validator.registerAsync = function (name, fn, message, fnReplacement) {
|
|
631
|
+
var lang = Validator.getDefaultLang();
|
|
632
|
+
Rules.registerAsync(name, fn);
|
|
633
|
+
Lang._setRuleMessage(lang, name, message);
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Register asynchronous validation rule
|
|
638
|
+
*
|
|
639
|
+
* @param {string} name
|
|
640
|
+
* @param {function} fn
|
|
641
|
+
* @param {string} message
|
|
642
|
+
* @return {void}
|
|
643
|
+
*/
|
|
644
|
+
Validator.registerAsyncImplicit = function (name, fn, message) {
|
|
645
|
+
var lang = Validator.getDefaultLang();
|
|
646
|
+
Rules.registerAsyncImplicit(name, fn);
|
|
647
|
+
Lang._setRuleMessage(lang, name, message);
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Register validator for missed validation rule
|
|
652
|
+
*
|
|
653
|
+
* @param {string} name
|
|
654
|
+
* @param {function} fn
|
|
655
|
+
* @param {string} message
|
|
656
|
+
* @return {void}
|
|
657
|
+
*/
|
|
658
|
+
Validator.registerMissedRuleValidator = function(fn, message) {
|
|
659
|
+
Rules.registerMissedRuleValidator(fn, message);
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
module.exports = Validator;
|