diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 9a91dd2..db04bab 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -11,11 +11,14 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - - name: Install + - name: Install dependencies run: yarn install env: CI: true + - name: Install prettier + run: yarn global add prettier + - name: Run prettier run: yarn run prettier --write 'src/**/*.js' 'tests/**/*.js' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cad5938..0a7575a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,16 +11,5 @@ jobs: - name: Checkout code uses: actions/checkout@v2 - - name: Set the locale - run: | - sudo apt-get update && sudo apt-get install tzdata locales -y && sudo locale-gen en_GB.UTF-8 - sudo localectl set-locale LANG="en_GB.UTF-8" - export LANG="en_GB.UTF-8" - sudo update-locale - locale -a - locale - locale -c -k LC_NUMERIC - localectl status - - name: Run Jest uses: stefanoeb/jest-action@1.0.2 \ No newline at end of file diff --git a/dist/iodine.min.js b/dist/iodine.min.js index a99af4a..e107fe5 100644 --- a/dist/iodine.min.js +++ b/dist/iodine.min.js @@ -1,2 +1,2 @@ -var t=function(){this.messages=this._defaultMessages()};t.prototype._dateCompare=function(t,e,r,i){return void 0===i&&(i=!1),!!this.isDate(t)&&!(!this.isDate(e)&&!this.isInteger(e))&&(e="number"==typeof e?e:e.getTime(),"less"===r&&i?t.getTime()<=e:"less"!==r||i?"more"===r&&i?t.getTime()>=e:"more"!==r||i?void 0:t.getTime()>e:t.getTime()=e},t.prototype.isNotIn=function(t,e){return!this.isIn(t,e)},t.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.prototype.isOptional=function(t){return[null,void 0,""].includes(t)},t.prototype.isRegexMatch=function(t,e){return new RegExp(e).test(String(t).toLowerCase())},t.prototype.isRequired=function(t){return!this.isOptional(t)},t.prototype.isSame=function(t,e){return t==e},t.prototype.isStartingWith=function(t,e){return this.isString(t)&&t.startsWith(e)},t.prototype.isString=function(t){return"string"==typeof t},t.prototype.isTruthy=function(t){return[1,"1",!0,"true"].includes(t)},t.prototype.isUrl=function(t){return new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$").test(String(t).toLowerCase())},t.prototype.isUuid=function(t){return new RegExp("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$").test(String(t).toLowerCase())},t.prototype.is=function(t,e){if(void 0===e&&(e=[]),!e.length)return!0;if("optional"===e[0]&&this.isOptional(t))return!0;for(var r in e)if("optional"!==e[r]&&!this["is"+(e[r].split(":")[0][0].toUpperCase()+e[r].split(":")[0].slice(1))].apply(this,[t,e[r].split(":")[1]]))return e[r];return!0},t.prototype.setErrorMessages=function(t){this.messages=t},window.Iodine=new t; +var t=function(){this.locale=void 0,this.messages=this._defaultMessages()};t.prototype._dateCompare=function(t,e,r,i){return void 0===i&&(i=!1),!!this.isDate(t)&&!(!this.isDate(e)&&!this.isInteger(e))&&(e="number"==typeof e?e:e.getTime(),"less"===r&&i?t.getTime()<=e:"less"!==r||i?"more"===r&&i?t.getTime()>=e:"more"!==r||i?void 0:t.getTime()>e:t.getTime()=e},t.prototype.isNotIn=function(t,e){return!this.isIn(t,e)},t.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.prototype.isOptional=function(t){return[null,void 0,""].includes(t)},t.prototype.isRegexMatch=function(t,e){return new RegExp(e).test(String(t).toLowerCase())},t.prototype.isRequired=function(t){return!this.isOptional(t)},t.prototype.isSame=function(t,e){return t==e},t.prototype.isStartingWith=function(t,e){return this.isString(t)&&t.startsWith(e)},t.prototype.isString=function(t){return"string"==typeof t},t.prototype.isTruthy=function(t){return[1,"1",!0,"true"].includes(t)},t.prototype.isUrl=function(t){return new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$").test(String(t).toLowerCase())},t.prototype.isUuid=function(t){return new RegExp("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$").test(String(t).toLowerCase())},t.prototype.is=function(t,e){if(void 0===e&&(e=[]),!e.length)return!0;if("optional"===e[0]&&this.isOptional(t))return!0;for(var r in e)if("optional"!==e[r]&&!this["is"+(e[r].split(":")[0][0].toUpperCase()+e[r].split(":")[0].slice(1))].apply(this,[t,e[r].split(":")[1]]))return e[r];return!0},t.prototype.setErrorMessages=function(t){this.messages=t},t.prototype.setLocale=function(t){this.locale=t},window.Iodine=new t; //# sourceMappingURL=iodine.min.js.map diff --git a/dist/iodine.min.js.map b/dist/iodine.min.js.map index 05fb6f2..6f4935b 100644 --- a/dist/iodine.min.js.map +++ b/dist/iodine.min.js.map @@ -1 +1 @@ -{"version":3,"file":"iodine.min.js","sources":["../src/iodine.js"],"sourcesContent":["/*\n|--------------------------------------------------------------------------\n| Iodine - JavaScript Library\n|--------------------------------------------------------------------------\n|\n| This library contains a collection of useful validation rules that can\n| be used to quickly verify whether items meet certain conditions.\n|\n*/\nclass Iodine\n{\n\n /**\n * Constructor.\n *\n **/\n constructor()\n {\n this.messages = this._defaultMessages();\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false)\n {\n if (! this.isDate(first)) return false;\n\n if (! this.isDate(second) && ! this.isInteger(second)) return false;\n\n second = typeof second === 'number' ? second : second.getTime();\n\n if (type === 'less' && equals) return first.getTime() <= second;\n if (type === 'less' && ! equals) return first.getTime() < second;\n if (type === 'more' && equals) return first.getTime() >= second;\n if (type === 'more' && ! equals) return first.getTime() > second;\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _defaultMessages()\n {\n return {\n after : `The date must be after: '[PARAM]'`,\n afterOrEqual : `The date must be after or equal to: '[PARAM]'`,\n array : `Value must be an array`,\n before : `The date must be before: '[PARAM]'`,\n beforeOrEqual : `The date must be before or equal to: '[PARAM]'`,\n boolean : `Value must be true or false`,\n date : `Value must be a date`,\n different : `Value must be different to '[PARAM]'`,\n endingWith : `Value must end with '[PARAM]'`,\n email : `Value must be a valid email address`,\n falsy : `Value must be a falsy value (false, 'false', 0 or '0')`,\n in : `Value must be one of the following options: [PARAM]`,\n integer : `Value must be an integer`,\n json : `Value must be a parsable JSON object string`,\n maximum : `Value must not be greater than '[PARAM]' in size or character length`,\n minimum : `Value must not be less than '[PARAM]' in size or character length`,\n notIn : `Value must not be one of the following options: [PARAM]`,\n numeric : `Value must be numeric`,\n optional : `Value is optional`,\n regexMatch : `Value must satisify the regular expression: [PARAM]`,\n required : `Value must be present`,\n same : `Value must be '[PARAM]'`,\n startingWith : `Value must start with '[PARAM]'`,\n string : `Value must be a string`,\n truthy : `Value must be a truthy value (true, 'true', 1 or '1')`,\n url : `Value must be a valid url`,\n uuid : `Value must be a valid UUID`,\n };\n }\n\n\n\n /**\n * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure)\n {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined)\n {\n let key = rule.split(':')[0];\n let param = arg || rule.split(':')[1];\n\n if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) {\n param = new Date(parseInt(param)).toLocaleTimeString(undefined, {\n year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric'\n });\n }\n\n return [null, undefined].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n }\n\n\n\n /**\n * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after)\n {\n return this._dateCompare(value, after, 'more', false);\n }\n\n\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after)\n {\n return this._dateCompare(value, after, 'more', true);\n }\n\n\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value)\n {\n return Array.isArray(value);\n }\n\n\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before)\n {\n return this._dateCompare(value, before, 'less', false);\n }\n\n\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before)\n {\n return this._dateCompare(value, before, 'less', true);\n }\n\n\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value)\n {\n return [true, false].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value)\n {\n return value && Object.prototype.toString.call(value) === '[object Date]' && ! isNaN(value);\n }\n\n\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different)\n {\n return value != different;\n }\n\n\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub)\n {\n return this.isString(value) && value.endsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value)\n {\n return new RegExp('^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$').test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value)\n {\n return [0, '0', false, 'false'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options)\n {\n options = typeof options === 'string'\n ? options.split(',')\n : options;\n\n return options.includes(value);\n }\n\n\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value)\n {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\n }\n\n\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value)\n {\n try {\n return typeof JSON.parse(value) === 'object';\n } catch (e) {\n return false;\n }\n }\n\n\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options)\n {\n return ! this.isIn(value, options);\n }\n\n\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value)\n {\n return ! isNaN(parseFloat(value)) && isFinite(value);\n }\n\n\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value)\n {\n return [null, undefined, ''].includes(value);\n }\n\n\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression)\n {\n return new RegExp(expression).test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value)\n {\n return ! this.isOptional(value);\n }\n\n\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same)\n {\n return value == same;\n }\n\n\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub)\n {\n return this.isString(value) && value.startsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value)\n {\n return typeof value === 'string';\n }\n\n\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value)\n {\n return [1, '1', true, 'true'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value)\n {\n return new RegExp('^(https?:\\\\/\\\\/)?((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*(\\\\?[;&a-z\\\\d%_.~+=-]*)?(\\\\#[-a-z\\\\d_]*)?$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value)\n {\n return new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = [])\n {\n if (! rules.length) return true;\n\n if (rules[0] === 'optional' && this.isOptional(value)) return true;\n\n for (let index in rules) {\n\n if (rules[index] === 'optional') continue;\n\n let rule = rules[index].split(':')[0][0].toUpperCase()\n + rules[index].split(':')[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [value, rules[index].split(':')[1]]);\n\n if (! result) return rules[index];\n\n }\n\n return true;\n }\n\n\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages)\n {\n this.messages = messages;\n }\n\n}\n\n\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","messages","this","_defaultMessages","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","maximum","minimum","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","addRule","name","closure","prototype","toUpperCase","slice","getErrorMessage","rule","arg","undefined","key","split","param","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","replace","isAfter","value","isAfterOrEqual","isArray","Array","isBefore","isBeforeOrEqual","isBoolean","Object","toString","call","isNaN","isDifferent","isEndingWith","sub","isString","endsWith","isEmail","RegExp","test","String","toLowerCase","isFalsy","isIn","options","Number","isJson","JSON","parse","e","isMaximum","limit","length","parseFloat","isMinimum","isNotIn","isNumeric","isFinite","isOptional","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","rules","let","index","apply","setErrorMessages","window"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"iodine.min.js","sources":["../src/iodine.js"],"sourcesContent":["/*\n|--------------------------------------------------------------------------\n| Iodine - JavaScript Library\n|--------------------------------------------------------------------------\n|\n| This library contains a collection of useful validation rules that can\n| be used to quickly verify whether items meet certain conditions.\n|\n*/\nclass Iodine\n{\n\n /**\n * Constructor.\n *\n **/\n constructor()\n {\n this.locale = undefined;\n this.messages = this._defaultMessages();\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false)\n {\n if (! this.isDate(first)) return false;\n\n if (! this.isDate(second) && ! this.isInteger(second)) return false;\n\n second = typeof second === 'number' ? second : second.getTime();\n\n if (type === 'less' && equals) return first.getTime() <= second;\n if (type === 'less' && ! equals) return first.getTime() < second;\n if (type === 'more' && equals) return first.getTime() >= second;\n if (type === 'more' && ! equals) return first.getTime() > second;\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _defaultMessages()\n {\n return {\n after : `The date must be after: '[PARAM]'`,\n afterOrEqual : `The date must be after or equal to: '[PARAM]'`,\n array : `Value must be an array`,\n before : `The date must be before: '[PARAM]'`,\n beforeOrEqual : `The date must be before or equal to: '[PARAM]'`,\n boolean : `Value must be true or false`,\n date : `Value must be a date`,\n different : `Value must be different to '[PARAM]'`,\n endingWith : `Value must end with '[PARAM]'`,\n email : `Value must be a valid email address`,\n falsy : `Value must be a falsy value (false, 'false', 0 or '0')`,\n in : `Value must be one of the following options: [PARAM]`,\n integer : `Value must be an integer`,\n json : `Value must be a parsable JSON object string`,\n maximum : `Value must not be greater than '[PARAM]' in size or character length`,\n minimum : `Value must not be less than '[PARAM]' in size or character length`,\n notIn : `Value must not be one of the following options: [PARAM]`,\n numeric : `Value must be numeric`,\n optional : `Value is optional`,\n regexMatch : `Value must satisify the regular expression: [PARAM]`,\n required : `Value must be present`,\n same : `Value must be '[PARAM]'`,\n startingWith : `Value must start with '[PARAM]'`,\n string : `Value must be a string`,\n truthy : `Value must be a truthy value (true, 'true', 1 or '1')`,\n url : `Value must be a valid url`,\n uuid : `Value must be a valid UUID`,\n };\n }\n\n\n\n /**\n * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure)\n {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined)\n {\n let key = rule.split(':')[0];\n let param = arg || rule.split(':')[1];\n\n if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) {\n param = new Date(parseInt(param)).toLocaleTimeString(this.locale, {\n year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric'\n });\n }\n\n return [null, undefined].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n }\n\n\n\n /**\n * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after)\n {\n return this._dateCompare(value, after, 'more', false);\n }\n\n\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after)\n {\n return this._dateCompare(value, after, 'more', true);\n }\n\n\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value)\n {\n return Array.isArray(value);\n }\n\n\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before)\n {\n return this._dateCompare(value, before, 'less', false);\n }\n\n\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before)\n {\n return this._dateCompare(value, before, 'less', true);\n }\n\n\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value)\n {\n return [true, false].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value)\n {\n return value && Object.prototype.toString.call(value) === '[object Date]' && ! isNaN(value);\n }\n\n\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different)\n {\n return value != different;\n }\n\n\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub)\n {\n return this.isString(value) && value.endsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value)\n {\n return new RegExp('^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$').test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value)\n {\n return [0, '0', false, 'false'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options)\n {\n options = typeof options === 'string'\n ? options.split(',')\n : options;\n\n return options.includes(value);\n }\n\n\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value)\n {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\n }\n\n\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value)\n {\n try {\n return typeof JSON.parse(value) === 'object';\n } catch (e) {\n return false;\n }\n }\n\n\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options)\n {\n return ! this.isIn(value, options);\n }\n\n\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value)\n {\n return ! isNaN(parseFloat(value)) && isFinite(value);\n }\n\n\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value)\n {\n return [null, undefined, ''].includes(value);\n }\n\n\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression)\n {\n return new RegExp(expression).test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value)\n {\n return ! this.isOptional(value);\n }\n\n\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same)\n {\n return value == same;\n }\n\n\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub)\n {\n return this.isString(value) && value.startsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value)\n {\n return typeof value === 'string';\n }\n\n\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value)\n {\n return [1, '1', true, 'true'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value)\n {\n return new RegExp('^(https?:\\\\/\\\\/)?((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*(\\\\?[;&a-z\\\\d%_.~+=-]*)?(\\\\#[-a-z\\\\d_]*)?$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value)\n {\n return new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = [])\n {\n if (! rules.length) return true;\n\n if (rules[0] === 'optional' && this.isOptional(value)) return true;\n\n for (let index in rules) {\n\n if (rules[index] === 'optional') continue;\n\n let rule = rules[index].split(':')[0][0].toUpperCase()\n + rules[index].split(':')[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [value, rules[index].split(':')[1]]);\n\n if (! result) return rules[index];\n\n }\n\n return true;\n }\n\n\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages)\n {\n this.messages = messages;\n }\n\n\n\n /**\n * Replace the default locale with a new value.\n *\n **/\n setLocale(locale)\n {\n this.locale = locale;\n }\n\n}\n\n\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","locale","undefined","messages","this","_defaultMessages","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","maximum","minimum","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","addRule","name","closure","prototype","toUpperCase","slice","getErrorMessage","rule","arg","key","split","param","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","replace","isAfter","value","isAfterOrEqual","isArray","Array","isBefore","isBeforeOrEqual","isBoolean","Object","toString","call","isNaN","isDifferent","isEndingWith","sub","isString","endsWith","isEmail","RegExp","test","String","toLowerCase","isFalsy","isIn","options","Number","isJson","JSON","parse","e","isMaximum","limit","length","parseFloat","isMinimum","isNotIn","isNumeric","isFinite","isOptional","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","rules","let","index","apply","setErrorMessages","setLocale","window"],"mappings":"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"} \ No newline at end of file diff --git a/dist/iodine.min.mjs b/dist/iodine.min.mjs index 64bdc4a..898ed00 100644 --- a/dist/iodine.min.mjs +++ b/dist/iodine.min.mjs @@ -1,2 +1,2 @@ -var t=function(){this.messages=this._defaultMessages()};t.prototype._dateCompare=function(t,e,r,i){return void 0===i&&(i=!1),!!this.isDate(t)&&!(!this.isDate(e)&&!this.isInteger(e))&&(e="number"==typeof e?e:e.getTime(),"less"===r&&i?t.getTime()<=e:"less"!==r||i?"more"===r&&i?t.getTime()>=e:"more"!==r||i?void 0:t.getTime()>e:t.getTime()=e},t.prototype.isNotIn=function(t,e){return!this.isIn(t,e)},t.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.prototype.isOptional=function(t){return[null,void 0,""].includes(t)},t.prototype.isRegexMatch=function(t,e){return new RegExp(e).test(String(t).toLowerCase())},t.prototype.isRequired=function(t){return!this.isOptional(t)},t.prototype.isSame=function(t,e){return t==e},t.prototype.isStartingWith=function(t,e){return this.isString(t)&&t.startsWith(e)},t.prototype.isString=function(t){return"string"==typeof t},t.prototype.isTruthy=function(t){return[1,"1",!0,"true"].includes(t)},t.prototype.isUrl=function(t){return new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$").test(String(t).toLowerCase())},t.prototype.isUuid=function(t){return new RegExp("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$").test(String(t).toLowerCase())},t.prototype.is=function(t,e){if(void 0===e&&(e=[]),!e.length)return!0;if("optional"===e[0]&&this.isOptional(t))return!0;for(var r in e)if("optional"!==e[r]&&!this["is"+(e[r].split(":")[0][0].toUpperCase()+e[r].split(":")[0].slice(1))].apply(this,[t,e[r].split(":")[1]]))return e[r];return!0},t.prototype.setErrorMessages=function(t){this.messages=t},window.Iodine=new t; +var t=function(){this.locale=void 0,this.messages=this._defaultMessages()};t.prototype._dateCompare=function(t,e,r,i){return void 0===i&&(i=!1),!!this.isDate(t)&&!(!this.isDate(e)&&!this.isInteger(e))&&(e="number"==typeof e?e:e.getTime(),"less"===r&&i?t.getTime()<=e:"less"!==r||i?"more"===r&&i?t.getTime()>=e:"more"!==r||i?void 0:t.getTime()>e:t.getTime()=e},t.prototype.isNotIn=function(t,e){return!this.isIn(t,e)},t.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.prototype.isOptional=function(t){return[null,void 0,""].includes(t)},t.prototype.isRegexMatch=function(t,e){return new RegExp(e).test(String(t).toLowerCase())},t.prototype.isRequired=function(t){return!this.isOptional(t)},t.prototype.isSame=function(t,e){return t==e},t.prototype.isStartingWith=function(t,e){return this.isString(t)&&t.startsWith(e)},t.prototype.isString=function(t){return"string"==typeof t},t.prototype.isTruthy=function(t){return[1,"1",!0,"true"].includes(t)},t.prototype.isUrl=function(t){return new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$").test(String(t).toLowerCase())},t.prototype.isUuid=function(t){return new RegExp("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$").test(String(t).toLowerCase())},t.prototype.is=function(t,e){if(void 0===e&&(e=[]),!e.length)return!0;if("optional"===e[0]&&this.isOptional(t))return!0;for(var r in e)if("optional"!==e[r]&&!this["is"+(e[r].split(":")[0][0].toUpperCase()+e[r].split(":")[0].slice(1))].apply(this,[t,e[r].split(":")[1]]))return e[r];return!0},t.prototype.setErrorMessages=function(t){this.messages=t},t.prototype.setLocale=function(t){this.locale=t},window.Iodine=new t; //# sourceMappingURL=iodine.min.mjs.map diff --git a/dist/iodine.min.mjs.map b/dist/iodine.min.mjs.map index 1eaa715..cf9832b 100644 --- a/dist/iodine.min.mjs.map +++ b/dist/iodine.min.mjs.map @@ -1 +1 @@ -{"version":3,"file":"iodine.min.mjs","sources":["../src/iodine.js"],"sourcesContent":["/*\n|--------------------------------------------------------------------------\n| Iodine - JavaScript Library\n|--------------------------------------------------------------------------\n|\n| This library contains a collection of useful validation rules that can\n| be used to quickly verify whether items meet certain conditions.\n|\n*/\nclass Iodine\n{\n\n /**\n * Constructor.\n *\n **/\n constructor()\n {\n this.messages = this._defaultMessages();\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false)\n {\n if (! this.isDate(first)) return false;\n\n if (! this.isDate(second) && ! this.isInteger(second)) return false;\n\n second = typeof second === 'number' ? second : second.getTime();\n\n if (type === 'less' && equals) return first.getTime() <= second;\n if (type === 'less' && ! equals) return first.getTime() < second;\n if (type === 'more' && equals) return first.getTime() >= second;\n if (type === 'more' && ! equals) return first.getTime() > second;\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _defaultMessages()\n {\n return {\n after : `The date must be after: '[PARAM]'`,\n afterOrEqual : `The date must be after or equal to: '[PARAM]'`,\n array : `Value must be an array`,\n before : `The date must be before: '[PARAM]'`,\n beforeOrEqual : `The date must be before or equal to: '[PARAM]'`,\n boolean : `Value must be true or false`,\n date : `Value must be a date`,\n different : `Value must be different to '[PARAM]'`,\n endingWith : `Value must end with '[PARAM]'`,\n email : `Value must be a valid email address`,\n falsy : `Value must be a falsy value (false, 'false', 0 or '0')`,\n in : `Value must be one of the following options: [PARAM]`,\n integer : `Value must be an integer`,\n json : `Value must be a parsable JSON object string`,\n maximum : `Value must not be greater than '[PARAM]' in size or character length`,\n minimum : `Value must not be less than '[PARAM]' in size or character length`,\n notIn : `Value must not be one of the following options: [PARAM]`,\n numeric : `Value must be numeric`,\n optional : `Value is optional`,\n regexMatch : `Value must satisify the regular expression: [PARAM]`,\n required : `Value must be present`,\n same : `Value must be '[PARAM]'`,\n startingWith : `Value must start with '[PARAM]'`,\n string : `Value must be a string`,\n truthy : `Value must be a truthy value (true, 'true', 1 or '1')`,\n url : `Value must be a valid url`,\n uuid : `Value must be a valid UUID`,\n };\n }\n\n\n\n /**\n * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure)\n {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined)\n {\n let key = rule.split(':')[0];\n let param = arg || rule.split(':')[1];\n\n if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) {\n param = new Date(parseInt(param)).toLocaleTimeString(undefined, {\n year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric'\n });\n }\n\n return [null, undefined].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n }\n\n\n\n /**\n * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after)\n {\n return this._dateCompare(value, after, 'more', false);\n }\n\n\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after)\n {\n return this._dateCompare(value, after, 'more', true);\n }\n\n\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value)\n {\n return Array.isArray(value);\n }\n\n\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before)\n {\n return this._dateCompare(value, before, 'less', false);\n }\n\n\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before)\n {\n return this._dateCompare(value, before, 'less', true);\n }\n\n\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value)\n {\n return [true, false].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value)\n {\n return value && Object.prototype.toString.call(value) === '[object Date]' && ! isNaN(value);\n }\n\n\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different)\n {\n return value != different;\n }\n\n\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub)\n {\n return this.isString(value) && value.endsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value)\n {\n return new RegExp('^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$').test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value)\n {\n return [0, '0', false, 'false'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options)\n {\n options = typeof options === 'string'\n ? options.split(',')\n : options;\n\n return options.includes(value);\n }\n\n\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value)\n {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\n }\n\n\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value)\n {\n try {\n return typeof JSON.parse(value) === 'object';\n } catch (e) {\n return false;\n }\n }\n\n\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options)\n {\n return ! this.isIn(value, options);\n }\n\n\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value)\n {\n return ! isNaN(parseFloat(value)) && isFinite(value);\n }\n\n\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value)\n {\n return [null, undefined, ''].includes(value);\n }\n\n\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression)\n {\n return new RegExp(expression).test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value)\n {\n return ! this.isOptional(value);\n }\n\n\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same)\n {\n return value == same;\n }\n\n\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub)\n {\n return this.isString(value) && value.startsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value)\n {\n return typeof value === 'string';\n }\n\n\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value)\n {\n return [1, '1', true, 'true'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value)\n {\n return new RegExp('^(https?:\\\\/\\\\/)?((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*(\\\\?[;&a-z\\\\d%_.~+=-]*)?(\\\\#[-a-z\\\\d_]*)?$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value)\n {\n return new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = [])\n {\n if (! rules.length) return true;\n\n if (rules[0] === 'optional' && this.isOptional(value)) return true;\n\n for (let index in rules) {\n\n if (rules[index] === 'optional') continue;\n\n let rule = rules[index].split(':')[0][0].toUpperCase()\n + rules[index].split(':')[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [value, rules[index].split(':')[1]]);\n\n if (! result) return rules[index];\n\n }\n\n return true;\n }\n\n\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages)\n {\n this.messages = messages;\n }\n\n}\n\n\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","messages","this","_defaultMessages","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","maximum","minimum","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","addRule","name","closure","prototype","toUpperCase","slice","getErrorMessage","rule","arg","undefined","key","split","param","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","replace","isAfter","value","isAfterOrEqual","isArray","Array","isBefore","isBeforeOrEqual","isBoolean","Object","toString","call","isNaN","isDifferent","isEndingWith","sub","isString","endsWith","isEmail","RegExp","test","String","toLowerCase","isFalsy","isIn","options","Number","isJson","JSON","parse","e","isMaximum","limit","length","parseFloat","isMinimum","isNotIn","isNumeric","isFinite","isOptional","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","rules","let","index","apply","setErrorMessages","window"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"iodine.min.mjs","sources":["../src/iodine.js"],"sourcesContent":["/*\n|--------------------------------------------------------------------------\n| Iodine - JavaScript Library\n|--------------------------------------------------------------------------\n|\n| This library contains a collection of useful validation rules that can\n| be used to quickly verify whether items meet certain conditions.\n|\n*/\nclass Iodine\n{\n\n /**\n * Constructor.\n *\n **/\n constructor()\n {\n this.locale = undefined;\n this.messages = this._defaultMessages();\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false)\n {\n if (! this.isDate(first)) return false;\n\n if (! this.isDate(second) && ! this.isInteger(second)) return false;\n\n second = typeof second === 'number' ? second : second.getTime();\n\n if (type === 'less' && equals) return first.getTime() <= second;\n if (type === 'less' && ! equals) return first.getTime() < second;\n if (type === 'more' && equals) return first.getTime() >= second;\n if (type === 'more' && ! equals) return first.getTime() > second;\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _defaultMessages()\n {\n return {\n after : `The date must be after: '[PARAM]'`,\n afterOrEqual : `The date must be after or equal to: '[PARAM]'`,\n array : `Value must be an array`,\n before : `The date must be before: '[PARAM]'`,\n beforeOrEqual : `The date must be before or equal to: '[PARAM]'`,\n boolean : `Value must be true or false`,\n date : `Value must be a date`,\n different : `Value must be different to '[PARAM]'`,\n endingWith : `Value must end with '[PARAM]'`,\n email : `Value must be a valid email address`,\n falsy : `Value must be a falsy value (false, 'false', 0 or '0')`,\n in : `Value must be one of the following options: [PARAM]`,\n integer : `Value must be an integer`,\n json : `Value must be a parsable JSON object string`,\n maximum : `Value must not be greater than '[PARAM]' in size or character length`,\n minimum : `Value must not be less than '[PARAM]' in size or character length`,\n notIn : `Value must not be one of the following options: [PARAM]`,\n numeric : `Value must be numeric`,\n optional : `Value is optional`,\n regexMatch : `Value must satisify the regular expression: [PARAM]`,\n required : `Value must be present`,\n same : `Value must be '[PARAM]'`,\n startingWith : `Value must start with '[PARAM]'`,\n string : `Value must be a string`,\n truthy : `Value must be a truthy value (true, 'true', 1 or '1')`,\n url : `Value must be a valid url`,\n uuid : `Value must be a valid UUID`,\n };\n }\n\n\n\n /**\n * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure)\n {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined)\n {\n let key = rule.split(':')[0];\n let param = arg || rule.split(':')[1];\n\n if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) {\n param = new Date(parseInt(param)).toLocaleTimeString(this.locale, {\n year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric'\n });\n }\n\n return [null, undefined].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n }\n\n\n\n /**\n * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after)\n {\n return this._dateCompare(value, after, 'more', false);\n }\n\n\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after)\n {\n return this._dateCompare(value, after, 'more', true);\n }\n\n\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value)\n {\n return Array.isArray(value);\n }\n\n\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before)\n {\n return this._dateCompare(value, before, 'less', false);\n }\n\n\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before)\n {\n return this._dateCompare(value, before, 'less', true);\n }\n\n\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value)\n {\n return [true, false].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value)\n {\n return value && Object.prototype.toString.call(value) === '[object Date]' && ! isNaN(value);\n }\n\n\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different)\n {\n return value != different;\n }\n\n\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub)\n {\n return this.isString(value) && value.endsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value)\n {\n return new RegExp('^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$').test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value)\n {\n return [0, '0', false, 'false'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options)\n {\n options = typeof options === 'string'\n ? options.split(',')\n : options;\n\n return options.includes(value);\n }\n\n\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value)\n {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\n }\n\n\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value)\n {\n try {\n return typeof JSON.parse(value) === 'object';\n } catch (e) {\n return false;\n }\n }\n\n\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options)\n {\n return ! this.isIn(value, options);\n }\n\n\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value)\n {\n return ! isNaN(parseFloat(value)) && isFinite(value);\n }\n\n\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value)\n {\n return [null, undefined, ''].includes(value);\n }\n\n\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression)\n {\n return new RegExp(expression).test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value)\n {\n return ! this.isOptional(value);\n }\n\n\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same)\n {\n return value == same;\n }\n\n\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub)\n {\n return this.isString(value) && value.startsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value)\n {\n return typeof value === 'string';\n }\n\n\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value)\n {\n return [1, '1', true, 'true'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value)\n {\n return new RegExp('^(https?:\\\\/\\\\/)?((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*(\\\\?[;&a-z\\\\d%_.~+=-]*)?(\\\\#[-a-z\\\\d_]*)?$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value)\n {\n return new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = [])\n {\n if (! rules.length) return true;\n\n if (rules[0] === 'optional' && this.isOptional(value)) return true;\n\n for (let index in rules) {\n\n if (rules[index] === 'optional') continue;\n\n let rule = rules[index].split(':')[0][0].toUpperCase()\n + rules[index].split(':')[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [value, rules[index].split(':')[1]]);\n\n if (! result) return rules[index];\n\n }\n\n return true;\n }\n\n\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages)\n {\n this.messages = messages;\n }\n\n\n\n /**\n * Replace the default locale with a new value.\n *\n **/\n setLocale(locale)\n {\n this.locale = locale;\n }\n\n}\n\n\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","locale","undefined","messages","this","_defaultMessages","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","maximum","minimum","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","addRule","name","closure","prototype","toUpperCase","slice","getErrorMessage","rule","arg","key","split","param","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","replace","isAfter","value","isAfterOrEqual","isArray","Array","isBefore","isBeforeOrEqual","isBoolean","Object","toString","call","isNaN","isDifferent","isEndingWith","sub","isString","endsWith","isEmail","RegExp","test","String","toLowerCase","isFalsy","isIn","options","Number","isJson","JSON","parse","e","isMaximum","limit","length","parseFloat","isMinimum","isNotIn","isNumeric","isFinite","isOptional","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","rules","let","index","apply","setErrorMessages","setLocale","window"],"mappings":"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"} \ No newline at end of file diff --git a/dist/iodine.min.umd.js b/dist/iodine.min.umd.js index 0b9973b..1d278d8 100644 --- a/dist/iodine.min.umd.js +++ b/dist/iodine.min.umd.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e():"function"==typeof define&&define.amd?define(e):e()}(0,function(){var t=function(){this.messages=this._defaultMessages()};t.prototype._dateCompare=function(t,e,r,i){return void 0===i&&(i=!1),!!this.isDate(t)&&!(!this.isDate(e)&&!this.isInteger(e))&&(e="number"==typeof e?e:e.getTime(),"less"===r&&i?t.getTime()<=e:"less"!==r||i?"more"===r&&i?t.getTime()>=e:"more"!==r||i?void 0:t.getTime()>e:t.getTime()=e},t.prototype.isNotIn=function(t,e){return!this.isIn(t,e)},t.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.prototype.isOptional=function(t){return[null,void 0,""].includes(t)},t.prototype.isRegexMatch=function(t,e){return new RegExp(e).test(String(t).toLowerCase())},t.prototype.isRequired=function(t){return!this.isOptional(t)},t.prototype.isSame=function(t,e){return t==e},t.prototype.isStartingWith=function(t,e){return this.isString(t)&&t.startsWith(e)},t.prototype.isString=function(t){return"string"==typeof t},t.prototype.isTruthy=function(t){return[1,"1",!0,"true"].includes(t)},t.prototype.isUrl=function(t){return new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$").test(String(t).toLowerCase())},t.prototype.isUuid=function(t){return new RegExp("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$").test(String(t).toLowerCase())},t.prototype.is=function(t,e){if(void 0===e&&(e=[]),!e.length)return!0;if("optional"===e[0]&&this.isOptional(t))return!0;for(var r in e)if("optional"!==e[r]&&!this["is"+(e[r].split(":")[0][0].toUpperCase()+e[r].split(":")[0].slice(1))].apply(this,[t,e[r].split(":")[1]]))return e[r];return!0},t.prototype.setErrorMessages=function(t){this.messages=t},window.Iodine=new t}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e():"function"==typeof define&&define.amd?define(e):e()}(0,function(){var t=function(){this.locale=void 0,this.messages=this._defaultMessages()};t.prototype._dateCompare=function(t,e,r,o){return void 0===o&&(o=!1),!!this.isDate(t)&&!(!this.isDate(e)&&!this.isInteger(e))&&(e="number"==typeof e?e:e.getTime(),"less"===r&&o?t.getTime()<=e:"less"!==r||o?"more"===r&&o?t.getTime()>=e:"more"!==r||o?void 0:t.getTime()>e:t.getTime()=e},t.prototype.isNotIn=function(t,e){return!this.isIn(t,e)},t.prototype.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.prototype.isOptional=function(t){return[null,void 0,""].includes(t)},t.prototype.isRegexMatch=function(t,e){return new RegExp(e).test(String(t).toLowerCase())},t.prototype.isRequired=function(t){return!this.isOptional(t)},t.prototype.isSame=function(t,e){return t==e},t.prototype.isStartingWith=function(t,e){return this.isString(t)&&t.startsWith(e)},t.prototype.isString=function(t){return"string"==typeof t},t.prototype.isTruthy=function(t){return[1,"1",!0,"true"].includes(t)},t.prototype.isUrl=function(t){return new RegExp("^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$").test(String(t).toLowerCase())},t.prototype.isUuid=function(t){return new RegExp("^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$").test(String(t).toLowerCase())},t.prototype.is=function(t,e){if(void 0===e&&(e=[]),!e.length)return!0;if("optional"===e[0]&&this.isOptional(t))return!0;for(var r in e)if("optional"!==e[r]&&!this["is"+(e[r].split(":")[0][0].toUpperCase()+e[r].split(":")[0].slice(1))].apply(this,[t,e[r].split(":")[1]]))return e[r];return!0},t.prototype.setErrorMessages=function(t){this.messages=t},t.prototype.setLocale=function(t){this.locale=t},window.Iodine=new t}); //# sourceMappingURL=iodine.min.umd.js.map diff --git a/dist/iodine.min.umd.js.map b/dist/iodine.min.umd.js.map index 18707ce..d2f1008 100644 --- a/dist/iodine.min.umd.js.map +++ b/dist/iodine.min.umd.js.map @@ -1 +1 @@ -{"version":3,"file":"iodine.min.umd.js","sources":["../src/iodine.js"],"sourcesContent":["/*\n|--------------------------------------------------------------------------\n| Iodine - JavaScript Library\n|--------------------------------------------------------------------------\n|\n| This library contains a collection of useful validation rules that can\n| be used to quickly verify whether items meet certain conditions.\n|\n*/\nclass Iodine\n{\n\n /**\n * Constructor.\n *\n **/\n constructor()\n {\n this.messages = this._defaultMessages();\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false)\n {\n if (! this.isDate(first)) return false;\n\n if (! this.isDate(second) && ! this.isInteger(second)) return false;\n\n second = typeof second === 'number' ? second : second.getTime();\n\n if (type === 'less' && equals) return first.getTime() <= second;\n if (type === 'less' && ! equals) return first.getTime() < second;\n if (type === 'more' && equals) return first.getTime() >= second;\n if (type === 'more' && ! equals) return first.getTime() > second;\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _defaultMessages()\n {\n return {\n after : `The date must be after: '[PARAM]'`,\n afterOrEqual : `The date must be after or equal to: '[PARAM]'`,\n array : `Value must be an array`,\n before : `The date must be before: '[PARAM]'`,\n beforeOrEqual : `The date must be before or equal to: '[PARAM]'`,\n boolean : `Value must be true or false`,\n date : `Value must be a date`,\n different : `Value must be different to '[PARAM]'`,\n endingWith : `Value must end with '[PARAM]'`,\n email : `Value must be a valid email address`,\n falsy : `Value must be a falsy value (false, 'false', 0 or '0')`,\n in : `Value must be one of the following options: [PARAM]`,\n integer : `Value must be an integer`,\n json : `Value must be a parsable JSON object string`,\n maximum : `Value must not be greater than '[PARAM]' in size or character length`,\n minimum : `Value must not be less than '[PARAM]' in size or character length`,\n notIn : `Value must not be one of the following options: [PARAM]`,\n numeric : `Value must be numeric`,\n optional : `Value is optional`,\n regexMatch : `Value must satisify the regular expression: [PARAM]`,\n required : `Value must be present`,\n same : `Value must be '[PARAM]'`,\n startingWith : `Value must start with '[PARAM]'`,\n string : `Value must be a string`,\n truthy : `Value must be a truthy value (true, 'true', 1 or '1')`,\n url : `Value must be a valid url`,\n uuid : `Value must be a valid UUID`,\n };\n }\n\n\n\n /**\n * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure)\n {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined)\n {\n let key = rule.split(':')[0];\n let param = arg || rule.split(':')[1];\n\n if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) {\n param = new Date(parseInt(param)).toLocaleTimeString(undefined, {\n year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric'\n });\n }\n\n return [null, undefined].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n }\n\n\n\n /**\n * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after)\n {\n return this._dateCompare(value, after, 'more', false);\n }\n\n\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after)\n {\n return this._dateCompare(value, after, 'more', true);\n }\n\n\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value)\n {\n return Array.isArray(value);\n }\n\n\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before)\n {\n return this._dateCompare(value, before, 'less', false);\n }\n\n\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before)\n {\n return this._dateCompare(value, before, 'less', true);\n }\n\n\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value)\n {\n return [true, false].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value)\n {\n return value && Object.prototype.toString.call(value) === '[object Date]' && ! isNaN(value);\n }\n\n\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different)\n {\n return value != different;\n }\n\n\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub)\n {\n return this.isString(value) && value.endsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value)\n {\n return new RegExp('^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$').test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value)\n {\n return [0, '0', false, 'false'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options)\n {\n options = typeof options === 'string'\n ? options.split(',')\n : options;\n\n return options.includes(value);\n }\n\n\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value)\n {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\n }\n\n\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value)\n {\n try {\n return typeof JSON.parse(value) === 'object';\n } catch (e) {\n return false;\n }\n }\n\n\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options)\n {\n return ! this.isIn(value, options);\n }\n\n\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value)\n {\n return ! isNaN(parseFloat(value)) && isFinite(value);\n }\n\n\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value)\n {\n return [null, undefined, ''].includes(value);\n }\n\n\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression)\n {\n return new RegExp(expression).test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value)\n {\n return ! this.isOptional(value);\n }\n\n\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same)\n {\n return value == same;\n }\n\n\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub)\n {\n return this.isString(value) && value.startsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value)\n {\n return typeof value === 'string';\n }\n\n\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value)\n {\n return [1, '1', true, 'true'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value)\n {\n return new RegExp('^(https?:\\\\/\\\\/)?((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*(\\\\?[;&a-z\\\\d%_.~+=-]*)?(\\\\#[-a-z\\\\d_]*)?$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value)\n {\n return new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = [])\n {\n if (! rules.length) return true;\n\n if (rules[0] === 'optional' && this.isOptional(value)) return true;\n\n for (let index in rules) {\n\n if (rules[index] === 'optional') continue;\n\n let rule = rules[index].split(':')[0][0].toUpperCase()\n + rules[index].split(':')[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [value, rules[index].split(':')[1]]);\n\n if (! result) return rules[index];\n\n }\n\n return true;\n }\n\n\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages)\n {\n this.messages = messages;\n }\n\n}\n\n\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","messages","this","_defaultMessages","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","maximum","minimum","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","addRule","name","closure","prototype","toUpperCase","slice","getErrorMessage","rule","arg","undefined","key","split","param","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","replace","isAfter","value","isAfterOrEqual","isArray","Array","isBefore","isBeforeOrEqual","isBoolean","Object","toString","call","isNaN","isDifferent","isEndingWith","sub","isString","endsWith","isEmail","RegExp","test","String","toLowerCase","isFalsy","isIn","options","Number","isJson","JSON","parse","e","isMaximum","limit","length","parseFloat","isMinimum","isNotIn","isNumeric","isFinite","isOptional","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","rules","let","index","apply","setErrorMessages","window"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"iodine.min.umd.js","sources":["../src/iodine.js"],"sourcesContent":["/*\n|--------------------------------------------------------------------------\n| Iodine - JavaScript Library\n|--------------------------------------------------------------------------\n|\n| This library contains a collection of useful validation rules that can\n| be used to quickly verify whether items meet certain conditions.\n|\n*/\nclass Iodine\n{\n\n /**\n * Constructor.\n *\n **/\n constructor()\n {\n this.locale = undefined;\n this.messages = this._defaultMessages();\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false)\n {\n if (! this.isDate(first)) return false;\n\n if (! this.isDate(second) && ! this.isInteger(second)) return false;\n\n second = typeof second === 'number' ? second : second.getTime();\n\n if (type === 'less' && equals) return first.getTime() <= second;\n if (type === 'less' && ! equals) return first.getTime() < second;\n if (type === 'more' && equals) return first.getTime() >= second;\n if (type === 'more' && ! equals) return first.getTime() > second;\n }\n\n\n\n /**\n * @internal.\n *\n **/\n _defaultMessages()\n {\n return {\n after : `The date must be after: '[PARAM]'`,\n afterOrEqual : `The date must be after or equal to: '[PARAM]'`,\n array : `Value must be an array`,\n before : `The date must be before: '[PARAM]'`,\n beforeOrEqual : `The date must be before or equal to: '[PARAM]'`,\n boolean : `Value must be true or false`,\n date : `Value must be a date`,\n different : `Value must be different to '[PARAM]'`,\n endingWith : `Value must end with '[PARAM]'`,\n email : `Value must be a valid email address`,\n falsy : `Value must be a falsy value (false, 'false', 0 or '0')`,\n in : `Value must be one of the following options: [PARAM]`,\n integer : `Value must be an integer`,\n json : `Value must be a parsable JSON object string`,\n maximum : `Value must not be greater than '[PARAM]' in size or character length`,\n minimum : `Value must not be less than '[PARAM]' in size or character length`,\n notIn : `Value must not be one of the following options: [PARAM]`,\n numeric : `Value must be numeric`,\n optional : `Value is optional`,\n regexMatch : `Value must satisify the regular expression: [PARAM]`,\n required : `Value must be present`,\n same : `Value must be '[PARAM]'`,\n startingWith : `Value must start with '[PARAM]'`,\n string : `Value must be a string`,\n truthy : `Value must be a truthy value (true, 'true', 1 or '1')`,\n url : `Value must be a valid url`,\n uuid : `Value must be a valid UUID`,\n };\n }\n\n\n\n /**\n * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure)\n {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined)\n {\n let key = rule.split(':')[0];\n let param = arg || rule.split(':')[1];\n\n if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) {\n param = new Date(parseInt(param)).toLocaleTimeString(this.locale, {\n year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric'\n });\n }\n\n return [null, undefined].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n }\n\n\n\n /**\n * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after)\n {\n return this._dateCompare(value, after, 'more', false);\n }\n\n\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after)\n {\n return this._dateCompare(value, after, 'more', true);\n }\n\n\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value)\n {\n return Array.isArray(value);\n }\n\n\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before)\n {\n return this._dateCompare(value, before, 'less', false);\n }\n\n\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before)\n {\n return this._dateCompare(value, before, 'less', true);\n }\n\n\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value)\n {\n return [true, false].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value)\n {\n return value && Object.prototype.toString.call(value) === '[object Date]' && ! isNaN(value);\n }\n\n\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different)\n {\n return value != different;\n }\n\n\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub)\n {\n return this.isString(value) && value.endsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value)\n {\n return new RegExp('^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$').test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value)\n {\n return [0, '0', false, 'false'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options)\n {\n options = typeof options === 'string'\n ? options.split(',')\n : options;\n\n return options.includes(value);\n }\n\n\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value)\n {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\n }\n\n\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value)\n {\n try {\n return typeof JSON.parse(value) === 'object';\n } catch (e) {\n return false;\n }\n }\n\n\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit)\n {\n value = typeof value === 'string' ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options)\n {\n return ! this.isIn(value, options);\n }\n\n\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value)\n {\n return ! isNaN(parseFloat(value)) && isFinite(value);\n }\n\n\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value)\n {\n return [null, undefined, ''].includes(value);\n }\n\n\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression)\n {\n return new RegExp(expression).test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value)\n {\n return ! this.isOptional(value);\n }\n\n\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same)\n {\n return value == same;\n }\n\n\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub)\n {\n return this.isString(value) && value.startsWith(sub);\n }\n\n\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value)\n {\n return typeof value === 'string';\n }\n\n\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value)\n {\n return [1, '1', true, 'true'].includes(value);\n }\n\n\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value)\n {\n return new RegExp('^(https?:\\\\/\\\\/)?((([a-z\\\\d]([a-z\\\\d-]*[a-z\\\\d])*)\\\\.)+[a-z]{2,}|((\\\\d{1,3}\\\\.){3}\\\\d{1,3}))(\\\\:\\\\d+)?(\\\\/[-a-z\\\\d%_.~+]*)*(\\\\?[;&a-z\\\\d%_.~+=-]*)?(\\\\#[-a-z\\\\d_]*)?$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value)\n {\n return new RegExp('^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$')\n .test(String(value).toLowerCase());\n }\n\n\n\n /**\n * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = [])\n {\n if (! rules.length) return true;\n\n if (rules[0] === 'optional' && this.isOptional(value)) return true;\n\n for (let index in rules) {\n\n if (rules[index] === 'optional') continue;\n\n let rule = rules[index].split(':')[0][0].toUpperCase()\n + rules[index].split(':')[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [value, rules[index].split(':')[1]]);\n\n if (! result) return rules[index];\n\n }\n\n return true;\n }\n\n\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages)\n {\n this.messages = messages;\n }\n\n\n\n /**\n * Replace the default locale with a new value.\n *\n **/\n setLocale(locale)\n {\n this.locale = locale;\n }\n\n}\n\n\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","locale","undefined","messages","this","_defaultMessages","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","maximum","minimum","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","addRule","name","closure","prototype","toUpperCase","slice","getErrorMessage","rule","arg","key","split","param","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","replace","isAfter","value","isAfterOrEqual","isArray","Array","isBefore","isBeforeOrEqual","isBoolean","Object","toString","call","isNaN","isDifferent","isEndingWith","sub","isString","endsWith","isEmail","RegExp","test","String","toLowerCase","isFalsy","isIn","options","Number","isJson","JSON","parse","e","isMaximum","limit","length","parseFloat","isMinimum","isNotIn","isNumeric","isFinite","isOptional","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","rules","let","index","apply","setErrorMessages","setLocale","window"],"mappings":"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"} \ No newline at end of file diff --git a/src/iodine.js b/src/iodine.js index ec7b1b3..bcef5e1 100644 --- a/src/iodine.js +++ b/src/iodine.js @@ -16,6 +16,7 @@ class Iodine **/ constructor() { + this.locale = undefined; this.messages = this._defaultMessages(); } @@ -101,7 +102,7 @@ class Iodine let param = arg || rule.split(':')[1]; if (['after', 'afterOrEqual', 'before', 'beforeOrEqual'].includes(key)) { - param = new Date(parseInt(param)).toLocaleTimeString(undefined, { + param = new Date(parseInt(param)).toLocaleTimeString(this.locale, { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: 'numeric' }); } @@ -461,6 +462,17 @@ class Iodine this.messages = messages; } + + + /** + * Replace the default locale with a new value. + * + **/ + setLocale(locale) + { + this.locale = locale; + } + } diff --git a/tests/test.js b/tests/test.js index 43dedc1..34f656a 100644 --- a/tests/test.js +++ b/tests/test.js @@ -398,12 +398,14 @@ test('it validates values against multiple rules', () => { **/ test('it retrieves formatted error messages for rules', () => { let time = Date.UTC(2020, 4, 2, 3, 17, 0); + Iodine.setLocale('en-US'); + let hour = new Date().getTimezoneOffset() === -60 ? 4 : 3; expect(Iodine.getErrorMessage('array')).toBe('Value must be an array'); expect(Iodine.getErrorMessage('endingWith')).toBe(`Value must end with '[PARAM]'`); expect(Iodine.getErrorMessage('endingWith:world')).toBe(`Value must end with 'world'`); expect(Iodine.getErrorMessage('endingWith', 'world')).toBe(`Value must end with 'world'`); - expect(Iodine.getErrorMessage(`after:${time}`)).toBe(`The date must be after: '2 May 2020, 04:17'`); - expect(Iodine.getErrorMessage(`after`, time)).toBe(`The date must be after: '2 May 2020, 04:17'`); + expect(Iodine.getErrorMessage(`after:${time}`)).toBe(`The date must be after: 'May 2, 2020, 0${hour}:17 AM'`); + expect(Iodine.getErrorMessage(`after`, time)).toBe(`The date must be after: 'May 2, 2020, 0${hour}:17 AM'`); });