mighty-duck v1.1.1
Mightyduck
This is a fork of Jos de Jong's Ducktype.
Installation
npm install --save mighty-duck
Flexible data validation using a duck type interface for JavaScript and Node.js.
As JavaScript is a loosely typed language, any variable can contain any type of data, and any type of data can be passed as arguments to any function. When dealing with data inputs coming from external sources, there is a need to validate the type and contents of the data. Mightyduck offers an easy way to validate both basic data types as well as complex structured data types in a flexible way.
Replace this kind of type checking mess:
function save (contact) {
if (contact && isInteger(contact.id) && (contact.id > 0) && isString(contact.name) &&
contact.address && isString(contact.address.city) && isString(contact.address.street)) {
// ... save contact
}
else {
throw new Error('Invalid contact');
}
}
with this:
var contactType = mightyduck({
id: mightyduck(Number, {integer: true, min: 0}),
name: String,
address: {
city: String,
street: String,
}
});
function save (contact) {
contactType.validate(contact);
// ... save contact
}
Install
npm
npm install mighty-duck
bower
bower install mighty-duck
Load
Node.js
var mightyDuck = require('mighty-duck');
browser
<!DOCTYPE HTML>
<html>
<head>
<script src="mightyduck.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
// use Mightyduck...
</script>
</body>
</html>
Use
Basic types
// use built-in types
mightyDuck.number.test(2.3); // true
mightyDuck.number.test('hi'); // false
mightyDuck.number.test(true); // false
mightyDuck.date.test(new Date()); // true
mightyDuck.date.test(2.3); // false
mightyDuck.string.test('hello'); // true
// create a Mightyduck
var type = mightyDuck(Number);
type.test(2.3); // true
type.test('hi'); // false
type.test(true); // false
// create a Mightyduck with options
var nullableString = Mightyduck(String, {nullable: true});
nullableString.test('string'); // true
nullableString.test(null); // true
nullableString.test(2.3); // false
Combined types
// combination of types
var combi = Mightyduck(Number, String);
combi.test(2.3); // true
combi.test('hi'); // true
combi.test(true); // false
Structured objects
// structured object
var person = Mightyduck({
name: String,
age: Number,
address: {
city: String,
street: String,
country: String
},
email: Mightyduck(String, {optional: true})
});
person.test({
name: 'John',
age: 32,
address: {
city: 'Sunnyvale, CA 95125',
street: '701 First Ave.',
country: 'United States'
}
}); // true
person.test({
name: 'Mary',
age: 26
}); // false
Structured Arrays
// structured arrays
var numberArray = Mightyduck([Number]);
numberArray.test([1, 2, 3]); // true
numberArray.test([1, 'string', 3]); // false
// structured object and array
var family = Mightyduck({
name: String,
age: Mightyduck(Number, {optional: true}),
children: [
{
name: String,
age: Mightyduck(Number, {optional: true})
}
]
});
family.test({
name: 'John',
children: [
{
'name': 'Mary',
'age': 6
},
{
'name': 'Grant'
}
]
}); // true
family.test({
name: 'John',
children: [
{
'firstName': 'Mary',
'age': 6
},
{
'firstName': 'Grant'
}
]
}); // false
Function arguments
var type = mightyDuck([Number, Number]);
function add (a, b) {
type.validate(arguments);
return a + b;
}
var sum = add(2, 3); // ok
var sum = add(2, 'string'); // will throw a TypeError
Alternatively, a Mightyduck wrapper can be created which validates the function arguments against the Mightyduck:
var add = mightyDuck([Number, Number]).wrap(function add (a, b) {
return a + b;
});
var sum = add(2, 3); // ok
var sum = add(2, 'string'); // will throw a TypeError
API
construction
A Mightyduck can be constructed as:
mightyDuck(type)
mightyDuck(type, options)
mightyDuck(type1, type2, ...)
mightyDuck(type1, type2, ..., options)
Where:
type
can be:- A basic type. Choose from
Array
,Boolean
,Date
,Function
,Number
,Object
,RegExp
,String
,null
,undefined
. - Another Mightyduck.
- An object. All properties of the object will be checked. Each property can be a basic type, Mightyduck, object, or array.
- An array.
An array can have zero, one or multiple elements which can be
a basic type, Mightyduck, object, or array.
Providing an array with zero elements will just return a
Mightyduck(Array)
. Providing an array with one element will return a Mightyduck which will test each of tested arrays elements against the given type, for exampleMightyduck([Number]).test(1, 2, 3)
. Providing an array with multiple elements will validate the length of the tested array, and validate each of the array elements one to one against the provided types. This can be used to test the number and type of function arguments. Example:Mightyduck([Number, String]).test(2, 'str')
.
- A basic type. Choose from
options
is an object which can contain properties:- A string
name
- A boolean
optional
- A boolean
nullable
- A boolean
integer
. Test whether a number has an integer value. Only applicable for Numbers. - A number
min
. Test whether a number is larger or equal to a minimum value. Only applicable for Numbers. - A number
max
. Test whether a number is smaller or equal to a maximum value. Only applicable for Numbers.
- A string
A created Mightyduck has functions:
test(object)
. A function which returns true when provided object matches the Mightyduck, and false otherwise.validate(object)
. A function which will throw a TypeError when the provided object does not match the Mightyduck.wrap(fn)
. Creates a wrapper function around the provided function, which validates the function arguments against the Mightyduck. Only applicable for Mightyducks containing an array, as the Mightyduck is tested against an array with the function arguments.
Built-in types
Mightyduck comes with a set of built-in types:
mightyDuck.array
mightyDuck.boolean
mightyDuck.date
mightyDuck.email
mightyDuck.integer
mightyDuck.function
mightyDuck.number
mightyDuck.object
mightyDuck.regexp
mightyDuck.string
mightyDuck.url
The built-in types can be used as:
mightyDuck.number.test(2.3); // true
mightyDuck.string.test(2.3); // false
Test
To execute tests for the library, run:
npm test
Roadmap
- Implement more options for specific types:
- Number: finite, odd, even, positive, negative, nan, ...
- String: lowercase, uppercase, alpha, alphanumeric, empty, ...
- Array: length, length.min, length.max, ...
- Implement non-strict type checking: when an object can be converted to the desired type, it is ok. For example a string containing a numeric value can be considered a valid Number, or a string containing an ISO date can be considered a valid Date.
License
Copyright (C) 2018 José Muñoz jdmg93+npm@gmail.com
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.