divhide-core
Javascript codebase to use on the Browser, NodeJS and other javascript platforms. This provides a set of utilities that you can use everywhere.
Install
npm install divhide
var Divhide = require("divhide");
...
bower install divhide
<script type="text/javascript" src="//bower_components/divhide/dist/divhide.js"></script>
<script type="text/javascript">
var fn = Divhide.Safe.function();
...
</script>
API
Type
Type facility provides an API that can help you with typical operations using the javascript
data Types.
var Type = Divhide.Type;
var type = Type.of({});
expect(type).toBe("object");
var type = Type.of([]);
expect(type).toBe("array");
var type = Type.of(1);
expect(type).toBe("number");
var type = Type.of("name");
expect(type).toBe("string");
var type = Type.of(true);
expect(type).toBe("boolean");
var isArray = Type.isArray([]);
expect(isArray).toBe(true);
var isBoolean = Type.isBoolean(true);
expect(isBoolean).toBe(true);
var isFunction = Type.isFunction(function(){});
expect(isFunction).toBe(true);
var isString = Type.isString("");
expect(isString).toBe(true);
var isObject = Type.isObject({});
expect(isObject).toBe(true);
var isObject = Type.isObject(null);
expect(isObject).toBe(false);
var isRegExp = Type.isRegExp(/reg/);
expect(isRegExp).toBe(true);
var isNumber = Type.isNumber(1);
expect(isNumber).toBe(true);
var isNumber = Type.isNumber("1.1");
expect(isNumber).toBe(true);
var isDefined = Type.isDefined(null);
expect(isDefined).toBe(false);
var isDefined = Type.isDefined(undefined);
expect(isDefined).toBe(false);
var isEmpty = Type.isEmpty("");
expect(isEmpty).toBe(true);
var isEmpty = Type.isEmpty([]);
expect(isEmpty).toBe(true);
var isEmpty = Type.isEmpty({});
expect(isEmpty).toBe(true);
var isEmpty = Type.isEmpty(null);
expect(isEmpty).toBe(true);
Safe
Safe facility provides an API that can helps you safelly working with javascript data types.
var Safe = Divhide.Safe;
var value = Safe.array(1);
expect(value)
.equals([1]);
var value = Safe.array(1);
expect(value)
.equals([1]);
var value = Safe.array([1, 2]);
expect(value)
.equals([1, 2]);
var value = Safe.array(null, [ 1, 2 ]);
expect(value)
.equals([1, 2]);
var value = Safe.array("1", [1, 2]);
expect(value)
.equals(["1"]);
var Safe = Divhide.Safe;
var value = Safe.boolean(true);
expect(value).toBe(true);
var value = Safe.boolean(false);
expect(value).toBe(false);
var value = Safe.boolean(1);
expect(value).toBe(true);
var value = Safe.boolean("1");
expect(value).toBe(true);
var value = Safe.boolean("0");
expect(value).toBe(false);
var value = Safe.boolean({});
expect(value).toBe(false);
var value = Safe.boolean({}, true);
expect(value).toBe(true);
var value = Safe.boolean([]);
expect(value).toBe(false);
var value = Safe.boolean(null);
expect(value).toBe(false);
var Safe = Divhide.Safe;
var fn = Safe.function(function(){});
expect(fn())
.toBe(undefined);
var fn = Safe.function("");
expect(fn())
.toBe(undefined);
var fn = Safe.function("", function(){ return 1; });
expect(fn())
.toBe(1);
var Safe = Divhide.Safe;
var value = Safe.length([1, 2]);
expect(value).toBe(2);
var value = Safe.length({ one: 1, two: 2});
expect(value).toBe(2);
var value = Safe.length(2);
expect(value).toBe(2);
var value = Safe.length("hello");
expect(value).toBe(5);
var Safe = Divhide.Safe;
var value = Safe.number(1);
expect(value).equals(1);
var value = Safe.number("");
expect(value).equals(0);
var value = Safe.number("1");
expect(value).equals(1);
var value = Safe.number({});
expect(value).equals(0);
var value = Safe.number("", 1);
expect(value).equals(1);
var Safe = Divhide.Safe;
var value = Safe.object({ one: 1 });
expect(value).equals({ one: 1 });
var value = Safe.object([]);
expect(value).equals({});
var value = Safe.object([], { one: 1 });
expect(value).equals({ one: 1 });
var Safe = Divhide.Safe;
var value = Safe.regexp(/regexp/);
expect(value)
.toEqual(/regexp/);
var value = Safe.regexp("/regexp/");
expect(value)
.toEqual(/regexp/);
var value = Safe.regexp("");
expect(value)
.toEqual(/^$/);
var value = Safe.regexp("name");
expect(value)
.toEqual(/^name$/);
var value = Safe.regexp({}, /regexp/);
expect(value)
.toEqual(/regexp/);
var Safe = Divhide.Safe;
var value = Safe.string("");
expect(value).toBe("");
var value = Safe.string({});
expect(value).toBe("");
var value = Safe.string({}, "default");
expect(value).toBe("default");
var Safe = Divhide.Safe;
var value = Safe.value(1);
expect(value).toBe(1);
var value = Safe.value("1");
expect(value).toBe("1");
var value = Safe.value(null);
expect(value).toBe(null);
var value = Safe.value(undefined);
expect(value).toBe(null);
var value = Safe.value(null, 1);
expect(value).toBe(1);
Obj
Object facility provides some utility function to use on Objects.
var Obj = Divhide.Obj;
var results = Obj.filter({ "one": 1, "two": 2 });
expect(results)
.toEqual(["one", "two"]);
var results = Obj.filter({ "one": 1, "two": 2 }, "one");
expect(results)
.toEqual(["one"]);
var results = Obj.filter({ "one": 1, "two": 2 }, "three");
expect(results)
.toEqual([]);
Arr
Array facility provides an API to easily manage array references.
var Arr = Divhide.Arr;
var value = Arr.index([1 ,2, 3], 0);
expect(value).toBe(1);
var value = Arr.index([1 ,2, 3], 10);
expect(value).toBeNull();
var first = Arr.first([1 ,2, 3]);
expect(first).toBe(first);
var last = Arr.last([1 ,2, 3]);
expect(last).toBe(3);
var length = Arr.length([1 ,2, 3]);
expect(last).toBe(3);
var array = [1, 2, 3];
Arr.insert(array, 4);
expect(array).toEqual([1, 2, 3, 4]);
var array = Arr.insert([1 ,2, 3], [4, 5]);
expect(array).toEqual([1, 2, 3, 4, 5]);
var array = Arr.insert([1 ,2, 3], -1, 0);
expect(array).toEqual([-1, 1, 2, 3]);
var array = [1, 2, 3];
Arr.remove(array, 0);
expect(array).toEqual([2, 3]);
var array = [1, 2, 3];
Arr.remove(array, 0, 2);
expect(array).toEqual([3]);
I18N
Internationalization package. This package provides you with some utilities that will help you
on your internationalization tasks.
There's no intention for this library to contain translations for other languages.
I18NString
The I18NString is a String representation that can be translation. This string can be a plain String or
a lodash template that can be binded to some data.
When getting the result a translation dictionary can be provided. If the string/template exists on the
translation dictionary the translation is returned.
This implementation creates a clear separation between the translation mechanism and it's internal logic.
Exception
The Exception package provides you with some utilities created in order to
normalize the Error handling.
All the Exceptions classes inherit from Error. This means that you can throw
Errors with these!
Exception
The Exception class inherits from Error. This class is integrated with I18N package.
var Exception = Divhide.Exception.Exception;
var Portuguese = {
"The maximum value allowed is <%= value %>.": "Valor máximo é <%= value %>."
};
var error = new Exception(
"The maximum value allowed is <%= value %>.",
{ value: 10 });
expect(error instanceof Error).equals(true);
expect(error.toString())
.equals("The maximum value allowed is 10.");
expect(error.toString(Portuguese))
.equals("Valor máximo é 10.");
ExceptionList
The ExceptionList is also an instance of Error. This allows you to create an Exception that contains
multiple sub Exceptions.
var Exception = Divhide.Exception.Exception,
ExceptionList = Divhide.Exception.ExceptionList;
var errors = new ExceptionList();
expect(errors instanceof Error).toEqual(true);
errors.push( new Exception("Error1") );
errors.push( new Exception("Error2") );
errors.push( new Exception("Error3") );
expect(errors.length).toEqual(3);
expect(errors.items[0].toString())
.toEqual("Error1");
Chain
Chain facility provides an API to create chainable functions. Each Chain is created by a list of chainable functions, a list of evaluation
function and some options.
var Chain = Divhide.Chain;
var Maths = new Chain(
{
sum: function(i,j){
return i + j;
},
sub: function(i, j){
return i - j;
}
},
{
calculate: function(result, err){
return result;
}
},
{
pipe: true
});
var value = Maths.sum(5)
.sub(3)
.sum(10)
.calculate(0);
expect(value)
.toBe(12);
Chainable functions are functions which can be chained. Each function can have as many arguments as you want but the first arguments will be
injected by the evalutaion function or the previous executed function ( if pipe: true is defined on options ).
A Evaluation function will execute the list of chainable functions previous defined. This function receives as argument the result of the
chain execution and the if exists the execution error. The evaluation function can have several parameters; the ''err'' parameter is injected
in the end.
The specified functions share the same scope. This means that you can share values between execution by using the function context.
Assert
Assert facility provides an API to build expressions that can be evaluated with
.isValid() and .assert().
var Assert = Divhide.Assert;
var isValid = Assert
.required()
.string()
.regex("^M")
.max(10)
.min(5)
.isValid("Mary");
expect(isValid)
.toBe(false);
var obj = Assert
.required()
.array()
.max(5)
.assert([1, 2, 4, 5]);
expect(obj)
.equals([1, 2, 4, 5]);
var fn = function(){
Assert.required()
.array()
.max(1)
.assert(["first", "second"]);
};
expect(fn)
.toThrow();
The following methods are provided by default.
given value.
.required()
.string()
.array()
.object()
.number()
.max(10)
.min(5)
.regex("^M")
Assertion
Assertion facility provides a way to build custom Asserts. You can create your own assertion functions
and integrate them with the Assert facility.
var Assertion = Divhide.Assertion;
var Assert = new Assertion({
startsWith: function(val, str){
if(val.indexOf(str) !== 0){
throw new Error("Does not starts with " + str);
}
}
});
var isValid = Assert
.required()
.string()
.startsWith("Mary")
.isValid("Mary and Peter");
expect(isValid)
.toBe(true)
var value = Assert
.required()
.string()
.startsWith("Mary")
.assert("Mary and Peter");
expect(value)
.equals("Mary and Peter");
Schema
The Schema facility provide an easy way to write validation rules. Using a chainable API you can
compile and/or evaluate the rules.
Overview
var Schema = Divhide.Schema;
var schema = Schema.object({
data: Schema.array([ "" ]).repeatable().max(10),
"/.*/": Schema.string().optional()
}).required();
var value = schema.value(
{
data: [ 1, 2, 3, 4, 5 , 6],
timestamp: "1404373579473"
});
expect(value).equals(
{
data: [ '1', '2', '3', '4', '5' , '6'],
timestamp: "1404373579473"
});
Schema chainable API:
.any()
Set the expected type as any object.
.string()
Set the expected type as a string
.number()
Set the expected type as a number
.object(value)
Set the expected type as an object. The value is an object with rules.
.array(value)
Set the expected type as an object. The value is an array with rules.
.required()
Set as required. By default every rule is required!
.optional()
Set as optional
.default(value)
Set the default value. This is used when the schema its required and the provided value is null.
.repeatable()
Set the type as repeatable. This repeats the schema through the structure (array only!).
.min(value)
Set the min value expected. If in number context the value is used. If in string context the length is used.
If in array context the length is used. If in object context the number of keys is used.
.max(value)
Set the max value expected. If in number context the value is used. If in string context the length is used.
If in array context the length is used. If in object context the number of keys is used.
.regex(value)
Sets a regexp condition ( only use on string context! )
Schema evaluation API:
.compile()
Compiles the schema. If you are using the same Schema multiple time you can compile it for performance reasons.
This avoid compiling the Schema before every usage.
.value(value)
Test the schema returning the normalized value if valid. Throws an Error if invalid.
.isValid(value)
Test the schema return if its valid or not.
.errors(value)
Test the schema returning an Array with the errors
Example 1: String Schema
var Schema = Divhide.Schema;
var schema = Schema.string()
.required()
.min(3)
.max(5);
var value = schema.value("hello");
expect(value).toBe("hello");
expect(
function(){
schema.value();
})
.toThrow(new Error("Value is required."));
expect(
function(){
schema.value("hello world");
})
.toThrow(new Error("The maximum value allowed is 5."));
var isValid = schema.isValid("");
expect(isValid).toBe(false);
var isValid = schema.isValid("hello");
expect(isValid).toBe(true);
var isValid = schema.isValid("hello world");
expect(isValid).toBe(false);
Time to see some code! Some usage examples are described below.
Example 2: Number Schema
var Schema = Divhide.Schema;
var schema = Schema.number()
.optional()
.min(3)
.max(5)
.compile();
var value = schema.value(3);
expect(value).toBe(3)
var value = schema.value();
expect(value).equals(null);
expect(
function(){
schema.value(0);
})
.toThrow(
new Error("The minimum value allowed is 3.")
);
expect(
function(){
schema.value(10);
})
.toThrow(
new Error("The maximum value allowed is 5.")
);
var isValid = schema.isValid();
expect(isValid).toBe(true);
isValid = schema.isValid(3);
expect(isValid).toBe(true);
isValid = schema.isValid(10);
expect(isValid).toBe(false);
Example 3: Any Schema
var Schema = Divhide.Schema;
var schema = Schema
.any()
.required()
.compile();
var value = schema.value("str");
expect(value).equals(value);
value = schema.value([1,2]);
expect(value).equals([1,2]);
expect(
function(){
schema.value(null);
})
.toThrow(
new Error("Value is required.")
);
Example 4: Object Schema
Objects schema is set by applying rules to each property of the object. You can also use regular expressions on
the schema object keys to give better filtering.
You can also set the schema object keys to primitive values which will be interpreted as required().default(value)
in the schema.
var Schema = Divhide.Schema;
var schema =
Schema.object({
"/^optional/" : Schema.string().optional(),
"number" : 0,
"string" : "",
})
.required()
.compile();
var value = schema.value({
string : "awesome!",
number : "0",
optional1 : "1",
optional2 : "2",
other : 1
});
expect(value).equals({
"number": 0,
"string": "awesome!",
"optional1": "1",
"optional2": "2"
});
Example 5: Array Schema
The following example describe an array rule that is optional and its expecting three items.
var Schema = Divhide.Schema;
var schema = Schema
.array([ Schema.string().default("value"), Schema.number(), Schema.string() ])
.optional()
.compile();
var value = schema.value();
expect(value).toBe(null);
value = schema.value([ '1', 2, '3' ]);
expect(value).equals([ '1', 2, '3']);
expect(
function(){
schema.value([ '1', 2, '3', 4, 5, 6 ])
})
.toThrow(
new Error("Expected list with 3 items but found 6.")
);
expect(
function(){
schema.value(10);
})
.toThrow(
new Error("'array' was expected but found 'number' instead.")
);
var schema = Schema
.array([ Schema.string(), Schema.number() ])
.repeatable()
.optional()
.compile();
var value = schema.value(["1", 2, "3", 4]);
expect(value).equals(["1", 2, "3", 4]);
expect(
function(){
schema.value(["1", 2, "3"])
})
.toThrow(
new Error("Expected list length to be multiple of 2 but found length of 3.")
);
Contribute
Testing
The purpose of the project is to provide a library that can be used across every platform that uses javascript. The tests are done using jasmine and using the browser to debug. Every file save on the "src" folder will recompile
the browserify bundle.
grunt dev
Build
The build process will run a set of tasks including linting and testing. To contribute please add
tests to the fix/feature you've worked.
Also, when building the documention is compiled into the README.md. Each module iniside the "src" directory
should contain a ".md" file to document it's behaviour.
The following command will run the build.
grunt
Release
grunt release
grunt minor-release
Authors
Oscar Brito
License
Copyright (c) 2014 Oscar Brito aetheon@gmail.com, contributors.
Released under the license