Skip to content

Instantly share code, notes, and snippets.

@alexeygolev
Created August 6, 2015 14:22
Show Gist options
  • Save alexeygolev/7ae127e6e6c7254fd236 to your computer and use it in GitHub Desktop.
Save alexeygolev/7ae127e6e6c7254fd236 to your computer and use it in GitHub Desktop.
Extract validation
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;
};
import t from 'union-type';
if (process.env.NODE_ENV === 'development') {
import validate from 'validation';
var Type = t(validate);
} else {
var Type = t();
}
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