{"version":3,"file":"v8n.min.js","sources":["src/Rule.js","src/Modifier.js","src/ValidationError.js","src/Context.js","src/v8n.js"],"sourcesContent":["class Rule {\n constructor(name, fn, args, modifiers) {\n this.name = name;\n this.fn = fn;\n this.args = args;\n this.modifiers = modifiers;\n }\n\n _test(value) {\n let fn = this.fn;\n\n try {\n testAux(this.modifiers.slice(), fn)(value);\n } catch (ex) {\n fn = () => false;\n }\n\n try {\n return testAux(this.modifiers.slice(), fn)(value);\n } catch (ex) {\n return false;\n }\n }\n\n _check(value) {\n try {\n testAux(this.modifiers.slice(), this.fn)(value);\n } catch (ex) {\n if (testAux(this.modifiers.slice(), it => it)(false)) {\n return;\n }\n }\n\n if (!testAux(this.modifiers.slice(), this.fn)(value)) {\n throw null;\n }\n }\n\n _testAsync(value) {\n return new Promise((resolve, reject) => {\n testAsyncAux(this.modifiers.slice(), this.fn)(value)\n .then(valid => {\n if (valid) {\n resolve(value);\n } else {\n reject(null);\n }\n })\n .catch(ex => reject(ex));\n });\n }\n}\n\nfunction pickFn(fn, variant = \"simple\") {\n return typeof fn === \"object\" ? fn[variant] : fn;\n}\n\nfunction testAux(modifiers, fn) {\n if (modifiers.length) {\n const modifier = modifiers.shift();\n const nextFn = testAux(modifiers, fn);\n return modifier.perform(nextFn);\n } else {\n return pickFn(fn);\n }\n}\n\nfunction testAsyncAux(modifiers, fn) {\n if (modifiers.length) {\n const modifier = modifiers.shift();\n const nextFn = testAsyncAux(modifiers, fn);\n return modifier.performAsync(nextFn);\n } else {\n return value => Promise.resolve(pickFn(fn, \"async\")(value));\n }\n}\n\nexport default Rule;\n","class Modifier {\n constructor(name, perform, performAsync) {\n this.name = name;\n this.perform = perform;\n this.performAsync = performAsync;\n }\n}\n\nexport default Modifier;\n","class ValidationError extends Error {\n constructor(rule, value, cause, target, ...remaining) {\n super(remaining);\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ValidationError);\n }\n this.rule = rule;\n this.value = value;\n this.cause = cause;\n this.target = target;\n }\n}\n\nexport default ValidationError;\n","import Rule from \"./Rule\";\nimport Modifier from \"./Modifier\";\nimport ValidationError from \"./ValidationError\";\n\nclass Context {\n constructor(chain = [], nextRuleModifiers = []) {\n this.chain = chain;\n this.nextRuleModifiers = nextRuleModifiers;\n }\n\n _applyRule(ruleFn, name) {\n return (...args) => {\n this.chain.push(\n new Rule(name, ruleFn.apply(this, args), args, this.nextRuleModifiers)\n );\n this.nextRuleModifiers = [];\n return this;\n };\n }\n\n _applyModifier(modifier, name) {\n this.nextRuleModifiers.push(\n new Modifier(name, modifier.simple, modifier.async)\n );\n return this;\n }\n\n _clone() {\n return new Context(this.chain.slice(), this.nextRuleModifiers.slice());\n }\n\n test(value) {\n return this.chain.every(rule => rule._test(value));\n }\n\n testAll(value) {\n const err = [];\n this.chain.forEach(rule => {\n try {\n rule._check(value);\n } catch (ex) {\n err.push(new ValidationError(rule, value, ex));\n }\n });\n return err;\n }\n\n check(value) {\n this.chain.forEach(rule => {\n try {\n rule._check(value);\n } catch (ex) {\n throw new ValidationError(rule, value, ex);\n }\n });\n }\n\n testAsync(value) {\n return new Promise((resolve, reject) => {\n executeAsyncRules(value, this.chain.slice(), resolve, reject);\n });\n }\n}\n\nfunction executeAsyncRules(value, rules, resolve, reject) {\n if (rules.length) {\n const rule = rules.shift();\n rule._testAsync(value).then(\n () => {\n executeAsyncRules(value, rules, resolve, reject);\n },\n cause => {\n reject(new ValidationError(rule, value, cause));\n }\n );\n } else {\n resolve(value);\n }\n}\n\nexport default Context;\n","import Context from \"./Context\";\n\nfunction v8n() {\n return proxyContext(new Context());\n}\n\n// Custom rules\nlet customRules = {};\n\nv8n.extend = function(newRules) {\n Object.assign(customRules, newRules);\n};\n\nv8n.clearCustomRules = function() {\n customRules = {};\n};\n\nfunction proxyContext(context) {\n return new Proxy(context, {\n get(obj, prop) {\n if (prop in obj) {\n return obj[prop];\n }\n\n const newContext = proxyContext(context._clone());\n\n if (prop in availableModifiers) {\n return newContext._applyModifier(availableModifiers[prop], prop);\n }\n if (prop in customRules) {\n return newContext._applyRule(customRules[prop], prop);\n }\n if (prop in availableRules) {\n return newContext._applyRule(availableRules[prop], prop);\n }\n }\n });\n}\n\nconst availableModifiers = {\n not: {\n simple: fn => value => !fn(value),\n async: fn => value =>\n Promise.resolve(fn(value))\n .then(result => !result)\n .catch(e => true)\n },\n\n some: {\n simple: fn => value => {\n return split(value).some(item => {\n try {\n return fn(item);\n } catch (ex) {\n return false;\n }\n });\n },\n async: fn => value => {\n return Promise.all(\n split(value).map(item => {\n try {\n return fn(item).catch(e => false);\n } catch (ex) {\n return false;\n }\n })\n ).then(result => result.some(Boolean));\n }\n },\n\n every: {\n simple: fn => value => split(value).every(fn),\n async: fn => value =>\n Promise.all(split(value).map(fn)).then(result => result.every(Boolean))\n }\n};\n\nfunction split(value) {\n if (typeof value === \"string\") {\n return value.split(\"\");\n }\n return value;\n}\n\nconst availableRules = {\n // Value\n\n equal: expected => value => value == expected,\n\n exact: expected => value => value === expected,\n\n // Types\n\n number: (allowInfinite = true) => value =>\n typeof value === \"number\" && (allowInfinite || isFinite(value)),\n\n integer: () => value => {\n const isInteger = Number.isInteger || isIntegerPolyfill;\n return isInteger(value);\n },\n\n numeric: () => value => !isNaN(parseFloat(value)) && isFinite(value),\n\n string: () => testType(\"string\"),\n\n boolean: () => testType(\"boolean\"),\n\n undefined: () => testType(\"undefined\"),\n\n null: () => testType(\"null\"),\n\n array: () => testType(\"array\"),\n\n object: () => testType(\"object\"),\n\n instanceOf: instance => value => value instanceof instance,\n\n // Pattern\n\n pattern: expected => value => expected.test(value),\n\n lowercase: () => value => /^([a-z]+\\s*)+$/.test(value),\n\n uppercase: () => value => /^([A-Z]+\\s*)+$/.test(value),\n\n vowel: () => value => /^[aeiou]+$/i.test(value),\n\n consonant: () => value => /^(?=[^aeiou])([a-z]+)$/i.test(value),\n\n // Value at\n\n first: expected => value => value[0] == expected,\n\n last: expected => value => value[value.length - 1] == expected,\n\n // Length\n\n empty: () => value => value.length === 0,\n\n length: (min, max) => value =>\n value.length >= min && value.length <= (max || min),\n\n minLength: min => value => value.length >= min,\n\n maxLength: max => value => value.length <= max,\n\n // Range\n\n negative: () => value => value < 0,\n\n positive: () => value => value >= 0,\n\n between: (a, b) => value => value >= a && value <= b,\n\n range: (a, b) => value => value >= a && value <= b,\n\n lessThan: n => value => value < n,\n\n lessThanOrEqual: n => value => value <= n,\n\n greaterThan: n => value => value > n,\n\n greaterThanOrEqual: n => value => value >= n,\n\n // Divisible\n\n even: () => value => value % 2 === 0,\n\n odd: () => value => value % 2 !== 0,\n\n includes: expected => value => ~value.indexOf(expected),\n\n schema: schema => testSchema(schema),\n\n // branching\n\n passesAnyOf: (...validations) => value =>\n validations.some(validation => validation.test(value)),\n\n optional: (validation, considerTrimmedEmptyString = false) => value => {\n if (\n considerTrimmedEmptyString &&\n typeof value === \"string\" &&\n value.trim() === \"\"\n ) {\n return true;\n }\n\n if (value !== undefined && value !== null) validation.check(value);\n return true;\n }\n};\n\nfunction testType(expected) {\n return value => {\n return (\n (Array.isArray(value) && expected === \"array\") ||\n (value === null && expected === \"null\") ||\n typeof value === expected\n );\n };\n}\n\nfunction isIntegerPolyfill(value) {\n return (\n typeof value === \"number\" && isFinite(value) && Math.floor(value) === value\n );\n}\n\nfunction testSchema(schema) {\n return {\n simple: value => {\n const causes = [];\n Object.keys(schema).forEach(key => {\n const nestedValidation = schema[key];\n try {\n nestedValidation.check((value || {})[key]);\n } catch (ex) {\n ex.target = key;\n causes.push(ex);\n }\n });\n if (causes.length > 0) {\n throw causes;\n }\n return true;\n },\n async: value => {\n const causes = [];\n const nested = Object.keys(schema).map(key => {\n const nestedValidation = schema[key];\n return nestedValidation.testAsync((value || {})[key]).catch(ex => {\n ex.target = key;\n causes.push(ex);\n });\n });\n return Promise.all(nested).then(values => {\n if (causes.length > 0) {\n throw causes;\n }\n\n return true;\n });\n }\n };\n}\n\nexport default v8n;\n"],"names":["Rule","name","fn","args","modifiers","value","this","slice","ex","testAux","it","Promise","resolve","reject","testAsyncAux","length","modifier","shift","nextFn","performAsync","pickFn","_this","then","valid","catch","variant","perform","Modifier","ValidationError","rule","cause","target","remaining","Error","captureStackTrace","Context","chain","nextRuleModifiers","ruleFn","push","apply","simple","async","every","_test","err","forEach","_check","executeAsyncRules","rules","_testAsync","_this2","v8n","proxyContext","context","Proxy","obj","prop","newContext","_clone","availableModifiers","_applyModifier","customRules","_applyRule","availableRules","extend","newRules","assign","clearCustomRules","result","split","some","item","all","map","Boolean","expected","allowInfinite","isFinite","Number","isInteger","isIntegerPolyfill","isNaN","parseFloat","testType","instance","test","min","max","a","b","n","indexOf","schema","causes","keys","nestedValidation","key","check","nested","Object","testAsync","validations","validation","considerTrimmedEmptyString","trim","Array","isArray","Math","floor"],"mappings":"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"}