quival 0.2.6 → 0.2.8

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.6 (https://github.com/apih/quival)
2
+ * quival v0.2.8 (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())}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}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)}}class f{static#a={};static#c={};static#n=["active_url","bail","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,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,,a=0,c=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,,a=0,c=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))[,a,c,,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))[,a,c,,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(),[,a=0,c=0,,u=0,h="am"]=t.map(l)}}return r>=10&&r<100&&(r+=2e3),"pm"===h.toLowerCase()&&a<12&&(a+=12),new Date(`${r}-${s}-${i} ${a}:${c}:${u}`)}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 u=new Date;let h=c[i.years],l=c[i.months],o=c[i.days],p=c[i.hours]??0,d=c[i.minutes]??0,f=c[i.seconds]??0,g=c[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()&&p<12&&(p+=12),new Date(`${h}-${l}-${o} ${p}:${d}:${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 a=this.validator.getValue(i);return a=void 0===a?u(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(!l(t=i.hasOwnProperty("date_format")?c(t,i.date_format[0]):a(t)))return!1;const n=r[0]??"";let u=this.validator.getValue(n);if(void 0===u)u=a(n);else{const e=this.validator.getRule(n);u=e.hasOwnProperty("date_format")?c(u,e.date_format[0]):a(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(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 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)}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[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 l=new RegExp(c,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 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 u;this.#e.hasOwnProperty(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 p=`"${r(a.substring(c)).replaceAll("\\*",'[^."]+')}":`,d=0;return p+=l?"string"==typeof t?`"${o}"`:`${o}`:`(${o}|"${o}")`,p+="[,}]+",d+=u.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()}constructor(){this.#r={}}}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 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#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_unless","required_with","required_with_all","required_without","required_without_all"];#r;#h;#l;#o;#p;#d;#f;#g;#m;#y;#k;static setLocale(e){d.locale(e)}static setMessages(e,t){d.setMessages(e,t)}static addChecker(e,t,r){g.#a[e]=t,r&&d.set(e,r)}static addImplicitChecker(e,t,r){g.addChecker(e,t,r),g.#u.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.#y=!1,this.#k=!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.#d=new o(this),this.#f=new f(this);for(const[e,r]of Object.entries(g.#a))this.#d[t("check_"+e)]=r;for(const[e,r]of Object.entries(g.#c))this.#f[t("replace_"+e)]=r;this.#g=new p}setProperties(e={},t={},r={},i={},a={}){return this.#r=e,this.#h=this.parseRules(t),this.#l=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.#l=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(e=!0){return this.#y=e,this}alwaysBail(e=!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,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.#d.clearCaches(),this.#g=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[u,h]of Object.entries(r)){if(""===u)continue;if(!g.#u.includes(u)&&(void 0===s||"string"==typeof s&&""===s.trim()||a&&null===s))continue;let r,l,o;const p=t("check_"+u);if("function"==typeof this.#d[p])r=await this.#d[p](e,s,h);else{if(!g.#n.includes(u))throw new Error(`Invalid validation rule: ${u}`);r=!0}if("boolean"==typeof r?l=r:({status:l,message:o}=r),!l&&(c=!0,o=n(o)?this.getMessage(e,u):o,o=this.makeReplacements(o,e,u,h),this.#g.add(e,o),i||g.#u.includes(u)))break}if(this.#y&&c)break}if(this.#g.isNotEmpty())throw this.#g}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.#l.hasOwnProperty(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":"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 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(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: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: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.#g}}return e.Checkers=o,e.ErrorBag=p,e.Lang=d,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.6",
3
+ "version": "0.2.8",
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": "^2.8.8",
34
- "rollup": "^3.21.5"
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
@@ -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
  }
@@ -672,6 +676,10 @@ export default class Checkers {
672
676
  return false;
673
677
  }
674
678
 
679
+ checkExtensions(attribute, value, parameters) {
680
+ return this.checkMimes(attribute, value, parameters);
681
+ }
682
+
675
683
  async checkImage(attribute, value, parameters) {
676
684
  let result = this.checkMimes(attribute, value, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp']);
677
685
 
@@ -766,6 +774,10 @@ export default class Checkers {
766
774
  return true;
767
775
  }
768
776
 
777
+ checkHexColor(attribute, value, parameters) {
778
+ return /^#(?:(?:[0-9a-f]{3}){1,2}|(?:[0-9a-f]{4}){1,2})$/i.test(value);
779
+ }
780
+
769
781
  checkMacAddress(attribute, value, parameters) {
770
782
  value = String(value);
771
783
 
package/src/Replacers.js CHANGED
@@ -257,4 +257,8 @@ export default class Replacers {
257
257
  replaceMimes(message, attribute, rule, parameters) {
258
258
  return this.replaceMimetypes(message, attribute, rule, parameters);
259
259
  }
260
+
261
+ replaceExtensions(message, attribute, rule, parameters) {
262
+ return this.replaceMimetypes(message, attribute, rule, parameters);
263
+ }
260
264
  }
package/src/Validator.js CHANGED
@@ -11,6 +11,7 @@ export default class Validator {
11
11
  static #dummyRules = [
12
12
  'active_url',
13
13
  'bail',
14
+ 'can',
14
15
  'current_password',
15
16
  'enum',
16
17
  'exclude',
package/src/locales/en.js CHANGED
@@ -21,6 +21,7 @@ export default {
21
21
  string: 'The :attribute field must be between :min and :max characters.',
22
22
  },
23
23
  boolean: 'The :attribute field must be true or false.',
24
+ can: 'The :attribute field contains an unauthorized value.',
24
25
  confirmed: 'The :attribute field confirmation does not match.',
25
26
  current_password: 'The password is incorrect.',
26
27
  date: 'The :attribute field must be a valid date.',
@@ -40,6 +41,7 @@ export default {
40
41
  ends_with: 'The :attribute field must end with one of the following: :values.',
41
42
  enum: 'The selected :attribute is invalid.',
42
43
  exists: 'The selected :attribute is invalid.',
44
+ extensions: 'The :attribute field must have one of the following extensions: :values.',
43
45
  file: 'The :attribute field must be a file.',
44
46
  filled: 'The :attribute field must have a value.',
45
47
  gt: {
@@ -54,6 +56,7 @@ export default {
54
56
  numeric: 'The :attribute field must be greater than or equal to :value.',
55
57
  string: 'The :attribute field must be greater than or equal to :value characters.',
56
58
  },
59
+ hex_color: 'The :attribute field must be a valid hexadecimal color.',
57
60
  image: 'The :attribute field must be an image.',
58
61
  in: 'The selected :attribute is invalid.',
59
62
  in_array: 'The :attribute field must exist in :other.',
@@ -62,6 +65,7 @@ export default {
62
65
  ipv4: 'The :attribute field must be a valid IPv4 address.',
63
66
  ipv6: 'The :attribute field must be a valid IPv6 address.',
64
67
  json: 'The :attribute field must be a valid JSON string.',
68
+ list: 'The :attribute field must be a list.',
65
69
  lowercase: 'The :attribute field must be lowercase.',
66
70
  lt: {
67
71
  array: 'The :attribute field must have less than :value items.',
package/src/locales/ms.js CHANGED
@@ -21,6 +21,7 @@ export default {
21
21
  string: 'Medan :attribute mesti antara :min dan :max huruf.',
22
22
  },
23
23
  boolean: 'Medan :attribute mesti benar atau salah.',
24
+ can: 'Medan :attribute field mengandungi nilai yang tidak dibenarkan.',
24
25
  confirmed: 'Pengesahan medan :attribute tidak sepadan.',
25
26
  current_password: 'Kata laluan tidak sah.',
26
27
  date: 'Medan :attribute mesti tarikh yang sah.',
@@ -40,6 +41,7 @@ export default {
40
41
  ends_with: 'Medan :attribute mesti berakhir dengan salah satu daripada berikut: :values.',
41
42
  enum: 'Nilai :attribute yang dipilih tidak sah.',
42
43
  exists: 'Nilai :attribute yang dipilih tidak sah.',
44
+ extensions: 'Medan :attribute mesti salah satu daripada sambungan berikut: :values.',
43
45
  file: 'Medan :attribute mesti fail.',
44
46
  filled: 'Medan :attribute mesti mempunyai nilai.',
45
47
  gt: {
@@ -54,6 +56,7 @@ export default {
54
56
  numeric: 'Medan :attribute mesti lebih besar daripada atau sama dengan :value.',
55
57
  string: 'Medan :attribute mesti lebih besar daripada atau sama dengan :value huruf.',
56
58
  },
59
+ hex_color: 'Medan :attribute mesti warna heksadesimal yang sah.',
57
60
  image: 'Medan :attribute mesti imej.',
58
61
  in: 'Nilai :attribute yang dipilih tidak sah.',
59
62
  in_array: 'Medan :attribute mesti wujud dalam :other.',
@@ -62,6 +65,7 @@ export default {
62
65
  ipv4: 'Medan :attribute mesti alamat IPv4 yang sah.',
63
66
  ipv6: 'Medan :attribute mesti alamat IPv6 yang sah.',
64
67
  json: 'Medan :attribute mesti rentetan JSON yang sah.',
68
+ list: 'Medan :attribute mesti berbentuk senarai.',
65
69
  lowercase: 'Medan :attribute mesti dalam huruf kecil.',
66
70
  lt: {
67
71
  array: 'Medan :attribute mesti mempunyai kurang daripada :value item.',
package/test/test.js CHANGED
@@ -945,6 +945,26 @@ describe('Validation', () => {
945
945
  });
946
946
  });
947
947
 
948
+ describe(`Rule 'extensions'`, () => {
949
+ const rules = { field: 'extensions:jpg,png' };
950
+
951
+ it(`Passes when the field has a valid extension`, async () => {
952
+ const validator = new Validator({ field: new File('hello.jpg', 5 * 1024, 'image/jpg') }, rules);
953
+ assert(await validator.passes());
954
+
955
+ validator.setData({ field: new File('hello.png', 5 * 1024, 'image/png') });
956
+ assert(await validator.passes());
957
+ });
958
+
959
+ it(`Fails when the field has an invalid extension`, async () => {
960
+ const validator = new Validator({ field: new File('hello.doc', 5 * 1024, 'application/msword') }, rules);
961
+ assert(await validator.fails());
962
+
963
+ validator.setData({ field: new File('hello.txt', 5 * 1024, 'text/plain') });
964
+ assert(await validator.fails());
965
+ });
966
+ });
967
+
948
968
  describe(`Rule 'file'`, () => {
949
969
  const rules = { field: 'file' };
950
970
 
@@ -1237,6 +1257,63 @@ describe('Validation', () => {
1237
1257
  });
1238
1258
  });
1239
1259
 
1260
+ describe(`Rule 'hex_color'`, () => {
1261
+ it(`Passes when the field is a valid color`, async () => {
1262
+ const validator = new Validator({
1263
+ field_1: '#abc',
1264
+ field_2: '#abcd',
1265
+ field_3: '#abcabc',
1266
+ field_4: '#abcdabcd',
1267
+ }, {
1268
+ field_1: 'hex_color',
1269
+ field_2: 'hex_color',
1270
+ field_3: 'hex_color',
1271
+ field_4: 'hex_color',
1272
+ });
1273
+
1274
+ assert(await validator.passes());
1275
+ });
1276
+
1277
+ it(`Fails when the field is not a valid color`, async () => {
1278
+ const validator = new Validator({
1279
+ field_1: '#ghi',
1280
+ field_2: '#ghij',
1281
+ field_3: '#ghighi',
1282
+ field_4: '#ghijghij',
1283
+ field_5: 'abc',
1284
+ field_6: 123,
1285
+ field_7: [1, 2, 3],
1286
+ }, {
1287
+ field_1: 'hex_color',
1288
+ field_2: 'hex_color',
1289
+ field_3: 'hex_color',
1290
+ field_4: 'hex_color',
1291
+ field_5: 'hex_color',
1292
+ field_6: 'hex_color',
1293
+ field_7: 'hex_color',
1294
+ });
1295
+
1296
+ assert(await validator.fails());
1297
+ });
1298
+
1299
+ it(`Fails when the color's value is not 3, 4, 6 or 8 digits.`, async () => {
1300
+ const validator = new Validator({
1301
+ field_1: '#1',
1302
+ field_2: '#12',
1303
+ field_3: '#12345',
1304
+ field_4: '#1234567',
1305
+ field_4: '#123456789',
1306
+ }, {
1307
+ field_1: 'hex_color',
1308
+ field_2: 'hex_color',
1309
+ field_3: 'hex_color',
1310
+ field_4: 'hex_color',
1311
+ });
1312
+
1313
+ assert(await validator.fails());
1314
+ });
1315
+ });
1316
+
1240
1317
  describe(`Rule 'image'`, () => {
1241
1318
  const rules = { field: 'image' };
1242
1319
 
@@ -1410,6 +1487,26 @@ describe('Validation', () => {
1410
1487
  });
1411
1488
  });
1412
1489
 
1490
+ describe(`Rule 'list'`, () => {
1491
+ const rules = { field: 'list' };
1492
+
1493
+ it(`Passes when the field is a list`, async () => {
1494
+ const validator = new Validator({ field: [1, 2, 3] }, rules);
1495
+ assert(await validator.passes());
1496
+ });
1497
+
1498
+ it(`Fails when the field is not a list`, async () => {
1499
+ const validator = new Validator({ field: { a: 1, b: 2, c: 3} }, rules);
1500
+ assert(await validator.fails());
1501
+
1502
+ validator.setData({ field: 123 });
1503
+ assert(await validator.fails());
1504
+
1505
+ validator.setData({ field: 'abc' });
1506
+ assert(await validator.fails());
1507
+ });
1508
+ });
1509
+
1413
1510
  describe(`Rule 'lowercase'`, () => {
1414
1511
  const rules = { field: 'lowercase' };
1415
1512