quival 0.2.7 → 0.3.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.
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * quival v0.2.7 (https://github.com/apih/quival)
2
+ * quival v0.3.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){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return Object.keys(e).reduce(((r,i)=>{const a=t?`${t}.${i}`:i;return"object"==typeof e[i]&&null!==e[i]?Object.assign(r,s(e[i],a)):r[a]=e[i],r}),{})}function i(e){const t=[];let r="",s=!1;for(let i=0;i<e.length;i++){const a=e[i];'"'===a?s&&'"'===e[i+1]?(r+='"',i++):(s=!s,s&&(r=r.trim())):","!==a||s?r+=a:(t.push(r),r="")}return t.push(r),t}function a(e){if(n(e)||"string"!=typeof e)return new Date("");if(e instanceof Date)return e;let t,r,s,i,a,c,l,h;const u=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,,a=0,c=0,,l=0,h="am"]=t.map(u);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,,a=0,c=0,,l=0,h="am"]=t.map(u);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))[,a,c,,l,h="am",r,s,i]=t.map(u);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))[,a,c,,l,h="am",i,s,r]=t.map(u);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(),[,a=0,c=0,,l=0,h="am"]=t.map(u)}}return r>=10&&r<100&&(r+=2e3),"pm"===h.toLowerCase()&&a<12&&(a+=12),new Date(`${r}-${s}-${i} ${a}:${c}:${l}`)}function c(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},a=1;for(const e of t)r.hasOwnProperty(e)?(s+=r[e],-1!==["Y","y"].indexOf(e)?i.years=a++:-1!==["m","n"].indexOf(e)?i.months=a++:-1!==["d","j"].indexOf(e)?i.days=a++:-1!==["G","g","H","h"].indexOf(e)?i.hours=a++:"i"===e?i.minutes=a++:"s"===e?i.seconds=a++:-1!==["A","a"].indexOf(e)&&(i.meridiem=a++)):s+="\\"+e;s+="$";let c=e.match(new RegExp(s));if(null===c)return new Date("");c=c.map((e=>e&&/^\d*$/.test(e)?parseInt(e):e));const l=new Date;let h=c[i.years],u=c[i.months],o=c[i.days],p=c[i.hours]??0,d=c[i.minutes]??0,g=c[i.seconds]??0,f=c[i.meridiem]??"am";return h||u||o?!h||u||o?h||!u||o?h||u||!o||(h=l.getFullYear(),u=l.getMonth()+1):(h=l.getFullYear(),o=1):(u=1,o=1):(h=l.getFullYear(),u=l.getMonth()+1,o=l.getDate()),h>=10&&h<100&&(h+=2e3),"pm"===f.toLowerCase()&&p<12&&(p+=12),new Date(`${h}-${u}-${o} ${p}:${d}:${g}`)}function n(e){return""===e||null==e}function l(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 u(e){return e instanceof Date&&"Invalid Date"!==e.toDateString()}class o{validator;#e={};#t={};constructor(e){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){let i=arguments.length>4&&void 0!==arguments[4]&&arguments[4];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 a=this.validator.getValue(i);return a=void 0===a?l(i)?parseFloat(i,10):null:this.validator.getSize(i,a),!n(a)&&s(this.validator.getSize(e,t),a)}compareDates(e,t,r,s){const i=this.validator.getRule(e);if(!u(t=i.hasOwnProperty("date_format")?c(t,i.date_format[0]):a(t)))return!1;const n=r[0]??"";let l=this.validator.getValue(n);if(void 0===l)l=a(n);else{const e=this.validator.getRule(n);l=e.hasOwnProperty("date_format")?c(l,e.date_format[0]):a(l)}return!!u(l)&&s(t.getTime(),l.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}checkBoolean(e,t,r){return[!0,!1,0,1,"0","1"].includes(t)}checkDate(e,t,r){return u(a(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 l(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(!l(t)||!l(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)}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){let s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:(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){let s=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if("string"!=typeof t&&!l(t))return!1;const i=r.join(",");let[a,c,h]=i.match(/^\/(.*)\/([gimu]*)$/)??[];if(n(a))throw new Error(`Invalid regular expression pattern: ${i}`);h.includes("u")&&(c=c.replace(/\\A/g,"^").replace(/\\z/gi,"$").replace(/\\([pP])([CLMNPSZ])/g,"\\$1{$2}").replace(/\\\x\{([0-9a-f]+)\}/g,"\\u{$1}"));const u=new RegExp(c,h).test(t);return s?!u:u}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 a="^";for(const e of s)i.hasOwnProperty(e)?a+=i[e]:a+="\\"+e;return a+="$",new RegExp(a).test(t)}checkDistinct(e,t,i){const a=this.validator.getPrimaryAttribute(e);if(!a.includes("*"))return!0;const c=a.indexOf("*"),n=a.substring(0,c-1);let l;this.#e.hasOwnProperty(n)?l=this.#e[n]:(l=JSON.stringify(s(this.validator.getValue(n)??{})),this.#e[n]=l);const h=i.includes("ignore_case"),u=!h&&i.includes("strict"),o=r(String(t));let p=`"${r(a.substring(c)).replaceAll("\\*",'[^."]+')}":`,d=0;return p+=u?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,p+="[,}]+",d+=l.match(new RegExp(p,"g"+(h?"i":"")))?.length??0,1===d}checkInArray(e,t,r){const i=this.validator.getPrimaryAttribute(r[0]);if(!i.includes("*"))return!1;const a=this.validator.getValue(i.split(".*")[0])??{};return Object.values(s(a)).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)||!this.#t.hasOwnProperty(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],a=i.naturalWidth,c=i.naturalHeight;return!(s.hasOwnProperty("width")&&s.width!==a||s.hasOwnProperty("height")&&s.height!==c||s.hasOwnProperty("min_width")&&s.min_width>a||s.hasOwnProperty("min_height")&&s.min_height>c||s.hasOwnProperty("max_width")&&s.max_width<a||s.hasOwnProperty("max_height")&&s.max_height<c)&&(!s.hasOwnProperty("ratio")||Math.abs(s.ratio-a/c)<=1/(Math.max(a,c)+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,a;for([i,a]of Object.entries(s))if(t.includes(i))break;const c=t.split(i);if(c.length!==12/a)return!1;for(const e of c)if(!new RegExp("^[0-9a-f]{"+a+"}$","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 p{#r={};keys(){return Object.keys(this.#r)}values(){return Object.values(this.#r)}entries(){return Object.entries(this.#r)}add(e,t){this.#r.hasOwnProperty(e)?this.#r[e].push(t):this.#r[e]=[t]}get(e){if(!e.includes("*"))return this.#r.hasOwnProperty(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)}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()}}class d{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 g{validator;constructor(e){this.validator=e}replace(e,t){return Object.entries(t).forEach((t=>{let[r,s]=t;return e=e.replaceAll(":"+r,s)})),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)}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 f{static#a={};static#c={};static#n=["active_url","bail","can","current_password","enum","exclude","exclude_if","exclude_unless","exclude_with","exclude_without","exists","nullable","sometimes","unique"];static#l=["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_unless","required_with","required_with_all","required_without","required_without_all"];#r;#h;#u;#o;#p;#d;#g;#f;#m={};#y=!1;#k=!1;fileRules=["file","image","mimetypes","mimes"];numericRules=["decimal","numeric","integer"];sizeRules=["size","between","min","max","gt","lt","gte","lte"];static setLocale(e){d.locale(e)}static setMessages(e,t){d.setMessages(e,t)}static addChecker(e,t,r){f.#a[e]=t,r&&d.set(e,r)}static addImplicitChecker(e,t,r){f.addChecker(e,t,r),f.#l.push(e)}static addReplacer(e,t){f.#c[e]=t}static addDummyRule(e){f.#n.push(e)}constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};this.setProperties(e,r,s,i,a),this.#d=new o(this),this.#g=new g(this);for(const[e,r]of Object.entries(f.#a))this.#d[t("check_"+e)]=r;for(const[e,r]of Object.entries(f.#c))this.#g[t("replace_"+e)]=r;this.#f=new p}setProperties(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};return this.#r=e,this.#h=this.parseRules(t),this.#u=r,this.#o=i,this.#p=s(a),this}setData(e){return this.#r=e,this}setRules(e){return this.#h=this.parseRules(e),this}setCustomMessages(e){return this.#u=e,this}setCustomAttributes(e){return this.#o=e,this}setCustomValues(e){return this.#p=s(e),this}addImplicitAttribute(e,t){return this.#m[e]=t,this}stopOnFirstFailure(){let e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return this.#y=e,this}alwaysBail(){let e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return this.#k=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),a=this.getValue(s);return Array.isArray(a)||h(a)?(Object.entries(a).forEach((r=>{let[a,c]=r;const n=`${s}.${a}.${i}`.replace(/\.$/,""),l=n.includes("*")?this.parseWildcardAttribute(n):[n];t.push(...l),l.forEach((t=>this.#m[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.#d.clearCaches(),this.#f=new p;for(const[e,r]of Object.entries(this.#h)){let s=this.getValue(e);if(r.hasOwnProperty("sometimes")&&void 0===s)continue;const i=this.#k||r.hasOwnProperty("bail"),a=r.hasOwnProperty("nullable");let c=!1;for(const[l,h]of Object.entries(r)){if(""===l)continue;if(!f.#l.includes(l)&&(void 0===s||"string"==typeof s&&""===s.trim()||a&&null===s))continue;let r,u,o;const p=t("check_"+l);if("function"==typeof this.#d[p])r=await this.#d[p](e,s,h);else{if(!f.#n.includes(l))throw new Error(`Invalid validation rule: ${l}`);r=!0}if("boolean"==typeof r?u=r:({status:u,message:o}=r),!u&&(c=!0,o=n(o)?this.getMessage(e,l):o,o=this.makeReplacements(o,e,l,h),this.#f.add(e,o),i||f.#l.includes(l)))break}if(this.#y&&c)break}if(this.#f.isNotEmpty())throw this.#f}async passes(){try{await this.validate()}catch(e){if(e instanceof Error)throw e;return!1}return!0}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(this.#u.hasOwnProperty(r)){s=this.#u[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":"number"==typeof r||this.hasRule(e,this.numericRules)?i+=".numeric":i+=".string"),s=d.get(i)}return s??`validation.${t}`}makeReplacements(e,r,s,i){const a=this.getDisplayableAttribute(r),c=this.getValue(r),n={attribute:a,ATTRIBUTE:a.toLocaleUpperCase(),Attribute:a.charAt(0).toLocaleUpperCase()+a.substring(1),input:this.getDisplayableValue(r,c)};for(const[t,r]of Object.entries(n))e=e.replaceAll(":"+t,r);const l=r.match(/\.(\d+)\.?/),h=null===l?-1:parseInt(l[1],10);-1!==h&&(e=e.replaceAll(":index",h).replaceAll(":position",h+1));const u=t("replace_"+s);return"function"==typeof this.#g[u]&&(e=this.#g[u](e,r,s,i)),e}getDisplayableAttribute(e){const t=this.getPrimaryAttribute(e);for(const r of[e,t]){if(this.#o.hasOwnProperty(r))return this.#o[r];if(d.has(`attributes.${r}`))return d.get(`attributes.${r}`)}return this.#m.hasOwnProperty(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":this.#p.hasOwnProperty(r)?this.#p[r]:d.has(`values.${r}`)?d.get(`values.${r}`):t}getSize(e,t){return n(t)?0:l(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:t.hasOwnProperty("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,!this.#h.hasOwnProperty(e))return!1;for(const r of t)if(this.#h[e].hasOwnProperty(r))return!0;return!1}getPrimaryAttribute(e){return this.#m.hasOwnProperty(e)?this.#m[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(!i.hasOwnProperty(e))return r;i=i[e]}return i}(this.#r,e)}errors(){return this.#f}}return e.Checkers=o,e.ErrorBag=p,e.Lang=d,e.Replacers=g,e.Validator=f,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 a=t?`${t}.${i}`:i;return"object"==typeof e[i]&&null!==e[i]?Object.assign(r,s(e[i],a)):r[a]=e[i],r}),{})}function i(e){const t=[];let r="",s=!1;for(let i=0;i<e.length;i++){const a=e[i];'"'===a?s&&'"'===e[i+1]?(r+='"',i++):(s=!s,s&&(r=r.trim())):","!==a||s?r+=a:(t.push(r),r="")}return t.push(r),t}function a(e){if(n(e)||"string"!=typeof e)return new Date("");if(e instanceof Date)return e;let t,r,s,i,a,c,l,h;const u=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,,a=0,c=0,,l=0,h="am"]=t.map(u);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,,a=0,c=0,,l=0,h="am"]=t.map(u);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))[,a,c,,l,h="am",r,s,i]=t.map(u);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))[,a,c,,l,h="am",i,s,r]=t.map(u);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(),[,a=0,c=0,,l=0,h="am"]=t.map(u)}}return r>=10&&r<100&&(r+=2e3),"pm"===h.toLowerCase()&&a<12&&(a+=12),new Date(`${r}-${s}-${i} ${a}:${c}:${l}`)}function c(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},a=1;for(const e of t)Object.hasOwn(r,e)?(s+=r[e],-1!==["Y","y"].indexOf(e)?i.years=a++:-1!==["m","n"].indexOf(e)?i.months=a++:-1!==["d","j"].indexOf(e)?i.days=a++:-1!==["G","g","H","h"].indexOf(e)?i.hours=a++:"i"===e?i.minutes=a++:"s"===e?i.seconds=a++:-1!==["A","a"].indexOf(e)&&(i.meridiem=a++)):s+="\\"+e;s+="$";let c=e.match(new RegExp(s));if(null===c)return new Date("");c=c.map((e=>e&&/^\d*$/.test(e)?parseInt(e):e));const l=new Date;let h=c[i.years],u=c[i.months],o=c[i.days],d=c[i.hours]??0,p=c[i.minutes]??0,f=c[i.seconds]??0,g=c[i.meridiem]??"am";return h||u||o?!h||u||o?h||!u||o?h||u||!o||(h=l.getFullYear(),u=l.getMonth()+1):(h=l.getFullYear(),o=1):(u=1,o=1):(h=l.getFullYear(),u=l.getMonth()+1,o=l.getDate()),h>=10&&h<100&&(h+=2e3),"pm"===g.toLowerCase()&&d<12&&(d+=12),new Date(`${h}-${u}-${o} ${d}:${p}:${f}`)}function n(e){return""===e||null==e}function l(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 u(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 a=this.validator.getValue(i);return a=void 0===a?l(i)?parseFloat(i,10):null:this.validator.getSize(i,a),!n(a)&&s(this.validator.getSize(e,t),a)}compareDates(e,t,r,s){const i=this.validator.getRule(e);if(!u(t=Object.hasOwn(i,"date_format")?c(t,i.date_format[0]):a(t)))return!1;const n=r[0]??"";let l=this.validator.getValue(n);if(void 0===l)l=a(n);else{const e=this.validator.getRule(n);l=Object.hasOwn(e,"date_format")?c(l,e.date_format[0]):a(l)}return!!u(l)&&s(t.getTime(),l.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 u(a(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 l(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(!l(t)||!l(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)}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&&!l(t))return!1;const i=r.join(",");let[a,c,h]=i.match(/^\/(.*)\/([gimu]*)$/)??[];if(n(a))throw new Error(`Invalid regular expression pattern: ${i}`);h.includes("u")&&(c=c.replace(/\\A/g,"^").replace(/\\z/gi,"$").replace(/\\([pP])([CLMNPSZ])/g,"\\$1{$2}").replace(/\\\x\{([0-9a-f]+)\}/g,"\\u{$1}"));const u=new RegExp(c,h).test(t);return s?!u:u}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 a="^";for(const e of s)Object.hasOwn(i,e)?a+=i[e]:a+="\\"+e;return a+="$",new RegExp(a).test(t)}checkDistinct(e,t,i){const a=this.validator.getPrimaryAttribute(e);if(!a.includes("*"))return!0;const c=a.indexOf("*"),n=a.substring(0,c-1);let l;Object.hasOwn(this.#e,n)?l=this.#e[n]:(l=JSON.stringify(s(this.validator.getValue(n)??{})),this.#e[n]=l);const h=i.includes("ignore_case"),u=!h&&i.includes("strict"),o=r(String(t));let d=`"${r(a.substring(c)).replaceAll("\\*",'[^."]+')}":`,p=0;return d+=u?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,d+="[,}]+",p+=l.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 a=this.validator.getValue(i.split(".*")[0])??{};return Object.values(s(a)).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],a=i.naturalWidth,c=i.naturalHeight;return!(Object.hasOwn(s,"width")&&s.width!==a||Object.hasOwn(s,"height")&&s.height!==c||Object.hasOwn(s,"min_width")&&s.min_width>a||Object.hasOwn(s,"min_height")&&s.min_height>c||Object.hasOwn(s,"max_width")&&s.max_width<a||Object.hasOwn(s,"max_height")&&s.max_height<c)&&(!Object.hasOwn(s,"ratio")||Math.abs(s.ratio-a/c)<=1/(Math.max(a,c)+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,a;for([i,a]of Object.entries(s))if(t.includes(i))break;const c=t.split(i);if(c.length!==12/a)return!1;for(const e of c)if(!new RegExp("^[0-9a-f]{"+a+"}$","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)}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)}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#a={};static#c={};static#n=["active_url","bail","can","current_password","enum","exclude","exclude_if","exclude_unless","exclude_with","exclude_without","exists","nullable","sometimes","unique"];static#l=["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_unless","required_with","required_with_all","required_without","required_without_all"];#r;#h;#u;#o;#d;#p;#f;#g;#m;#k;#b;static setLocale(e){p.locale(e)}static setMessages(e,t){p.setMessages(e,t)}static addChecker(e,t,r){g.#a[e]=t,r&&p.set(e,r)}static addImplicitChecker(e,t,r){g.addChecker(e,t,r),g.#l.push(e)}static addReplacer(e,t){g.#c[e]=t}static addDummyRule(e){g.#n.push(e)}constructor(e={},r={},s={},i={},a={}){this.#m={},this.#k=!1,this.#b=!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,a),this.#p=new o(this),this.#f=new f(this);for(const[e,r]of Object.entries(g.#a))this.#p[t("check_"+e)]=r;for(const[e,r]of Object.entries(g.#c))this.#f[t("replace_"+e)]=r;this.#g=new d}setProperties(e={},t={},r={},i={},a={}){return this.#r=e,this.#h=this.parseRules(t),this.#u=r,this.#o=i,this.#d=s(a),this}setData(e){return this.#r=e,this}setRules(e){return this.#h=this.parseRules(e),this}setCustomMessages(e){return this.#u=e,this}setCustomAttributes(e){return this.#o=e,this}setCustomValues(e){return this.#d=s(e),this}addImplicitAttribute(e,t){return this.#m[e]=t,this}stopOnFirstFailure(e=!0){return this.#k=e,this}alwaysBail(e=!0){return this.#b=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),a=this.getValue(s);return Array.isArray(a)||h(a)?(Object.entries(a).forEach((([r,a])=>{const c=`${s}.${r}.${i}`.replace(/\.$/,""),n=c.includes("*")?this.parseWildcardAttribute(c):[c];t.push(...n),n.forEach((t=>this.#m[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=[];for(const[r,s]of Object.entries(this.#h)){let i=this.getValue(r);Object.hasOwn(s,"sometimes")&&void 0===i||e.push((async()=>{const e=this.#b||Object.hasOwn(s,"bail"),a=Object.hasOwn(s,"nullable");let c=!0;for(const[l,h]of Object.entries(s)){if(""===l)continue;if(!g.#l.includes(l)&&(void 0===i||"string"==typeof i&&""===i.trim()||a&&null===i))continue;let s,u,o;const d=t("check_"+l);if("function"==typeof this.#p[d])s=await this.#p[d](r,i,h);else{if(!g.#n.includes(l))throw new Error(`Invalid validation rule: ${l}`);s=!0}if("boolean"==typeof s?u=s:({success:u,message:o}=s),!u&&(c=!1,o=n(o)?this.getMessage(r,l):o,o=this.makeReplacements(o,r,l,h),this.#g.add(r,o),e||g.#l.includes(l)))break}return c}))}if(this.#k){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.#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.#u,r)){s=this.#u[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":l(r)||this.hasRule(e,this.numericRules)?i+=".numeric":i+=".string"),s=p.get(i)}return s??`validation.${t}`}makeReplacements(e,r,s,i){const a=this.getDisplayableAttribute(r),c=this.getValue(r),n={attribute:a,ATTRIBUTE:a.toLocaleUpperCase(),Attribute:a.charAt(0).toLocaleUpperCase()+a.substring(1),input:this.getDisplayableValue(r,c)};for(const[t,r]of Object.entries(n))e=e.replaceAll(":"+t,r);const l=r.match(/\.(\d+)\.?/),h=null===l?-1:parseInt(l[1],10);-1!==h&&(e=e.replaceAll(":index",h).replaceAll(":position",h+1));const u=t("replace_"+s);return"function"==typeof this.#f[u]&&(e=this.#f[u](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.#m,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:l(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.#m,e)?this.#m[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}}return e.Checkers=o,e.ErrorBag=d,e.Lang=p,e.Replacers=f,e.Validator=g,e}({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quival",
3
- "version": "0.2.7",
3
+ "version": "0.3.0",
4
4
  "description": "Data validation à la Laravel Validation",
5
5
  "author": "Mohd Hafizuddin M Marzuki <hafizuddin_83@yahoo.com>",
6
6
  "license": "MIT",
@@ -23,15 +23,14 @@
23
23
  "url": "https://github.com/apih/quival"
24
24
  },
25
25
  "devDependencies": {
26
- "@babel/core": "^7.21.8",
27
- "@babel/preset-env": "^7.21.5",
28
- "@rollup/plugin-babel": "^6.0.3",
29
26
  "@rollup/plugin-node-resolve": "^15.0.2",
27
+ "@rollup/plugin-swc": "^0.3.0",
30
28
  "@rollup/plugin-terser": "^0.4.1",
31
29
  "eslint": "^8.39.0",
32
30
  "mocha": "^10.2.0",
33
- "prettier": "^3.1.0",
34
- "rollup": "^4.6.1"
31
+ "prettier": "^3.2.5",
32
+ "rollup": "^4.6.1",
33
+ "rollup-plugin-prettier": "^4.1.1"
35
34
  },
36
35
  "scripts": {
37
36
  "build": "rollup --config",
package/rollup.config.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import babel from '@rollup/plugin-babel';
3
+ import swc from '@rollup/plugin-swc';
4
4
  import resolve from '@rollup/plugin-node-resolve';
5
5
  import terser from '@rollup/plugin-terser';
6
+ import prettier from 'rollup-plugin-prettier';
6
7
 
7
8
  const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
8
9
  const banner = `/*!
@@ -20,6 +21,7 @@ const options = [
20
21
  format: 'iife',
21
22
  name: 'quival',
22
23
  banner,
24
+ plugins: [prettier(JSON.parse(fs.readFileSync('.prettierrc.json')))],
23
25
  },
24
26
  {
25
27
  file: 'dist/quival.min.js',
@@ -31,19 +33,15 @@ const options = [
31
33
  ],
32
34
  plugins: [
33
35
  resolve(),
34
- babel({
36
+ swc({
37
+ swc: {
38
+ env: {
39
+ targets: 'last 1 year',
40
+ mode: 'entry',
41
+ coreJs: '3.22',
42
+ },
43
+ },
35
44
  exclude: 'node_modules/**',
36
- babelHelpers: 'bundled',
37
- presets: [
38
- [
39
- '@babel/preset-env',
40
- {
41
- targets: {
42
- browsers: 'last 1 year',
43
- },
44
- },
45
- ],
46
- ],
47
45
  }),
48
46
  ],
49
47
  },
package/src/Checkers.js CHANGED
@@ -91,7 +91,7 @@ export default class Checkers {
91
91
  compareDates(attribute, value, parameters, callback) {
92
92
  const rule = this.validator.getRule(attribute);
93
93
 
94
- value = rule.hasOwnProperty('date_format') ? parseDateByFormat(value, rule.date_format[0]) : parseDate(value);
94
+ value = Object.hasOwn(rule, 'date_format') ? parseDateByFormat(value, rule.date_format[0]) : parseDate(value);
95
95
 
96
96
  if (!isValidDate(value)) {
97
97
  return false;
@@ -105,7 +105,7 @@ export default class Checkers {
105
105
  } else {
106
106
  const otherRule = this.validator.getRule(other);
107
107
 
108
- otherValue = otherRule.hasOwnProperty('date_format') ? parseDateByFormat(otherValue, otherRule.date_format[0]) : parseDate(otherValue);
108
+ otherValue = Object.hasOwn(otherRule, 'date_format') ? parseDateByFormat(otherValue, otherRule.date_format[0]) : parseDate(otherValue);
109
109
  }
110
110
 
111
111
  if (!isValidDate(otherValue)) {
@@ -132,6 +132,10 @@ export default class Checkers {
132
132
  return true;
133
133
  }
134
134
 
135
+ checkList(attribute, value, parameters) {
136
+ return Array.isArray(value);
137
+ }
138
+
135
139
  checkBoolean(attribute, value, parameters) {
136
140
  return [true, false, 0, 1, '0', '1'].includes(value);
137
141
  }
@@ -569,7 +573,7 @@ export default class Checkers {
569
573
  let pattern = '^';
570
574
 
571
575
  for (const char of format) {
572
- if (formats.hasOwnProperty(char)) {
576
+ if (Object.hasOwn(formats, char)) {
573
577
  pattern += formats[char];
574
578
  } else {
575
579
  pattern += '\\' + char;
@@ -594,7 +598,7 @@ export default class Checkers {
594
598
 
595
599
  let stringified;
596
600
 
597
- if (this.#distinctCache.hasOwnProperty(parentPath)) {
601
+ if (Object.hasOwn(this.#distinctCache, parentPath)) {
598
602
  stringified = this.#distinctCache[parentPath];
599
603
  } else {
600
604
  stringified = JSON.stringify(flattenObject(this.validator.getValue(parentPath) ?? {}));
@@ -705,7 +709,7 @@ export default class Checkers {
705
709
  }
706
710
 
707
711
  async checkDimensions(attribute, value, parameters) {
708
- if (!this.checkImage(attribute, value) || !this.#imageCache.hasOwnProperty(attribute)) {
712
+ if (!this.checkImage(attribute, value) || !Object.hasOwn(this.#imageCache, attribute)) {
709
713
  return false;
710
714
  }
711
715
 
@@ -728,17 +732,17 @@ export default class Checkers {
728
732
  const height = image.naturalHeight;
729
733
 
730
734
  if (
731
- (constraints.hasOwnProperty('width') && constraints.width !== width) ||
732
- (constraints.hasOwnProperty('height') && constraints.height !== height) ||
733
- (constraints.hasOwnProperty('min_width') && constraints.min_width > width) ||
734
- (constraints.hasOwnProperty('min_height') && constraints.min_height > height) ||
735
- (constraints.hasOwnProperty('max_width') && constraints.max_width < width) ||
736
- (constraints.hasOwnProperty('max_height') && constraints.max_height < height)
735
+ (Object.hasOwn(constraints, 'width') && constraints.width !== width) ||
736
+ (Object.hasOwn(constraints, 'height') && constraints.height !== height) ||
737
+ (Object.hasOwn(constraints, 'min_width') && constraints.min_width > width) ||
738
+ (Object.hasOwn(constraints, 'min_height') && constraints.min_height > height) ||
739
+ (Object.hasOwn(constraints, 'max_width') && constraints.max_width < width) ||
740
+ (Object.hasOwn(constraints, 'max_height') && constraints.max_height < height)
737
741
  ) {
738
742
  return false;
739
743
  }
740
744
 
741
- if (constraints.hasOwnProperty('ratio')) {
745
+ if (Object.hasOwn(constraints, 'ratio')) {
742
746
  return Math.abs(constraints.ratio - width / height) <= 1 / (Math.max(width, height) + 1);
743
747
  }
744
748
 
package/src/ErrorBag.js CHANGED
@@ -14,7 +14,7 @@ export default class ErrorBag {
14
14
  }
15
15
 
16
16
  add(key, message) {
17
- if (this.#data.hasOwnProperty(key)) {
17
+ if (Object.hasOwn(this.#data, key)) {
18
18
  this.#data[key].push(message);
19
19
  } else {
20
20
  this.#data[key] = [message];
@@ -23,7 +23,7 @@ export default class ErrorBag {
23
23
 
24
24
  get(key) {
25
25
  if (!key.includes('*')) {
26
- return this.#data.hasOwnProperty(key) ? this.#data[key] : {};
26
+ return Object.hasOwn(this.#data, key) ? this.#data[key] : {};
27
27
  }
28
28
 
29
29
  const pattern = new RegExp('^' + key.replaceAll('*', '.*?') + '$');
@@ -77,4 +77,16 @@ export default class ErrorBag {
77
77
  isNotEmpty() {
78
78
  return !this.isEmpty();
79
79
  }
80
+
81
+ sortByKeys(keys) {
82
+ const data = {};
83
+
84
+ for (const key of keys) {
85
+ if (Object.hasOwn(this.#data, key)) {
86
+ data[key] = this.#data[key];
87
+ }
88
+ }
89
+
90
+ this.#data = data;
91
+ }
80
92
  }
package/src/Validator.js CHANGED
@@ -239,77 +239,83 @@ export default class Validator {
239
239
  this.#checkers.clearCaches();
240
240
  this.#errors = new ErrorBag();
241
241
 
242
+ const tasks = [];
243
+
242
244
  for (const [attribute, rules] of Object.entries(this.#rules)) {
243
245
  let value = this.getValue(attribute);
244
246
 
245
- if (rules.hasOwnProperty('sometimes') && typeof value === 'undefined') {
247
+ if (Object.hasOwn(rules, 'sometimes') && typeof value === 'undefined') {
246
248
  continue;
247
249
  }
248
250
 
249
- const doBail = this.#alwaysBail || rules.hasOwnProperty('bail');
250
- const isNullable = rules.hasOwnProperty('nullable');
251
- let hasError = false;
251
+ tasks.push(async () => {
252
+ const doBail = this.#alwaysBail || Object.hasOwn(rules, 'bail');
253
+ const isNullable = Object.hasOwn(rules, 'nullable');
254
+ let noError = true;
252
255
 
253
- for (const [rule, parameters] of Object.entries(rules)) {
254
- if (rule === '') {
255
- continue;
256
- }
256
+ for (const [rule, parameters] of Object.entries(rules)) {
257
+ if (rule === '') {
258
+ continue;
259
+ }
257
260
 
258
- if (
259
- !Validator.#implicitRules.includes(rule) &&
260
- (typeof value === 'undefined' || (typeof value === 'string' && value.trim() === '') || (isNullable && value === null))
261
- ) {
262
- continue;
263
- }
261
+ if (
262
+ !Validator.#implicitRules.includes(rule) &&
263
+ (typeof value === 'undefined' || (typeof value === 'string' && value.trim() === '') || (isNullable && value === null))
264
+ ) {
265
+ continue;
266
+ }
264
267
 
265
- let result, status, message;
266
- const camelRule = toCamelCase('check_' + rule);
268
+ let result, success, message;
269
+ const camelRule = toCamelCase('check_' + rule);
267
270
 
268
- if (typeof this.#checkers[camelRule] === 'function') {
269
- result = await this.#checkers[camelRule](attribute, value, parameters);
270
- } else if (Validator.#dummyRules.includes(rule)) {
271
- result = true;
272
- } else {
273
- throw new Error(`Invalid validation rule: ${rule}`);
274
- }
271
+ if (typeof this.#checkers[camelRule] === 'function') {
272
+ result = await this.#checkers[camelRule](attribute, value, parameters);
273
+ } else if (Validator.#dummyRules.includes(rule)) {
274
+ result = true;
275
+ } else {
276
+ throw new Error(`Invalid validation rule: ${rule}`);
277
+ }
275
278
 
276
- if (typeof result === 'boolean') {
277
- status = result;
278
- } else {
279
- ({ status, message } = result);
280
- }
279
+ if (typeof result === 'boolean') {
280
+ success = result;
281
+ } else {
282
+ ({ success, message } = result);
283
+ }
281
284
 
282
- if (!status) {
283
- hasError = true;
284
- message = isEmpty(message) ? this.getMessage(attribute, rule) : message;
285
- message = this.makeReplacements(message, attribute, rule, parameters);
285
+ if (!success) {
286
+ noError = false;
287
+ message = isEmpty(message) ? this.getMessage(attribute, rule) : message;
288
+ message = this.makeReplacements(message, attribute, rule, parameters);
286
289
 
287
- this.#errors.add(attribute, message);
290
+ this.#errors.add(attribute, message);
288
291
 
289
- if (doBail || Validator.#implicitRules.includes(rule)) {
290
- break;
292
+ if (doBail || Validator.#implicitRules.includes(rule)) {
293
+ break;
294
+ }
291
295
  }
292
296
  }
293
- }
294
297
 
295
- if (this.#stopOnFirstFailure && hasError) {
296
- break;
297
- }
298
+ return noError;
299
+ });
298
300
  }
299
301
 
300
- if (this.#errors.isNotEmpty()) {
301
- throw this.#errors;
302
+ if (this.#stopOnFirstFailure) {
303
+ for (const task of tasks) {
304
+ if (!(await task())) break;
305
+ }
306
+ } else {
307
+ await Promise.allSettled(tasks.map((task) => task()));
308
+
309
+ this.#errors.sortByKeys(Object.keys(this.#rules));
302
310
  }
311
+
312
+ return this.#errors;
303
313
  }
304
314
 
305
315
  async passes() {
306
- try {
307
- await this.validate();
308
- } catch (error) {
309
- if (error instanceof Error) {
310
- throw error;
311
- }
316
+ await this.validate();
312
317
 
318
+ if (this.#errors.isNotEmpty()) {
313
319
  return false;
314
320
  }
315
321
 
@@ -327,7 +333,7 @@ export default class Validator {
327
333
  let message;
328
334
 
329
335
  for (const key of [`${attribute}.${rule}`, rule]) {
330
- if (this.#customMessages.hasOwnProperty(key)) {
336
+ if (Object.hasOwn(this.#customMessages, key)) {
331
337
  message = this.#customMessages[key];
332
338
 
333
339
  break;
@@ -342,7 +348,7 @@ export default class Validator {
342
348
  key += '.array';
343
349
  } else if (value instanceof File || this.hasRule(attribute, this.fileRules)) {
344
350
  key += '.file';
345
- } else if (typeof value === 'number' || this.hasRule(attribute, this.numericRules)) {
351
+ } else if (isNumeric(value) || this.hasRule(attribute, this.numericRules)) {
346
352
  key += '.numeric';
347
353
  } else {
348
354
  key += '.string';
@@ -390,14 +396,14 @@ export default class Validator {
390
396
  const unparsed = this.getPrimaryAttribute(attribute);
391
397
 
392
398
  for (const name of [attribute, unparsed]) {
393
- if (this.#customAttributes.hasOwnProperty(name)) {
399
+ if (Object.hasOwn(this.#customAttributes, name)) {
394
400
  return this.#customAttributes[name];
395
401
  } else if (Lang.has(`attributes.${name}`)) {
396
402
  return Lang.get(`attributes.${name}`);
397
403
  }
398
404
  }
399
405
 
400
- if (this.#implicitAttributes.hasOwnProperty(attribute)) {
406
+ if (Object.hasOwn(this.#implicitAttributes, attribute)) {
401
407
  return attribute;
402
408
  }
403
409
 
@@ -413,7 +419,7 @@ export default class Validator {
413
419
  return 'empty';
414
420
  } else if (typeof value === 'boolean' || this.hasRule(attribute, 'boolean')) {
415
421
  return Number(value) ? 'true' : 'false';
416
- } else if (this.#customValues.hasOwnProperty(path)) {
422
+ } else if (Object.hasOwn(this.#customValues, path)) {
417
423
  return this.#customValues[path];
418
424
  } else if (Lang.has(`values.${path}`)) {
419
425
  return Lang.get(`values.${path}`);
@@ -431,7 +437,7 @@ export default class Validator {
431
437
  return value.size / 1024;
432
438
  } else if (isPlainObject(value)) {
433
439
  return Object.keys(value).length;
434
- } else if (value.hasOwnProperty('length')) {
440
+ } else if (Object.hasOwn(value, 'length')) {
435
441
  return value.length;
436
442
  }
437
443
 
@@ -448,7 +454,7 @@ export default class Validator {
448
454
  attribute = this.getPrimaryAttribute(attribute);
449
455
  rules = typeof rules === 'string' ? [rules] : rules;
450
456
 
451
- if (!this.#rules.hasOwnProperty(attribute)) {
457
+ if (!Object.hasOwn(this.#rules, attribute)) {
452
458
  return false;
453
459
  }
454
460
 
@@ -462,7 +468,7 @@ export default class Validator {
462
468
  }
463
469
 
464
470
  getPrimaryAttribute(attribute) {
465
- return this.#implicitAttributes.hasOwnProperty(attribute) ? this.#implicitAttributes[attribute] : attribute;
471
+ return Object.hasOwn(this.#implicitAttributes, attribute) ? this.#implicitAttributes[attribute] : attribute;
466
472
  }
467
473
 
468
474
  hasAttribute(attribute) {
package/src/helpers.js CHANGED
@@ -19,7 +19,7 @@ export function getByPath(obj, path, defaultValue) {
19
19
  let current = obj;
20
20
 
21
21
  for (const key of keys) {
22
- if (!current.hasOwnProperty(key)) {
22
+ if (!Object.hasOwn(current, key)) {
23
23
  return defaultValue;
24
24
  }
25
25
 
@@ -34,7 +34,7 @@ export function setByPath(obj, path, value) {
34
34
  let current = obj;
35
35
 
36
36
  for (const key of keys.slice(0, -1)) {
37
- if (!current.hasOwnProperty(key)) {
37
+ if (!Object.hasOwn(current, key)) {
38
38
  current[key] = {};
39
39
  }
40
40
 
@@ -173,7 +173,7 @@ export function parseDateByFormat(value, format) {
173
173
  let index = 1;
174
174
 
175
175
  for (const char of format) {
176
- if (formats.hasOwnProperty(char)) {
176
+ if (Object.hasOwn(formats, char)) {
177
177
  pattern += formats[char];
178
178
 
179
179
  if (['Y', 'y'].indexOf(char) !== -1) {
package/src/locales/en.js CHANGED
@@ -65,6 +65,7 @@ export default {
65
65
  ipv4: 'The :attribute field must be a valid IPv4 address.',
66
66
  ipv6: 'The :attribute field must be a valid IPv6 address.',
67
67
  json: 'The :attribute field must be a valid JSON string.',
68
+ list: 'The :attribute field must be a list.',
68
69
  lowercase: 'The :attribute field must be lowercase.',
69
70
  lt: {
70
71
  array: 'The :attribute field must have less than :value items.',
package/src/locales/ms.js CHANGED
@@ -65,6 +65,7 @@ export default {
65
65
  ipv4: 'Medan :attribute mesti alamat IPv4 yang sah.',
66
66
  ipv6: 'Medan :attribute mesti alamat IPv6 yang sah.',
67
67
  json: 'Medan :attribute mesti rentetan JSON yang sah.',
68
+ list: 'Medan :attribute mesti berbentuk senarai.',
68
69
  lowercase: 'Medan :attribute mesti dalam huruf kecil.',
69
70
  lt: {
70
71
  array: 'Medan :attribute mesti mempunyai kurang daripada :value item.',