Created
August 6, 2015 14:22
-
-
Save alexeygolev/7ae127e6e6c7254fd236 to your computer and use it in GitHub Desktop.
Extract validation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {curryN} from 'ramda'; | |
var _validate = function(){}; | |
function Constructor(group, name, validators) { | |
let cons = Object.create(group, { | |
_ctor: { | |
value: name | |
}, | |
toString: { | |
value: function(){ | |
return `${name}(${this.value.toString()})` | |
} | |
} | |
}); | |
return curryN(validators.length, function(...args) { | |
var val = Object.create(cons), validator; | |
val.value = _validate(group, name, arguments, validators) || args; | |
return val; | |
}); | |
} | |
function rawCase(type, cases, action, arg) { | |
if (!type.isPrototypeOf(action)) throw new TypeError(`Data constructor ${action.name} is not in scope`); | |
var _case = cases[action._ctor] || cases['_']; | |
if (!_case) { | |
throw new Error('Non-exhaustive patterns in a function'); | |
} | |
return _case.apply(undefined, arg !== undefined ? action.value.concat([arg]) : action.value); | |
} | |
var typeCase = curryN(3, rawCase); | |
var caseOn = curryN(4, rawCase); | |
function Type(desc) { | |
var obj = {}; | |
Object.keys(desc).forEach( key => { | |
obj[key] = Constructor(obj, key, desc[key]); | |
}); | |
obj.caseOf = typeCase(obj); | |
obj.caseOn = caseOn(obj); | |
return obj; | |
} | |
module.exports = (validate) => { | |
_validate = validate || _validate; | |
return Type; | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import t from 'union-type'; | |
if (process.env.NODE_ENV === 'development') { | |
import validate from 'validation'; | |
var Type = t(validate); | |
} else { | |
var Type = t(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function isString(s) { | |
return typeof s === 'string'; | |
} | |
function isNumber(n) { | |
return typeof n === 'number'; | |
} | |
function isBoolean(b) { | |
return typeof b === 'boolean'; | |
} | |
function isObject(value) { | |
var type = typeof value; | |
return !!value && (type == 'object' || type == 'function'); | |
} | |
function isFunction(f) { | |
return typeof f === 'function'; | |
} | |
var isArray = Array.isArray || function (a) { | |
return 'length' in a; | |
}; | |
var mapConstrToFn = function (group, constr) { | |
return constr === String ? isString | |
: constr === Number ? isNumber | |
: constr === Boolean ? isBoolean | |
: constr === Object ? isObject | |
: constr === Array ? isArray | |
: constr === Function ? isFunction | |
: constr === undefined ? group | |
: constr; | |
}; | |
export default function validate(group, name, args, validators) { | |
var val = [], v, validator; | |
for (var i = 0; i < args.length; ++i) { | |
v = args[i]; | |
validator = mapConstrToFn(group, validators[i]); | |
if ((typeof validator === 'function' && validator(v)) || | |
(v !== undefined && v !== null && v._ctor in validator)) { | |
val[i] = v; | |
} else { | |
throw new TypeError(`Couldn't match expected type ${validators[i].name || validators[i]} with actual type ${typeof v}. Expression ${name}(${v})`); | |
} | |
} | |
return val; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment