@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.
Files changed (109) hide show
  1. package/.eslintrc.js +27 -0
  2. package/CONTRIBUTE.md +34 -0
  3. package/LICENSE +20 -0
  4. package/README.md +607 -0
  5. package/dist/lang/ar.js +66 -0
  6. package/dist/lang/az.js +104 -0
  7. package/dist/lang/be.js +105 -0
  8. package/dist/lang/bg.js +105 -0
  9. package/dist/lang/bs.js +106 -0
  10. package/dist/lang/ca.js +40 -0
  11. package/dist/lang/cs.js +107 -0
  12. package/dist/lang/cy.js +106 -0
  13. package/dist/lang/da.js +51 -0
  14. package/dist/lang/de.js +46 -0
  15. package/dist/lang/el.js +43 -0
  16. package/dist/lang/en.js +54 -0
  17. package/dist/lang/es.js +40 -0
  18. package/dist/lang/et.js +106 -0
  19. package/dist/lang/eu.js +106 -0
  20. package/dist/lang/fa.js +42 -0
  21. package/dist/lang/fi.js +51 -0
  22. package/dist/lang/fr.js +40 -0
  23. package/dist/lang/hr.js +106 -0
  24. package/dist/lang/hu.js +106 -0
  25. package/dist/lang/id.js +51 -0
  26. package/dist/lang/it.js +41 -0
  27. package/dist/lang/ja.js +54 -0
  28. package/dist/lang/ka.js +106 -0
  29. package/dist/lang/ko.js +106 -0
  30. package/dist/lang/lt.js +106 -0
  31. package/dist/lang/lv.js +106 -0
  32. package/dist/lang/mk.js +106 -0
  33. package/dist/lang/mn.js +106 -0
  34. package/dist/lang/ms.js +106 -0
  35. package/dist/lang/nb_NO.js +42 -0
  36. package/dist/lang/nl.js +51 -0
  37. package/dist/lang/pl.js +42 -0
  38. package/dist/lang/pt.js +110 -0
  39. package/dist/lang/pt_BR.js +105 -0
  40. package/dist/lang/ro.js +51 -0
  41. package/dist/lang/ru.js +40 -0
  42. package/dist/lang/se.js +106 -0
  43. package/dist/lang/sl.js +106 -0
  44. package/dist/lang/sq.js +106 -0
  45. package/dist/lang/sr.js +106 -0
  46. package/dist/lang/sv.js +105 -0
  47. package/dist/lang/tr.js +51 -0
  48. package/dist/lang/ua.js +40 -0
  49. package/dist/lang/uk.js +106 -0
  50. package/dist/lang/vi.js +42 -0
  51. package/dist/lang/zh.js +42 -0
  52. package/dist/lang/zh_TW.js +42 -0
  53. package/dist/validator.js +2183 -0
  54. package/package.json +78 -0
  55. package/src/async.js +81 -0
  56. package/src/attributes.js +199 -0
  57. package/src/errors.js +77 -0
  58. package/src/lang/ar.js +63 -0
  59. package/src/lang/az.js +101 -0
  60. package/src/lang/be.js +102 -0
  61. package/src/lang/bg.js +102 -0
  62. package/src/lang/bs.js +103 -0
  63. package/src/lang/ca.js +37 -0
  64. package/src/lang/cs.js +104 -0
  65. package/src/lang/cy.js +103 -0
  66. package/src/lang/da.js +48 -0
  67. package/src/lang/de.js +43 -0
  68. package/src/lang/el.js +40 -0
  69. package/src/lang/en.js +51 -0
  70. package/src/lang/es.js +37 -0
  71. package/src/lang/et.js +103 -0
  72. package/src/lang/eu.js +103 -0
  73. package/src/lang/fa.js +39 -0
  74. package/src/lang/fi.js +48 -0
  75. package/src/lang/fr.js +37 -0
  76. package/src/lang/hr.js +103 -0
  77. package/src/lang/hu.js +103 -0
  78. package/src/lang/id.js +48 -0
  79. package/src/lang/it.js +38 -0
  80. package/src/lang/ja.js +51 -0
  81. package/src/lang/ka.js +103 -0
  82. package/src/lang/ko.js +103 -0
  83. package/src/lang/lt.js +103 -0
  84. package/src/lang/lv.js +103 -0
  85. package/src/lang/mk.js +103 -0
  86. package/src/lang/mn.js +103 -0
  87. package/src/lang/ms.js +103 -0
  88. package/src/lang/nb_NO.js +39 -0
  89. package/src/lang/nl.js +48 -0
  90. package/src/lang/pl.js +39 -0
  91. package/src/lang/pt.js +107 -0
  92. package/src/lang/pt_BR.js +102 -0
  93. package/src/lang/ro.js +48 -0
  94. package/src/lang/ru.js +37 -0
  95. package/src/lang/se.js +47 -0
  96. package/src/lang/sl.js +103 -0
  97. package/src/lang/sq.js +103 -0
  98. package/src/lang/sr.js +103 -0
  99. package/src/lang/sv.js +102 -0
  100. package/src/lang/tr.js +48 -0
  101. package/src/lang/ua.js +37 -0
  102. package/src/lang/uk.js +103 -0
  103. package/src/lang/vi.js +39 -0
  104. package/src/lang/zh.js +39 -0
  105. package/src/lang/zh_TW.js +39 -0
  106. package/src/lang.js +78 -0
  107. package/src/messages.js +152 -0
  108. package/src/rules.js +864 -0
  109. package/src/validator.js +662 -0
@@ -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;