UNPKG

38.1 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue-property-decorator'), require('dayjs-ext')) :
3 typeof define === 'function' && define.amd ? define(['vue-property-decorator', 'dayjs-ext'], factory) :
4 (global['dist/cee-validate'] = global['dist/cee-validate'] || {}, global['dist/cee-validate'].umd = global['dist/cee-validate'].umd || {}, global['dist/cee-validate'].umd.js = factory(global.vuePropertyDecorator,global.dayjs));
5}(this, (function (vuePropertyDecorator,dayjs) { 'use strict';
6
7 dayjs = dayjs && dayjs.hasOwnProperty('default') ? dayjs['default'] : dayjs;
8
9 /*! *****************************************************************************
10 Copyright (c) Microsoft Corporation. All rights reserved.
11 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
12 this file except in compliance with the License. You may obtain a copy of the
13 License at http://www.apache.org/licenses/LICENSE-2.0
14
15 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
17 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
18 MERCHANTABLITY OR NON-INFRINGEMENT.
19
20 See the Apache Version 2.0 License for specific language governing permissions
21 and limitations under the License.
22 ***************************************************************************** */
23 /* global Reflect, Promise */
24
25 var extendStatics = function(d, b) {
26 extendStatics = Object.setPrototypeOf ||
27 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
28 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
29 return extendStatics(d, b);
30 };
31
32 function __extends(d, b) {
33 extendStatics(d, b);
34 function __() { this.constructor = d; }
35 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
36 }
37
38 var __assign = function() {
39 __assign = Object.assign || function __assign(t) {
40 for (var s, i = 1, n = arguments.length; i < n; i++) {
41 s = arguments[i];
42 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
43 }
44 return t;
45 };
46 return __assign.apply(this, arguments);
47 };
48
49 function __decorate(decorators, target, key, desc) {
50 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
51 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
52 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
53 return c > 3 && r && Object.defineProperty(target, key, r), r;
54 }
55
56 var FieldBag = /** @class */ (function () {
57 function FieldBag(items) {
58 this._items = items || [];
59 }
60 Object.defineProperty(FieldBag.prototype, "items", {
61 set: function (items) {
62 this.push(items);
63 },
64 enumerable: true,
65 configurable: true
66 });
67 /**
68 * Returns the corresping Field instance, or undefined if not found.
69 *
70 * @param {String} field - The name of the field.
71 * @param {String} scope? - Optional scope of the field.
72 * @returns {Field | undefined} - The Field instance, or undefined if not found.
73 */
74 FieldBag.prototype.get = function (field, scope) {
75 return this._items.find(function (item) { return scope
76 ? item.name === field && item.scope === scope
77 : item.name === field; });
78 };
79 /**
80 * Returns all fields registered in the FieldBag
81 *
82 * @param {String} scope? - If present, returns all the fields from that scope
83 * @returns {Array<Field>} - Array of field items
84 */
85 FieldBag.prototype.all = function (scope) {
86 return scope
87 ? this._items.filter(function (f) { return f.scope === scope; })
88 : this._items;
89 };
90 /**
91 * Check to see if a Field is preseint in the FieldBag, or if a Field
92 * exists in a given scope.
93 *
94 * @param {String} field - The name of the field
95 * @param {String} scope? - Optional scope of the field
96 * @returns {Boolean}
97 */
98 FieldBag.prototype.has = function (field, scope) {
99 return !!this._items.find(function (item) { return scope
100 ? item.name === field && item.scope === scope
101 : item.name === field; });
102 };
103 /**
104 * Add a new Field or an array of Field instances to the existing _items
105 * arrays.
106 *
107 * @param {Field | Array<Field>} scope? - If present, returns all the fields
108 * from that scope.
109 * @returns {void}
110 */
111 FieldBag.prototype.push = function (item) {
112 // Check if item is already present in the FieldBag instance
113 this._items.push.apply(this._items, Array.isArray(item) ? item : [item]);
114 };
115 /**
116 * Removes an existing field from the FieldBag instance.
117 *
118 * @param {String} field - The name of the field
119 * @param {String} scope? - Optional scope of the field
120 * @returns {void}
121 */
122 FieldBag.prototype.remove = function (field, scope) {
123 this._items = this._items.filter(function (item) { return scope && item.scope === scope
124 ? item.name !== field
125 : item.name !== field; });
126 };
127 return FieldBag;
128 }());
129
130 var RULES = {};
131 var RuleContainer = /** @class */ (function () {
132 function RuleContainer() {
133 }
134 Object.defineProperty(RuleContainer, "rules", {
135 get: function () {
136 return RULES;
137 },
138 enumerable: true,
139 configurable: true
140 });
141 /**
142 * Get a specific rule from the container.
143 *
144 * @param {String} ruleName - The name of the rule.
145 * @returns {ValidationRule} - the respective ValidationRule object.
146 */
147 RuleContainer.getRule = function (ruleName) {
148 return RULES[ruleName];
149 };
150 /**
151 * Adds a new rule to the container.
152 *
153 * @param ruleName - The name of the rule to be added.
154 * @param rule - The ValidationRule object.
155 * @returns {Void}
156 */
157 RuleContainer.add = function (ruleName, rule) {
158 RULES[ruleName] = rule;
159 };
160 /**
161 * Removes a rule from the container.
162 *
163 * @param ruleName - The name of the rule to be removed.
164 * @returns {Void}
165 */
166 RuleContainer.remove = function (ruleName) {
167 delete RULES[ruleName];
168 };
169 /**
170 * Checks if a rule exists in the container
171 *
172 * @param ruleName - The name of the rule.
173 * @returns {Boolean}
174 */
175 RuleContainer.has = function (ruleName) {
176 return !!RULES[ruleName];
177 };
178 return RuleContainer;
179 }());
180
181 /**
182 * Check value's constructor name.
183 * @param {*} value
184 * @param {String} constructor
185 * @returns {Boolean}
186 *
187 * @author Vitor Luiz Cavalcanti (https://github.com/VitorLuizC)
188 */
189 var is = function (value, constructor) {
190 return Object.prototype.toString.call(value) === "[object " + constructor + "]";
191 };
192
193 /**
194 * Test to see if an entity of the form `validations` object is an scope
195 * and not a FormValidation object.
196 *
197 * @param {Any} formEntity - The entity to be tested.
198 *
199 * @author Erik Isidore
200 * @version 0.1
201 */
202 var isFormScope = function (formEntity) {
203 if (!is(formEntity, 'Object'))
204 return false;
205 return Object.keys(formEntity)
206 .every(function (name) { return !RuleContainer.has(name); });
207 };
208
209 var Field = /** @class */ (function () {
210 function Field(options) {
211 this._flags = {
212 pristine: false,
213 dirty: false,
214 changed: false,
215 touched: false,
216 valid: false,
217 errors: []
218 };
219 this.el = options.el;
220 this._vm = options.vm;
221 this.name = options.name;
222 this.value = options.value;
223 this.scope = options.scope;
224 this.rules = this.mapRules(options.rules);
225 this.initialValue = options.value;
226 this.init(options);
227 }
228 Object.defineProperty(Field.prototype, "validate", {
229 get: function () {
230 if (!this._vm || !this._vm.$validator)
231 return function () { return []; };
232 var validate = this._vm.$validator.validate;
233 return validate.bind(this._vm.$validator, this.name, this.scope);
234 },
235 enumerable: true,
236 configurable: true
237 });
238 Object.defineProperty(Field.prototype, "watch", {
239 get: function () {
240 if (!this._vm || !this._vm.$validator)
241 return;
242 return this._vm.$watch.bind(this._vm);
243 },
244 enumerable: true,
245 configurable: true
246 });
247 Object.defineProperty(Field.prototype, "options", {
248 get: function () {
249 if (!this._vm || !this._vm.$validator)
250 return;
251 return this._vm.$validator.options;
252 },
253 enumerable: true,
254 configurable: true
255 });
256 Object.defineProperty(Field.prototype, "flags", {
257 get: function () { return this._flags; },
258 enumerable: true,
259 configurable: true
260 });
261 Object.defineProperty(Field.prototype, "errors", {
262 get: function () { return this._flags.errors; },
263 enumerable: true,
264 configurable: true
265 });
266 Object.defineProperty(Field.prototype, "error", {
267 get: function () { return this._flags.errors[0] || ''; },
268 enumerable: true,
269 configurable: true
270 });
271 /**
272 * Sets a new value to one of the instance's FieldFlags.
273 *
274 * @param {Keyof FieldFlags} flag - The flag name
275 * @param {Boolean | Array<String>} value - the new value to assigned to the flag
276 * @returns {void}
277 * @author Erik Isidore
278 */
279 Field.prototype.setFlag = function (flag, value) {
280 if (!Object.keys(this._flags).includes(flag))
281 return;
282 this._flags[flag] = value;
283 };
284 /**
285 * Initializes the Field instance.
286 *
287 * @param {FieldItem} options
288 * @returns {void}
289 * @author Erik Isidore
290 */
291 Field.prototype.init = function (options) {
292 if (process.env.NODE_ENV !== 'production' && !this.name)
293 console.warn('CeeValidate: A field declaration is missing a "name" attribute');
294 this.initFlags();
295 this.addValueListeners();
296 };
297 /**
298 * Initializes or resets the Field flags to their default values.
299 *
300 * @returns {void}
301 * @author Erik Isidore
302 */
303 Field.prototype.initFlags = function () {
304 var _this = this;
305 var flagNames = Object.keys(this._flags);
306 var defaultFlags = {
307 pristine: !this.value,
308 dirty: !!this.value,
309 touched: false,
310 changed: false,
311 valid: false,
312 errors: []
313 };
314 flagNames.forEach(function (flag) {
315 _this._flags[flag] = defaultFlags[flag];
316 });
317 };
318 /**
319 * Adds event listener for the blur event on the input, so that we can
320 * tell when the input has been `touched` by the user, and attaches a
321 * watcher to the input value, validating it's value whenever it changes.
322 *
323 * @returns {void}
324 * @author Erik Isidore
325 */
326 Field.prototype.addValueListeners = function () {
327 var _this = this;
328 if (!this.watch || !this.el)
329 return;
330 var onBlur = function () {
331 if (!_this._flags.touched)
332 _this._flags.touched = true;
333 if (!_this.options.noListeners)
334 _this.validate();
335 };
336 var onInput = function (value) {
337 _this.value = value;
338 _this._flags.changed = _this.value !== _this.initialValue;
339 if (!_this.options.noListeners)
340 _this.validate();
341 if (!_this._flags.dirty) {
342 _this._flags.dirty = true;
343 _this._flags.pristine = false;
344 }
345 };
346 this.el.addEventListener('focusout', onBlur.bind(this));
347 this.watch(this.scope ? this.scope + "." + this.name : this.name, onInput.bind(this));
348 };
349 /**
350 * Receives a FieldValidation entity, which can be
351 * A string: 'required|dateFormat:DD/MM/YYYY'
352 * An array of strings: ['required', 'dateFormat:DD/MM/YYYY']
353 * Or an object: { required: true, dateFormat: 'DD/MM/YYYY' }
354 *
355 * And turns this entity into a array of NormalizedRules, this
356 * array will contain an NormalizedRule object for every rule
357 * found in FieldValidation. A NormalizedRule is simply an
358 * object with the format: { ruleName: <name>, args: [<...>] }
359 *
360 * @param {FieldValidation} rules - The validation rules defined for the field.
361 * @returns {Array<NormalizedRule>} - A array containing a NormalizedRule for
362 * every validation rule defined for the field.
363 *
364 * @author Erik Isidore
365 */
366 Field.prototype.mapRules = function (rules) {
367 var stringToRules = function (ruleDef) { return ({
368 ruleName: ruleDef.split(':')[0],
369 args: ruleDef.split(':')[1] && ruleDef.split(':')[1].split(',')
370 }); };
371 var objToRules = function (rulesObj) {
372 return Object.keys(rulesObj).map(function (ruleName) { return ({
373 ruleName: ruleName,
374 args: !Array.isArray(rulesObj[ruleName])
375 ? [rulesObj[ruleName]]
376 : rulesObj[ruleName]
377 }); });
378 };
379 return typeof rules === 'string' && rules.length
380 ? rules.split('|').map(stringToRules)
381 : Array.isArray(rules) ? rules.map(stringToRules)
382 : rules && is(rules, 'Object') ? objToRules(rules)
383 : [];
384 };
385 /**
386 * Resets the field flags and it's value.
387 *
388 * @returns {void}
389 * @author Erik Isidore
390 */
391 Field.prototype.reset = function () {
392 this.value = this.initialValue;
393 this.initFlags();
394 };
395 /**
396 * Dynamically updates the field's rules and remaps them.
397 *
398 * @param {FieldValidation} rule - The new rules to be applied
399 * @returns {void}
400 *
401 * @author Erik Isidore
402 */
403 Field.prototype.setRule = function (rule) {
404 this.rules = this.mapRules(rule);
405 };
406 return Field;
407 }());
408
409 /**
410 * Checks if all characters in a given value are alphanumeric (letters
411 * and numbers), ignores whitespace.
412 *
413 * @param {String} value - the input value to be tested.
414 * @returns {boolean}
415 *
416 * @author Viniazvd, Erik Isidore
417 * @version 0.1
418 */
419 var rule = {
420 validate: function (value) {
421 if (!value)
422 return true;
423 return !!value.trim() && /^([0-9a-zA-Z\s]*)?$/.test(value.trim());
424 },
425 message: 'Deve conter apenas letras e números'
426 };
427 RuleContainer.add('alphanumeric', rule);
428
429 /**
430 * Executes a callback or an array of callbacks with `value` as an argument
431 * and returns true if every callback passes
432 *
433 * @param {Any} value - the input value to be validated.
434 * @param {Function | Array<Function>} - The callback or array of callbacks
435 * to be called on the value.
436 * @returns {boolean} - Returns true if every callback passes, false otherwise.
437 *
438 * @author Viniazvd, Erik Isidore
439 * @version 0.1
440 */
441 var rule$1 = {
442 validate: function (value) {
443 var callbacks = [];
444 for (var _i = 1; _i < arguments.length; _i++) {
445 callbacks[_i - 1] = arguments[_i];
446 }
447 return callbacks.every(function (f) { return f(value); });
448 },
449 message: 'Campo inválido'
450 };
451 RuleContainer.add('custom', rule$1);
452
453 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
454
455 function createCommonjsModule(fn, module) {
456 return module = { exports: {} }, fn(module, module.exports), module.exports;
457 }
458
459 var customParseFormat = createCommonjsModule(function (module, exports) {
460 !function(n,t){module.exports=t();}(commonjsGlobal,function(){var i=/(\[[^[]*\])|([-:/.()\s]+)|(A|a|YYYY|YY?|MM?|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d\d/,t=/\d\d?/,r=/[+-]\d\d:?\d\d/,a={},f={},y={},m=[31,0,31,30,31,30,31,31,30,31,30,31];function w(n){var c=n.match(i);if(!c)throw new Error('Invalid format: "'+n+'".');for(var d=c.length,t=0;t<d;t+=1){var r=c[t],e=a[r],o=f[r];c[t]=o?{regex:e,parser:o}:r.replace(/^\[|\]$/g,"");}return function(n){for(var t={},r=0,e=0;r<d;r+=1){var o=c[r];if("string"==typeof o){if(n.indexOf(o,e)!==e){var i=n.substr(e,o.length);throw new Error('Expected "'+o+'" at character '+e+', found "'+i+'".')}e+=o.length;}else{var a=o.regex,f=o.parser,s=n.substr(e),u=a.exec(s);if(!u||0!==u.index)throw new Error('Matching "'+a+'" at character '+e+' failed with "'+s+'".');var h=u[0];f.call(t,h),e+=h.length;}}return function(n){var t,r,e=n.day,o=n.month;if(t=2===o?(r=n.year)%4==0&&r%100!=0||r%400==0?29:28:m[o-1],!(1<=e&&e<=t))throw new Error('Invalid day: "'+e+'".')}(t),function(n){var t=n.afternoon;if(void 0!==t){var r=n.hours;t?r<12&&(n.hours+=12):12===r&&(n.hours=0),delete n.afternoon;}}(t),t}}function e(n,t){a[n]=t;}function o(n,r,e){var t;"string"==typeof n&&(n=[n]),t="string"==typeof r?e?function(n){var t=+n;if(!e(t))throw new Error("Invalid "+r+': "'+n+'".');this[r]=t;}:function(n){this[r]=+n;}:r;for(var o=0,i=n.length;o<i;o+=1)f[n[o]]=t;}e("A",/[AP]M/),o(["A"],function(n){this.afternoon="PM"===n;}),e("a",/[ap]m/),o(["a"],function(n){this.afternoon="pm"===n;}),e("S",/\d/),e("SS",n),e("SSS",/\d{3}/);for(var s=function(n,t){o(n,function(n){this.milliseconds=+n*t;});},u="S",h=100;1<=h;u+="S",h/=10)s(u,h);e("s",t),e("ss",n),o(["s","ss"],"seconds",function(n){return n<=59}),e("m",t),e("mm",n),o(["m","mm"],"minutes",function(n){return n<=59}),e("H",t),e("h",t),e("HH",n),e("hh",n),o(["H","HH"],"hours",function(n){return n<=23}),o(["h","hh"],"hours",function(n){return 1<=n&&n<=12}),e("D",t),e("DD",n),o(["D","DD"],"day"),e("M",t),e("MM",n),o(["M","MM"],"month",function(n){return 1<=n&&n<=12}),e("Y",/[+-]?\d+/),e("YY",n),e("YYYY",/\d{4}/),o(["Y","YYYY"],"year"),o("YY",function(n){n=+n,this.year=n+(68<n?1900:2e3);}),e("z",/[A-Z]{3,4}/),o("z",function(n){(this.zone||(this.zone={})).abbreviation=n;}),e("Z",r),e("ZZ",r),o(["Z","ZZ"],function(n){(this.zone||(this.zone={})).offset=function(n){var t=n.match(/([+-]|\d\d)/g),r=60*t[1]+ +t[2],e=0===r?0:"+"===t[0]?-r:r;if(!(e%15==0&&Math.abs(e)<=765))throw new Error('Invalid time zone offset: "'+n+'".');return e}(n);});return function(n,t){var r=t.prototype,p=r.parse;r.parse=function(n){var t,r,e,o=n.date,i=n.format;if(i){try{var a,f=(t=o,(e=y[r=i])||(e=w(r),y[r]=e),e(t)),s=f.year,u=f.month,h=f.day,c=f.hours,d=f.minutes,m=f.seconds,v=f.milliseconds,l=f.zone;if(l){var Y=Date.UTC(s,u-1,h,c||0,d||0,m||0,v||0)+60*l.offset*1e3;a=new Date(Y);}else a=new Date(s,u-1,h,c||0,d||0,m||0,v||0);this.$d=a;}catch(n){this.$d=new Date(Number.NaN);}this.init(n);}else p.call(this,n);};}});
461
462 });
463
464 dayjs.extend(customParseFormat);
465 /**
466 * Validate if the input value produces a valid date and optionally if
467 * it follows a given date format.
468 *
469 * @param {String | Number} value - The value of the input to be validated,
470 * if `value` is a String, the validator may also receive a format param to
471 * check if the string has the correct format.
472 * @param {String} format? - Optional parameter to validate whether the the
473 * given input value has the correct format. If given, the value must be a
474 * string, otherwise this parameter is completely ignored.
475 * @returns {boolean} True if the given value is valid or empty, false otherwise.
476 * If you want to check for empty value, use the 'required' rule.
477 *
478 * @author Erik Isidore
479 * @version 0.1
480 */
481 var rule$2 = {
482 validate: function (value, format) {
483 if (format === void 0) { format = 'DD/MM/YYYY'; }
484 if (!value)
485 return true;
486 var options = is(value, 'String') ? { format: format } : {};
487 var date = dayjs(value, options);
488 return date.isValid();
489 },
490 message: 'Data inválida.'
491 };
492 RuleContainer.add('dateFormat', rule$2);
493
494 /**
495 * Checks if all characters in a given value are numeric, ignores whitespace.
496 *
497 * @param {String} value - The input value to be validated.
498 * @returns {Boolean}
499 *
500 * @author Viniazvd, Erik Isidore
501 * @version 0.1
502 */
503 var rule$3 = {
504 validate: function (value) {
505 if (!value)
506 return true;
507 return !!value.trim() && /^(\d+(\.\d+)?$)/.test(value.trim());
508 },
509 message: 'Deve conter apenas números.'
510 };
511 RuleContainer.add('numeric', rule$3);
512
513 /**
514 * Receives a value and a regular expression and returns the result of
515 * executing the regex on the value.
516 *
517 * @param {String} value - Input value.
518 * @param {Regex} regex - Regular expression object.
519 * @returns {boolean}
520 *
521 * @author Erik Isidore
522 * @version 0.1
523 */
524 var rule$4 = {
525 validate: function (value, regex) {
526 if (!value)
527 return true;
528 if (!is(value, 'String') || !is(regex, 'RegExp'))
529 return false;
530 return !!value && regex.test(value);
531 },
532 message: 'Formato inválido.'
533 };
534 RuleContainer.add('regex', rule$4);
535
536 /**
537 * Validate if the given value is not empty
538 *
539 * @param {Any} value - The value of the input to be validated.
540 * @returns {boolean} - True if the given value is not empty, false otherwise.
541 *
542 * @author Viniazvd, Erik Isidore
543 * @version 0.1
544 */
545 var rule$5 = {
546 validate: function (value) {
547 if (Array.isArray(value))
548 return !!value.length;
549 if (typeof value === 'object')
550 return !!Object.keys(value).length;
551 if (typeof value === 'string')
552 return !!value.trim().length;
553 if (typeof value === 'number')
554 return !!value;
555 if (typeof value === 'boolean')
556 return true;
557 return !!value;
558 },
559 message: 'Campo obrigatório.'
560 };
561 RuleContainer.add('required', rule$5);
562
563 /**
564 * Checks to see if a given value is bigger than max length, if value
565 * is string/array, checks the string length, if it is a number,
566 * checks the value itself.
567 *
568 * @param {Array<any> | String | Number} value - Then given value
569 * @param {Number | String} maxLength - the max length.
570 * @returns {Boolean} - False if value exceeds max length.
571 *
572 * @author Erik Isidore
573 * @version 0.1
574 */
575 var rule$6 = {
576 validate: function (value, maxLength) {
577 if (!value)
578 return true;
579 if (Array.isArray(value) || typeof value === 'string')
580 return (value || []).length <= maxLength;
581 return maxLength >= value;
582 },
583 message: 'Valor acima do limite.'
584 };
585 RuleContainer.add('maxLength', rule$6);
586
587 /**
588 * Checks to see if a given value is bigger than min length, if value
589 * is string/array, checks the string length, if it is a number,
590 * checks the value itself.
591 *
592 * @param {Array<any> | String | Number} value - Then given value
593 * @param {Number | String} minLength - the min length.
594 * @returns {Boolean} - False if value is smaller than min length.
595 *
596 * @author Erik Isidore
597 * @version 0.1
598 */
599 var rule$7 = {
600 validate: function (value, minLength) {
601 if (!value)
602 return true;
603 if (Array.isArray(value) || typeof value === 'string')
604 return (value || []).length >= minLength;
605 return value >= minLength;
606 },
607 message: 'Valor abaixo do limite.'
608 };
609 RuleContainer.add('minLength', rule$7);
610
611 var rule$8 = {
612 validate: function (value) {
613 if (!value)
614 return true;
615 var FTAP = '3298765432';
616 var numPis = (value + '').replace(/[^\d]+/g, '');
617 var total = FTAP
618 .split('')
619 .reduce(function (total, digit, index) { return total + (+numPis[index] * +digit); }, 0);
620 var rest = (total % 11);
621 if (rest !== 0)
622 rest = 11 - rest;
623 if (rest === 10 || rest === 11)
624 rest = (rest + '').slice(1, 2);
625 if (+rest !== +(numPis.slice(10, 11)))
626 return false;
627 return true;
628 },
629 message: 'Número de PIS inválido'
630 };
631 RuleContainer.add('pis', rule$8);
632
633 var ScopedValidator = /** @class */ (function () {
634 function ScopedValidator(vm) {
635 var _this = this;
636 this.scopes = [];
637 this._options = {};
638 this.validations = {};
639 this._vm = vm;
640 this.fields = new FieldBag();
641 vm.$nextTick(function () {
642 if (_this._vm.$options.validatorOptions)
643 _this.options = _this._vm.$options.validatorOptions;
644 if (_this._vm.$options.validations)
645 _this.init(_this._vm.$options.validations);
646 });
647 }
648 Object.defineProperty(ScopedValidator.prototype, "options", {
649 get: function () {
650 return this._options;
651 },
652 set: function (options) {
653 this._options = is(options, 'Function')
654 ? options(this._vm)
655 : __assign({}, options);
656 },
657 enumerable: true,
658 configurable: true
659 });
660 /**
661 * This two following functions are responsible for bootstraping
662 * the ScopedValidation class with the given validation options.
663 * The public init function exists to ensure that whenever we're
664 * bootstraping the ScopedValidator class, the DOM will be accessible
665 * through the _vm.
666 *
667 * @param template - The form validations template object.
668 * @returns {void}
669 *
670 * @author Erik Isidore
671 */
672 ScopedValidator.prototype.init = function (template) {
673 this._vm.$nextTick(this.__init.bind(this, template));
674 };
675 ScopedValidator.prototype.__init = function (template) {
676 this.scopes = Object.keys(template).filter(function (key) { return isFormScope(template[key]); });
677 this.fields.items = this.initFields(template);
678 this.validations = this.mapValidations();
679 };
680 /**
681 * Receives a FormTemplate object and maps the fields validation rules
682 * in it to populate the `fields` instance property with Field instances.
683 *
684 * @param {FormTemplate} template - The form or forms validation object.
685 * @returns {void}
686 *
687 * @author Erik Isidore
688 */
689 ScopedValidator.prototype.initFields = function (template) {
690 var _this = this;
691 var _a;
692 var mapField = function (name, rules, scope) {
693 var fieldOptions = {
694 name: name,
695 rules: rules,
696 scope: scope,
697 vm: _this._vm,
698 el: _this.getFieldEl(name, scope),
699 value: scope ? _this._vm[scope][name] : _this._vm[name],
700 };
701 return new Field(fieldOptions);
702 };
703 // This will map each form scope name to an array of Field instances,
704 // producing an Array of Field arrays, crazy rite? Each field will
705 // have its respective scope assigned to it.
706 var scopes = this.scopes.map(function (scope) {
707 var formScope = template[scope];
708 return Object.keys(formScope)
709 .map(function (fieldName) { return mapField(fieldName, formScope[fieldName], scope); });
710 });
711 var fields = Object.keys(template)
712 .filter(function (key) { return !isFormScope(template[key]); })
713 .map(function (key) { return mapField(key, template[key]); });
714 return (_a = Array.prototype).concat.apply(_a, [fields].concat(scopes));
715 };
716 /**
717 * Generetes the validation flags object based on the form scopes.
718 *
719 * @returns {FormValidationFlags}
720 *
721 * @author Erik Isidore
722 */
723 ScopedValidator.prototype.mapValidations = function () {
724 var _this = this;
725 var mapFlags = function (scope) { return _this.fields.all(scope)
726 .reduce(function (acc, field) {
727 var _a;
728 return (__assign({}, acc, (_a = {}, _a[field.name] = field.flags, _a)));
729 }, {}); };
730 var mapFormScopes = function (acc, scope) {
731 var _a;
732 return (__assign({}, acc, (_a = {}, _a[scope] = mapFlags(scope), _a)));
733 };
734 return this.scopes.length > 1
735 ? this.scopes.reduce(mapFormScopes, {})
736 : mapFlags();
737 };
738 /**
739 * Receives a fieldName and optionally it's scope and returns the HTML
740 * Element corresponding to that field in the DOM.
741 *
742 * @param {String} fieldName - The name of the field
743 * @param {String} scope? - Optional form scope.
744 * @returns {Element} - The first matching element found in the component DOM.
745 *
746 * @author Erik Isidore
747 */
748 ScopedValidator.prototype.getFieldEl = function (fieldName, scope) {
749 var fieldQuery = scope
750 ? "form[name=\"" + scope + "\"] [name=\"" + fieldName + "\"]"
751 : "[name=\"" + fieldName + "\"]";
752 var fields = this._vm.$el.querySelectorAll(fieldQuery);
753 if (process.env.NODE_ENV !== 'production' && !fields.length)
754 console.warn("CeeValidate: Field \"" + fieldName + "\" could not be found in the DOM");
755 return fields[0];
756 };
757 /**
758 * @param {String} fieldName -
759 * @param {String} scope? -
760 * @returns {void}
761 *
762 * @author Erik Isidore
763 */
764 ScopedValidator.prototype.validate = function (fieldName, scope) {
765 var field = this.fields.get(fieldName, scope);
766 // Field doesn't exist, return false (invalid field)
767 if (!field)
768 return false;
769 var mapErrors = function (_a) {
770 var ruleName = _a.ruleName, args = _a.args;
771 var rule = RuleContainer.getRule(ruleName);
772 var hasError = !rule.validate.apply(null, [field.value].concat((args || [])));
773 var errorMessage = rule.message;
774 return hasError ? errorMessage : '';
775 };
776 var fieldErrors = field.rules
777 .map(mapErrors)
778 .filter(function (message) { return !!message; });
779 field.setFlag('errors', fieldErrors);
780 field.setFlag('valid', !fieldErrors.length);
781 return !fieldErrors.length;
782 };
783 /**
784 * Executes the validate() method on all Field instances.
785 *
786 * @param {String} scope? -
787 * @returns {void}
788 *
789 * @author Erik Isidore
790 */
791 ScopedValidator.prototype.validateAll = function (scope) {
792 var fieldFlags = this.fields.all(scope)
793 .map(function (field) { return field.validate(); });
794 var isValid = fieldFlags.every(function (isValid) { return !!isValid; });
795 this.options = __assign({}, (this.options || {}), { noListeners: false });
796 return isValid;
797 };
798 /**
799 * Resets all of the fields validation flags.
800 *
801 * @param {String} scope? -
802 * @returns {void}
803 *
804 * @author Erik Isidore
805 */
806 ScopedValidator.prototype.reset = function (scope) {
807 this.fields.all(scope).forEach(function (field) { return field.reset(); });
808 };
809 /**
810 * Attaches a new field to the validator.
811 *
812 * @param {}
813 * @returns {void}
814 *
815 * @author Erik Isidore
816 */
817 ScopedValidator.prototype.attach = function (field) {
818 var newField = new Field({
819 vm: this._vm,
820 name: field.name,
821 rules: field.rules,
822 scope: field.scope,
823 el: this.getFieldEl(field.name, field.scope),
824 value: field.scope ? this._vm[field.scope][field.name] : this._vm[field.name]
825 });
826 this.fields.push(newField);
827 this.validations = this.mapValidations();
828 };
829 /**
830 * Detaches an existing field from the validator.
831 *
832 * @param {String} field - The name of the field
833 * @param {String} scope? - Optional scope of the field
834 * @returns {void}
835 *
836 * @author Erik Isidore
837 */
838 ScopedValidator.prototype.detach = function (field, scope) {
839 this.fields.remove(field, scope);
840 this.validations = this.mapValidations();
841 };
842 /**
843 * Sets the rule of a field and validate it if it has changed.
844 *
845 * @param {Object<name: string, scope: string>} field - Object with name
846 * and scope of the field.
847 * @param {FieldValidation} rules - The rules to be set in the field
848 * @returns {void}
849 */
850 ScopedValidator.prototype.setFieldRule = function (field, rules) {
851 var fieldInstance = this.fields.get(field.name, field.scope);
852 if (!fieldInstance)
853 return;
854 fieldInstance.setRule(rules);
855 if (fieldInstance.flags.changed)
856 fieldInstance.validate();
857 };
858 return ScopedValidator;
859 }());
860
861 // eslint-disable
862 var FormValidator = /** @class */ (function (_super) {
863 __extends(FormValidator, _super);
864 function FormValidator() {
865 return _super !== null && _super.apply(this, arguments) || this;
866 }
867 // In the future we'll use this function to pass mixin options
868 // and make some checkings before instantiating the ScopedValidator
869 FormValidator.prototype.beforeCreate = function () {
870 var _this = this;
871 // Get Vue constructor
872 var Vue = this.$options._base;
873 this.$validator = new ScopedValidator(this);
874 // Setup computed properties on the component
875 if (!this.$options.computed)
876 this.$options.computed = {};
877 Vue.util.defineReactive(this.$validator, 'validations', this.$validator.validations);
878 this.$options.computed['$validations'] = function () { return _this.$validator.validations; };
879 };
880 FormValidator = __decorate([
881 vuePropertyDecorator.Component
882 ], FormValidator);
883 return FormValidator;
884 }(vuePropertyDecorator.Vue));
885
886 return FormValidator;
887
888})));
889//# sourceMappingURL=cee-validate.umd.js.map