diff --git a/lib/check.js b/lib/check.js index 412bb14..cef9a71 100644 --- a/lib/check.js +++ b/lib/check.js @@ -1,6 +1,6 @@ // Generated by LiveScript 1.6.0 (function(){ - var ref$, any, all, isItNaN, types, defaultType, customTypes, toString$ = {}.toString; + var ref$, any, all, isItNaN, types, defaultType, toString$ = {}.toString; ref$ = require('prelude-ls'), any = ref$.any, all = ref$.all, isItNaN = ref$.isItNaN; types = { Number: { @@ -36,24 +36,24 @@ array: 'Array', tuple: 'Array' }; - function checkArray(input, type){ + function checkArray(input, type, options){ return all(function(it){ - return checkMultiple(it, type.of); + return checkMultiple(it, type.of, options); }, input); } - function checkTuple(input, type){ + function checkTuple(input, type, options){ var i, i$, ref$, len$, types; i = 0; for (i$ = 0, len$ = (ref$ = type.of).length; i$ < len$; ++i$) { types = ref$[i$]; - if (!checkMultiple(input[i], types)) { + if (!checkMultiple(input[i], types, options)) { return false; } i++; } return input.length <= i; } - function checkFields(input, type){ + function checkFields(input, type, options){ var inputKeys, numInputKeys, k, numOfKeys, key, ref$, types; inputKeys = {}; numInputKeys = 0; @@ -64,7 +64,7 @@ numOfKeys = 0; for (key in ref$ = type.of) { types = ref$[key]; - if (!checkMultiple(input[key], types)) { + if (!checkMultiple(input[key], types, options)) { return false; } if (inputKeys[key]) { @@ -73,31 +73,31 @@ } return type.subset || numInputKeys === numOfKeys; } - function checkStructure(input, type){ + function checkStructure(input, type, options){ if (!(input instanceof Object)) { return false; } switch (type.structure) { case 'fields': - return checkFields(input, type); + return checkFields(input, type, options); case 'array': - return checkArray(input, type); + return checkArray(input, type, options); case 'tuple': - return checkTuple(input, type); + return checkTuple(input, type, options); } } - function check(input, typeObj){ + function check(input, typeObj, options){ var type, structure, setting, that; type = typeObj.type, structure = typeObj.structure; if (type) { if (type === '*') { return true; } - setting = customTypes[type] || types[type]; + setting = options.customTypes[type] || types[type]; if (setting) { return (setting.typeOf === void 8 || setting.typeOf === toString$.call(input).slice(8, -1)) && setting.validate(input); } else { - return type === toString$.call(input).slice(8, -1) && (!structure || checkStructure(input, typeObj)); + return type === toString$.call(input).slice(8, -1) && (!structure || checkStructure(input, typeObj, options)); } } else if (structure) { if (that = defaultType[structure]) { @@ -105,22 +105,24 @@ return false; } } - return checkStructure(input, typeObj); + return checkStructure(input, typeObj, options); } else { throw new Error("No type defined. Input: " + input + "."); } } - function checkMultiple(input, types){ + function checkMultiple(input, types, options){ if (toString$.call(types).slice(8, -1) !== 'Array') { throw new Error("Types must be in an array. Input: " + input + "."); } return any(function(it){ - return check(input, it); + return check(input, it, options); }, types); } module.exports = function(parsedType, input, options){ options == null && (options = {}); - customTypes = options.customTypes || {}; - return checkMultiple(input, parsedType); + if (!options.customTypes) { + options.customTypes = {}; + } + return checkMultiple(input, parsedType, options); }; }).call(this); diff --git a/src/check.ls b/src/check.ls index e268e9c..0a68fa8 100644 --- a/src/check.ls +++ b/src/check.ls @@ -21,17 +21,17 @@ default-type = array: 'Array' tuple: 'Array' -function check-array input, type - all (-> check-multiple it, type.of), input +function check-array input, type, options + all (-> check-multiple it, type.of, options), input -function check-tuple input, type +function check-tuple input, type, options i = 0 for types in type.of - return false unless check-multiple input[i], types + return false unless check-multiple input[i], types, options i++ input.length <= i # may be less if using 'Undefined' or 'Maybe' at the end -function check-fields input, type +function check-fields input, type, options input-keys = {} num-input-keys = 0 for k of input @@ -39,39 +39,38 @@ function check-fields input, type num-input-keys++ num-of-keys = 0 for key, types of type.of - return false unless check-multiple input[key], types + return false unless check-multiple input[key], types, options num-of-keys++ if input-keys[key] type.subset or num-input-keys is num-of-keys -function check-structure input, type +function check-structure input, type, options return false if input not instanceof Object switch type.structure - | 'fields' => check-fields input, type - | 'array' => check-array input, type - | 'tuple' => check-tuple input, type + | 'fields' => check-fields input, type, options + | 'array' => check-array input, type, options + | 'tuple' => check-tuple input, type, options -function check input, type-obj +function check input, type-obj, options {type, structure} = type-obj if type return true if type is '*' # wildcard - setting = custom-types[type] or types[type] + setting = options.custom-types[type] or types[type] if setting (setting.type-of is void or setting.type-of is typeof! input) and setting.validate input else # Booleam, String, Null, Undefined, Error, user defined objects, etc. - type is typeof! input and (not structure or check-structure input, type-obj) + type is typeof! input and (not structure or check-structure input, type-obj, options) else if structure return false unless that is typeof! input if default-type[structure] - check-structure input, type-obj + check-structure input, type-obj, options else throw new Error "No type defined. Input: #input." -function check-multiple input, types +function check-multiple input, types, options throw new Error "Types must be in an array. Input: #input." unless typeof! types is 'Array' - any (-> check input, it), types + any (-> check input, it, options), types -var custom-types module.exports = (parsed-type, input, options = {}) -> - custom-types := options.custom-types or {} - check-multiple input, parsed-type + options.custom-types = {} unless options.custom-types + check-multiple input, parsed-type, options diff --git a/test/check.ls b/test/check.ls index a09c357..b3961dd 100644 --- a/test/check.ls +++ b/test/check.ls @@ -219,6 +219,18 @@ suite 'check' -> assert c 'str', 'foo', o assert not c 'str', 1, o + test 'nested check with custom types' -> + o = + custom-types: + A: + type-of: 'Object' + validate: -> c 'String', it.foo and it.foo = 'A' + B: + type-of: 'Object' + validate: -> c 'String', it.bar and it.bar = 'B' + + assert c '{a: A, b: B}', {a: {foo: 'A'}, b: {bar: 'B'}}, o + test 'nested' -> type = '{a: (String, [Number], {x: {a: Maybe Number}, y: Array, ...}), b: Error{message: String, ...}}' assert c type, {a: ['hi', [1, 2, 3], {x: {a: 42}, y: [1, 'bye']}], b: new Error 'message'}