Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

typology

Package Overview
Dependencies
Maintainers
2
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typology - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

2

package.json
{
"name": "typology",
"version": "0.3.0",
"version": "0.3.1",
"description": "A data validation library for Node.js and the browser.",

@@ -5,0 +5,0 @@ "main": "typology.js",

/**
* typology.js - A data validation library for Node.js and the browser,
*
* Version: 0.3.0
* Version: 0.3.1
* Sources: http://github.com/jacomyal/typology

@@ -33,35 +33,114 @@ * Doc: http://github.com/jacomyal/typology#readme

var k,
className,
classes = [
'Arguments',
'Boolean',
'Number',
'String',
'Function',
'Array',
'Date',
'RegExp',
'Object'
],
class2type = {},
nativeTypes = ['*'];
/**
* Code conventions:
* *****************
* - 80 characters max per line
* - Write "__myVar" for any global private variable
* - Write "_myVar" for any instance private variable
* - Write "myVar" any local variable
*/
// Fill types
for (k in classes) {
className = classes[k];
nativeTypes.push(className.toLowerCase());
class2type['[object ' + className + ']'] = className.toLowerCase();
}
/**
* Main object
* PRIVATE GLOBALS:
* ****************
*/
/**
* This object is a dictionnary that maps "[object Something]" strings to the
* typology form "something":
*/
var __class2type = {};
/**
* This array is the list of every types considered native by typology:
*/
var __nativeTypes = ['*'];
(function() {
var k,
className,
classes = [
'Arguments',
'Boolean',
'Number',
'String',
'Function',
'Array',
'Date',
'RegExp',
'Object'
];
// Fill types
for (k in classes) {
className = classes[k];
__nativeTypes.push(className.toLowerCase());
__class2type['[object ' + className + ']'] = className.toLowerCase();
}
})();
/**
* CONSTRUCTOR:
* ************
*/
function Typology(defs) {
// Privates
var _self = this,
_customTypes = {};
/**
* INSTANCE PRIVATES:
* ******************
*/
// Validate the given data against the given type, but returns a more
// specific object
var _self = this;
/**
* This objects will contain every instance-specific custom types:
*/
var _customTypes = {};
/**
* This function will recursively scan an object to check wether or not it
* matches a given type. It will return null if it matches, and an Error
* object else.
*
* Examples:
* *********
* 1. When the type matches:
* > _scan('abc', 'string');
* will return null.
*
* 2. When a top-level type does not match:
* > _scan('abc', 'number');
* will return an Error object with the following information:
* - message: Expected a "number" but found a "string".
*
* 3. When a sub-object type does not its type:
* > _scan({ a: 'abc' }, { a: 'number' });
* will return an Error object with the following information:
* - message: Expected a "number" but found a "string".
* - path: [ 'a' ]
*
* 4. When a deep sub-object type does not its type:
* > _scan({ a: [ 123, 'abc' ] }, { a: ['number'] });
* will return an Error object with the following information:
* - message: Expected a "number" but found a "string".
* - path: [ 'a', 1 ]
*
* 5. When a required key is missing:
* > _scan({}, { a: 'number' });
* will return an Error object with the following information:
* - message: Expected a "number" but found a "undefined".
* - path: [ 'a' ]
*
* 6. When an unexpected key is present:
* > _scan({ a: 123, b: 456 }, { a: 'number' });
* will return an Error object with the following information:
* - message: Unexpected key "b".
*
* @param {*} obj The value to validate.
* @param {type} type The type.
* @return {?Error} Returns null or an Error object.
*/
function _scan(obj, type) {

@@ -84,3 +163,3 @@ var a,

for (i = 0; i < l; i++)
if (nativeTypes.indexOf(a[i]) < 0 && !(a[i] in _customTypes))
if (__nativeTypes.indexOf(a[i]) < 0 && !(a[i] in _customTypes))
throw new Error('Invalid type.');

@@ -211,7 +290,61 @@

/**
* Methods
* INSTANCE METHODS:
* *****************
*/
// Adding a custom type
/**
* This method registers a custom type into the Typology instance. A type
* is registered under a unique name, and is described by an object (like
* classical C structures) or a function.
*
* Variant 1:
* **********
* > types.add('user', { id: 'string', name: '?string' });
*
* @param {string} id The unique id of the type.
* @param {object} type The corresponding structure.
* @return {Typology} Returns this.
*
* Variant 2:
* **********
* > types.add('integer', function(value) {
* > return typeof value === 'number' && value === value | 0;
* > });
*
* @param {string} id The unique id of the type.
* @param {function} type The function validating the type.
* @return {Typology} Returns this.
*
* Variant 3:
* **********
* > types.add({
* > id: 'user',
* > type: { id: 'string', name: '?string' }
* > });
*
* > types.add({
* > id: 'integer',
* > type: function(value) {
* > return typeof value === 'number' && value === value | 0;
* > }
* > });
*
* @param {object} specs An object describing fully the type.
* @return {Typology} Returns this.
*
* Recognized parameters:
* **********************
* Here is the exhaustive list of every accepted parameters in the specs
* object:
*
* {string} id The unique id of the type.
* {function|object} type The function or the structure object
* validating the type.
* {?[string]} proto Eventually an array of ids of types that are
* referenced in the structure but do not exist
* yet.
*/
this.add = function(a1, a2) {

@@ -252,3 +385,3 @@ var o,

if (~nativeTypes.indexOf(id))
if (~__nativeTypes.indexOf(id))
throw new Error('"' + id + '" is a reserved type name.');

@@ -293,3 +426,9 @@

// Check whether this typology has the given type
/**
* This method returns true if a custom type is already registered in this
* instance under the given key.
*
* @param {string} key A type name.
* @return {boolean} Returns true if the key is registered.
*/
this.has = function(key) {

@@ -299,10 +438,48 @@ return !!_customTypes[key];

// Get the native type of the given variable
/**
* This method returns the native type of a given value.
*
* Examples:
* *********
* > types.get({ a: 1 }); // returns "object"
* > types.get('abcde'); // returns "string"
* > types.get(1234567); // returns "number"
* > types.get([1, 2]); // returns "array"
*
* @param {*} value Anything.
* @return {string} Returns the native type of the value.
*/
this.get = function(obj) {
return (obj === null || obj === undefined) ?
String(obj) :
class2type[Object.prototype.toString.call(obj)] || 'object';
__class2type[Object.prototype.toString.call(obj)] || 'object';
};
// Validate the given data against the given type
/**
* This method validates some value against a given type. If the flag throws
* has a truthy value, then the method will throw an error instead of
* returning false.
*
* To know more about the error thrown, you can read the documentation of
* the private method _scan.
*
* Examples:
* *********
* > types.check({ a: 1 }, 'object'); // returns true
* > types.check({ a: 1 }, { a: 'string' }); // returns true
* > types.check({ a: 1 }, { a: 'string', b: '?number' }); // returns true
*
* > types.check({ a: 1 }, { a: 'string', b: 'number' }); // returns false
* > types.check({ a: 1 }, { a: 'number' }); // returns false
* > types.check({ a: 1 }, 'array'); // returns false
*
* > types.check({ a: 1 }, 'array', true); // throws an Error
*
* @param {*} value Anything.
* @param {type} type A valid type.
* @param {?boolean} throws If true, this method will throw an error
* instead of returning false.
* @return {boolean} Returns true if the value matches the type, and
* not else.
*/
this.check = function(obj, type, throws) {

@@ -316,3 +493,30 @@ var result = _scan(obj, type);

// Is the given type valid?
/**
* This method validates a type. If the type is not referenced or is not
* valid, it will return false.
*
* To know more about that function, don't hesitate to read the related
* unit tests.
*
* Examples:
* *********
* > types.isValid('string'); // returns true
* > types.isValid('?string'); // returns true
* > types.isValid('!string'); // returns true
* > types.isValid('string|number'); // returns true
* > types.isValid({ a: 'string' }); // returns true
* > types.isValid(['string']); // returns true
*
* > types.isValid('!?string'); // returns false
* > types.isValid('myNotDefinedType'); // returns false
* > types.isValid(['myNotDefinedType']); // returns false
* > types.isValid({ a: 'myNotDefinedType' }); // returns false
*
* > types.isValid('user'); // returns false
* > types.add('user', { id: 'string' }); // makes the type become valid
* > types.isValid('user'); // returns true
*
* @param {*} type The type to get checked.
* @return {boolean} Returns true if the type is valid, and false else.
*/
this.isValid = function(type) {

@@ -326,3 +530,3 @@ var a,

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;

@@ -345,7 +549,10 @@ return true;

/**
* Instantiation routine
* INSTANTIATION ROUTINE:
* **********************
*/
// Add a type "type" to shortcut the isValid method:
// Add a type "type" to shortcut the #isValid method:
this.add('type', (function(v) {

@@ -360,3 +567,3 @@ return this.isValid(v);

// Adding custom types at instantiation
// Adding custom types at instantiation:
defs = defs || {};

@@ -370,17 +577,23 @@ if (this.get(defs) !== 'object')

/**
* Public interface
* GLOBAL PUBLIC API:
* ******************
*/
// Creating a "main" typology instance to export
// Creating a "main" typology instance to export:
var types = Typology;
Typology.call(types);
// Version
// Version:
Object.defineProperty(types, 'version', {
value: '0.3.0'
value: '0.3.1'
});
/**
* Export
* EXPORT:
* *******
*/

@@ -387,0 +600,0 @@ if (typeof exports !== 'undefined') {

/**
* typology - A data validation library for Node.js and the browser.
* @version v0.3.0
* @version v0.3.1
* @link https://github.com/jacomyal/typology
* @license MIT
*/
!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);
!function(){"use strict";function e(e){function n(e,t){var a,s,f,u,d,p,h,l,c=!1,g=!1,y=i.get(e);if("string"===i.get(t)){for(a=t.replace(/^[\?\!]/,"").split(/\|/),f=a.length,s=0;f>s;s++)if(r.indexOf(a[s])<0&&!(a[s]in o))throw new Error("Invalid type.");if(t.match(/^\?/)&&(c=!0),t.replace(/^\?/,"").match(/^\!/)&&(g=!0),g&&c)throw new Error("Invalid type.");for(s in a)if(o[a[s]]&&("function"==typeof o[a[s]].type?o[a[s]].type.call(i,e)===!0:!n(e,o[a[s]].type)))return g?(d=new Error,d.message='Expected a "'+t+'" but found a "'+a[s]+'".',d.expected=t,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 "'+t+'" but found a "'+y+'".',d.expected=t,d.type=y,d.value=e,d):(h=~a.indexOf("*"),l=~a.indexOf(y),g&&(h||l)?(d=new Error,d.message='Expected a "'+t+'" but found a "'+(l?y:"*")+'".',d.type=l?y:"*",d.expected=t,d.value=e,d):g||h||l?null:(d=new Error,d.message='Expected a "'+t+'" but found a "'+y+'".',d.expected=t,d.type=y,d.value=e,d))}if("object"===i.get(t)){if("object"!==y)return d=new Error,d.message='Expected an object but found a "'+y+'".',d.expected=t,d.type=y,d.value=e,d;for(u in t)if(p=n(e[u],t[u]))return d=p,d.path=d.path?[u].concat(d.path):[u],d;for(u in e)if(void 0===t[u])return d=new Error,d.message='Unexpected key "'+u+'".',d.type=y,d.value=e,d;return null}if("array"===i.get(t)){if(1!==t.length)throw new Error("Invalid type.");if("array"!==y)return d=new Error,d.message='Expected an array but found a "'+y+'".',d.expected=t,d.type=y,d.value=e,d;for(f=e.length,s=0;f>s;s++)if(p=n(e[s],t[0]))return d=p,d.path=d.path?[s].concat(d.path):[s],d;return null}throw new Error("Invalid type.")}var i=this,o={};if(this.add=function(e,t){var n,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.");n=e,s=n.id,u=n.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!==o[s]&&"proto"!==o[s])throw new Error('The type "'+s+'" already exists.');if(~r.indexOf(s))throw new Error('"'+s+'" is a reserved type name.');o[s]=1,a=(n||{}).proto||[],a=Array.isArray(a)?a:[a],f={};for(i in a)void 0===o[a[i]]&&(o[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(o[s]=void 0===n?{id:s,type:u}:{},void 0!==n)for(i in n)o[s][i]=n[i];for(i in f)i!==s&&delete o[i];return this},this.has=function(e){return!!o[e]},this.get=function(e){return null===e||void 0===e?String(e):t[Object.prototype.toString.call(e)]||"object"},this.check=function(e,t,r){var i=n(e,t);if(r&&i)throw i;return!i},this.isValid=function(e){var t,n,i;if("string"===this.get(e)){t=e.replace(/^[\?\!]/,"").split(/\|/);for(i in t)if(r.indexOf(t[i])<0&&!(t[i]in o))return!1;return!0}if("object"===this.get(e)){for(n in e)if(!this.isValid(e[n]))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=["*"];!function(){var e,n,i=["Arguments","Boolean","Number","String","Function","Array","Date","RegExp","Object"];for(e in i)n=i[e],r.push(n.toLowerCase()),t["[object "+n+"]"]=n.toLowerCase()}();var n=e;e.call(n),Object.defineProperty(n,"version",{value:"0.3.1"}),"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=n),exports.types=n):"function"==typeof define&&define.amd?define("typology",[],function(){return n}):this.types=n}(this);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc