{"version":3,"file":"iodine.min.esm.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 * Constructor.\n *\n **/\n constructor() {\n this.locale = undefined;\n this.messages = this._defaultMessages();\n }\n\n /**\n * @internal.\n *\n **/\n _dateCompare(first, second, type, equals = false) {\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 * @internal.\n *\n **/\n _defaultMessages() {\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 * Attach a custom validation rule to the library.\n *\n **/\n addRule(name, closure) {\n Iodine.prototype[`is${name[0].toUpperCase()}${name.slice(1)}`] = closure;\n }\n\n /**\n * Retrieve an error message for the given rule.\n *\n **/\n getErrorMessage(rule, arg = undefined) {\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\",\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n 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 * Determine if the given date is after another given date.\n *\n **/\n isAfter(value, after) {\n return this._dateCompare(value, after, \"more\", false);\n }\n\n /**\n * Determine if the given date is after or equal to another given date.\n *\n **/\n isAfterOrEqual(value, after) {\n return this._dateCompare(value, after, \"more\", true);\n }\n\n /**\n * Determine if the given value is an array.\n *\n **/\n isArray(value) {\n return Array.isArray(value);\n }\n\n /**\n * Determine if the given date is before another given date.\n *\n **/\n isBefore(value, before) {\n return this._dateCompare(value, before, \"less\", false);\n }\n\n /**\n * Determine if the given date is before or equal to another given date.\n *\n **/\n isBeforeOrEqual(value, before) {\n return this._dateCompare(value, before, \"less\", true);\n }\n\n /**\n * Determine if the given value is a boolean.\n *\n **/\n isBoolean(value) {\n return [true, false].includes(value);\n }\n\n /**\n * Determine if the given value is a date object.\n *\n **/\n isDate(value) {\n return (\n value &&\n Object.prototype.toString.call(value) === \"[object Date]\" &&\n !isNaN(value)\n );\n }\n\n /**\n * Determine if the given value is different to another given value.\n *\n **/\n isDifferent(value, different) {\n return value != different;\n }\n\n /**\n * Determine if the given value ends with another given value.\n *\n **/\n isEndingWith(value, sub) {\n return this.isString(value) && value.endsWith(sub);\n }\n\n /**\n * Determine if the given value is a valid email address.\n *\n **/\n isEmail(value) {\n return new RegExp(\"^\\\\S+@\\\\S+[\\\\.][0-9a-z]+$\").test(\n String(value).toLowerCase()\n );\n }\n\n /**\n * Determine if the given value is falsy.\n *\n **/\n isFalsy(value) {\n return [0, \"0\", false, \"false\"].includes(value);\n }\n\n /**\n * Determine if the given value is within the given array of options.\n *\n **/\n isIn(value, options) {\n options = typeof options === \"string\" ? options.split(\",\") : options;\n\n return options.includes(value);\n }\n\n /**\n * Determine if the given value is an integer.\n *\n **/\n isInteger(value) {\n return (\n Number.isInteger(value) && parseInt(value).toString() === value.toString()\n );\n }\n\n /**\n * Determine if the given value is a JSON string.\n *\n **/\n isJson(value) {\n try {\n return typeof JSON.parse(value) === \"object\";\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Determine if the given value meets the given maximum limit.\n *\n **/\n isMaximum(value, limit) {\n value = typeof value === \"string\" ? value.length : value;\n\n return parseFloat(value) <= limit;\n }\n\n /**\n * Determine if the given value meets the given minimum limit.\n *\n **/\n isMinimum(value, limit) {\n value = typeof value === \"string\" ? value.length : value;\n\n return parseFloat(value) >= limit;\n }\n\n /**\n * Determine if the given value is not within the given array of options.\n *\n **/\n isNotIn(value, options) {\n return !this.isIn(value, options);\n }\n\n /**\n * Determine if the given value is numeric (an integer or a float).\n *\n **/\n isNumeric(value) {\n return !isNaN(parseFloat(value)) && isFinite(value);\n }\n\n /**\n * Determine if the given value is optional.\n *\n **/\n isOptional(value) {\n return [null, undefined, \"\"].includes(value);\n }\n\n /**\n * Determine if the given value satisifies the given regular expression.\n *\n **/\n isRegexMatch(value, expression) {\n return new RegExp(expression).test(String(value));\n }\n\n /**\n * Determine if the given value is present.\n *\n **/\n isRequired(value) {\n return !this.isOptional(value);\n }\n\n /**\n * Determine if the given value is the same as another given value.\n *\n **/\n isSame(value, same) {\n return value == same;\n }\n\n /**\n * Determine if the given value starts with another given value.\n *\n **/\n isStartingWith(value, sub) {\n return this.isString(value) && value.startsWith(sub);\n }\n\n /**\n * Determine if the given value is a string.\n *\n **/\n isString(value) {\n return typeof value === \"string\";\n }\n\n /**\n * Determine if the given value is truthy.\n *\n **/\n isTruthy(value) {\n return [1, \"1\", true, \"true\"].includes(value);\n }\n\n /**\n * Determine if the given value is a valid URL.\n *\n **/\n isUrl(value) {\n return new RegExp(\n \"^(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 * Determine if the given value is a valid UUID.\n *\n **/\n isUuid(value) {\n return new RegExp(\n \"^[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 * Determine whether the given value meets the given rules.\n *\n **/\n is(value, rules = []) {\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 if (rules[index] === \"optional\") continue;\n\n let rule =\n rules[index].split(\":\")[0][0].toUpperCase() +\n rules[index].split(\":\")[0].slice(1);\n\n let result = this[`is${rule}`].apply(this, [\n value,\n rules[index].split(\":\")[1],\n ]);\n\n if (!result) return rules[index];\n }\n\n return true;\n }\n\n /**\n * Replace the default error messages with a new set.\n *\n **/\n setErrorMessages(messages) {\n this.messages = messages;\n }\n\n /**\n * Replace the default locale with a new value.\n *\n **/\n setLocale(locale) {\n this.locale = locale;\n }\n}\n\n/**\n * Create an instance of the library.\n *\n **/\nwindow.Iodine = new Iodine();\n"],"names":["Iodine","constructor","this","locale","undefined","messages","_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","index","apply","setErrorMessages","setLocale","window"],"mappings":"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"}