Flexible data validation using a ducktype interface. For JavaScript and Node.js.
APACHE-2.0 License
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. Ducktype 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 = ducktype({
id: ducktype(Number, {integer: true, min: 0}),
name: String,
address: {
city: String,
street: String,
}
});
function save (contact) {
contactType.validate(contact);
// ... save contact
}
npm install ducktype
bower install ducktype
var ducktype = require('ducktype');
<!DOCTYPE HTML>
<html>
<head>
<script src="ducktype.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
// use ducktype...
</script>
</body>
</html>
// use built-in types
ducktype.number.test(2.3); // true
ducktype.number.test('hi'); // false
ducktype.number.test(true); // false
ducktype.date.test(new Date()); // true
ducktype.date.test(2.3); // false
ducktype.string.test('hello'); // true
// create a ducktype
var type = ducktype(Number);
type.test(2.3); // true
type.test('hi'); // false
type.test(true); // false
// create a ducktype with options
var nullableString = ducktype(String, {nullable: true});
nullableString.test('string'); // true
nullableString.test(null); // true
nullableString.test(2.3); // false
// combination of types
var combi = ducktype(Number, String);
combi.test(2.3); // true
combi.test('hi'); // true
combi.test(true); // false
// structured object
var person = ducktype({
name: String,
age: Number,
address: {
city: String,
street: String,
country: String
},
email: ducktype(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
var numberArray = ducktype([Number]);
numberArray.test([1, 2, 3]); // true
numberArray.test([1, 'string', 3]); // false
// structured object and array
var family = ducktype({
name: String,
age: ducktype(Number, {optional: true}),
children: [
{
name: String,
age: ducktype(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
var type = ducktype([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 ducktype wrapper can be created which validates the function arguments against the ducktype:
var add = ducktype([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
A ducktype can be constructed as:
ducktype(type)
ducktype(type, options)
ducktype(type1, type2, ...)
ducktype(type1, type2, ..., options)
Where:
type
can be:
Array
, Boolean
, Date
, Function
, Number
,Object
, RegExp
, String
, null
, undefined
.ducktype(Array)
.ducktype([Number]).test(1, 2, 3)
.ducktype([Number, String]).test(2, 'str')
.options
is an object which can contain properties:
name
optional
nullable
integer
. Test whether a number has an integer value.min
. Test whether a number is larger or equal to a minimummax
. Test whether a number is smaller or equal to a maximumA created ducktype has functions:
test(object)
. A function which returns true when provided object matchesvalidate(object)
. A function which will throw a TypeError when the providedwrap(fn)
. Creates a wrapper function around the provided function, whichDucktype comes with a set of built-in types:
ducktype.array
ducktype.boolean
ducktype.date
ducktype.email
ducktype.integer
ducktype.function
ducktype.number
ducktype.object
ducktype.regexp
ducktype.string
ducktype.null
ducktype.undefined
ducktype.url
The built-in types can be used as:
ducktype.number.test(2.3); // true
ducktype.string.test(2.3); // false
To execute tests for the library, run:
npm test
Copyright (C) 2013-2020 Jos de Jong [email protected]
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.