{"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*/\nexport class Iodine {\n /**\n * Constructor.\n *\n */\n constructor() {\n this.locale = undefined;\n\n this.messages = this._defaultMessages();\n\n this.defaultFieldName = 'Value';\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 : `[FIELD] 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 : `[FIELD] must be true or false`,\n date : `[FIELD] must be a date`,\n different : `[FIELD] must be different to '[PARAM]'`,\n endingWith : `[FIELD] must end with '[PARAM]'`,\n email : `[FIELD] must be a valid email address`,\n falsy : `[FIELD] must be a falsy value (false, 'false', 0 or '0')`,\n in : `[FIELD] must be one of the following options: [PARAM]`,\n integer : `[FIELD] must be an integer`,\n json : `[FIELD] must be a parsable JSON object string`,\n max : `[FIELD] must be less than or equal to [PARAM]`,\n min : `[FIELD] must be greater than or equal to [PARAM]`,\n maxLength : `[FIELD] must not be greater than '[PARAM]' in character length`,\n minLength : `[FIELD] must not be less than '[PARAM]' character length`,\n notIn : `[FIELD] must not be one of the following options: [PARAM]`,\n numeric : `[FIELD] must be numeric`,\n optional : `[FIELD] is optional`,\n regexMatch : `[FIELD] must satisify the regular expression: [PARAM]`,\n required : `[FIELD] must be present`,\n same : `[FIELD] must be '[PARAM]'`,\n startingWith : `[FIELD] must start with '[PARAM]'`,\n string : `[FIELD] must be a string`,\n truthy : `[FIELD] must be a truthy value (true, 'true', 1 or '1')`,\n url : `[FIELD] must be a valid url`,\n uuid : `[FIELD] must be a valid UUID`,\n };\n }\n\n /**\n * @internal.\n *\n */\n _prepare(value, rules = [])\n {\n if (!rules.length) return [];\n\n if (rules[0] === 'optional' && this.isOptional(value)) return [];\n\n return rules.filter(rule => rule !== 'optional')\n .map(rule => [rule, this._titleCase(rule.split(':').shift()), rule.split(':').slice(1)]);\n }\n\n /**\n * @internal.\n *\n */\n _titleCase(value)\n {\n return `${value[0].toUpperCase()}${value.slice(1)}`;\n }\n\n /**\n * Attach a custom validation rule to the library.\n *\n */\n addRule(name, closure) {\n Iodine.prototype[`is${this._titleCase(name)}`] = closure;\n }\n\n /**\n * Determine whether the given value meets the given synchronous or asynchronous rules.\n *\n */\n async asyncIs(value, rules = []) {\n for (let index in rules = this._prepare(value, rules)) {\n if (!await this[`is${rules[index][1]}`].apply(this, [value, rules[index][2].join(':')])) {\n return await rules[index][0];\n }\n }\n\n return true;\n }\n\n /**\n * Determine whether the given value meets the given rules.\n *\n */\n async asyncIsValid(value, rules = []) {\n return await this.asyncIs(value, rules) === true;\n }\n\n /**\n * Retrieve an error message for the given rule.\n *\n */\n getErrorMessage(rule, args = undefined) {\n let { param, field } = typeof args === 'object' ? args : { param: args, field: undefined };\n\n const chunks = rule.split(':');\n\n let key = chunks.shift();\n\n param = param || chunks.join(':');\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 hour12 : false,\n });\n }\n\n let message = [null, undefined, ''].includes(param)\n ? this.messages[key]\n : this.messages[key].replace('[PARAM]', param);\n\n return [null, undefined, ''].includes(field)\n ? message.replace('[FIELD]', this.defaultFieldName)\n : message.replace('[FIELD]', field);\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 (value && Object.prototype.toString.call(value) === '[object Date]' && !isNaN(value));\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(String(value).toLowerCase());\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 return (typeof options === 'string' ? options.split(',') : options).includes(value);\n }\n\n /**\n * Determine if the given value is an integer.\n *\n */\n isInteger(value) {\n return Number.isInteger(value) && parseInt(value).toString() === value.toString();\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 number is less than or equal to the maximum limit.\n *\n */\n isMax(value, limit) {\n return parseFloat(value) <= limit;\n }\n\n /**\n * Determine if the given number is greater than or equal to the minimum limit.\n *\n */\n isMin(value, limit) {\n return parseFloat(value) >= limit;\n }\n\n /**\n * Determine if the given value string length is less than or equal to the maximum limit.\n *\n */\n isMaxLength(value, limit) {\n return typeof value === 'string' ? value.length <= limit : false;\n }\n\n /**\n * Determine if the given value string length is greater than or equal to the minimum limit.\n *\n */\n isMinLength(value, limit) {\n return typeof value === 'string' ? value.length >= limit : false;\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 let regex = \"^(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\n return new RegExp(regex).test(String(value).toLowerCase());\n }\n\n /**\n * Determine if the given value is a valid UUID.\n *\n */\n isUuid(value) {\n let regex = \"^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$\";\n\n return new RegExp(regex).test(String(value).toLowerCase());\n }\n\n /**\n * Determine whether the given value meets the given rules.\n *\n */\n is(value, rules = []) {\n for (let index in rules = this._prepare(value, rules)) {\n if (!this[`is${rules[index][1]}`].apply(this, [value, rules[index][2].join(':')])) {\n return rules[index][0];\n }\n }\n\n return true;\n }\n\n /**\n * Determine whether the given value meets the given rules.\n *\n */\n isValid(value, rules = []) {\n return this.is(value, rules) === 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 * Add or replace an error message.\n *\n */\n setErrorMessage(key, message) {\n this.messages[key] = message;\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 * Replace the default field name with a new value.\n */\n setDefaultFieldName(fieldName) {\n this.defaultFieldName = fieldName;\n }\n}\n\n/**\n * Create an instance of the library.\n *\n */\nwindow.Iodine = new Iodine();\n"],"names":["pact","state","value","s","o","_settle","bind","v","then","observer","_Pact","prototype","onFulfilled","onRejected","result","this","callback","e","_this","Iodine","constructor","locale","undefined","messages","_defaultMessages","defaultFieldName","_dateCompare","first","second","type","equals","isDate","isInteger","getTime","after","afterOrEqual","array","before","beforeOrEqual","boolean","date","different","endingWith","email","falsy","in","integer","json","max","min","maxLength","minLength","notIn","numeric","optional","regexMatch","required","same","startingWith","string","truthy","url","uuid","_prepare","rules","length","isOptional","filter","rule","map","_titleCase","split","shift","slice","toUpperCase","addRule","name","closure","asyncIs","target","body","check","keys","key","push","reject","i","_cycle","thenable","index","apply","join","asyncIsValid","getErrorMessage","args","param","field","chunks","includes","Date","parseInt","toLocaleTimeString","year","month","day","hour","minute","hour12","message","replace","isAfter","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","isMax","limit","parseFloat","isMin","isMaxLength","isMinLength","isNotIn","isNumeric","isFinite","isRegexMatch","expression","isRequired","isSame","isStartingWith","startsWith","isTruthy","isUrl","isUuid","is","isValid","setErrorMessages","setErrorMessage","setLocale","setDefaultFieldName","fieldName","window"],"mappings":"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"}