Comparing version 0.2.1 to 0.3.0
{ | ||
"name": "typology", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "A data validation library for Node.js and the browser.", | ||
@@ -34,4 +34,5 @@ "main": "typology.js", | ||
"gulp-uglify": "^1.0.1", | ||
"jshint-stylish": "^1.0.0" | ||
"jshint-stylish": "^1.0.0", | ||
"lodash": "^2.4.1" | ||
} | ||
} |
249
typology.js
/** | ||
* typology.js - A data validation library for Node.js and the browser, | ||
* | ||
* Version: 0.2.1 | ||
* Version: 0.3.0 | ||
* Sources: http://github.com/jacomyal/typology | ||
@@ -60,7 +60,151 @@ * Doc: http://github.com/jacomyal/typology#readme | ||
function Typology(defs) { | ||
defs = defs || {}; | ||
// Privates | ||
var customTypes = {}; | ||
var _self = this, | ||
_customTypes = {}; | ||
// Validate the given data against the given type, but returns a more | ||
// specific object | ||
function _scan(obj, type) { | ||
var a, | ||
i, | ||
l, | ||
k, | ||
error, | ||
subError, | ||
hasStar, | ||
hasTypeOf, | ||
optional = false, | ||
exclusive = false, | ||
typeOf = _self.get(obj); | ||
if (_self.get(type) === 'string') { | ||
a = type.replace(/^[\?\!]/, '').split(/\|/); | ||
l = a.length; | ||
for (i = 0; i < l; i++) | ||
if (nativeTypes.indexOf(a[i]) < 0 && !(a[i] in _customTypes)) | ||
throw new Error('Invalid type.'); | ||
if (type.match(/^\?/)) | ||
optional = true; | ||
if (type.replace(/^\?/, '').match(/^\!/)) | ||
exclusive = true; | ||
if (exclusive && optional) | ||
throw new Error('Invalid type.'); | ||
for (i in a) | ||
if (_customTypes[a[i]]) | ||
if ( | ||
(typeof _customTypes[a[i]].type === 'function') ? | ||
(_customTypes[a[i]].type.call(_self, obj) === true) : | ||
!_scan(obj, _customTypes[a[i]].type) | ||
) { | ||
if (exclusive) { | ||
error = new Error(); | ||
error.message = 'Expected a "' + type + '" but found a ' + | ||
'"' + a[i] + '".'; | ||
error.expected = type; | ||
error.type = a[i]; | ||
error.value = obj; | ||
return error; | ||
} else | ||
return null; | ||
} | ||
if (obj === null || obj === undefined) { | ||
if (!exclusive && !optional) { | ||
error = new Error(); | ||
error.message = 'Expected a "' + type + '" but found a ' + | ||
'"' + typeOf + '".'; | ||
error.expected = type; | ||
error.type = typeOf; | ||
error.value = obj; | ||
return error; | ||
} else | ||
return null; | ||
} else { | ||
hasStar = ~a.indexOf('*'); | ||
hasTypeOf = ~a.indexOf(typeOf); | ||
if (exclusive && (hasStar || hasTypeOf)) { | ||
error = new Error(); | ||
error.message = 'Expected a "' + type + '" but found a ' + | ||
'"' + (hasTypeOf ? typeOf : '*') + '".'; | ||
error.type = hasTypeOf ? typeOf : '*'; | ||
error.expected = type; | ||
error.value = obj; | ||
return error; | ||
} else if (!exclusive && !(hasStar || hasTypeOf)) { | ||
error = new Error(); | ||
error.message = 'Expected a "' + type + '" but found a ' + | ||
'"' + typeOf + '".'; | ||
error.expected = type; | ||
error.type = typeOf; | ||
error.value = obj; | ||
return error; | ||
} else | ||
return null; | ||
} | ||
} else if (_self.get(type) === 'object') { | ||
if (typeOf !== 'object') { | ||
error = new Error(); | ||
error.message = 'Expected an object but found a "' + typeOf + '".'; | ||
error.expected = type; | ||
error.type = typeOf; | ||
error.value = obj; | ||
return error; | ||
} | ||
for (k in type) | ||
if ((subError = _scan(obj[k], type[k]))) { | ||
error = subError; | ||
error.path = error.path ? | ||
[k].concat(error.path) : | ||
[k]; | ||
return error; | ||
} | ||
for (k in obj) | ||
if (type[k] === undefined) { | ||
error = new Error(); | ||
error.message = 'Unexpected key "' + k + '".'; | ||
error.type = typeOf; | ||
error.value = obj; | ||
return error; | ||
} | ||
return null; | ||
} else if (_self.get(type) === 'array') { | ||
if (type.length !== 1) | ||
throw new Error('Invalid type.'); | ||
if (typeOf !== 'array') { | ||
error = new Error(); | ||
error.message = 'Expected an array but found a "' + typeOf + '".'; | ||
error.expected = type; | ||
error.type = typeOf; | ||
error.value = obj; | ||
return error; | ||
} | ||
l = obj.length; | ||
for (i = 0; i < l; i++) | ||
if ((subError = _scan(obj[i], type[0]))) { | ||
error = subError; | ||
error.path = error.path ? | ||
[i].concat(error.path) : | ||
[i]; | ||
return error; | ||
} | ||
return null; | ||
} else | ||
throw new Error('Invalid type.'); | ||
} | ||
/** | ||
@@ -103,3 +247,3 @@ * Methods | ||
if (customTypes[id] !== undefined && customTypes[id] !== 'proto') | ||
if (_customTypes[id] !== undefined && _customTypes[id] !== 'proto') | ||
throw new Error('The type "' + id + '" already exists.'); | ||
@@ -110,3 +254,3 @@ | ||
customTypes[id] = 1; | ||
_customTypes[id] = 1; | ||
@@ -118,4 +262,4 @@ // Check given prototypes: | ||
for (k in a) | ||
if (customTypes[a[k]] === undefined) { | ||
customTypes[a[k]] = 1; | ||
if (_customTypes[a[k]] === undefined) { | ||
_customTypes[a[k]] = 1; | ||
tmp[a[k]] = 1; | ||
@@ -130,3 +274,3 @@ } | ||
// Effectively add the type: | ||
customTypes[id] = (o === undefined) ? | ||
_customTypes[id] = (o === undefined) ? | ||
{ | ||
@@ -140,3 +284,3 @@ id: id, | ||
for (k in o) | ||
customTypes[id][k] = o[k]; | ||
_customTypes[id][k] = o[k]; | ||
@@ -146,3 +290,3 @@ // Delete prototypes: | ||
if (k !== id) | ||
delete customTypes[k]; | ||
delete _customTypes[k]; | ||
@@ -154,3 +298,3 @@ return this; | ||
this.has = function(key) { | ||
return !!customTypes[key]; | ||
return !!_customTypes[key]; | ||
}; | ||
@@ -166,70 +310,8 @@ | ||
// Validate the given data against the given type | ||
this.check = function(obj, type) { | ||
var a, | ||
i, | ||
k, | ||
optional = false, | ||
exclusive = false, | ||
typeOf = this.get(obj); | ||
if (this.get(type) === 'string') { | ||
a = type.replace(/^[?!]/, '').split(/\|/); | ||
for (i in a) | ||
if (nativeTypes.indexOf(a[i]) < 0 && !(a[i] in customTypes)) { | ||
throw new Error('Invalid type.'); | ||
return false; | ||
} | ||
if (type.match(/^\?/)) { | ||
optional = true; | ||
type = type.replace(/^\?/, ''); | ||
} | ||
if (type.match(/^!/)) { | ||
exclusive = true; | ||
type = type.replace(/^!/, ''); | ||
} | ||
for (i in a) | ||
if (customTypes[a[i]]) | ||
if ( | ||
(typeof customTypes[a[i]].type === 'function') ? | ||
(customTypes[a[i]].type.call(this, obj) === true) : | ||
this.check(obj, customTypes[a[i]].type) | ||
) | ||
return !exclusive; | ||
if (obj === null || obj === undefined) | ||
return !exclusive ? optional : !optional; | ||
else | ||
return !exclusive ? | ||
!!(~a.indexOf('*') || ~a.indexOf(typeOf)) : | ||
!(~a.indexOf('*') || ~a.indexOf(typeOf)); | ||
} else if (this.get(type) === 'object') { | ||
if (typeOf !== 'object') | ||
return false; | ||
for (k in type) | ||
if (!this.check(obj[k], type[k])) | ||
return false; | ||
for (k in obj) | ||
if (type[k] === undefined) | ||
return false; | ||
return true; | ||
} else if (this.get(type) === 'array') { | ||
if (typeOf !== 'array') | ||
return false; | ||
if (type.length !== 1) { | ||
throw new Error('Invalid type.'); | ||
} | ||
for (k in obj) | ||
if (!this.check(obj[k], type[0])) | ||
return false; | ||
return true; | ||
} else | ||
return false; | ||
this.check = function(obj, type, throws) { | ||
var result = _scan(obj, type); | ||
if (throws && result) | ||
throw result; | ||
else | ||
return !result; | ||
}; | ||
@@ -244,5 +326,5 @@ | ||
if (this.get(type) === 'string') { | ||
a = type.replace(/^[?!]/, '').split(/\|/); | ||
a = type.replace(/^[\?\!]/, '').split(/\|/); | ||
for (i in a) | ||
if (nativeTypes.indexOf(a[i]) < 0 && !(a[i] in customTypes)) | ||
if (nativeTypes.indexOf(a[i]) < 0 && !(a[i] in _customTypes)) | ||
return false; | ||
@@ -280,2 +362,3 @@ return true; | ||
// Adding custom types at instantiation | ||
defs = defs || {}; | ||
if (this.get(defs) !== 'object') | ||
@@ -298,3 +381,3 @@ throw Error('Invalid argument.'); | ||
Object.defineProperty(types, 'version', { | ||
value: '0.2.1' | ||
value: '0.3.0' | ||
}); | ||
@@ -301,0 +384,0 @@ |
/** | ||
* typology - A data validation library for Node.js and the browser. | ||
* @version v0.2.1 | ||
* @version v0.3.0 | ||
* @link https://github.com/jacomyal/typology | ||
* @license MIT | ||
*/ | ||
!function(){"use strict";function t(t){t=t||{};var e={};if(this.add=function(t,r){var i,n,s,f,a,h;if(1===arguments.length){if("object"!==this.get(t))throw new Error("If types.add is called with one argument, this one has to be an object.");i=t,f=i.id,h=i.type}else{if(2!==arguments.length)throw new Error("types.add has to be called with one or two arguments.");if("string"!=typeof t||!t)throw new Error("If types.add is called with more than one argument, the first one must be the string id.");f=t,h=r}if("string"!==this.get(f)||0===f.length)throw new Error("A type requires an string id.");if(void 0!==e[f]&&"proto"!==e[f])throw new Error('The type "'+f+'" already exists.');if(~o.indexOf(f))throw new Error('"'+f+'" is a reserved type name.');e[f]=1,s=(i||{}).proto||[],s=Array.isArray(s)?s:[s],a={};for(n in s)void 0===e[s[n]]&&(e[s[n]]=1,a[s[n]]=1);if("function"!==this.get(h)&&!this.isValid(h))throw new Error("A type requires a valid definition. This one can be a preexistant type or else a function testing given objects.");if(e[f]=void 0===i?{id:f,type:h}:{},void 0!==i)for(n in i)e[f][n]=i[n];for(n in a)n!==f&&delete e[n];return this},this.has=function(t){return!!e[t]},this.get=function(t){return null===t||void 0===t?String(t):n[Object.prototype.toString.call(t)]||"object"},this.check=function(t,r){var i,n,s,f=!1,a=!1,h=this.get(t);if("string"===this.get(r)){i=r.replace(/^[?!]/,"").split(/\|/);for(n in i)if(o.indexOf(i[n])<0&&!(i[n]in e))throw new Error("Invalid type.");r.match(/^\?/)&&(f=!0,r=r.replace(/^\?/,"")),r.match(/^!/)&&(a=!0,r=r.replace(/^!/,""));for(n in i)if(e[i[n]]&&("function"==typeof e[i[n]].type?e[i[n]].type.call(this,t)===!0:this.check(t,e[i[n]].type)))return!a;return null===t||void 0===t?a?!f:f:a?!(~i.indexOf("*")||~i.indexOf(h)):!(!~i.indexOf("*")&&!~i.indexOf(h))}if("object"===this.get(r)){if("object"!==h)return!1;for(s in r)if(!this.check(t[s],r[s]))return!1;for(s in t)if(void 0===r[s])return!1;return!0}if("array"===this.get(r)){if("array"!==h)return!1;if(1!==r.length)throw new Error("Invalid type.");for(s in t)if(!this.check(t[s],r[0]))return!1;return!0}return!1},this.isValid=function(t){var r,i,n;if("string"===this.get(t)){r=t.replace(/^[?!]/,"").split(/\|/);for(n in r)if(o.indexOf(r[n])<0&&!(r[n]in e))return!1;return!0}if("object"===this.get(t)){for(i in t)if(!this.isValid(t[i]))return!1;return!0}return"array"===this.get(t)&&1===t.length?this.isValid(t[0]):!1},this.add("type",function(t){return this.isValid(t)}.bind(this)),this.add("primitive",function(t){return!t||!(t instanceof Object||"object"==typeof t)}),"object"!==this.get(t))throw Error("Invalid argument.");for(var r in t)this.add(r,t[r])}var e,r,i=["Arguments","Boolean","Number","String","Function","Array","Date","RegExp","Object"],n={},o=["*"];for(e in i)r=i[e],o.push(r.toLowerCase()),n["[object "+r+"]"]=r.toLowerCase();var s=t;t.call(s),Object.defineProperty(s,"version",{value:"0.2.1"}),"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=s),exports.types=s):"function"==typeof define&&define.amd?define("typology",[],function(){return s}):this.types=s}(this); | ||
!function(){"use strict";function e(e){function t(e,i){var a,s,f,u,d,p,h,l,c=!1,g=!1,y=r.get(e);if("string"===r.get(i)){for(a=i.replace(/^[\?\!]/,"").split(/\|/),f=a.length,s=0;f>s;s++)if(o.indexOf(a[s])<0&&!(a[s]in n))throw new Error("Invalid type.");if(i.match(/^\?/)&&(c=!0),i.replace(/^\?/,"").match(/^\!/)&&(g=!0),g&&c)throw new Error("Invalid type.");for(s in a)if(n[a[s]]&&("function"==typeof n[a[s]].type?n[a[s]].type.call(r,e)===!0:!t(e,n[a[s]].type)))return g?(d=new Error,d.message='Expected a "'+i+'" but found a "'+a[s]+'".',d.expected=i,d.type=a[s],d.value=e,d):null;return null===e||void 0===e?g||c?null:(d=new Error,d.message='Expected a "'+i+'" but found a "'+y+'".',d.expected=i,d.type=y,d.value=e,d):(h=~a.indexOf("*"),l=~a.indexOf(y),g&&(h||l)?(d=new Error,d.message='Expected a "'+i+'" but found a "'+(l?y:"*")+'".',d.type=l?y:"*",d.expected=i,d.value=e,d):g||h||l?null:(d=new Error,d.message='Expected a "'+i+'" but found a "'+y+'".',d.expected=i,d.type=y,d.value=e,d))}if("object"===r.get(i)){if("object"!==y)return d=new Error,d.message='Expected an object but found a "'+y+'".',d.expected=i,d.type=y,d.value=e,d;for(u in i)if(p=t(e[u],i[u]))return d=p,d.path=d.path?[u].concat(d.path):[u],d;for(u in e)if(void 0===i[u])return d=new Error,d.message='Unexpected key "'+u+'".',d.type=y,d.value=e,d;return null}if("array"===r.get(i)){if(1!==i.length)throw new Error("Invalid type.");if("array"!==y)return d=new Error,d.message='Expected an array but found a "'+y+'".',d.expected=i,d.type=y,d.value=e,d;for(f=e.length,s=0;f>s;s++)if(p=t(e[s],i[0]))return d=p,d.path=d.path?[s].concat(d.path):[s],d;return null}throw new Error("Invalid type.")}var r=this,n={};if(this.add=function(e,t){var r,i,a,s,f,u;if(1===arguments.length){if("object"!==this.get(e))throw new Error("If types.add is called with one argument, this one has to be an object.");r=e,s=r.id,u=r.type}else{if(2!==arguments.length)throw new Error("types.add has to be called with one or two arguments.");if("string"!=typeof e||!e)throw new Error("If types.add is called with more than one argument, the first one must be the string id.");s=e,u=t}if("string"!==this.get(s)||0===s.length)throw new Error("A type requires an string id.");if(void 0!==n[s]&&"proto"!==n[s])throw new Error('The type "'+s+'" already exists.');if(~o.indexOf(s))throw new Error('"'+s+'" is a reserved type name.');n[s]=1,a=(r||{}).proto||[],a=Array.isArray(a)?a:[a],f={};for(i in a)void 0===n[a[i]]&&(n[a[i]]=1,f[a[i]]=1);if("function"!==this.get(u)&&!this.isValid(u))throw new Error("A type requires a valid definition. This one can be a preexistant type or else a function testing given objects.");if(n[s]=void 0===r?{id:s,type:u}:{},void 0!==r)for(i in r)n[s][i]=r[i];for(i in f)i!==s&&delete n[i];return this},this.has=function(e){return!!n[e]},this.get=function(e){return null===e||void 0===e?String(e):i[Object.prototype.toString.call(e)]||"object"},this.check=function(e,r,n){var i=t(e,r);if(n&&i)throw i;return!i},this.isValid=function(e){var t,r,i;if("string"===this.get(e)){t=e.replace(/^[\?\!]/,"").split(/\|/);for(i in t)if(o.indexOf(t[i])<0&&!(t[i]in n))return!1;return!0}if("object"===this.get(e)){for(r in e)if(!this.isValid(e[r]))return!1;return!0}return"array"===this.get(e)&&1===e.length?this.isValid(e[0]):!1},this.add("type",function(e){return this.isValid(e)}.bind(this)),this.add("primitive",function(e){return!e||!(e instanceof Object||"object"==typeof e)}),e=e||{},"object"!==this.get(e))throw Error("Invalid argument.");for(var a in e)this.add(a,e[a])}var t,r,n=["Arguments","Boolean","Number","String","Function","Array","Date","RegExp","Object"],i={},o=["*"];for(t in n)r=n[t],o.push(r.toLowerCase()),i["[object "+r+"]"]=r.toLowerCase();var a=e;e.call(a),Object.defineProperty(a,"version",{value:"0.3.0"}),"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=a),exports.types=a):"function"==typeof define&&define.amd?define("typology",[],function(){return a}):this.types=a}(this); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23051
391
9