quival 0.3.3 → 0.4.0
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/README.md +14 -1
- package/dist/locales/en.js +1 -1
- package/dist/locales/en.min.js +1 -1
- package/dist/locales/ms.js +1 -1
- package/dist/locales/ms.min.js +1 -1
- package/dist/quival.js +69 -27
- package/dist/quival.min.js +2 -2
- package/package.json +1 -1
- package/src/Checkers.js +11 -3
- package/src/Validator.js +65 -24
- package/test/validation.js +279 -5
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ There are 2 ways to start using `quival` in your project.
|
|
|
29
29
|
Get the script from [jsDelivr CDN page](https://www.jsdelivr.com/package/npm/quival) and include it in your HTML page.
|
|
30
30
|
|
|
31
31
|
```html
|
|
32
|
-
<script src="https://cdn.jsdelivr.net/npm/quival@0.
|
|
32
|
+
<script src="https://cdn.jsdelivr.net/npm/quival@0.4.x/dist/quival.min.js"></script>
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
Extract `Validator` class from `quival` global variable, and you are good to go.
|
|
@@ -83,6 +83,7 @@ Validator.addChecker(
|
|
|
83
83
|
|
|
84
84
|
// Prepare arguments
|
|
85
85
|
const data = {
|
|
86
|
+
refcode: '1bc',
|
|
86
87
|
username: 'idea💡',
|
|
87
88
|
name: '',
|
|
88
89
|
email: 'test',
|
|
@@ -98,6 +99,15 @@ const data = {
|
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
const rules = {
|
|
102
|
+
refcode: [
|
|
103
|
+
'required',
|
|
104
|
+
function (attribute, value) { // Closure rule
|
|
105
|
+
return {
|
|
106
|
+
success: /^[a-z]/i.test(value),
|
|
107
|
+
message: 'The :attribute field must start with a letter.',
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
],
|
|
101
111
|
username: ['required', 'ascii', 'min:3'],
|
|
102
112
|
name: ['required', 'min:3'],
|
|
103
113
|
email: ['required', 'email'],
|
|
@@ -138,6 +148,9 @@ The produced error messages for the code snippet above.
|
|
|
138
148
|
|
|
139
149
|
```json
|
|
140
150
|
{
|
|
151
|
+
"refcode": [
|
|
152
|
+
"The refcode field must start with a letter."
|
|
153
|
+
],
|
|
141
154
|
"username": [
|
|
142
155
|
"The username field must only contain single-byte alphanumeric characters and symbols."
|
|
143
156
|
],
|
package/dist/locales/en.js
CHANGED
package/dist/locales/en.min.js
CHANGED
package/dist/locales/ms.js
CHANGED
package/dist/locales/ms.min.js
CHANGED
package/dist/quival.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* quival v0.
|
|
2
|
+
* quival v0.4.0 (https://github.com/apih/quival)
|
|
3
3
|
* (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -736,10 +736,16 @@ var quival = (function (exports) {
|
|
|
736
736
|
return false;
|
|
737
737
|
}
|
|
738
738
|
checkMimes(attribute, value, parameters) {
|
|
739
|
-
if (this.checkFile(attribute, value)) {
|
|
740
|
-
return
|
|
739
|
+
if (!this.checkFile(attribute, value)) {
|
|
740
|
+
return false;
|
|
741
741
|
}
|
|
742
|
-
|
|
742
|
+
if (parameters.includes('jpg') && !parameters.includes('jpeg')) {
|
|
743
|
+
parameters.push('jpeg');
|
|
744
|
+
}
|
|
745
|
+
if (parameters.includes('jpeg') && !parameters.includes('jpg')) {
|
|
746
|
+
parameters.push('jpg');
|
|
747
|
+
}
|
|
748
|
+
return parameters.includes(value.name.split('.').pop().toLowerCase());
|
|
743
749
|
}
|
|
744
750
|
checkExtensions(attribute, value, parameters) {
|
|
745
751
|
return this.checkMimes(attribute, value, parameters);
|
|
@@ -1362,10 +1368,9 @@ var quival = (function (exports) {
|
|
|
1362
1368
|
for (const [attribute, attributeRules] of Object.entries(rules)) {
|
|
1363
1369
|
const attributes = attribute.includes('*') ? this.parseWildcardAttribute(attribute) : [attribute];
|
|
1364
1370
|
for (const attribute of attributes) {
|
|
1365
|
-
const parsedAttributeRules =
|
|
1371
|
+
const parsedAttributeRules = [];
|
|
1366
1372
|
for (const attributeRule of this.parseAttributeRules(attributeRules)) {
|
|
1367
|
-
|
|
1368
|
-
parsedAttributeRules[rule] = parameters;
|
|
1373
|
+
parsedAttributeRules.push(this.parseAttributeRule(attributeRule));
|
|
1369
1374
|
}
|
|
1370
1375
|
parsedRules[attribute] = parsedAttributeRules;
|
|
1371
1376
|
}
|
|
@@ -1392,13 +1397,17 @@ var quival = (function (exports) {
|
|
|
1392
1397
|
parseAttributeRules(rules) {
|
|
1393
1398
|
if (Array.isArray(rules)) {
|
|
1394
1399
|
return rules;
|
|
1400
|
+
} else if (typeof rules === 'function') {
|
|
1401
|
+
return [rules];
|
|
1395
1402
|
} else {
|
|
1396
1403
|
return String(rules).split('|');
|
|
1397
1404
|
}
|
|
1398
1405
|
}
|
|
1399
1406
|
parseAttributeRule(rule) {
|
|
1400
1407
|
if (Array.isArray(rule)) {
|
|
1401
|
-
return [rule
|
|
1408
|
+
return [rule[0] ?? '', rule.slice(1)];
|
|
1409
|
+
} else if (typeof rule === 'function') {
|
|
1410
|
+
return [rule, []];
|
|
1402
1411
|
}
|
|
1403
1412
|
const index = rule.indexOf(':');
|
|
1404
1413
|
if (index === -1) {
|
|
@@ -1412,39 +1421,61 @@ var quival = (function (exports) {
|
|
|
1412
1421
|
this.#errors = new ErrorBag();
|
|
1413
1422
|
const tasks = [];
|
|
1414
1423
|
const skippedAttributes = [];
|
|
1424
|
+
for (const [attribute, rules] of Object.entries(this.#rules)) {
|
|
1425
|
+
for (const [rule] of rules) {
|
|
1426
|
+
if (
|
|
1427
|
+
rule === '' ||
|
|
1428
|
+
typeof rule === 'function' ||
|
|
1429
|
+
typeof this.#checkers[toCamelCase('check_' + rule)] === 'function' ||
|
|
1430
|
+
Validator.#dummyRules.includes(rule)
|
|
1431
|
+
)
|
|
1432
|
+
continue;
|
|
1433
|
+
throw new Error(`Invalid validation rule: ${rule}`);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1415
1436
|
for (const [attribute, rules] of Object.entries(this.#rules)) {
|
|
1416
1437
|
let value = this.getValue(attribute);
|
|
1417
|
-
|
|
1438
|
+
const hasRule = (ruleName) => rules.some((rule) => rule[0] === ruleName);
|
|
1439
|
+
if (hasRule('sometimes') && typeof value === 'undefined') {
|
|
1418
1440
|
skippedAttributes.push(attribute);
|
|
1419
1441
|
continue;
|
|
1420
1442
|
}
|
|
1421
1443
|
tasks.push(async () => {
|
|
1422
|
-
const doBail = this.#alwaysBail ||
|
|
1423
|
-
const isNullable =
|
|
1444
|
+
const doBail = this.#alwaysBail || hasRule('bail');
|
|
1445
|
+
const isNullable = hasRule('nullable');
|
|
1424
1446
|
let noError = true;
|
|
1425
|
-
for (const [rule, parameters] of
|
|
1447
|
+
for (const [rule, parameters] of rules) {
|
|
1426
1448
|
if (
|
|
1427
1449
|
rule === '' ||
|
|
1428
|
-
(
|
|
1450
|
+
(typeof rule !== 'function' &&
|
|
1451
|
+
!Validator.#implicitRules.includes(rule) &&
|
|
1429
1452
|
(typeof value === 'undefined' || (typeof value === 'string' && value.trim() === '') || (isNullable && value === null)))
|
|
1430
1453
|
) {
|
|
1431
1454
|
skippedAttributes.push(attribute);
|
|
1432
1455
|
continue;
|
|
1433
1456
|
}
|
|
1434
1457
|
let result, success, message;
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1458
|
+
const checker = (() => {
|
|
1459
|
+
if (typeof rule === 'function') {
|
|
1460
|
+
return rule;
|
|
1461
|
+
} else {
|
|
1462
|
+
const checker = this.#checkers[toCamelCase('check_' + rule)] ?? null;
|
|
1463
|
+
if (checker === null && Validator.#dummyRules.includes(rule)) {
|
|
1464
|
+
return () => true;
|
|
1465
|
+
}
|
|
1466
|
+
return checker;
|
|
1467
|
+
}
|
|
1468
|
+
})();
|
|
1469
|
+
if (checker === null) {
|
|
1441
1470
|
throw new Error(`Invalid validation rule: ${rule}`);
|
|
1442
1471
|
}
|
|
1472
|
+
result = await checker.call(this.#checkers, attribute, value, parameters);
|
|
1443
1473
|
if (typeof result === 'boolean') {
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1474
|
+
result = {
|
|
1475
|
+
success: result,
|
|
1476
|
+
};
|
|
1447
1477
|
}
|
|
1478
|
+
({ success, message = '' } = result);
|
|
1448
1479
|
if (!success) {
|
|
1449
1480
|
noError = false;
|
|
1450
1481
|
message = isEmpty(message) ? this.getMessage(attribute, rule) : message;
|
|
@@ -1463,7 +1494,13 @@ var quival = (function (exports) {
|
|
|
1463
1494
|
if (!(await task())) break;
|
|
1464
1495
|
}
|
|
1465
1496
|
} else {
|
|
1466
|
-
await Promise.allSettled(tasks.map((task) => task()))
|
|
1497
|
+
await Promise.allSettled(tasks.map((task) => task())).then((results) => {
|
|
1498
|
+
for (const result of results) {
|
|
1499
|
+
if (result.status === 'rejected') {
|
|
1500
|
+
throw result.reason;
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
});
|
|
1467
1504
|
this.#errors.sortByKeys(Object.keys(this.#rules));
|
|
1468
1505
|
}
|
|
1469
1506
|
this.#skippedAttributes = skippedAttributes.filter((value, index, array) => array.indexOf(value) === index);
|
|
@@ -1480,6 +1517,9 @@ var quival = (function (exports) {
|
|
|
1480
1517
|
return !(await this.passes());
|
|
1481
1518
|
}
|
|
1482
1519
|
getMessage(attribute, rule) {
|
|
1520
|
+
if (typeof rule === 'function') {
|
|
1521
|
+
return '';
|
|
1522
|
+
}
|
|
1483
1523
|
const value = this.getValue(attribute);
|
|
1484
1524
|
attribute = this.getPrimaryAttribute(attribute);
|
|
1485
1525
|
let message;
|
|
@@ -1523,9 +1563,11 @@ var quival = (function (exports) {
|
|
|
1523
1563
|
if (index !== -1) {
|
|
1524
1564
|
message = message.replaceAll(':index', index).replaceAll(':position', index + 1);
|
|
1525
1565
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1566
|
+
if (typeof rule === 'string') {
|
|
1567
|
+
const replacer = this.#replacers[toCamelCase('replace_' + rule)] ?? null;
|
|
1568
|
+
if (replacer) {
|
|
1569
|
+
message = replacer.call(this.#replacers, message, attribute, rule, parameters);
|
|
1570
|
+
}
|
|
1529
1571
|
}
|
|
1530
1572
|
return message;
|
|
1531
1573
|
}
|
|
@@ -1582,7 +1624,7 @@ var quival = (function (exports) {
|
|
|
1582
1624
|
return false;
|
|
1583
1625
|
}
|
|
1584
1626
|
for (const rule of rules) {
|
|
1585
|
-
if (this.#rules[attribute].
|
|
1627
|
+
if (this.#rules[attribute].some((attributeRule) => attributeRule[0] === rule)) {
|
|
1586
1628
|
return true;
|
|
1587
1629
|
}
|
|
1588
1630
|
}
|
package/dist/quival.min.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* quival v0.
|
|
2
|
+
* quival v0.4.0 (https://github.com/apih/quival)
|
|
3
3
|
* (c) 2023 Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
var quival=function(e){"use strict";function t(e){return e.replace(/[-_]/g," ").replace(/\s+/," ").trim().replace(/(\s\w)/g,(e=>e[1].toUpperCase()))}function r(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(e,t=""){return Object.keys(e).reduce(((r,i)=>{const c=t?`${t}.${i}`:i;return"object"==typeof e[i]&&null!==e[i]?Object.assign(r,s(e[i],c)):r[c]=e[i],r}),{})}function i(e){const t=[];let r="",s=!1;for(let i=0;i<e.length;i++){const c=e[i];'"'===c?s&&'"'===e[i+1]?(r+='"',i++):(s=!s,s&&(r=r.trim())):","!==c||s?r+=c:(t.push(r),r="")}return t.push(r),t}function c(e){if(n(e)||"string"!=typeof e)return new Date("");if(e instanceof Date)return e;let t,r,s,i,c,a,u,h;const l=e=>e&&/^\d*$/.test(e)?parseInt(e):e;if(null!==(t=e.match(/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{2,4})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i)))[,i,s,r,,c=0,a=0,,u=0,h="am"]=t.map(l);else if(null!==(t=e.match(/^(\d{2,4})[.\/-](\d{1,2})[.\/-](\d{1,2})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i))||null!==(t=e.match(/^(\d{4})(\d{2})(\d{2})\s?((\d{2})(\d{2})((\d{2}))?\s?(am|pm)?)?/i)))[,r,s,i,,c=0,a=0,,u=0,h="am"]=t.map(l);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{4})[.\/-](\d{2})[.\/-](\d{2})/i))[,c,a,,u,h="am",r,s,i]=t.map(l);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{2})[.\/-](\d{2})[.\/-](\d{4})/i))[,c,a,,u,h="am",i,s,r]=t.map(l);else{if(!(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?/i)))return new Date(e);{const e=new Date;r=e.getFullYear(),s=e.getMonth()+1,i=e.getDate(),[,c=0,a=0,,u=0,h="am"]=t.map(l)}}return r>=10&&r<100&&(r+=2e3),"pm"===h.toLowerCase()&&c<12&&(c+=12),new Date(`${r}-${s}-${i} ${c}:${a}:${u}`)}function a(e,t){if(n(e))return new Date("");t=t.split("");const r={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let s="^",i={years:-1,months:-1,days:-1,hours:-1,minutes:-1,seconds:-1,meridiem:-1},c=1;for(const e of t)Object.hasOwn(r,e)?(s+=r[e],-1!==["Y","y"].indexOf(e)?i.years=c++:-1!==["m","n"].indexOf(e)?i.months=c++:-1!==["d","j"].indexOf(e)?i.days=c++:-1!==["G","g","H","h"].indexOf(e)?i.hours=c++:"i"===e?i.minutes=c++:"s"===e?i.seconds=c++:-1!==["A","a"].indexOf(e)&&(i.meridiem=c++)):s+="\\"+e;s+="$";let a=e.match(new RegExp(s));if(null===a)return new Date("");a=a.map((e=>e&&/^\d*$/.test(e)?parseInt(e):e));const u=new Date;let h=a[i.years],l=a[i.months],o=a[i.days],d=a[i.hours]??0,p=a[i.minutes]??0,f=a[i.seconds]??0,g=a[i.meridiem]??"am";return h||l||o?!h||l||o?h||!l||o?h||l||!o||(h=u.getFullYear(),l=u.getMonth()+1):(h=u.getFullYear(),o=1):(l=1,o=1):(h=u.getFullYear(),l=u.getMonth()+1,o=u.getDate()),h>=10&&h<100&&(h+=2e3),"pm"===g.toLowerCase()&&d<12&&(d+=12),new Date(`${h}-${l}-${o} ${d}:${p}:${f}`)}function n(e){return""===e||null==e}function u(e){const t=Number(e);return null!==e&&"boolean"!=typeof e&&"number"==typeof t&&!isNaN(t)}function h(e){return"[object Object]"===Object.prototype.toString.call(e)}function l(e){return e instanceof Date&&"Invalid Date"!==e.toDateString()}class o{#e;#t;constructor(e){this.#e={},this.#t={},this.validator=e}clearCaches(){this.#e={},this.#t={}}isDependent(e){const t=this.validator.getValue(e[0]);return e.slice(1).some((e=>e==t))}collectRequiredsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkRequired(e,this.validator.getValue(e)));return!s(i)||this.checkRequired(e,t)}collectMissingsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkMissing(e));return!s(i)||this.checkMissing(e)}testStringUsingRegex(e,t,r,s,i=!1){return("string"==typeof t||"number"==typeof t)&&(t=String(t),i||this.validator.hasRule(e,"ascii")?r.test(t):s.test(t))}compareValues(e,t,r,s){if(n(t))return!1;const i=r[0]??"";let c=this.validator.getValue(i);return c=void 0===c?u(i)?parseFloat(i,10):null:this.validator.getSize(i,c),!n(c)&&s(this.validator.getSize(e,t),c)}compareDates(e,t,r,s){const i=this.validator.getRule(e);if(!l(t=Object.hasOwn(i,"date_format")?a(t,i.date_format[0]):c(t)))return!1;const n=r[0]??"";let u=this.validator.getValue(n);if(void 0===u)u=c(n);else{const e=this.validator.getRule(n);u=Object.hasOwn(e,"date_format")?a(u,e.date_format[0]):c(u)}return!!l(u)&&s(t.getTime(),u.getTime())}checkArray(e,t,r){if(!Array.isArray(t)&&!h(t))return!1;if(r&&r.length>0)for(const e of Object.keys(t))if(!r.includes(e))return!1;return!0}checkList(e,t,r){return Array.isArray(t)}checkBoolean(e,t,r){return[!0,!1,0,1,"0","1"].includes(t)}checkDate(e,t,r){return l(c(t))}checkFile(e,t,r){return t instanceof File}checkInteger(e,t,r){return String(parseInt(t,10))===String(t)}checkNumeric(e,t,r){return u(t)}checkString(e,t,r){return"string"==typeof t}checkDecimal(e,t,r){if(!this.checkNumeric(e,t))return!1;const s=(String(t).split(".")[1]??"").length;return 1===r.length?s==r[0]:s>=r[0]&&s<=r[1]}checkMultipleOf(e,t,r){if(!u(t)||!u(r[0]))return!1;const s=parseInt(t,10),i=parseInt(r[0],10);return(0!==s||0!==i)&&(0===s||0!==i&&s%i==0)}checkAccepted(e,t,r){return["yes","on","1",1,!0,"true"].includes(t)}checkAcceptedIf(e,t,r){return!this.isDependent(r)||this.checkAccepted(e,t,r)}checkDeclined(e,t,r){return["no","off","0",0,!1,"false"].includes(t)}checkDeclinedIf(e,t,r){return!this.isDependent(r)||this.checkDeclined(e,t,r)}checkRequired(e,t,r){return!n(t)&&(Array.isArray(t)?t.length>0:t instanceof File?t.size>0:(t=String(t).replace(/\s/g,"")).length>0)}checkRequiredArrayKeys(e,t,r){if(!this.checkArray(e,t))return!1;const s=Object.keys(t);for(const e of r)if(!s.includes(e))return!1;return!0}checkRequiredIf(e,t,r){return!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredIfAccepted(e,t,r){return!this.checkAccepted(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredIfDeclined(e,t,r){return!this.checkDeclined(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredUnless(e,t,r){return!!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredWith(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>e.includes(!0)))}checkRequiredWithAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>!e.includes(!1)))}checkRequiredWithout(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>e.includes(!1)))}checkRequiredWithoutAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>!e.includes(!0)))}checkFilled(e,t,r){return void 0===t||this.checkRequired(e,t)}checkPresent(e,t,r){return void 0!==t}checkMissing(e,t,r){return!this.validator.hasAttribute(e)}checkMissingIf(e,t,r){return!this.isDependent(r)||this.checkMissing(e)}checkMissingUnless(e,t,r){return!!this.isDependent(r)||this.checkMissing(e)}checkMissingWith(e,t,r){return this.collectMissingsThenTest(e,t,r,(e=>e.includes(!1)))}checkMissingWithAll(e,t,r){return this.collectMissingsThenTest(e,t,r,(e=>!e.includes(!0)))}checkProhibited(e,t,r){return!this.checkRequired(e,t)}checkProhibitedIf(e,t,r){return!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibitedUnless(e,t,r){return!!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibits(e,t,r){if(this.checkRequired(e,t))for(const e of r)if(this.checkRequired(e,this.validator.getValue(e)))return!1;return!0}checkSize(e,t,r){return this.validator.getSize(e,t)===parseFloat(r[0])}checkMin(e,t,r){return this.validator.getSize(e,t)>=parseFloat(r[0])}checkMax(e,t,r){return this.validator.getSize(e,t)<=parseFloat(r[0])}checkBetween(e,t,r){return this.checkMin(e,t,[r[0]])&&this.checkMax(e,t,[r[1]])}checkDigits(e,t,r,s=(e,t)=>e===t){return!!function(e){return-1===String(e).search(/[^0-9]/)}(t=String(t??""))&&s(t.length,parseInt(r[0],10),parseInt(r[1]??0,10))}checkMinDigits(e,t,r){return this.checkDigits(e,t,r,((e,t)=>e>=t))}checkMaxDigits(e,t,r){return this.checkDigits(e,t,r,((e,t)=>e<=t))}checkDigitsBetween(e,t,r){return this.checkDigits(e,t,r,((e,t,r)=>e>=t&&e<=r))}checkAlpha(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z]+$/i,/^[\p{L}\p{M}]+$/u,r.includes("ascii"))}checkAlphaDash(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9_-]+$/i,/^[\p{L}\p{M}\p{N}_-]+$/u,r.includes("ascii"))}checkAlphaNum(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9]+$/i,/^[\p{L}\p{M}\p{N}]+$/u,r.includes("ascii"))}checkAscii(e,t,r){return!/[^\x09\x10\x13\x0A\x0D\x20-\x7E]/.test(t)}checkRegex(e,t,r,s=!1){if("string"!=typeof t&&!u(t))return!1;const i=r.join(",");let[c,a,h]=i.match(/^\/(.*)\/([gimu]*)$/)??[];if(n(c))throw new Error(`Invalid regular expression pattern: ${i}`);h.includes("u")&&(a=a.replace(/\\A/g,"^").replace(/\\z/gi,"$").replace(/\\([pP])([CLMNPSZ])/g,"\\$1{$2}").replace(/\\\x\{([0-9a-f]+)\}/g,"\\u{$1}"));const l=new RegExp(a,h).test(t);return s?!l:l}checkNotRegex(e,t,r){return this.checkRegex(e,t,r,!0)}checkLowercase(e,t,r){return t===String(t).toLocaleLowerCase()}checkUppercase(e,t,r){return t===String(t).toLocaleUpperCase()}checkStartsWith(e,t,r){t=String(t);for(const e of r)if(t.startsWith(e))return!0;return!1}checkDoesntStartWith(e,t,r){return!this.checkStartsWith(e,t,r)}checkEndsWith(e,t,r){t=String(t);for(const e of r)if(t.endsWith(e))return!0;return!1}checkDoesntEndWith(e,t,r){return!this.checkEndsWith(e,t,r)}checkSame(e,t,r){return t===this.validator.getValue(r[0])}checkDifferent(e,t,r){for(const e of r){const r=this.validator.getValue(e);if(void 0!==r&&t===r)return!1}return!0}checkConfirmed(e,t,r){return this.checkSame(e,t,[e+"_confirmation"])}checkGt(e,t,r){return this.compareValues(e,t,r,((e,t)=>e>t))}checkGte(e,t,r){return this.compareValues(e,t,r,((e,t)=>e>=t))}checkLt(e,t,r){return this.compareValues(e,t,r,((e,t)=>e<t))}checkLte(e,t,r){return this.compareValues(e,t,r,((e,t)=>e<=t))}checkAfter(e,t,r){return this.compareDates(e,t,r,((e,t)=>e>t))}checkAfterOrEqual(e,t,r){return this.compareDates(e,t,r,((e,t)=>e>=t))}checkBefore(e,t,r){return this.compareDates(e,t,r,((e,t)=>e<t))}checkBeforeOrEqual(e,t,r){return this.compareDates(e,t,r,((e,t)=>e<=t))}checkDateEquals(e,t,r){return this.compareDates(e,t,r,((e,t)=>e===t))}checkDateFormat(e,t,r){const s=r[0].split(""),i={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let c="^";for(const e of s)Object.hasOwn(i,e)?c+=i[e]:c+="\\"+e;return c+="$",new RegExp(c).test(t)}checkContains(e,t,r){if(!this.checkArray(e,t))return!1;for(const e of r)if(!t.includes(e))return!1;return!0}checkDistinct(e,t,i){const c=this.validator.getPrimaryAttribute(e);if(!c.includes("*"))return!0;const a=c.indexOf("*"),n=c.substring(0,a-1);let u;Object.hasOwn(this.#e,n)?u=this.#e[n]:(u=JSON.stringify(s(this.validator.getValue(n)??{})),this.#e[n]=u);const h=i.includes("ignore_case"),l=!h&&i.includes("strict"),o=r(String(t));let d=`"${r(c.substring(a)).replaceAll("\\*",'[^."]+')}":`,p=0;return d+=l?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,d+="[,}]+",p+=u.match(new RegExp(d,"g"+(h?"i":"")))?.length??0,1===p}checkInArray(e,t,r){const i=this.validator.getPrimaryAttribute(r[0]);if(!i.includes("*"))return!1;const c=this.validator.getValue(i.split(".*")[0])??{};return Object.values(s(c)).some((e=>e==t))}checkIn(e,t,r){if(!this.checkArray(e,t)||!this.validator.hasRule(e,"array"))return r.some((e=>e==t));for(const e of Object.values(t))if(!r.some((t=>t==e)))return!1;return!0}checkNotIn(e,t,r){return!this.checkIn(e,t,r)}checkMimetypes(e,t,r){return!!this.checkFile(e,t)&&r.includes(t.type)}checkMimes(e,t,r){return!!this.checkFile(e,t)&&r.includes(t.name.split(".").pop().toLowerCase())}checkExtensions(e,t,r){return this.checkMimes(e,t,r)}async checkImage(e,t,r){let s=this.checkMimes(e,t,["jpg","jpeg","png","gif","bmp","svg","webp"]);return s&&"undefined"!=typeof FileReader?(await new Promise(((e,r)=>{const s=new FileReader;s.onload=t=>e(t.target.result),s.onerror=r,s.readAsDataURL(t)})).then((async t=>{const r=new Image;r.src=t,await r.decode(),this.#t[e]=r})).catch((()=>{s=!1})),s):s}async checkDimensions(e,t,r){if(!this.checkImage(e,t)||!Object.hasOwn(this.#t,e))return!1;const s={};for(const e of r){const[t,r]=e.split("=",2);if("ratio"===t&&r.includes("/")){const[e,i]=r.split("/",2).map((e=>parseFloat(e,10)));s[t]=e/i}else s[t]=parseFloat(r,10)}const i=this.#t[e],c=i.naturalWidth,a=i.naturalHeight;return!(Object.hasOwn(s,"width")&&s.width!==c||Object.hasOwn(s,"height")&&s.height!==a||Object.hasOwn(s,"min_width")&&s.min_width>c||Object.hasOwn(s,"min_height")&&s.min_height>a||Object.hasOwn(s,"max_width")&&s.max_width<c||Object.hasOwn(s,"max_height")&&s.max_height<a)&&(!Object.hasOwn(s,"ratio")||Math.abs(s.ratio-c/a)<=1/(Math.max(c,a)+1))}checkEmail(e,t,r){if(!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(t)){return/^((?:[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]|[^\u0000-\u007F])+@(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?(?:\.(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?)+)*$/.test(t)}return!0}checkJson(e,t,r){try{JSON.parse(t)}catch(e){return!1}return!0}checkHexColor(e,t,r){return/^#(?:(?:[0-9a-f]{3}){1,2}|(?:[0-9a-f]{4}){1,2})$/i.test(t)}checkMacAddress(e,t,r){t=String(t);const s={"-":2,":":2,".":4};let i,c;for([i,c]of Object.entries(s))if(t.includes(i))break;const a=t.split(i);if(a.length!==12/c)return!1;for(const e of a)if(!new RegExp("^[0-9a-f]{"+c+"}$","i").test(e))return!1;return!0}checkIpv4(e,t,r){if(/[^\d.]/.test(t))return!1;const s=String(t).split(".");if(4!==s.length)return!1;for(const e of s)if(e<0||e>255)return!1;return!0}checkIpv6(e,t,r){if((t=String(t)).includes(":::")||t.split("::").length>2)return!1;const s=t.split(":");if(s.length<3||s.length>8)return!1;for(const e of s)if(""!==e&&!/^[0-9a-f]{1,4}$/i.test(e))return!1;return!0}checkIp(e,t,r){return this.checkIpv4(e,t,r)||this.checkIpv6(e,t,r)}checkTimezone(e,t,r){try{Intl.DateTimeFormat(void 0,{timeZone:t})}catch(e){if(String(e).toLowerCase().includes("invalid time zone"))return!1}return!0}checkUrl(e,t,r){try{new URL(t)}catch(e){return!1}return!0}checkUlid(e,t,r){return/[0-7][0-9A-HJKMNP-TV-Z]{25}/.test(t)}checkUuid(e,t,r){return/[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}/.test(t)}}class d{#r;keys(){return Object.keys(this.#r)}values(){return Object.values(this.#r)}entries(){return Object.entries(this.#r)}add(e,t){Object.hasOwn(this.#r,e)?this.#r[e].push(t):this.#r[e]=[t]}get(e){if(!e.includes("*"))return Object.hasOwn(this.#r,e)?this.#r[e]:{};const t=new RegExp("^"+e.replaceAll("*",".*?")+"$"),r={};for(const[e,s]of this.entries())t.test(e)&&(r[e]=s);return r}first(e){for(const t of Object.values(this.get(e)))return Array.isArray(t)?t[0]:t;return""}has(e){return""!==this.first(e)}remove(e){delete this.#r[e]}messages(){return this.#r}all(){const e=[];return this.values().forEach((t=>e.push(...t))),e}count(){let e=0;return this.values().forEach((t=>e+=t.length)),e}isEmpty(){return 0===this.keys().length}isNotEmpty(){return!this.isEmpty()}sortByKeys(e){const t={};for(const r of e)Object.hasOwn(this.#r,r)&&(t[r]=this.#r[r]);this.#r=t}constructor(){this.#r={}}}class p{static#s;static#i={};static locale(e){this.#s=e}static setMessages(e,t){this.#i[e]=s(t)}static get(e){if(this.#i[this.#s]&&this.#i[this.#s][e])return this.#i[this.#s][e]}static has(e){return void 0!==this.get(e)}static set(e,t){h(t)?Object.assign(this.#i[this.#s],s(t,e)):"string"==typeof t&&(this.#i[this.#s][e]=t)}}class f{constructor(e){this.validator=e}replace(e,t){return Object.entries(t).forEach((([t,r])=>e=e.replaceAll(":"+t,r))),e}replaceDecimal(e,t,r,s){return this.replace(e,{decimal:s.join("-")})}replaceMultipleOf(e,t,r,s){return this.replace(e,{value:s[0]})}replaceAcceptedIf(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),value:this.validator.getDisplayableValue(s[0],this.validator.getValue(s[0]))})}replaceDeclinedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredArrayKeys(e,t,r,s){return this.replace(e,{values:s.map((e=>this.validator.getDisplayableValue(t,e))).join(", ")})}replaceRequiredIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfAccepted(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfDeclined(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredUnless(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),values:s.slice(1).map((e=>this.validator.getDisplayableValue(s[0],e))).join(", ")})}replaceRequiredWith(e,t,r,s){return this.replace(e,{values:s.map((e=>this.validator.getDisplayableAttribute(e))).join(" / ")})}replaceRequiredWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithout(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithoutAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceMissingUnless(e,t,r,s){return this.replace(this.replaceRequiredUnless(e,t,r,s),{value:this.validator.getDisplayableValue(s[0],s[1])})}replaceMissingWith(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceProhibitedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceProhibitedUnless(e,t,r,s){return this.replaceRequiredUnless(e,t,r,s)}replaceProhibits(e,t,r,s){return this.replace(e,{other:s.map((e=>this.validator.getDisplayableAttribute(e))).join(" / ")})}replaceSize(e,t,r,s){return this.replace(e,{size:s[0]})}replaceMin(e,t,r,s){return this.replace(e,{min:s[0]})}replaceMax(e,t,r,s){return this.replace(e,{max:s[0]})}replaceBetween(e,t,r,s){return this.replace(e,{min:s[0],max:s[1]})}replaceDigits(e,t,r,s){return this.replace(e,{digits:s[0]})}replaceMinDigits(e,t,r,s){return this.replaceMin(e,t,r,s)}replaceMaxDigits(e,t,r,s){return this.replaceMax(e,t,r,s)}replaceDigitsBetween(e,t,r,s){return this.replaceBetween(e,t,r,s)}replaceStartsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntStartWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceEndsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntEndWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceSame(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceDifferent(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceGt(e,t,r,s){const i=this.validator.getValue(s[0]);return this.replace(e,{value:i?this.validator.getSize(s[0],i):this.validator.getDisplayableAttribute(s[0])})}replaceGte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLt(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceAfter(e,t,r,s){const i=s[0];return this.replace(e,{date:this.validator.hasAttribute(i)?this.validator.getDisplayableAttribute(i):i})}replaceAfterOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBefore(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBeforeOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateEquals(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateFormat(e,t,r,s){return this.replace(e,{format:s[0]})}replaceInArray(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceNotIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceMimetypes(e,t,r,s){return this.replace(e,{values:s.join(", ")})}replaceMimes(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}replaceExtensions(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}}class g{static#c={};static#a={};static#n=["active_url","bail","can","current_password","enum","exclude","exclude_if","exclude_unless","exclude_with","exclude_without","exists","nullable","sometimes","unique"];static#u=["accepted","accepted_if","declined","declined_if","filled","missing","missing_if","missing_unless","missing_with","missing_with_all","present","required","required_if","required_if_accepted","required_if_declined","required_unless","required_with","required_with_all","required_without","required_without_all"];#r;#h;#l;#o;#d;#p;#f;#g;#m;#k;#b;#A;static setLocale(e){p.locale(e)}static setMessages(e,t){p.setMessages(e,t)}static addChecker(e,t,r){g.#c[e]=t,r&&p.set(e,r)}static addImplicitChecker(e,t,r){g.addChecker(e,t,r),g.#u.push(e)}static addReplacer(e,t){g.#a[e]=t}static addDummyRule(e){g.#n.push(e)}constructor(e={},r={},s={},i={},c={}){this.#m=[],this.#k={},this.#b=!1,this.#A=!1,this.fileRules=["file","image","mimetypes","mimes"],this.numericRules=["decimal","numeric","integer"],this.sizeRules=["size","between","min","max","gt","lt","gte","lte"],this.setProperties(e,r,s,i,c),this.#p=new o(this),this.#f=new f(this);for(const[e,r]of Object.entries(g.#c))this.#p[t("check_"+e)]=r;for(const[e,r]of Object.entries(g.#a))this.#f[t("replace_"+e)]=r;this.#g=new d}setProperties(e={},t={},r={},i={},c={}){return this.#r=e,this.#h=this.parseRules(t),this.#l=r,this.#o=i,this.#d=s(c),this}setData(e){return this.#r=e,this}setRules(e){return this.#h=this.parseRules(e),this}setCustomMessages(e){return this.#l=e,this}setCustomAttributes(e){return this.#o=e,this}setCustomValues(e){return this.#d=s(e),this}addImplicitAttribute(e,t){return this.#k[e]=t,this}stopOnFirstFailure(e=!0){return this.#b=e,this}alwaysBail(e=!0){return this.#A=e,this}parseRules(e){const t={};for(const[r,s]of Object.entries(e)){const e=r.includes("*")?this.parseWildcardAttribute(r):[r];for(const r of e){const e={};for(const t of this.parseAttributeRules(s)){const[r,s]=this.parseAttributeRule(t);e[r]=s}t[r]=e}}return t}parseWildcardAttribute(e){const t=[],r=e.indexOf("*"),s=e.substring(0,r-1),i=e.substring(r+2),c=this.getValue(s);return Array.isArray(c)||h(c)?(Object.entries(c).forEach((([r,c])=>{const a=`${s}.${r}.${i}`.replace(/\.$/,""),n=a.includes("*")?this.parseWildcardAttribute(a):[a];t.push(...n),n.forEach((t=>this.#k[t]=e))})),t):[e]}parseAttributeRules(e){return Array.isArray(e)?e:String(e).split("|")}parseAttributeRule(e){if(Array.isArray(e))return[e.shift()??"",e];const t=e.indexOf(":");return-1===t?[e,[]]:[e.substring(0,t),i(e.substring(t+1))]}async validate(){this.#p.clearCaches(),this.#g=new d;const e=[],r=[];for(const[s,i]of Object.entries(this.#h)){let c=this.getValue(s);Object.hasOwn(i,"sometimes")&&void 0===c?r.push(s):e.push((async()=>{const e=this.#A||Object.hasOwn(i,"bail"),a=Object.hasOwn(i,"nullable");let u=!0;for(const[h,l]of Object.entries(i)){if(""===h||!g.#u.includes(h)&&(void 0===c||"string"==typeof c&&""===c.trim()||a&&null===c)){r.push(s);continue}let i,o,d;const p=t("check_"+h);if("function"==typeof this.#p[p])i=await this.#p[p](s,c,l);else{if(!g.#n.includes(h))throw new Error(`Invalid validation rule: ${h}`);i=!0}if("boolean"==typeof i?o=i:({success:o,message:d}=i),!o&&(u=!1,d=n(d)?this.getMessage(s,h):d,d=this.makeReplacements(d,s,h,l),this.#g.add(s,d),e||g.#u.includes(h)))break}return u}))}if(this.#b){for(const t of e)if(!await t())break}else await Promise.allSettled(e.map((e=>e()))),this.#g.sortByKeys(Object.keys(this.#h));return this.#m=r.filter(((e,t,r)=>r.indexOf(e)===t)),this.#g}async passes(){return await this.validate(),!this.#g.isNotEmpty()}async fails(){return!await this.passes()}getMessage(e,t){const r=this.getValue(e);let s;e=this.getPrimaryAttribute(e);for(const r of[`${e}.${t}`,t])if(Object.hasOwn(this.#l,r)){s=this.#l[r];break}if(!s){let i=t;this.sizeRules.includes(i)&&(Array.isArray(r)||h(r)||this.hasRule(e,"array")?i+=".array":r instanceof File||this.hasRule(e,this.fileRules)?i+=".file":u(r)||this.hasRule(e,this.numericRules)?i+=".numeric":i+=".string"),s=p.get(i)}return s??`validation.${t}`}makeReplacements(e,r,s,i){const c=this.getDisplayableAttribute(r),a=this.getValue(r),n={attribute:c,ATTRIBUTE:c.toLocaleUpperCase(),Attribute:c.charAt(0).toLocaleUpperCase()+c.substring(1),input:this.getDisplayableValue(r,a)};for(const[t,r]of Object.entries(n))e=e.replaceAll(":"+t,r);const u=r.match(/\.(\d+)\.?/),h=null===u?-1:parseInt(u[1],10);-1!==h&&(e=e.replaceAll(":index",h).replaceAll(":position",h+1));const l=t("replace_"+s);return"function"==typeof this.#f[l]&&(e=this.#f[l](e,r,s,i)),e}getDisplayableAttribute(e){const t=this.getPrimaryAttribute(e);for(const r of[e,t]){if(Object.hasOwn(this.#o,r))return this.#o[r];if(p.has(`attributes.${r}`))return p.get(`attributes.${r}`)}return Object.hasOwn(this.#k,e)?e:(r=e,r.replace(/(.)(?=[A-Z])/g,(e=>e+"_")).toLowerCase()).replaceAll("_"," ");var r}getDisplayableValue(e,t){const r=`${e=this.getPrimaryAttribute(e)}.${t}`;return n(t)?"empty":"boolean"==typeof t||this.hasRule(e,"boolean")?Number(t)?"true":"false":Object.hasOwn(this.#d,r)?this.#d[r]:p.has(`values.${r}`)?p.get(`values.${r}`):t}getSize(e,t){return n(t)?0:u(t)&&this.hasRule(e,this.numericRules)?parseFloat("string"==typeof t?t.trim():t,10):t instanceof File?t.size/1024:h(t)?Object.keys(t).length:Object.hasOwn(t,"length")?t.length:t}getRule(e){return e=this.getPrimaryAttribute(e),this.#h[e]??{}}hasRule(e,t){if(e=this.getPrimaryAttribute(e),t="string"==typeof t?[t]:t,!Object.hasOwn(this.#h,e))return!1;for(const r of t)if(this.#h[e].hasOwnProperty(r))return!0;return!1}getPrimaryAttribute(e){return Object.hasOwn(this.#k,e)?this.#k[e]:e}hasAttribute(e){return void 0!==this.getValue(e)}getValue(e){return function(e,t,r){const s=t.split(".");let i=e;for(const e of s){if(!Object.hasOwn(i,e))return r;i=i[e]}return i}(this.#r,e)}errors(){return this.#g}skippedAttributes(){return this.#m}}return e.Checkers=o,e.ErrorBag=d,e.Lang=p,e.Replacers=f,e.Validator=g,e}({});
|
|
6
|
+
var quival=function(e){"use strict";function t(e){return e.replace(/[-_]/g," ").replace(/\s+/," ").trim().replace(/(\s\w)/g,(e=>e[1].toUpperCase()))}function r(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s(e,t=""){return Object.keys(e).reduce(((r,i)=>{const c=t?`${t}.${i}`:i;return"object"==typeof e[i]&&null!==e[i]?Object.assign(r,s(e[i],c)):r[c]=e[i],r}),{})}function i(e){const t=[];let r="",s=!1;for(let i=0;i<e.length;i++){const c=e[i];'"'===c?s&&'"'===e[i+1]?(r+='"',i++):(s=!s,s&&(r=r.trim())):","!==c||s?r+=c:(t.push(r),r="")}return t.push(r),t}function c(e){if(n(e)||"string"!=typeof e)return new Date("");if(e instanceof Date)return e;let t,r,s,i,c,a,u,l;const h=e=>e&&/^\d*$/.test(e)?parseInt(e):e;if(null!==(t=e.match(/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{2,4})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i)))[,i,s,r,,c=0,a=0,,u=0,l="am"]=t.map(h);else if(null!==(t=e.match(/^(\d{2,4})[.\/-](\d{1,2})[.\/-](\d{1,2})\s?((\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?)?/i))||null!==(t=e.match(/^(\d{4})(\d{2})(\d{2})\s?((\d{2})(\d{2})((\d{2}))?\s?(am|pm)?)?/i)))[,r,s,i,,c=0,a=0,,u=0,l="am"]=t.map(h);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{4})[.\/-](\d{2})[.\/-](\d{2})/i))[,c,a,,u,l="am",r,s,i]=t.map(h);else if(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?\s?(\d{2})[.\/-](\d{2})[.\/-](\d{4})/i))[,c,a,,u,l="am",i,s,r]=t.map(h);else{if(!(t=e.match(/(\d{1,2}):(\d{1,2})(:(\d{1,2}))?\s?(am|pm)?/i)))return new Date(e);{const e=new Date;r=e.getFullYear(),s=e.getMonth()+1,i=e.getDate(),[,c=0,a=0,,u=0,l="am"]=t.map(h)}}return r>=10&&r<100&&(r+=2e3),"pm"===l.toLowerCase()&&c<12&&(c+=12),new Date(`${r}-${s}-${i} ${c}:${a}:${u}`)}function a(e,t){if(n(e))return new Date("");t=t.split("");const r={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let s="^",i={years:-1,months:-1,days:-1,hours:-1,minutes:-1,seconds:-1,meridiem:-1},c=1;for(const e of t)Object.hasOwn(r,e)?(s+=r[e],-1!==["Y","y"].indexOf(e)?i.years=c++:-1!==["m","n"].indexOf(e)?i.months=c++:-1!==["d","j"].indexOf(e)?i.days=c++:-1!==["G","g","H","h"].indexOf(e)?i.hours=c++:"i"===e?i.minutes=c++:"s"===e?i.seconds=c++:-1!==["A","a"].indexOf(e)&&(i.meridiem=c++)):s+="\\"+e;s+="$";let a=e.match(new RegExp(s));if(null===a)return new Date("");a=a.map((e=>e&&/^\d*$/.test(e)?parseInt(e):e));const u=new Date;let l=a[i.years],h=a[i.months],o=a[i.days],d=a[i.hours]??0,p=a[i.minutes]??0,f=a[i.seconds]??0,g=a[i.meridiem]??"am";return l||h||o?!l||h||o?l||!h||o?l||h||!o||(l=u.getFullYear(),h=u.getMonth()+1):(l=u.getFullYear(),o=1):(h=1,o=1):(l=u.getFullYear(),h=u.getMonth()+1,o=u.getDate()),l>=10&&l<100&&(l+=2e3),"pm"===g.toLowerCase()&&d<12&&(d+=12),new Date(`${l}-${h}-${o} ${d}:${p}:${f}`)}function n(e){return""===e||null==e}function u(e){const t=Number(e);return null!==e&&"boolean"!=typeof e&&"number"==typeof t&&!isNaN(t)}function l(e){return"[object Object]"===Object.prototype.toString.call(e)}function h(e){return e instanceof Date&&"Invalid Date"!==e.toDateString()}class o{#e;#t;constructor(e){this.#e={},this.#t={},this.validator=e}clearCaches(){this.#e={},this.#t={}}isDependent(e){const t=this.validator.getValue(e[0]);return e.slice(1).some((e=>e==t))}collectRequiredsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkRequired(e,this.validator.getValue(e)));return!s(i)||this.checkRequired(e,t)}collectMissingsThenTest(e,t,r,s){let i=[];for(const e of r)i.push(this.checkMissing(e));return!s(i)||this.checkMissing(e)}testStringUsingRegex(e,t,r,s,i=!1){return("string"==typeof t||"number"==typeof t)&&(t=String(t),i||this.validator.hasRule(e,"ascii")?r.test(t):s.test(t))}compareValues(e,t,r,s){if(n(t))return!1;const i=r[0]??"";let c=this.validator.getValue(i);return c=void 0===c?u(i)?parseFloat(i,10):null:this.validator.getSize(i,c),!n(c)&&s(this.validator.getSize(e,t),c)}compareDates(e,t,r,s){const i=this.validator.getRule(e);if(!h(t=Object.hasOwn(i,"date_format")?a(t,i.date_format[0]):c(t)))return!1;const n=r[0]??"";let u=this.validator.getValue(n);if(void 0===u)u=c(n);else{const e=this.validator.getRule(n);u=Object.hasOwn(e,"date_format")?a(u,e.date_format[0]):c(u)}return!!h(u)&&s(t.getTime(),u.getTime())}checkArray(e,t,r){if(!Array.isArray(t)&&!l(t))return!1;if(r&&r.length>0)for(const e of Object.keys(t))if(!r.includes(e))return!1;return!0}checkList(e,t,r){return Array.isArray(t)}checkBoolean(e,t,r){return[!0,!1,0,1,"0","1"].includes(t)}checkDate(e,t,r){return h(c(t))}checkFile(e,t,r){return t instanceof File}checkInteger(e,t,r){return String(parseInt(t,10))===String(t)}checkNumeric(e,t,r){return u(t)}checkString(e,t,r){return"string"==typeof t}checkDecimal(e,t,r){if(!this.checkNumeric(e,t))return!1;const s=(String(t).split(".")[1]??"").length;return 1===r.length?s==r[0]:s>=r[0]&&s<=r[1]}checkMultipleOf(e,t,r){if(!u(t)||!u(r[0]))return!1;const s=parseInt(t,10),i=parseInt(r[0],10);return(0!==s||0!==i)&&(0===s||0!==i&&s%i==0)}checkAccepted(e,t,r){return["yes","on","1",1,!0,"true"].includes(t)}checkAcceptedIf(e,t,r){return!this.isDependent(r)||this.checkAccepted(e,t,r)}checkDeclined(e,t,r){return["no","off","0",0,!1,"false"].includes(t)}checkDeclinedIf(e,t,r){return!this.isDependent(r)||this.checkDeclined(e,t,r)}checkRequired(e,t,r){return!n(t)&&(Array.isArray(t)?t.length>0:t instanceof File?t.size>0:(t=String(t).replace(/\s/g,"")).length>0)}checkRequiredArrayKeys(e,t,r){if(!this.checkArray(e,t))return!1;const s=Object.keys(t);for(const e of r)if(!s.includes(e))return!1;return!0}checkRequiredIf(e,t,r){return!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredIfAccepted(e,t,r){return!this.checkAccepted(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredIfDeclined(e,t,r){return!this.checkDeclined(r[0],this.validator.getValue(r[0]))||this.checkRequired(e,t)}checkRequiredUnless(e,t,r){return!!this.isDependent(r)||this.checkRequired(e,t)}checkRequiredWith(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>e.includes(!0)))}checkRequiredWithAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>!e.includes(!1)))}checkRequiredWithout(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>e.includes(!1)))}checkRequiredWithoutAll(e,t,r){return this.collectRequiredsThenTest(e,t,r,(e=>!e.includes(!0)))}checkFilled(e,t,r){return void 0===t||this.checkRequired(e,t)}checkPresent(e,t,r){return void 0!==t}checkMissing(e,t,r){return!this.validator.hasAttribute(e)}checkMissingIf(e,t,r){return!this.isDependent(r)||this.checkMissing(e)}checkMissingUnless(e,t,r){return!!this.isDependent(r)||this.checkMissing(e)}checkMissingWith(e,t,r){return this.collectMissingsThenTest(e,t,r,(e=>e.includes(!1)))}checkMissingWithAll(e,t,r){return this.collectMissingsThenTest(e,t,r,(e=>!e.includes(!0)))}checkProhibited(e,t,r){return!this.checkRequired(e,t)}checkProhibitedIf(e,t,r){return!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibitedUnless(e,t,r){return!!this.isDependent(r)||!this.checkRequired(e,t)}checkProhibits(e,t,r){if(this.checkRequired(e,t))for(const e of r)if(this.checkRequired(e,this.validator.getValue(e)))return!1;return!0}checkSize(e,t,r){return this.validator.getSize(e,t)===parseFloat(r[0])}checkMin(e,t,r){return this.validator.getSize(e,t)>=parseFloat(r[0])}checkMax(e,t,r){return this.validator.getSize(e,t)<=parseFloat(r[0])}checkBetween(e,t,r){return this.checkMin(e,t,[r[0]])&&this.checkMax(e,t,[r[1]])}checkDigits(e,t,r,s=(e,t)=>e===t){return!!function(e){return-1===String(e).search(/[^0-9]/)}(t=String(t??""))&&s(t.length,parseInt(r[0],10),parseInt(r[1]??0,10))}checkMinDigits(e,t,r){return this.checkDigits(e,t,r,((e,t)=>e>=t))}checkMaxDigits(e,t,r){return this.checkDigits(e,t,r,((e,t)=>e<=t))}checkDigitsBetween(e,t,r){return this.checkDigits(e,t,r,((e,t,r)=>e>=t&&e<=r))}checkAlpha(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z]+$/i,/^[\p{L}\p{M}]+$/u,r.includes("ascii"))}checkAlphaDash(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9_-]+$/i,/^[\p{L}\p{M}\p{N}_-]+$/u,r.includes("ascii"))}checkAlphaNum(e,t,r){return this.testStringUsingRegex(e,t,/^[a-z0-9]+$/i,/^[\p{L}\p{M}\p{N}]+$/u,r.includes("ascii"))}checkAscii(e,t,r){return!/[^\x09\x10\x13\x0A\x0D\x20-\x7E]/.test(t)}checkRegex(e,t,r,s=!1){if("string"!=typeof t&&!u(t))return!1;const i=r.join(",");let[c,a,l]=i.match(/^\/(.*)\/([gimu]*)$/)??[];if(n(c))throw new Error(`Invalid regular expression pattern: ${i}`);l.includes("u")&&(a=a.replace(/\\A/g,"^").replace(/\\z/gi,"$").replace(/\\([pP])([CLMNPSZ])/g,"\\$1{$2}").replace(/\\\x\{([0-9a-f]+)\}/g,"\\u{$1}"));const h=new RegExp(a,l).test(t);return s?!h:h}checkNotRegex(e,t,r){return this.checkRegex(e,t,r,!0)}checkLowercase(e,t,r){return t===String(t).toLocaleLowerCase()}checkUppercase(e,t,r){return t===String(t).toLocaleUpperCase()}checkStartsWith(e,t,r){t=String(t);for(const e of r)if(t.startsWith(e))return!0;return!1}checkDoesntStartWith(e,t,r){return!this.checkStartsWith(e,t,r)}checkEndsWith(e,t,r){t=String(t);for(const e of r)if(t.endsWith(e))return!0;return!1}checkDoesntEndWith(e,t,r){return!this.checkEndsWith(e,t,r)}checkSame(e,t,r){return t===this.validator.getValue(r[0])}checkDifferent(e,t,r){for(const e of r){const r=this.validator.getValue(e);if(void 0!==r&&t===r)return!1}return!0}checkConfirmed(e,t,r){return this.checkSame(e,t,[e+"_confirmation"])}checkGt(e,t,r){return this.compareValues(e,t,r,((e,t)=>e>t))}checkGte(e,t,r){return this.compareValues(e,t,r,((e,t)=>e>=t))}checkLt(e,t,r){return this.compareValues(e,t,r,((e,t)=>e<t))}checkLte(e,t,r){return this.compareValues(e,t,r,((e,t)=>e<=t))}checkAfter(e,t,r){return this.compareDates(e,t,r,((e,t)=>e>t))}checkAfterOrEqual(e,t,r){return this.compareDates(e,t,r,((e,t)=>e>=t))}checkBefore(e,t,r){return this.compareDates(e,t,r,((e,t)=>e<t))}checkBeforeOrEqual(e,t,r){return this.compareDates(e,t,r,((e,t)=>e<=t))}checkDateEquals(e,t,r){return this.compareDates(e,t,r,((e,t)=>e===t))}checkDateFormat(e,t,r){const s=r[0].split(""),i={Y:"(\\d{4})",y:"(\\d{2})",m:"(\\d{2})",n:"([1-9]\\d?)",d:"(\\d{2})",j:"([1-9]\\d?)",G:"([1-9]\\d?)",g:"([1-9]\\d?)",H:"(\\d{2})",h:"(\\d{2})",i:"(\\d{2})",s:"(\\d{2})",A:"(AM|PM)",a:"(am|pm)"};let c="^";for(const e of s)Object.hasOwn(i,e)?c+=i[e]:c+="\\"+e;return c+="$",new RegExp(c).test(t)}checkContains(e,t,r){if(!this.checkArray(e,t))return!1;for(const e of r)if(!t.includes(e))return!1;return!0}checkDistinct(e,t,i){const c=this.validator.getPrimaryAttribute(e);if(!c.includes("*"))return!0;const a=c.indexOf("*"),n=c.substring(0,a-1);let u;Object.hasOwn(this.#e,n)?u=this.#e[n]:(u=JSON.stringify(s(this.validator.getValue(n)??{})),this.#e[n]=u);const l=i.includes("ignore_case"),h=!l&&i.includes("strict"),o=r(String(t));let d=`"${r(c.substring(a)).replaceAll("\\*",'[^."]+')}":`,p=0;return d+=h?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,d+="[,}]+",p+=u.match(new RegExp(d,"g"+(l?"i":"")))?.length??0,1===p}checkInArray(e,t,r){const i=this.validator.getPrimaryAttribute(r[0]);if(!i.includes("*"))return!1;const c=this.validator.getValue(i.split(".*")[0])??{};return Object.values(s(c)).some((e=>e==t))}checkIn(e,t,r){if(!this.checkArray(e,t)||!this.validator.hasRule(e,"array"))return r.some((e=>e==t));for(const e of Object.values(t))if(!r.some((t=>t==e)))return!1;return!0}checkNotIn(e,t,r){return!this.checkIn(e,t,r)}checkMimetypes(e,t,r){return!!this.checkFile(e,t)&&r.includes(t.type)}checkMimes(e,t,r){return!!this.checkFile(e,t)&&(r.includes("jpg")&&!r.includes("jpeg")&&r.push("jpeg"),r.includes("jpeg")&&!r.includes("jpg")&&r.push("jpg"),r.includes(t.name.split(".").pop().toLowerCase()))}checkExtensions(e,t,r){return this.checkMimes(e,t,r)}async checkImage(e,t,r){let s=this.checkMimes(e,t,["jpg","jpeg","png","gif","bmp","svg","webp"]);return s&&"undefined"!=typeof FileReader?(await new Promise(((e,r)=>{const s=new FileReader;s.onload=t=>e(t.target.result),s.onerror=r,s.readAsDataURL(t)})).then((async t=>{const r=new Image;r.src=t,await r.decode(),this.#t[e]=r})).catch((()=>{s=!1})),s):s}async checkDimensions(e,t,r){if(!this.checkImage(e,t)||!Object.hasOwn(this.#t,e))return!1;const s={};for(const e of r){const[t,r]=e.split("=",2);if("ratio"===t&&r.includes("/")){const[e,i]=r.split("/",2).map((e=>parseFloat(e,10)));s[t]=e/i}else s[t]=parseFloat(r,10)}const i=this.#t[e],c=i.naturalWidth,a=i.naturalHeight;return!(Object.hasOwn(s,"width")&&s.width!==c||Object.hasOwn(s,"height")&&s.height!==a||Object.hasOwn(s,"min_width")&&s.min_width>c||Object.hasOwn(s,"min_height")&&s.min_height>a||Object.hasOwn(s,"max_width")&&s.max_width<c||Object.hasOwn(s,"max_height")&&s.max_height<a)&&(!Object.hasOwn(s,"ratio")||Math.abs(s.ratio-c/a)<=1/(Math.max(c,a)+1))}checkEmail(e,t,r){if(!/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(t)){return/^((?:[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]|[^\u0000-\u007F])+@(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?(?:\.(?:[a-zA-Z0-9]|[^\u0000-\u007F])(?:(?:[a-zA-Z0-9-]|[^\u0000-\u007F]){0,61}(?:[a-zA-Z0-9]|[^\u0000-\u007F]))?)+)*$/.test(t)}return!0}checkJson(e,t,r){try{JSON.parse(t)}catch(e){return!1}return!0}checkHexColor(e,t,r){return/^#(?:(?:[0-9a-f]{3}){1,2}|(?:[0-9a-f]{4}){1,2})$/i.test(t)}checkMacAddress(e,t,r){t=String(t);const s={"-":2,":":2,".":4};let i,c;for([i,c]of Object.entries(s))if(t.includes(i))break;const a=t.split(i);if(a.length!==12/c)return!1;for(const e of a)if(!new RegExp("^[0-9a-f]{"+c+"}$","i").test(e))return!1;return!0}checkIpv4(e,t,r){if(/[^\d.]/.test(t))return!1;const s=String(t).split(".");if(4!==s.length)return!1;for(const e of s)if(e<0||e>255)return!1;return!0}checkIpv6(e,t,r){if((t=String(t)).includes(":::")||t.split("::").length>2)return!1;const s=t.split(":");if(s.length<3||s.length>8)return!1;for(const e of s)if(""!==e&&!/^[0-9a-f]{1,4}$/i.test(e))return!1;return!0}checkIp(e,t,r){return this.checkIpv4(e,t,r)||this.checkIpv6(e,t,r)}checkTimezone(e,t,r){try{Intl.DateTimeFormat(void 0,{timeZone:t})}catch(e){if(String(e).toLowerCase().includes("invalid time zone"))return!1}return!0}checkUrl(e,t,r){try{new URL(t)}catch(e){return!1}return!0}checkUlid(e,t,r){return/[0-7][0-9A-HJKMNP-TV-Z]{25}/.test(t)}checkUuid(e,t,r){return/[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}/.test(t)}}class d{#r;keys(){return Object.keys(this.#r)}values(){return Object.values(this.#r)}entries(){return Object.entries(this.#r)}add(e,t){Object.hasOwn(this.#r,e)?this.#r[e].push(t):this.#r[e]=[t]}get(e){if(!e.includes("*"))return Object.hasOwn(this.#r,e)?this.#r[e]:{};const t=new RegExp("^"+e.replaceAll("*",".*?")+"$"),r={};for(const[e,s]of this.entries())t.test(e)&&(r[e]=s);return r}first(e){for(const t of Object.values(this.get(e)))return Array.isArray(t)?t[0]:t;return""}has(e){return""!==this.first(e)}remove(e){delete this.#r[e]}messages(){return this.#r}all(){const e=[];return this.values().forEach((t=>e.push(...t))),e}count(){let e=0;return this.values().forEach((t=>e+=t.length)),e}isEmpty(){return 0===this.keys().length}isNotEmpty(){return!this.isEmpty()}sortByKeys(e){const t={};for(const r of e)Object.hasOwn(this.#r,r)&&(t[r]=this.#r[r]);this.#r=t}constructor(){this.#r={}}}class p{static#s;static#i={};static locale(e){this.#s=e}static setMessages(e,t){this.#i[e]=s(t)}static get(e){if(this.#i[this.#s]&&this.#i[this.#s][e])return this.#i[this.#s][e]}static has(e){return void 0!==this.get(e)}static set(e,t){l(t)?Object.assign(this.#i[this.#s],s(t,e)):"string"==typeof t&&(this.#i[this.#s][e]=t)}}class f{constructor(e){this.validator=e}replace(e,t){return Object.entries(t).forEach((([t,r])=>e=e.replaceAll(":"+t,r))),e}replaceDecimal(e,t,r,s){return this.replace(e,{decimal:s.join("-")})}replaceMultipleOf(e,t,r,s){return this.replace(e,{value:s[0]})}replaceAcceptedIf(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),value:this.validator.getDisplayableValue(s[0],this.validator.getValue(s[0]))})}replaceDeclinedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredArrayKeys(e,t,r,s){return this.replace(e,{values:s.map((e=>this.validator.getDisplayableValue(t,e))).join(", ")})}replaceRequiredIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfAccepted(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredIfDeclined(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceRequiredUnless(e,t,r,s){return this.replace(e,{other:this.validator.getDisplayableAttribute(s[0]),values:s.slice(1).map((e=>this.validator.getDisplayableValue(s[0],e))).join(", ")})}replaceRequiredWith(e,t,r,s){return this.replace(e,{values:s.map((e=>this.validator.getDisplayableAttribute(e))).join(" / ")})}replaceRequiredWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithout(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceRequiredWithoutAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceMissingUnless(e,t,r,s){return this.replace(this.replaceRequiredUnless(e,t,r,s),{value:this.validator.getDisplayableValue(s[0],s[1])})}replaceMissingWith(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceMissingWithAll(e,t,r,s){return this.replaceRequiredWith(e,t,r,s)}replaceProhibitedIf(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceProhibitedUnless(e,t,r,s){return this.replaceRequiredUnless(e,t,r,s)}replaceProhibits(e,t,r,s){return this.replace(e,{other:s.map((e=>this.validator.getDisplayableAttribute(e))).join(" / ")})}replaceSize(e,t,r,s){return this.replace(e,{size:s[0]})}replaceMin(e,t,r,s){return this.replace(e,{min:s[0]})}replaceMax(e,t,r,s){return this.replace(e,{max:s[0]})}replaceBetween(e,t,r,s){return this.replace(e,{min:s[0],max:s[1]})}replaceDigits(e,t,r,s){return this.replace(e,{digits:s[0]})}replaceMinDigits(e,t,r,s){return this.replaceMin(e,t,r,s)}replaceMaxDigits(e,t,r,s){return this.replaceMax(e,t,r,s)}replaceDigitsBetween(e,t,r,s){return this.replaceBetween(e,t,r,s)}replaceStartsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntStartWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceEndsWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceDoesntEndWith(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceSame(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceDifferent(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceGt(e,t,r,s){const i=this.validator.getValue(s[0]);return this.replace(e,{value:i?this.validator.getSize(s[0],i):this.validator.getDisplayableAttribute(s[0])})}replaceGte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLt(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceLte(e,t,r,s){return this.replaceGt(e,t,r,s)}replaceAfter(e,t,r,s){const i=s[0];return this.replace(e,{date:this.validator.hasAttribute(i)?this.validator.getDisplayableAttribute(i):i})}replaceAfterOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBefore(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceBeforeOrEqual(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateEquals(e,t,r,s){return this.replaceAfter(e,t,r,s)}replaceDateFormat(e,t,r,s){return this.replace(e,{format:s[0]})}replaceInArray(e,t,r,s){return this.replaceAcceptedIf(e,t,r,s)}replaceIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceNotIn(e,t,r,s){return this.replaceRequiredArrayKeys(e,t,r,s)}replaceMimetypes(e,t,r,s){return this.replace(e,{values:s.join(", ")})}replaceMimes(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}replaceExtensions(e,t,r,s){return this.replaceMimetypes(e,t,r,s)}}class g{static#c={};static#a={};static#n=["active_url","bail","can","current_password","enum","exclude","exclude_if","exclude_unless","exclude_with","exclude_without","exists","nullable","sometimes","unique"];static#u=["accepted","accepted_if","declined","declined_if","filled","missing","missing_if","missing_unless","missing_with","missing_with_all","present","required","required_if","required_if_accepted","required_if_declined","required_unless","required_with","required_with_all","required_without","required_without_all"];#r;#l;#h;#o;#d;#p;#f;#g;#m;#k;#b;#A;static setLocale(e){p.locale(e)}static setMessages(e,t){p.setMessages(e,t)}static addChecker(e,t,r){g.#c[e]=t,r&&p.set(e,r)}static addImplicitChecker(e,t,r){g.addChecker(e,t,r),g.#u.push(e)}static addReplacer(e,t){g.#a[e]=t}static addDummyRule(e){g.#n.push(e)}constructor(e={},r={},s={},i={},c={}){this.#m=[],this.#k={},this.#b=!1,this.#A=!1,this.fileRules=["file","image","mimetypes","mimes"],this.numericRules=["decimal","numeric","integer"],this.sizeRules=["size","between","min","max","gt","lt","gte","lte"],this.setProperties(e,r,s,i,c),this.#p=new o(this),this.#f=new f(this);for(const[e,r]of Object.entries(g.#c))this.#p[t("check_"+e)]=r;for(const[e,r]of Object.entries(g.#a))this.#f[t("replace_"+e)]=r;this.#g=new d}setProperties(e={},t={},r={},i={},c={}){return this.#r=e,this.#l=this.parseRules(t),this.#h=r,this.#o=i,this.#d=s(c),this}setData(e){return this.#r=e,this}setRules(e){return this.#l=this.parseRules(e),this}setCustomMessages(e){return this.#h=e,this}setCustomAttributes(e){return this.#o=e,this}setCustomValues(e){return this.#d=s(e),this}addImplicitAttribute(e,t){return this.#k[e]=t,this}stopOnFirstFailure(e=!0){return this.#b=e,this}alwaysBail(e=!0){return this.#A=e,this}parseRules(e){const t={};for(const[r,s]of Object.entries(e)){const e=r.includes("*")?this.parseWildcardAttribute(r):[r];for(const r of e){const e=[];for(const t of this.parseAttributeRules(s))e.push(this.parseAttributeRule(t));t[r]=e}}return t}parseWildcardAttribute(e){const t=[],r=e.indexOf("*"),s=e.substring(0,r-1),i=e.substring(r+2),c=this.getValue(s);return Array.isArray(c)||l(c)?(Object.entries(c).forEach((([r,c])=>{const a=`${s}.${r}.${i}`.replace(/\.$/,""),n=a.includes("*")?this.parseWildcardAttribute(a):[a];t.push(...n),n.forEach((t=>this.#k[t]=e))})),t):[e]}parseAttributeRules(e){return Array.isArray(e)?e:"function"==typeof e?[e]:String(e).split("|")}parseAttributeRule(e){if(Array.isArray(e))return[e[0]??"",e.slice(1)];if("function"==typeof e)return[e,[]];const t=e.indexOf(":");return-1===t?[e,[]]:[e.substring(0,t),i(e.substring(t+1))]}async validate(){this.#p.clearCaches(),this.#g=new d;const e=[],r=[];for(const[e,r]of Object.entries(this.#l))for(const[e]of r)if(""!==e&&"function"!=typeof e&&"function"!=typeof this.#p[t("check_"+e)]&&!g.#n.includes(e))throw new Error(`Invalid validation rule: ${e}`);for(const[s,i]of Object.entries(this.#l)){let c=this.getValue(s);const a=e=>i.some((t=>t[0]===e));a("sometimes")&&void 0===c?r.push(s):e.push((async()=>{const e=this.#A||a("bail"),u=a("nullable");let l=!0;for(const[a,h]of i){if(""===a||"function"!=typeof a&&!g.#u.includes(a)&&(void 0===c||"string"==typeof c&&""===c.trim()||u&&null===c)){r.push(s);continue}let i,o,d;const p=(()=>{if("function"==typeof a)return a;{const e=this.#p[t("check_"+a)]??null;return null===e&&g.#n.includes(a)?()=>!0:e}})();if(null===p)throw new Error(`Invalid validation rule: ${a}`);if(i=await p.call(this.#p,s,c,h),"boolean"==typeof i&&(i={success:i}),({success:o,message:d=""}=i),!o&&(l=!1,d=n(d)?this.getMessage(s,a):d,d=this.makeReplacements(d,s,a,h),this.#g.add(s,d),e||g.#u.includes(a)))break}return l}))}if(this.#b){for(const t of e)if(!await t())break}else await Promise.allSettled(e.map((e=>e()))).then((e=>{for(const t of e)if("rejected"===t.status)throw t.reason})),this.#g.sortByKeys(Object.keys(this.#l));return this.#m=r.filter(((e,t,r)=>r.indexOf(e)===t)),this.#g}async passes(){return await this.validate(),!this.#g.isNotEmpty()}async fails(){return!await this.passes()}getMessage(e,t){if("function"==typeof t)return"";const r=this.getValue(e);let s;e=this.getPrimaryAttribute(e);for(const r of[`${e}.${t}`,t])if(Object.hasOwn(this.#h,r)){s=this.#h[r];break}if(!s){let i=t;this.sizeRules.includes(i)&&(Array.isArray(r)||l(r)||this.hasRule(e,"array")?i+=".array":r instanceof File||this.hasRule(e,this.fileRules)?i+=".file":u(r)||this.hasRule(e,this.numericRules)?i+=".numeric":i+=".string"),s=p.get(i)}return s??`validation.${t}`}makeReplacements(e,r,s,i){const c=this.getDisplayableAttribute(r),a=this.getValue(r),n={attribute:c,ATTRIBUTE:c.toLocaleUpperCase(),Attribute:c.charAt(0).toLocaleUpperCase()+c.substring(1),input:this.getDisplayableValue(r,a)};for(const[t,r]of Object.entries(n))e=e.replaceAll(":"+t,r);const u=r.match(/\.(\d+)\.?/),l=null===u?-1:parseInt(u[1],10);if(-1!==l&&(e=e.replaceAll(":index",l).replaceAll(":position",l+1)),"string"==typeof s){const c=this.#f[t("replace_"+s)]??null;c&&(e=c.call(this.#f,e,r,s,i))}return e}getDisplayableAttribute(e){const t=this.getPrimaryAttribute(e);for(const r of[e,t]){if(Object.hasOwn(this.#o,r))return this.#o[r];if(p.has(`attributes.${r}`))return p.get(`attributes.${r}`)}return Object.hasOwn(this.#k,e)?e:(r=e,r.replace(/(.)(?=[A-Z])/g,(e=>e+"_")).toLowerCase()).replaceAll("_"," ");var r}getDisplayableValue(e,t){const r=`${e=this.getPrimaryAttribute(e)}.${t}`;return n(t)?"empty":"boolean"==typeof t||this.hasRule(e,"boolean")?Number(t)?"true":"false":Object.hasOwn(this.#d,r)?this.#d[r]:p.has(`values.${r}`)?p.get(`values.${r}`):t}getSize(e,t){return n(t)?0:u(t)&&this.hasRule(e,this.numericRules)?parseFloat("string"==typeof t?t.trim():t,10):t instanceof File?t.size/1024:l(t)?Object.keys(t).length:Object.hasOwn(t,"length")?t.length:t}getRule(e){return e=this.getPrimaryAttribute(e),this.#l[e]??{}}hasRule(e,t){if(e=this.getPrimaryAttribute(e),t="string"==typeof t?[t]:t,!Object.hasOwn(this.#l,e))return!1;for(const r of t)if(this.#l[e].some((e=>e[0]===r)))return!0;return!1}getPrimaryAttribute(e){return Object.hasOwn(this.#k,e)?this.#k[e]:e}hasAttribute(e){return void 0!==this.getValue(e)}getValue(e){return function(e,t,r){const s=t.split(".");let i=e;for(const e of s){if(!Object.hasOwn(i,e))return r;i=i[e]}return i}(this.#r,e)}errors(){return this.#g}skippedAttributes(){return this.#m}}return e.Checkers=o,e.ErrorBag=d,e.Lang=p,e.Replacers=f,e.Validator=g,e}({});
|
package/package.json
CHANGED
package/src/Checkers.js
CHANGED
|
@@ -691,11 +691,19 @@ export default class Checkers {
|
|
|
691
691
|
}
|
|
692
692
|
|
|
693
693
|
checkMimes(attribute, value, parameters) {
|
|
694
|
-
if (this.checkFile(attribute, value)) {
|
|
695
|
-
return
|
|
694
|
+
if (!this.checkFile(attribute, value)) {
|
|
695
|
+
return false;
|
|
696
696
|
}
|
|
697
697
|
|
|
698
|
-
|
|
698
|
+
if (parameters.includes('jpg') && !parameters.includes('jpeg')) {
|
|
699
|
+
parameters.push('jpeg');
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (parameters.includes('jpeg') && !parameters.includes('jpg')) {
|
|
703
|
+
parameters.push('jpg');
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return parameters.includes(value.name.split('.').pop().toLowerCase());
|
|
699
707
|
}
|
|
700
708
|
|
|
701
709
|
checkExtensions(attribute, value, parameters) {
|
package/src/Validator.js
CHANGED
|
@@ -178,12 +178,10 @@ export default class Validator {
|
|
|
178
178
|
const attributes = attribute.includes('*') ? this.parseWildcardAttribute(attribute) : [attribute];
|
|
179
179
|
|
|
180
180
|
for (const attribute of attributes) {
|
|
181
|
-
const parsedAttributeRules =
|
|
181
|
+
const parsedAttributeRules = [];
|
|
182
182
|
|
|
183
183
|
for (const attributeRule of this.parseAttributeRules(attributeRules)) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
parsedAttributeRules[rule] = parameters;
|
|
184
|
+
parsedAttributeRules.push(this.parseAttributeRule(attributeRule));
|
|
187
185
|
}
|
|
188
186
|
|
|
189
187
|
parsedRules[attribute] = parsedAttributeRules;
|
|
@@ -218,6 +216,8 @@ export default class Validator {
|
|
|
218
216
|
parseAttributeRules(rules) {
|
|
219
217
|
if (Array.isArray(rules)) {
|
|
220
218
|
return rules;
|
|
219
|
+
} else if (typeof rules === 'function') {
|
|
220
|
+
return [rules];
|
|
221
221
|
} else {
|
|
222
222
|
return String(rules).split('|');
|
|
223
223
|
}
|
|
@@ -225,7 +225,9 @@ export default class Validator {
|
|
|
225
225
|
|
|
226
226
|
parseAttributeRule(rule) {
|
|
227
227
|
if (Array.isArray(rule)) {
|
|
228
|
-
return [rule
|
|
228
|
+
return [rule[0] ?? '', rule.slice(1)];
|
|
229
|
+
} else if (typeof rule === 'function') {
|
|
230
|
+
return [rule, []];
|
|
229
231
|
}
|
|
230
232
|
|
|
231
233
|
const index = rule.indexOf(':');
|
|
@@ -244,23 +246,39 @@ export default class Validator {
|
|
|
244
246
|
const tasks = [];
|
|
245
247
|
const skippedAttributes = [];
|
|
246
248
|
|
|
249
|
+
for (const [attribute, rules] of Object.entries(this.#rules)) {
|
|
250
|
+
for (const [rule] of rules) {
|
|
251
|
+
if (
|
|
252
|
+
rule === '' ||
|
|
253
|
+
typeof rule === 'function' ||
|
|
254
|
+
typeof this.#checkers[toCamelCase('check_' + rule)] === 'function' ||
|
|
255
|
+
Validator.#dummyRules.includes(rule)
|
|
256
|
+
)
|
|
257
|
+
continue;
|
|
258
|
+
|
|
259
|
+
throw new Error(`Invalid validation rule: ${rule}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
247
263
|
for (const [attribute, rules] of Object.entries(this.#rules)) {
|
|
248
264
|
let value = this.getValue(attribute);
|
|
265
|
+
const hasRule = (ruleName) => rules.some((rule) => rule[0] === ruleName);
|
|
249
266
|
|
|
250
|
-
if (
|
|
267
|
+
if (hasRule('sometimes') && typeof value === 'undefined') {
|
|
251
268
|
skippedAttributes.push(attribute);
|
|
252
269
|
continue;
|
|
253
270
|
}
|
|
254
271
|
|
|
255
272
|
tasks.push(async () => {
|
|
256
|
-
const doBail = this.#alwaysBail ||
|
|
257
|
-
const isNullable =
|
|
273
|
+
const doBail = this.#alwaysBail || hasRule('bail');
|
|
274
|
+
const isNullable = hasRule('nullable');
|
|
258
275
|
let noError = true;
|
|
259
276
|
|
|
260
|
-
for (const [rule, parameters] of
|
|
277
|
+
for (const [rule, parameters] of rules) {
|
|
261
278
|
if (
|
|
262
279
|
rule === '' ||
|
|
263
|
-
(
|
|
280
|
+
(typeof rule !== 'function' &&
|
|
281
|
+
!Validator.#implicitRules.includes(rule) &&
|
|
264
282
|
(typeof value === 'undefined' || (typeof value === 'string' && value.trim() === '') || (isNullable && value === null)))
|
|
265
283
|
) {
|
|
266
284
|
skippedAttributes.push(attribute);
|
|
@@ -268,22 +286,33 @@ export default class Validator {
|
|
|
268
286
|
}
|
|
269
287
|
|
|
270
288
|
let result, success, message;
|
|
271
|
-
const camelRule = toCamelCase('check_' + rule);
|
|
272
289
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
290
|
+
const checker = (() => {
|
|
291
|
+
if (typeof rule === 'function') {
|
|
292
|
+
return rule;
|
|
293
|
+
} else {
|
|
294
|
+
const checker = this.#checkers[toCamelCase('check_' + rule)] ?? null;
|
|
295
|
+
|
|
296
|
+
if (checker === null && Validator.#dummyRules.includes(rule)) {
|
|
297
|
+
return () => true;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return checker;
|
|
301
|
+
}
|
|
302
|
+
})();
|
|
303
|
+
|
|
304
|
+
if (checker === null) {
|
|
278
305
|
throw new Error(`Invalid validation rule: ${rule}`);
|
|
279
306
|
}
|
|
280
307
|
|
|
308
|
+
result = await checker.call(this.#checkers, attribute, value, parameters);
|
|
309
|
+
|
|
281
310
|
if (typeof result === 'boolean') {
|
|
282
|
-
|
|
283
|
-
} else {
|
|
284
|
-
({ success, message } = result);
|
|
311
|
+
result = { success: result };
|
|
285
312
|
}
|
|
286
313
|
|
|
314
|
+
({ success, message = '' } = result);
|
|
315
|
+
|
|
287
316
|
if (!success) {
|
|
288
317
|
noError = false;
|
|
289
318
|
message = isEmpty(message) ? this.getMessage(attribute, rule) : message;
|
|
@@ -306,7 +335,13 @@ export default class Validator {
|
|
|
306
335
|
if (!(await task())) break;
|
|
307
336
|
}
|
|
308
337
|
} else {
|
|
309
|
-
await Promise.allSettled(tasks.map((task) => task()))
|
|
338
|
+
await Promise.allSettled(tasks.map((task) => task())).then((results) => {
|
|
339
|
+
for (const result of results) {
|
|
340
|
+
if (result.status === 'rejected') {
|
|
341
|
+
throw result.reason;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
});
|
|
310
345
|
|
|
311
346
|
this.#errors.sortByKeys(Object.keys(this.#rules));
|
|
312
347
|
}
|
|
@@ -331,6 +366,10 @@ export default class Validator {
|
|
|
331
366
|
}
|
|
332
367
|
|
|
333
368
|
getMessage(attribute, rule) {
|
|
369
|
+
if (typeof rule === 'function') {
|
|
370
|
+
return '';
|
|
371
|
+
}
|
|
372
|
+
|
|
334
373
|
const value = this.getValue(attribute);
|
|
335
374
|
attribute = this.getPrimaryAttribute(attribute);
|
|
336
375
|
|
|
@@ -387,10 +426,12 @@ export default class Validator {
|
|
|
387
426
|
message = message.replaceAll(':index', index).replaceAll(':position', index + 1);
|
|
388
427
|
}
|
|
389
428
|
|
|
390
|
-
|
|
429
|
+
if (typeof rule === 'string') {
|
|
430
|
+
const replacer = this.#replacers[toCamelCase('replace_' + rule)] ?? null;
|
|
391
431
|
|
|
392
|
-
|
|
393
|
-
|
|
432
|
+
if (replacer) {
|
|
433
|
+
message = replacer.call(this.#replacers, message, attribute, rule, parameters);
|
|
434
|
+
}
|
|
394
435
|
}
|
|
395
436
|
|
|
396
437
|
return message;
|
|
@@ -463,7 +504,7 @@ export default class Validator {
|
|
|
463
504
|
}
|
|
464
505
|
|
|
465
506
|
for (const rule of rules) {
|
|
466
|
-
if (this.#rules[attribute].
|
|
507
|
+
if (this.#rules[attribute].some((attributeRule) => attributeRule[0] === rule)) {
|
|
467
508
|
return true;
|
|
468
509
|
}
|
|
469
510
|
}
|
package/test/validation.js
CHANGED
|
@@ -24,6 +24,53 @@ describe('Validation', () => {
|
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
+
describe(`Invalid rule`, () => {
|
|
28
|
+
it(`Fails when the rule is invalid`, async () => {
|
|
29
|
+
const validator = new Validator({ field: 'abc' }, { field: 'foobar' });
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
await validator.passes();
|
|
33
|
+
assert.fail('Invalid rule should throw an error');
|
|
34
|
+
} catch (error) {
|
|
35
|
+
assert.equal(error.message, 'Invalid validation rule: foobar');
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe(`Closure rule`, () => {
|
|
41
|
+
const rules = {
|
|
42
|
+
field: function (attribute, value) {
|
|
43
|
+
return /^[a-z]/i.test(value);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
it(`Passes when the value starts with a letter`, async () => {
|
|
48
|
+
const validator = new Validator({ field: 'abc' }, rules);
|
|
49
|
+
assert(await validator.passes());
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it(`Fails when the value does not start with a letter`, async () => {
|
|
53
|
+
const validator = new Validator({ field: 123 }, rules);
|
|
54
|
+
assert(await validator.fails());
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it(`Passes when the error message is correct`, async () => {
|
|
58
|
+
const validator = new Validator(
|
|
59
|
+
{ field: 123 },
|
|
60
|
+
{
|
|
61
|
+
field: function (attribute, value) {
|
|
62
|
+
return {
|
|
63
|
+
success: /^[a-z]/i.test(value),
|
|
64
|
+
message: 'The :attribute must start with a letter.',
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
assert.equal((await validator.validate()).first('field'), 'The field must start with a letter.');
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
27
74
|
describe(`Rule 'accepted'`, () => {
|
|
28
75
|
const rules = { field: 'accepted' };
|
|
29
76
|
|
|
@@ -79,6 +126,34 @@ describe('Validation', () => {
|
|
|
79
126
|
const validator = new Validator({ field: true, other: 'bar' }, rules);
|
|
80
127
|
assert(await validator.passes());
|
|
81
128
|
});
|
|
129
|
+
|
|
130
|
+
const rules2 = { field: ['accepted_if:other1,foo', 'accepted_if:other2,bar'] };
|
|
131
|
+
|
|
132
|
+
it(`Passes when accepted if other fields' value are equal to provided values`, async () => {
|
|
133
|
+
const validator = new Validator({ field: true, other1: 'foo', other2: 'bar' }, rules2);
|
|
134
|
+
assert(await validator.passes());
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it(`Fails when declined if other fields' value are equal to provided values`, async () => {
|
|
138
|
+
const validator = new Validator({ field: false, other1: 'foo', other2: 'bar' }, rules2);
|
|
139
|
+
assert(await validator.fails());
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it(`Passes when accepted if any other fields' value is equal to provided value`, async () => {
|
|
143
|
+
const validator = new Validator({ field: true, other1: 'foo', other2: 'baz' }, rules2);
|
|
144
|
+
assert(await validator.passes());
|
|
145
|
+
|
|
146
|
+
validator.setData({ field: true, other1: 'baz', other2: 'bar' });
|
|
147
|
+
assert(await validator.passes());
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it(`Fails when declined if any other fields' value is equal to provided value`, async () => {
|
|
151
|
+
const validator = new Validator({ field: false, other1: 'foo', other2: 'baz' }, rules2);
|
|
152
|
+
assert(await validator.fails());
|
|
153
|
+
|
|
154
|
+
validator.setData({ field: false, other1: 'baz', other2: 'bar' });
|
|
155
|
+
assert(await validator.fails());
|
|
156
|
+
});
|
|
82
157
|
});
|
|
83
158
|
|
|
84
159
|
describe(`Rule 'after'`, () => {
|
|
@@ -632,6 +707,34 @@ describe('Validation', () => {
|
|
|
632
707
|
const validator = new Validator({ field: true, other: 'bar' }, rules);
|
|
633
708
|
assert(await validator.passes());
|
|
634
709
|
});
|
|
710
|
+
|
|
711
|
+
const rules2 = { field: ['declined_if:other1,foo', 'declined_if:other2,bar'] };
|
|
712
|
+
|
|
713
|
+
it(`Passes when declined if other fields' value are equal to provided values`, async () => {
|
|
714
|
+
const validator = new Validator({ field: false, other1: 'foo', other2: 'bar' }, rules2);
|
|
715
|
+
assert(await validator.passes());
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
it(`Fails when accepted if other fields' value are equal to provided values`, async () => {
|
|
719
|
+
const validator = new Validator({ field: true, other1: 'foo', other2: 'bar' }, rules2);
|
|
720
|
+
assert(await validator.fails());
|
|
721
|
+
});
|
|
722
|
+
|
|
723
|
+
it(`Passes when declined if any other fields' value is equal to provided value`, async () => {
|
|
724
|
+
const validator = new Validator({ field: false, other1: 'foo', other2: 'baz' }, rules2);
|
|
725
|
+
assert(await validator.passes());
|
|
726
|
+
|
|
727
|
+
validator.setData({ field: false, other1: 'baz', other2: 'bar' });
|
|
728
|
+
assert(await validator.passes());
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it(`Fails when accepted if any other fields' value is equal to provided value`, async () => {
|
|
732
|
+
const validator = new Validator({ field: true, other1: 'foo', other2: 'baz' }, rules2);
|
|
733
|
+
assert(await validator.fails());
|
|
734
|
+
|
|
735
|
+
validator.setData({ field: true, other1: 'baz', other2: 'bar' });
|
|
736
|
+
assert(await validator.fails());
|
|
737
|
+
});
|
|
635
738
|
});
|
|
636
739
|
|
|
637
740
|
describe(`Rule 'different'`, () => {
|
|
@@ -805,7 +908,7 @@ describe('Validation', () => {
|
|
|
805
908
|
const rules = { field: 'extensions:jpg,png' };
|
|
806
909
|
|
|
807
910
|
it(`Passes when the field has a valid extension`, async () => {
|
|
808
|
-
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/
|
|
911
|
+
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/jpeg') }, rules);
|
|
809
912
|
assert(await validator.passes());
|
|
810
913
|
|
|
811
914
|
validator.setData({ field: new File('hello.png', 5 * 1024, 'image/png') });
|
|
@@ -1183,7 +1286,10 @@ describe('Validation', () => {
|
|
|
1183
1286
|
const rules = { field: 'image' };
|
|
1184
1287
|
|
|
1185
1288
|
it(`Passes when the field is an image`, async () => {
|
|
1186
|
-
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/
|
|
1289
|
+
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/jpeg') }, rules);
|
|
1290
|
+
assert(await validator.passes());
|
|
1291
|
+
|
|
1292
|
+
validator.setData({ field: new File('hello.jpeg', 5 * 1024, 'image/jpeg') }, rules);
|
|
1187
1293
|
assert(await validator.passes());
|
|
1188
1294
|
});
|
|
1189
1295
|
|
|
@@ -1748,7 +1854,7 @@ describe('Validation', () => {
|
|
|
1748
1854
|
const rules = { field: 'mimes:jpg,png' };
|
|
1749
1855
|
|
|
1750
1856
|
it(`Passes when the field has a valid extension`, async () => {
|
|
1751
|
-
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/
|
|
1857
|
+
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/jpeg') }, rules);
|
|
1752
1858
|
assert(await validator.passes());
|
|
1753
1859
|
|
|
1754
1860
|
validator.setData({ field: new File('hello.png', 5 * 1024, 'image/png') });
|
|
@@ -1762,13 +1868,21 @@ describe('Validation', () => {
|
|
|
1762
1868
|
validator.setData({ field: new File('hello.txt', 5 * 1024, 'text/plain') });
|
|
1763
1869
|
assert(await validator.fails());
|
|
1764
1870
|
});
|
|
1871
|
+
|
|
1872
|
+
it(`Passes when the rule's parameter for JPEG file is defined as 'jpg' or 'jpeg'`, async () => {
|
|
1873
|
+
const validator = new Validator({ field: new File('hello.jpeg', 5 * 1024, 'image/jpeg') }, { field: 'mimes:jpg' });
|
|
1874
|
+
assert(await validator.passes());
|
|
1875
|
+
|
|
1876
|
+
validator.setProperties({ field: new File('hello.jpg', 5 * 1024, 'image/jpeg') }, { field: 'mimes:jpeg' });
|
|
1877
|
+
assert(await validator.passes());
|
|
1878
|
+
});
|
|
1765
1879
|
});
|
|
1766
1880
|
|
|
1767
1881
|
describe(`Rule 'mimetypes'`, () => {
|
|
1768
|
-
const rules = { field: 'mimetypes:image/
|
|
1882
|
+
const rules = { field: 'mimetypes:image/jpeg,image/png' };
|
|
1769
1883
|
|
|
1770
1884
|
it(`Passes when the field has a valid type`, async () => {
|
|
1771
|
-
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/
|
|
1885
|
+
const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/jpeg') }, rules);
|
|
1772
1886
|
assert(await validator.passes());
|
|
1773
1887
|
|
|
1774
1888
|
validator.setData({ field: new File('hello.png', 5 * 1024, 'image/png') });
|
|
@@ -1906,6 +2020,26 @@ describe('Validation', () => {
|
|
|
1906
2020
|
const validator = new Validator({ field: '', other: 'bar' }, rules);
|
|
1907
2021
|
assert(await validator.fails());
|
|
1908
2022
|
});
|
|
2023
|
+
|
|
2024
|
+
const rules2 = { field: ['missing_if:other1,foo,bar', 'missing_if:other2,win,amp'] };
|
|
2025
|
+
|
|
2026
|
+
it(`Passes when the field is present and other fields' value are not equal to provided values`, async () => {
|
|
2027
|
+
const validator = new Validator({ field: '', other1: 'baz', other2: 'rar' }, rules2);
|
|
2028
|
+
assert(await validator.passes());
|
|
2029
|
+
});
|
|
2030
|
+
|
|
2031
|
+
it(`Fails when the field is present and other fields' value are equal to provided values`, async () => {
|
|
2032
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'win' }, rules2);
|
|
2033
|
+
assert(await validator.fails());
|
|
2034
|
+
});
|
|
2035
|
+
|
|
2036
|
+
it(`Fails when the field is present and any other fields' value is equal to provided value`, async () => {
|
|
2037
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'rar' }, rules2);
|
|
2038
|
+
assert(await validator.fails());
|
|
2039
|
+
|
|
2040
|
+
validator.setData({ field: '', other1: 'baz', other2: 'win' });
|
|
2041
|
+
assert(await validator.fails());
|
|
2042
|
+
});
|
|
1909
2043
|
});
|
|
1910
2044
|
|
|
1911
2045
|
describe(`Rule 'missing_unless'`, () => {
|
|
@@ -1930,6 +2064,26 @@ describe('Validation', () => {
|
|
|
1930
2064
|
const validator = new Validator({ field: '', other: 'bob' }, rules);
|
|
1931
2065
|
assert(await validator.fails());
|
|
1932
2066
|
});
|
|
2067
|
+
|
|
2068
|
+
const rules2 = { field: ['missing_unless:other1,foo,bar', 'missing_unless:other2,win,amp'] };
|
|
2069
|
+
|
|
2070
|
+
it(`Passes when the field is present and other fields' value are equal to provided values`, async () => {
|
|
2071
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'win' }, rules2);
|
|
2072
|
+
assert(await validator.passes());
|
|
2073
|
+
});
|
|
2074
|
+
|
|
2075
|
+
it(`Fails when the field is present and other fields' value are not equal to provided values`, async () => {
|
|
2076
|
+
const validator = new Validator({ field: '', other1: 'baz', other2: 'rar' }, rules2);
|
|
2077
|
+
assert(await validator.fails());
|
|
2078
|
+
});
|
|
2079
|
+
|
|
2080
|
+
it(`Fails when the field is present and any other fields' value is not equal to provided value`, async () => {
|
|
2081
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'rar' }, rules2);
|
|
2082
|
+
assert(await validator.fails());
|
|
2083
|
+
|
|
2084
|
+
validator.setData({ field: '', other1: 'baz', other2: 'win' });
|
|
2085
|
+
assert(await validator.fails());
|
|
2086
|
+
});
|
|
1933
2087
|
});
|
|
1934
2088
|
|
|
1935
2089
|
describe(`Rule 'missing_with'`, () => {
|
|
@@ -2142,6 +2296,26 @@ describe('Validation', () => {
|
|
|
2142
2296
|
const validator = new Validator({ field: 'abc', other: 'bar' }, rules);
|
|
2143
2297
|
assert(await validator.fails());
|
|
2144
2298
|
});
|
|
2299
|
+
|
|
2300
|
+
const rules2 = { field: ['prohibited_if:other1,foo,bar', 'prohibited_if:other2,win,amp'] };
|
|
2301
|
+
|
|
2302
|
+
it(`Passes when the field is filled and other fields' value are not equal to provided values`, async () => {
|
|
2303
|
+
const validator = new Validator({ field: 'abc', other1: 'baz', other2: 'rar' }, rules2);
|
|
2304
|
+
assert(await validator.passes());
|
|
2305
|
+
});
|
|
2306
|
+
|
|
2307
|
+
it(`Fails when the field is filled and other fields' value are equal to provided values`, async () => {
|
|
2308
|
+
const validator = new Validator({ field: 'abc', other1: 'foo', other2: 'win' }, rules2);
|
|
2309
|
+
assert(await validator.fails());
|
|
2310
|
+
});
|
|
2311
|
+
|
|
2312
|
+
it(`Fails when the field is filled and any other fields' value is equal to provided value`, async () => {
|
|
2313
|
+
const validator = new Validator({ field: 'abc', other1: 'foo', other2: 'rar' }, rules2);
|
|
2314
|
+
assert(await validator.fails());
|
|
2315
|
+
|
|
2316
|
+
validator.setData({ field: 'abc', other1: 'baz', other2: 'win' });
|
|
2317
|
+
assert(await validator.fails());
|
|
2318
|
+
});
|
|
2145
2319
|
});
|
|
2146
2320
|
|
|
2147
2321
|
describe(`Rule 'prohibited_unless'`, () => {
|
|
@@ -2166,6 +2340,26 @@ describe('Validation', () => {
|
|
|
2166
2340
|
const validator = new Validator({ field: 'abc', other: 'bob' }, rules);
|
|
2167
2341
|
assert(await validator.fails());
|
|
2168
2342
|
});
|
|
2343
|
+
|
|
2344
|
+
const rules2 = { field: ['prohibited_unless:other1,foo,bar', 'prohibited_unless:other2,win,amp'] };
|
|
2345
|
+
|
|
2346
|
+
it(`Passes when the field is filled and other fields' value are equal to provided values`, async () => {
|
|
2347
|
+
const validator = new Validator({ field: 'abc', other1: 'foo', other2: 'win' }, rules2);
|
|
2348
|
+
assert(await validator.passes());
|
|
2349
|
+
});
|
|
2350
|
+
|
|
2351
|
+
it(`Fails when the field is filled and other fields' value are not equal to provided values`, async () => {
|
|
2352
|
+
const validator = new Validator({ field: 'abc', other1: 'baz', other2: 'rar' }, rules2);
|
|
2353
|
+
assert(await validator.fails());
|
|
2354
|
+
});
|
|
2355
|
+
|
|
2356
|
+
it(`Fails when the field is filled and any other fields' value is not equal to provided value`, async () => {
|
|
2357
|
+
const validator = new Validator({ field: 'abc', other1: 'foo', other2: 'rar' }, rules2);
|
|
2358
|
+
assert(await validator.fails());
|
|
2359
|
+
|
|
2360
|
+
validator.setData({ field: 'abc', other1: 'baz', other2: 'win' });
|
|
2361
|
+
assert(await validator.fails());
|
|
2362
|
+
});
|
|
2169
2363
|
});
|
|
2170
2364
|
|
|
2171
2365
|
describe(`Rule 'prohibits'`, () => {
|
|
@@ -2280,6 +2474,26 @@ describe('Validation', () => {
|
|
|
2280
2474
|
const validator = new Validator({ field: '', other: 'bar' }, rules);
|
|
2281
2475
|
assert(await validator.fails());
|
|
2282
2476
|
});
|
|
2477
|
+
|
|
2478
|
+
const rules2 = { field: ['required_if:other1,foo,bar', 'required_if:other2,win,amp'] };
|
|
2479
|
+
|
|
2480
|
+
it(`Passes when the field is empty and other fields' value are not equal to provided values`, async () => {
|
|
2481
|
+
const validator = new Validator({ field: '', other1: 'baz', other2: 'rar' }, rules2);
|
|
2482
|
+
assert(await validator.passes());
|
|
2483
|
+
});
|
|
2484
|
+
|
|
2485
|
+
it(`Fails when the field is empty and other fields' value are equal to provided values`, async () => {
|
|
2486
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'win' }, rules2);
|
|
2487
|
+
assert(await validator.fails());
|
|
2488
|
+
});
|
|
2489
|
+
|
|
2490
|
+
it(`Fails when the field is empty and any other fields' value is equal to provided value`, async () => {
|
|
2491
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'rar' }, rules2);
|
|
2492
|
+
assert(await validator.fails());
|
|
2493
|
+
|
|
2494
|
+
validator.setData({ field: '', other1: 'baz', other2: 'win' });
|
|
2495
|
+
assert(await validator.fails());
|
|
2496
|
+
});
|
|
2283
2497
|
});
|
|
2284
2498
|
|
|
2285
2499
|
describe(`Rule 'required_if_accepted'`, () => {
|
|
@@ -2304,6 +2518,26 @@ describe('Validation', () => {
|
|
|
2304
2518
|
const validator = new Validator({ field: '', foo: true }, rules);
|
|
2305
2519
|
assert(await validator.fails());
|
|
2306
2520
|
});
|
|
2521
|
+
|
|
2522
|
+
const rules2 = { field: ['required_if_accepted:other1', 'required_if_accepted:other2'] };
|
|
2523
|
+
|
|
2524
|
+
it(`Passes when the field is empty and other fields are declined`, async () => {
|
|
2525
|
+
const validator = new Validator({ field: '', other1: false, other2: false }, rules2);
|
|
2526
|
+
assert(await validator.passes());
|
|
2527
|
+
});
|
|
2528
|
+
|
|
2529
|
+
it(`Fails when the field is empty and all fields are accepted`, async () => {
|
|
2530
|
+
const validator = new Validator({ field: '', other1: true, other2: true }, rules2);
|
|
2531
|
+
assert(await validator.fails());
|
|
2532
|
+
});
|
|
2533
|
+
|
|
2534
|
+
it(`Fails when the field is empty and any field is accepted`, async () => {
|
|
2535
|
+
const validator = new Validator({ field: '', other1: true, other2: false }, rules2);
|
|
2536
|
+
assert(await validator.fails());
|
|
2537
|
+
|
|
2538
|
+
validator.setData({ field: '', other1: false, other2: true });
|
|
2539
|
+
assert(await validator.fails());
|
|
2540
|
+
});
|
|
2307
2541
|
});
|
|
2308
2542
|
|
|
2309
2543
|
describe(`Rule 'required_if_declined'`, () => {
|
|
@@ -2328,6 +2562,26 @@ describe('Validation', () => {
|
|
|
2328
2562
|
const validator = new Validator({ field: '', foo: false }, rules);
|
|
2329
2563
|
assert(await validator.fails());
|
|
2330
2564
|
});
|
|
2565
|
+
|
|
2566
|
+
const rules2 = { field: ['required_if_declined:other1', 'required_if_declined:other2'] };
|
|
2567
|
+
|
|
2568
|
+
it(`Passes when the field is empty and other fields are accepted`, async () => {
|
|
2569
|
+
const validator = new Validator({ field: '', other1: true, other2: true }, rules2);
|
|
2570
|
+
assert(await validator.passes());
|
|
2571
|
+
});
|
|
2572
|
+
|
|
2573
|
+
it(`Fails when the field is empty and all fields are declined`, async () => {
|
|
2574
|
+
const validator = new Validator({ field: '', other1: false, other2: false }, rules2);
|
|
2575
|
+
assert(await validator.fails());
|
|
2576
|
+
});
|
|
2577
|
+
|
|
2578
|
+
it(`Fails when the field is empty and any field is declined`, async () => {
|
|
2579
|
+
const validator = new Validator({ field: '', other1: true, other2: false }, rules2);
|
|
2580
|
+
assert(await validator.fails());
|
|
2581
|
+
|
|
2582
|
+
validator.setData({ field: '', other1: false, other2: true });
|
|
2583
|
+
assert(await validator.fails());
|
|
2584
|
+
});
|
|
2331
2585
|
});
|
|
2332
2586
|
|
|
2333
2587
|
describe(`Rule 'required_unless'`, () => {
|
|
@@ -2352,6 +2606,26 @@ describe('Validation', () => {
|
|
|
2352
2606
|
const validator = new Validator({ field: '', other: 'bob' }, rules);
|
|
2353
2607
|
assert(await validator.fails());
|
|
2354
2608
|
});
|
|
2609
|
+
|
|
2610
|
+
const rules2 = { field: ['required_unless:other1,foo,bar', 'required_unless:other2,win,amp'] };
|
|
2611
|
+
|
|
2612
|
+
it(`Passes when the field is empty and other fields' value are equal to provided values`, async () => {
|
|
2613
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'win' }, rules2);
|
|
2614
|
+
assert(await validator.passes());
|
|
2615
|
+
});
|
|
2616
|
+
|
|
2617
|
+
it(`Fails when the field is empty and other fields' value are not equal to provided values`, async () => {
|
|
2618
|
+
const validator = new Validator({ field: '', other1: 'baz', other2: 'rar' }, rules2);
|
|
2619
|
+
assert(await validator.fails());
|
|
2620
|
+
});
|
|
2621
|
+
|
|
2622
|
+
it(`Fails when the field is empty and any other fields' value is not equal to provided value`, async () => {
|
|
2623
|
+
const validator = new Validator({ field: '', other1: 'foo', other2: 'rar' }, rules2);
|
|
2624
|
+
assert(await validator.fails());
|
|
2625
|
+
|
|
2626
|
+
validator.setData({ field: '', other1: 'baz', other2: 'win' });
|
|
2627
|
+
assert(await validator.fails());
|
|
2628
|
+
});
|
|
2355
2629
|
});
|
|
2356
2630
|
|
|
2357
2631
|
describe(`Rule 'required_with'`, () => {
|