Socket
Socket
Sign inDemoInstall

tcomb

Package Overview
Dependencies
Maintainers
1
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tcomb - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

13

CHANGELOG.md

@@ -0,1 +1,14 @@

# v0.3.0
- added `Struct.extend(props, [name])`, fix #55
- added built-in immutable updates, fix #31
**BREAKING**
- change `dict(B)` combinator to `dict(A, B)` where A is the set of keys, fix #54
- removed `util.isKind`
- removed `util.isType`, use `Type.is` instead
- refactoring of `func`. Now is a proper type combinator. fix #42
- removed `options.update`
# v0.2.1

@@ -2,0 +15,0 @@

463

index.js

@@ -30,6 +30,5 @@ (function (root, factory) {

}
var options = {
onFail: onFail,
update: null
onFail: onFail
};

@@ -81,3 +80,3 @@

function merge() {
return Array.prototype.reduce.call(arguments, function (x, y) {
return Array.prototype.reduce.call(arguments, function reducer(x, y) {
return mixin(x, y, true);

@@ -120,41 +119,145 @@ }, {});

function isType(type) {
return Func.is(type) && Obj.is(type.meta);
}
function getName(type) {
assert(isType(type), 'Invalid argument `type` of value `%j` supplied to `getName()`, expected a type.', type);
assert(Type.is(type), 'Invalid argument `type` of value `%j` supplied to `getName()`, expected a type.', type);
return type.meta.name;
}
function deprecated(message) {
if (console && console.warn) {
console.warn(message);
}
}
function getKind(type) {
assert(isType(type), 'Invalid argument `type` of value `%j` supplied to `geKind()`, expected a type.', type);
assert(Type.is(type), 'Invalid argument `type` of value `%j` supplied to `geKind()`, expected a type.', type);
return type.meta.kind;
}
function isKind(type, kind) {
deprecated('`isKind(type, kind)` is deprecated, use `getKind(type) === kind` instead');
return getKind(type) === kind;
}
function blockNew(x, type) {
// DEBUG HINT: since in tcomb the only real constructors are those provided
// by `struct`, the `new` operator is forbidden for all types
assert(!(x instanceof type), 'Operator `new` is forbidden for `%s`', getName(type));
}
function update() {
assert(Func.is(options.update), 'Missing `options.update` implementation');
/*jshint validthis:true*/
var T = this;
var value = options.update.apply(T, arguments);
return T(value);
/*
function namespace(path, module) {
if (!Arr.is(path)) {
path = path.split('.');
}
var lastIndex = path.length - 1;
var init = {};
var isModule = arguments.length > 1;
path.reduce(function reducer(acc, x, i) {
return (acc[x] = isModule && i === lastIndex ? module : {});
}, init);
return init;
}
function update(instance, spec, value) {
if (!spec) { return instance; }
// handle update(instance, path, value)
if (Str.is(spec)) {
return update(instance, namespace(spec, {$set: value}));
}
value = shallowCopy(instance);
for (var k in spec) {
if (spec.hasOwnProperty(k)) {
var s = spec[k];
switch (k) {
case '$apply' :
return s(instance);
case '$concat' :
// TODO optimize
return value.concat(s);
case '$set' :
return spec[k];
case '$splice' :
value.splice.apply(value, s);
return value;
case '$swap' :
var el = value[s.to];
value[s.to] = value[s.from];
value[s.from] = el;
return value;
case '$remove' :
return update._;
case '$prepend' :
// TODO optimize
return [].concat(s).concat(value);
}
value[k] = update(value[k], s);
if (value[k] === update._) {
delete value[k];
}
}
}
return value;
}
update._ = {};
*/
function shallowCopy(x) {
return Arr.is(x) ? x.concat() : Obj.is(x) ? mixin({}, x) : x;
}
function update(instance, spec) {
assert(!Nil.is(instance));
assert(Obj.is(spec));
var value = shallowCopy(instance);
for (var k in spec) {
if (spec.hasOwnProperty(k)) {
if (update.commands.hasOwnProperty(k)) {
assert(Object.keys(spec).length === 1);
return update.commands[k](spec[k], value);
} else {
value[k] = update(value[k], spec[k]);
}
}
}
return value;
}
update.commands = {
'$apply': function (f, value) {
assert(Func.is(f));
return f(value);
},
'$push': function (elements, arr) {
assert(Arr.is(elements));
assert(Arr.is(arr));
return arr.concat(elements);
},
'$remove': function (keys, obj) {
assert(Arr.is(keys));
assert(Obj.is(obj));
for (var i = 0, len = keys.length ; i < len ; i++ ) {
delete obj[keys[i]];
}
return obj;
},
'$set': function (value) {
return value;
},
'$splice': function (splices, arr) {
assert(list(Arr).is(splices));
assert(Arr.is(arr));
return splices.reduce(function (acc, splice) {
acc.splice.apply(acc, splice);
return acc;
}, arr);
},
'$swap': function (config, arr) {
assert(Obj.is(config));
assert(Num.is(config.from));
assert(Num.is(config.to));
assert(Arr.is(arr));
var element = arr[config.to];
arr[config.to] = arr[config.from];
arr[config.from] = element;
return arr;
},
'$unshift': function (elements, arr) {
assert(Arr.is(elements));
assert(Arr.is(arr));
return elements.concat(arr);
}
};
//

@@ -194,47 +297,49 @@ // irriducibles

var Any = irriducible('Any', function () {
var Any = irriducible('Any', function isAny() {
return true;
});
var Nil = irriducible('Nil', function (x) {
return x === null || x === undefined;
var Nil = irriducible('Nil', function isNil(x) {
return x === null || x === void 0;
});
var Str = irriducible('Str', function (x) {
var Str = irriducible('Str', function isStr(x) {
return typeof x === 'string';
});
var Num = irriducible('Num', function (x) {
var Num = irriducible('Num', function isNum(x) {
return typeof x === 'number' && isFinite(x) && !isNaN(x);
});
var Bool = irriducible('Bool', function (x) {
var Bool = irriducible('Bool', function isBool(x) {
return x === true || x === false;
});
var Arr = irriducible('Arr', function (x) {
var Arr = irriducible('Arr', function isArr(x) {
return x instanceof Array;
});
var Obj = irriducible('Obj', function (x) {
var Obj = irriducible('Obj', function isObj(x) {
return !Nil.is(x) && typeof x === 'object' && !Arr.is(x);
});
var Func = irriducible('Func', function (x) {
var Func = irriducible('Func', function isFunc(x) {
return typeof x === 'function';
});
var Err = irriducible('Err', function (x) {
var Err = irriducible('Err', function isErr(x) {
return x instanceof Error;
});
var Re = irriducible('Re', function (x) {
var Re = irriducible('Re', function isRe(x) {
return x instanceof RegExp;
});
var Dat = irriducible('Dat', function (x) {
var Dat = irriducible('Dat', function isDat(x) {
return x instanceof Date;
});
var Type = irriducible('Type', isType);
var Type = irriducible('Type', function isType(x) {
return Func.is(x) && Obj.is(x.meta);
});

@@ -245,3 +350,3 @@ function struct(props, name) {

// mouse over the `props` variable to see what's wrong
assert(dict(Type).is(props), 'Invalid argument `props` supplied to `struct()`');
assert(dict(Str, Type).is(props), 'Invalid argument `props` supplied to `struct()`');

@@ -281,3 +386,3 @@ // DEBUG HINT: if the debugger stops here, the second argument is not a string

if (!mut) {
if (mut !== true) {
Object.freeze(this);

@@ -293,8 +398,14 @@ }

Struct.is = function (x) {
Struct.is = function isStruct(x) {
return x instanceof Struct;
};
Struct.update = update;
Struct.update = function updateStruct(instance, spec, value) {
return new Struct(update(instance, spec, value));
};
Struct.extend = function extendStruct(newProps, name) {
return struct(mixin(mixin({}, props), newProps), name);
};
return Struct;

@@ -330,3 +441,3 @@ }

// DEBUG HINT: if the debugger stops here, the `dispatch` static method returns no type
assert(isType(type), '%s.dispatch() returns no type', name);
assert(Type.is(type), '%s.dispatch() returns no type', name);

@@ -344,4 +455,4 @@ // DEBUG HINT: if the debugger stops here, `value` can't be converted to `type`

Union.is = function (x) {
return types.some(function (type) {
Union.is = function isUnion(x) {
return types.some(function isType(type) {
return type.is(x);

@@ -352,3 +463,3 @@ });

// default dispatch implementation
Union.dispatch = function (x) {
Union.dispatch = function dispatch(x) {
for (var i = 0, len = types.length ; i < len ; i++ ) {

@@ -367,3 +478,3 @@ if (types[i].is(x)) {

// DEBUG HINT: if the debugger stops here, the first argument is not a type
assert(isType(type), 'Invalid argument `type` supplied to `maybe()`');
assert(Type.is(type), 'Invalid argument `type` supplied to `maybe()`');

@@ -397,3 +508,3 @@ // makes the combinator idempotent

Maybe.is = function (x) {
Maybe.is = function isMaybe(x) {
return Nil.is(x) || type.is(x);

@@ -438,3 +549,3 @@ };

Enums.is = function (x) {
Enums.is = function isEnums(x) {
return Str.is(x) && map.hasOwnProperty(x);

@@ -446,3 +557,3 @@ };

enums.of = function (keys, name) {
enums.of = function enumsOf(keys, name) {
keys = Str.is(keys) ? keys.split(' ') : keys;

@@ -463,5 +574,2 @@ var value = {};

// DEBUG HINT: if the debugger stops here, there are too few types (they must be at least two)
assert(len >= 2, 'Invalid argument `types` supplied to `tuple()`');
// DEBUG HINT: if the debugger stops here, the second argument is not a string

@@ -475,5 +583,2 @@ // mouse over the `name` variable to see what's wrong

// DEBUG HINT: if the debugger stops here, you have used the `new` operator but it's forbidden
blockNew(this, Tuple);
// DEBUG HINT: if the debugger stops here, the value is not one of the defined enums

@@ -497,3 +602,3 @@ // mouse over the `value`, `name` and `len` variables to see what's wrong

if (!mut) {
if (mut !== true) {
Object.freeze(arr);

@@ -507,2 +612,3 @@ }

types: types,
length: len,
name: name

@@ -517,7 +623,9 @@ };

Tuple.is = function (x) {
Tuple.is = function isTuple(x) {
return Arr.is(x) && x.length === len && Tuple.isTuple(x);
};
Tuple.update = update;
Tuple.update = function updateTuple(instance, spec, value) {
return Tuple(update(instance, spec, value));
};

@@ -530,3 +638,3 @@ return Tuple;

// DEBUG HINT: if the debugger stops here, the first argument is not a type
assert(isType(type), 'Invalid argument `type` supplied to `subtype()`');
assert(Type.is(type), 'Invalid argument `type` supplied to `subtype()`');

@@ -567,6 +675,10 @@ // DEBUG HINT: if the debugger stops here, the second argument is not a function

Subtype.is = function (x) {
Subtype.is = function isSubtype(x) {
return type.is(x) && predicate(x);
};
Subtype.update = function updateSubtype(instance, spec, value) {
return Subtype(update(instance, spec, value));
};
return Subtype;

@@ -578,3 +690,3 @@ }

// DEBUG HINT: if the debugger stops here, the first argument is not a type
assert(isType(type), 'Invalid argument `type` supplied to `list()`');
assert(Type.is(type), 'Invalid argument `type` supplied to `list()`');

@@ -591,3 +703,2 @@ // DEBUG HINT: if the debugger stops here, the third argument is not a string

// DEBUG HINT: if the debugger stops here, you have used the `new` operator but it's forbidden
blockNew(this, List);

@@ -611,3 +722,3 @@ // DEBUG HINT: if the debugger stops here, the value is not one of the defined enums

if (!mut) {
if (mut !== true) {
Object.freeze(arr);

@@ -628,16 +739,20 @@ }

List.is = function (x) {
List.is = function isList(x) {
return Arr.is(x) && List.isList(x);
};
List.update = function updateList(instance, spec, value) {
return List(update(instance, spec, value));
};
List.update = update;
return List;
}
function dict(type, name) {
function dict(domain, codomain, name) {
// DEBUG HINT: if the debugger stops here, the first argument is not a type
assert(isType(type), 'Invalid argument `type` supplied to `dict()`');
assert(Type.is(domain), 'Invalid argument `domain` supplied to `dict()`');
// DEBUG HINT: if the debugger stops here, the second argument is not a type
assert(Type.is(codomain), 'Invalid argument `codomain` supplied to `dict()`');

@@ -649,10 +764,7 @@ // DEBUG HINT: if the debugger stops here, the third argument is not a string

// DEBUG HINT: always give a name to a type, the debug will be easier
name = name || format('dict(%s)', getName(type));
name = name || format('dict(%s, %s)', getName(domain), getName(codomain));
function Dict(value, mut) {
// DEBUG HINT: if the debugger stops here, you have used the `new` operator but it's forbidden
blockNew(this, Dict);
// DEBUG HINT: if the debugger stops here, the value is not one of the defined enums
// DEBUG HINT: if the debugger stops here, the value is not an object
// mouse over the `value` and `name` variables to see what's wrong

@@ -669,10 +781,13 @@ assert(Obj.is(value), 'Invalid `%s` supplied to `%s`, expected an `Obj`', value, name);

if (value.hasOwnProperty(k)) {
// DEBUG HINT: if the debugger stops here, the `k` value supplied to the `domain` type is invalid
// mouse over the `k` and `domain` variables to see what's wrong
k = domain(k);
var actual = value[k];
// DEBUG HINT: if the debugger stops here, the `actual` value supplied to the `type` type is invalid
// mouse over the `actual` and `type` variables to see what's wrong
obj[k] = type(actual, mut);
// DEBUG HINT: if the debugger stops here, the `actual` value supplied to the `codomain` type is invalid
// mouse over the `actual` and `codomain` variables to see what's wrong
obj[k] = codomain(actual, mut);
}
}
if (!mut) {
if (mut !== true) {
Object.freeze(obj);

@@ -685,3 +800,4 @@ }

kind: 'dict',
type: type,
domain: domain,
codomain: codomain,
name: name

@@ -692,4 +808,4 @@ };

for (var k in x) {
if (x.hasOwnProperty(k) && !type.is(x[k])) {
return false;
if (x.hasOwnProperty(k)) {
if (!domain.is(k) || !codomain.is(x[k])) { return false; }
}

@@ -700,3 +816,3 @@ }

Dict.is = function (x) {
Dict.is = function isDict(x) {
return Obj.is(x) && Dict.isDict(x);

@@ -706,3 +822,5 @@ };

Dict.update = update;
Dict.update = function updateDict(instance, spec, value) {
return Dict(update(instance, spec, value));
};

@@ -712,96 +830,108 @@ return Dict;

function func(Arguments, f, Return, name) {
name = name || 'func()';
Arguments = Arr.is(Arguments) ? tuple(Arguments, 'Arguments') : Arguments;
function func(domain, codomain, name) {
// DEBUG HINT: if the debugger stops here, the first argument is not a type
assert(isType(Arguments), 'Invalid argument `Arguments` supplied to `func()`');
// handle handy syntax for unary functions
domain = Arr.is(domain) ? domain : [domain];
// DEBUG HINT: if the debugger stops here, the second argument is not a function
assert(Func.is(f), 'Invalid argument `f` supplied to `func()`');
// DEBUG HINT: if the debugger stops here, the first argument is not a list of types
assert(list(Type).is(domain), 'Invalid argument `domain` supplied to `func()`');
// DEBUG HINT: if the debugger stops here, the third argument is not a type (or Nil)
assert(Nil.is(Return) || isType(Return), 'Invalid argument `Return` supplied to `func()`');
// DEBUG HINT: if the debugger stops here, the second argument is not a type
assert(Type.is(codomain), 'Invalid argument `codomain` supplied to `func()`');
// DEBUG HINT: if the debugger stops here, the third argument is not a string
// mouse over the `name` variable to see what's wrong
assert(maybe(Str).is(name), 'Invalid argument `name` supplied to `func()`');
// DEBUG HINT: always give a name to a type, the debug will be easier
name = name || format('func([%s], %s)', domain.map(getName).join(', '), getName(codomain));
// DEBUG HINT: always give a name to a type, the debug will be easier
name = name || f.name || 'func';
// makes the combinator idempotent
Return = Return || null;
if (isType(f) && f.meta.Arguments === Arguments && f.meta.Return === Return) {
return f;
}
function fn() {
var args = slice.call(arguments);
// handle optional arguments
if (args.length < f.length) {
args.length = f.length;
// cache the domain length
var domainLen = domain.length;
function Func(value) {
// automatically instrument the function if is not already instrumented
if (!func.is(value)) {
value = Func.of(value);
}
// DEBUG HINT: if the debugger stops here, the arguments of the function are invalid
// mouse over the `args` variable to see what's wrong
args = Arguments(args);
/*jshint validthis: true */
var r = f.apply(this, args);
if (Return) {
// DEBUG HINT: if the debugger stops here, the return value of the function is invalid
// mouse over the `r` variable to see what's wrong
r = Return(r);
}
return r;
// DEBUG HINT: if the debugger stops here, the first argument is invalid
// mouse over the `value` and `name` variables to see what's wrong
assert(Func.is(value), 'Invalid `%s` supplied to `%s`', value, name);
return value;
}
fn.is = function (x) {
return x === fn;
};
fn.meta = {
Func.meta = {
kind: 'func',
Arguments: Arguments,
f: f,
Return: Return,
domain: domain,
codomain: codomain,
name: name
};
return fn;
}
function alias(type, name) {
Func.is = function isFunc(x) {
return func.is(x) &&
x.func.domain.length === domain.length &&
x.func.domain.every(function (type, i) {
return type === domain[i];
}) &&
x.func.codomain === codomain;
};
// DEBUG HINT: if the debugger stops here, the first argument is not a type
assert(isType(type), 'Invalid argument `type` supplied to `alias()`');
// DEBUG HINT: if the debugger stops here, the third argument is not a string
// mouse over the `name` variable to see what's wrong
assert(maybe(Str).is(name), 'Invalid argument `name` supplied to `alias()`');
Func.of = function funcOf(f) {
// DEBUG HINT: always give a name to a type, the debug will be easier
name = name || 'alias(' + getName(type) + ')';
// DEBUG HINT: if the debugger stops here, f is not a function
assert(typeof f === 'function');
function Alias(value, mut) {
return type(value, mut);
}
// makes Func.of idempotent
if (Func.is(f)) {
return f;
}
Alias.is = function (x) {
return type.is(x);
function fn() {
var args = slice.call(arguments);
var len = Math.min(args.length, domainLen);
// DEBUG HINT: if the debugger stops here, you provided wrong arguments to the function
// mouse over the `args` variable to see what's wrong
args = tuple(domain.slice(0, len))(args);
if (len === domainLen) {
/* jshint validthis: true */
var r = f.apply(this, args);
// DEBUG HINT: if the debugger stops here, the return value of the function is invalid
// mouse over the `r` variable to see what's wrong
r = codomain(r);
return r;
} else {
var curried = Function.prototype.bind.apply(f, [this].concat(args));
var newdomain = func(domain.slice(len), codomain);
return newdomain.of(curried);
}
}
fn.func = {
domain: domain,
codomain: codomain,
f: f
};
return fn;
};
Alias.meta = type.meta;
Alias.name = name;
return Func;
return Alias;
}
// returns true if x is an instrumented function
func.is = function (f) {
return Func.is(f) && Obj.is(f.func);
};
return {

@@ -813,7 +943,7 @@

format: format,
isType: isType,
getName: getName,
getKind: getKind,
isKind: isKind,
slice: slice
slice: slice,
shallowCopy: shallowCopy,
update: update
},

@@ -847,5 +977,4 @@

dict: dict,
func: func,
alias: alias
func: func
};
}));
{
"name": "tcomb",
"version": "0.2.1",
"version": "0.3.0",
"description": "Pragmatic runtime type checking for JavaScript",
"main": "index.js",
"scripts": {
"cover": "istanbul cover _mocha -- --ui bdd -R dot"
"cover": "istanbul cover _mocha -- --ui bdd -R dot",
"compile-browser-tests": "watchify ./test/test.js -o ./test/browser -v"
},

@@ -9,0 +10,0 @@ "repository": {

@@ -1,9 +0,31 @@

% tcomb
> "Si vis pacem, para bellum" (Vegetius 5th century)
![tcomb logo](http://gcanti.github.io/resources/tcomb/logo.png)
tcomb is a library for Node.js and the browser which allows you to **check the types** of
JavaScript values at runtime with a simple syntax. It's great for **Domain Driven Design**,
for testing and for adding safety to your internal code.
tcomb is a library for Node.js and the browser which allows you to **check the types** of
JavaScript values at runtime with a simple syntax. It's great for **Domain Driven Design**,
for testing and for adding safety to your internal code.
# The Idea
tcomb is based on set theory.
What's a type? In tcomb a type is a function `T` such that
1. `T` has signature `T(value, [mut])` where `value` depends on the nature of `T` and the optional boolean `mut` makes the instance mutable (default `false`)
2. `T` is idempotent: `T(T(value, mut), mut) === T(value, mut)`
3. `T` owns a static function `T.is(x)` returning `true` if `x` is an instance of `T`
**Note**: 2. implies that `T` can be used as a default JSON decoder
# Articles on tcomb
- [JavaScript, Types and Sets Part 1](http://gcanti.github.io/2014/09/29/javascript-types-and-sets.html)
- [JavaScript, Types and Sets Part 2](https://gcanti.github.io/2014/10/07/javascript-types-and-sets-part-II.html)
- [What if your domain model could validate the UI for free?](http://gcanti.github.io/2014/08/12/what-if-your-domain-model-could-validate-the-ui-for-free.html)
- [JSON Deserialization Into An Object Model](http://gcanti.github.io/2014/09/12/json-deserialization-into-an-object-model.html)
- [JSON API Validation In Node.js](http://gcanti.github.io/2014/09/15/json-api-validation-in-node.html)
# Contributors
- [Giulio Canti](https://github.com/gcanti)
- [Becky Conning](https://github.com/beckyconning) 'func' combinator ideas and documentation.
# Contents

@@ -16,7 +38,5 @@

- [Tests](#tests)
- [The Idea](#the-idea)
- [Api](#api)
- [options](#options)
- [options.onFail](#optionsonfail)
- [options.update](#optionsupdate)
- [assert](#assert)

@@ -30,5 +50,5 @@ - [structs](#structs)

- [dicts](#dicts)
- [built-in (immutable) updates](#updates)
- [functions](#functions)
- [sweet.js macros (experimental)](#macros)
- [Articles on tcomb](#articles-on-tcomb)

@@ -42,3 +62,3 @@ # Features

The library provides a built-in `assert` function, if an assert fails the **debugger kicks in**
The library provides a built-in `assert` function, if an assert fails the **debugger kicks in**
so you can inspect the stack and quickly find out what's wrong.

@@ -78,3 +98,3 @@

```javascript
```js
var Product = struct({

@@ -86,5 +106,5 @@ name: Str, // required string

category: Category, // enum, one of [audio, video]
price: union([Num, Price]), // a price (dollars) OR in another currency
price: Price, // a price (dollars) OR in another currency
size: tuple([Num, Num]), // width x height
warranty: dict(Num) // a dictionary country -> covered years
warranty: dict(Str, Num) // a dictionary country -> covered years
});

@@ -95,7 +115,9 @@

});
var Category = enums.of('audio video');
var ForeignPrice = struct({ currency: Str, amount: Num });
var Price = union([Num, ForeignPrice]);
Price.dispatch = function (x) {
return Num.is(x) ? Num : ForeignPrice;
};
var Price = struct({ currency: Str, amount: Num });
// JSON of a product

@@ -122,3 +144,3 @@ var json = {

```javascript
```js
// your code: plain old JavaScript class

@@ -135,3 +157,3 @@ function Point (x, y) {

```javascript
```js
function Point (x, y) {

@@ -161,26 +183,4 @@ assert(Num.is(x));

This library uses a few ES5 methods
This library uses a few ES5 methods, you can use `es5-shim`, `es5-sham` and `json2` to support old browsers
- `Array.forEach()`
- `Array.map()`
- `Array.some()`
- `Array.every()`
- `Object.keys()`
- `Object.freeze()`
- `JSON.stringify()`
you can use `es5-shim`, `es5-sham` and `json2` to support old browsers
```html
<!--[if lt IE 9]>
<script src="json2.js"></script>
<script src="es5-shim.min.js"></script>
<script src="es5-sham.min.js"></script>
<![endif]-->
<script type="text/javascript" src="tcomb.js"></script>
<script type="text/javascript">
console.log(t);
</script>
```
# Tests

@@ -190,21 +190,11 @@

# The Idea
What's a type? In tcomb a type is a function `T` such that
1. `T` has signature `T(value, [mut])` where `value` depends on the nature of `T` and the optional boolean `mut` makes the instance mutable (default `false`)
2. `T` is idempotent: `T(T(value, mut), mut) === T(value, mut)`
3. `T` owns a static function `T.is(x)` returning `true` if `x` is an instance of `T`
**Note**: 2. implies that `T` can be used as a default JSON decoder
# Api
## options
### options.onFail
In production envs you don't want to leak failures to the user
```javascript
```js
// override onFail hook

@@ -221,18 +211,2 @@ options.onFail = function (message) {

```
### options.update
Adds to structs, tuples, lists and dicts a static method `update` that returns a new instance
without modifying the original.
Example
```javascript
// see http://facebook.github.io/react/docs/update.html
options.update = function (x, updates) {
return React.addons.update(mixin({}, x), updates);
};
var p1 = Point({x: 0, y: 0});
var p2 = Point.update(p1, {x: {$set: 1}}); // => Point({x: 1, y: 0})
```

@@ -244,11 +218,11 @@ ## assert

```
If `guard !== true` the debugger kicks in.
- `guard` boolean condition
- `message` optional string useful for debugging, formatted with values like [util.format in Node](http://nodejs.org/api/util.html#util_util_format_format)
Example
```javascript
```js
assert(1 === 2); // throws 'assert(): failed'

@@ -258,3 +232,3 @@ assert(1 === 2, 'error!'); // throws 'error!'

```
To customize failure behaviour, see `options.onFail`.

@@ -267,13 +241,13 @@

```
Defines a struct like type.
- `props` hash name -> type
- `name` optional string useful for debugging
Example
```javascript
```js
"use strict";
// defines a struct with two numerical props

@@ -284,3 +258,3 @@ var Point = struct({

});
// methods are defined as usual

@@ -290,21 +264,36 @@ Point.prototype.toString = function () {

};
// costructor usage, p is immutable
var p = Point({x: 1, y: 2});
p.x = 2; // => TypeError
p = Point({x: 1, y: 2}, true); // now p is mutable
p.x = 2; // ok
```
### is(x)
Returns `true` if `x` is an instance of the struct.
```javascript
```js
Point.is(p); // => true
```
### extend(props, [name])
Returns a new type with the additional specified `props`
```js
var Point = struct({
x: Num,
y: Num
}, 'Point');
var Point3D = Point.extend({z: Num}, 'Point3D'); // composition, not inheritance
var p = new Point3D({x: 1, y: 2, z: 3});
```
## unions

@@ -315,11 +304,11 @@

```
Defines a union of types.
- `types` array of types
- `name` optional string useful for debugging
Example
```javascript
```js
var Circle = struct({

@@ -329,3 +318,3 @@ center: Point,

});
var Rectangle = struct({

@@ -335,15 +324,23 @@ bl: Point, // bottom left vertex

});
var Shape = union([
Circle,
Circle,
Rectangle
]);
// you must implement the dispatch() function in order to use `Shape` as a contructor
Shape.dispatch = function (x) {
return x.hasOwnProperty('center') ? Circle : Rectangle;
};
var circle = Shape({center: {x: 1, y: 0}, radius: 10});
var rectangle = Shape({bl: {x: 0, y: 0}, tr: {x: 1, y: 1}});
```
### is(x)
Returns `true` if `x` belongs to the union.
```javascript
Shape.is(Circle({center: p, radius: 10})); // => true
```js
Shape.is(new Circle({center: p, radius: 10})); // => true
```

@@ -356,9 +353,9 @@

```
Same as `union([Nil, type])`.
```javascript
```js
// the value of a radio input where null = no selection
var Radio = maybe(Str);
Radio.is('a'); // => true

@@ -374,40 +371,40 @@ Radio.is(null); // => true

```
Defines an enum of strings.
- `map` hash enum -> value
- `name` optional string useful for debugging
Example
```javascript
```js
var Direction = enums({
North: 'North',
North: 'North',
East: 'East',
South: 'South',
South: 'South',
West: 'West'
});
```
### is(x)
Returns `true` if `x` belongs to the enum.
```javascript
```js
Direction.is('North'); // => true
```
### enums.of(keys, [name])
Returns an enums of an array of keys, useful when you don't mind to define
custom values for the enums.
- `keys` array (or string) of keys
- `name` optional string useful for debugging
Example
```javascript
```js
// result is the same as the main example
var Direction = enums.of(['North', 'East', 'South', 'West']);
// or..

@@ -422,22 +419,29 @@ Direction = enums.of('North East South West');

```
Defines a tuple whose coordinates have the specified types.
- `types` array of coordinates types
- `name` optional string useful for debugging
Example
```javascript
```js
var Area = tuple([Num, Num]);
// constructor usage, area is immutable
var area = Area([1, 2]);
```
0-tuples and 1-tuples are also supported
```js
var Nothing = tuple([]);
var JustNum = tuple([Num]);
```
### is(x)
Returns `true` if `x` belongs to the tuple.
```javascript
```js
Area.is([1, 2]); // => true

@@ -453,12 +457,12 @@ Area.is([1, 'a']); // => false, the second element is not a Num

```
Defines a subtype of an existing type.
- `type` the supertype
- `predicate` a function with signature `(x) -> boolean`
- `name` optional string useful for debugging
Example
```javascript
```js
// points of the first quadrant

@@ -468,19 +472,19 @@ var Q1Point = subtype(Point, function (p) {

});
// costructor usage, p is immutable
var p = Q1Point({x: 1, y: 2});
p = Q1Point({x: -1, y: -2}); // => fail!
```
**Note**. You can't add methods to `Q1Point` `prototype`, add them to the supertype `prototype` if needed.
### is(x)
Returns `true` if `x` belongs to the subtype.
```javascript
```js
var Int = subtype(Num, function (n) {
return n === parseInt(n, 10);
});
Int.is(2); // => true

@@ -495,25 +499,25 @@ Int.is(1.1); // => false

```
Defines an array where all the elements are of type `T`.
- `type` type of all the elements
- `name` optional string useful for debugging
Example
```javascript
```js
var Path = list(Point);
// costructor usage, path is immutable
var path = Path([
{x: 0, y: 0},
{x: 0, y: 0},
{x: 1, y: 1}
]);
```
### is(x)
Returns `true` if `x` belongs to the list.
```javascript
```js
var p1 = Point({x: 0, y: 0});

@@ -527,54 +531,191 @@ var p2 = Point({x: 1, y: 2});

```js
dict(type, [name])
dict(domain, codomain, [name])
```
Defines a dictionary Str -> type.
- `type` the type of the values
Defines a dictionary domain -> codomain.
- `domain` the type of the keys
- `codomain` the type of the values
- `name` optional string useful for debugging
Example
```javascript
```js
// defines a dictionary of numbers
var Tel = dict(Num);
var Tel = dict(Str, Num);
```
### is(x)
Returns `true` if `x` is an instance of the dict.
```javascript
```js
Tel.is({'jack': 4098, 'sape': 4139}); // => true
```
## Updates
```js
Type.update(instance, spec)
```
The following commands are compatible with the [Facebook Immutability Helpers](http://facebook.github.io/react/docs/update.html).
- $push
- $unshift
- $splice
- $set
- $apply
### Removing a value form a dict
`{$remove: keys}`
```js
var Type = dict(Str, Num);
var instance = Type({a: 1, b: 2});
var updated = Type.update(instance, {$remove: ['a']}); // => {b: 2}
```
### Swapping two list elements
`{$swap: {from: number, to: number}}`
```js
var Type = list(Num);
var instance = Type([1, 2, 3, 4]);
var updated = Type.update(instance, {'$swap': {from: 1, to: 2}}); // => [1, 3, 2, 4]
```
### Adding other commands
You can add your custom commands updating the `util.update.commands` hash.
## functions
Typed functions may be defined like this:
```js
func(Arguments, f, [Return], [name])
// add takes two `Num`s and returns a `Num`
var add = func([Num, Num], Num)
.of(function (x, y) { return x + y; });
```
Defines a function where the `arguments` and the return value are checked.
- `Arguments` the type of `arguments` (can be a list of types)
- `f` the function to execute
- `Return` optional, check the type of the return value
- `name` optional string useful for debugging
Example
```javascript
var sum = func([Num, Num], function (a, b) {
return a + b;
}, Num);
sum(1, 2); // => 3
sum(1, 'a'); // => fail!
And used like this:
```js
add("Hello", 2); // Raises error: Invalid `Hello` supplied to `Num`
add("Hello"); // Raises error: Invalid `Hello` supplied to `Num`
add(1, 2); // Returns: 3
add(1)(2); // Returns: 3
```
# Macros
### func(A, B, [name])
**Experimental**. I added a `tcomb.sjs` file containing some [sweet.js](http://sweetjs.org/) macros, here some examples:
```js
func(Domain, Codomain, name)
```
Returns a function type whose functions have their domain and codomain specified and constrained.
- `Domain`: the type of the function's argument (or `list` of types of the function's arguments)
- `Codomain`: the type of the function's return value
- `name`: optional string useful for debugging
`func` can be used to define function types using native types:
```js
// An `A` takes a `Str` and returns an `Num`
var A = func(Str, Num);
```
The domain and codomain can also be specified using types from any combinator including `func`:
```js
// A `B` takes a `Func` (which takes a `Str` and returns a `Num`) and returns a `Str`.
var B = func(func(Str, Num), Str);
// An `ExcitedStr` is a `Str` containing an exclamation mark
var ExcitedStr = subtype(Str, function (s) { return s.indexOf('!') !== -1; }, 'ExcitedStr');
// An `Exciter` takes a `Str` and returns an `ExcitedStr`
var Exciter = func(Str, ExcitedStr);
```
Additionally the domain can be expressed as a `list` of types:
```js
// A `C` takes an `A`, a `B` and a `Str` and returns a `Num`
var C = func([A, B, Str], Num);
```
### .of(f)
```js
func(A, B).of(f);
```
Returns a function where the domain and codomain are typechecked against the function type.
If the function is passed values which are outside of the domain or returns values which are outside of the codomain it will raise an error:
```js
var simpleQuestionator = Exciter.of(function (s) { return s + '?'; });
var simpleExciter = Exciter.of(function (s) { return s + '!'; });
// Raises error:
// Invalid `Hello?` supplied to `ExcitedStr`, insert a valid value for the subtype
simpleQuestionator('Hello');
// Raises error: Invalid `1` supplied to `Str`
simpleExciter(1);
// Returns: 'Hello!'
simpleExciter('Hello');
```
The returned function may also be partially applied:
```js
// We can reasonably suggest that add has the following type signature
// add : Num -> Num -> Num
var add = func([Num, Num], Num)
.of(function (x, y) { return x + y });
var addHello = add("Hello"); // As this raises: "Error: Invalid `Hello` supplied to `Num`"
var add2 = add(2);
add2(1); // And this returns: 3
```
### .is(x)
```js
func(A, B).is(x);
```
Returns true if x belongs to the type.
```js
Exciter.is(simpleExciter); // Returns: true
Exciter.is(simpleQuestionator); // Returns: true
var id = function (x) { return x; };
func([Num, Num], Num).is(func([Num, Num], Num).of(id)); // Returns: true
func([Num, Num], Num).is(func(Num, Num).of(id)); // Returns: false
```
### Rules
1. Typed functions' domains are checked when they are called
2. Typed functions' codomains are checked when they return
3. The domain and codomain of a typed function's type is checked when the typed function is passed to a function type (such as when used as an argument in another typed function).
# Macros (experimental)
I added a `tcomb.sjs` file containing some [sweet.js](http://sweetjs.org/) macros, here some examples:
```js
// structs

@@ -600,13 +741,13 @@ type Point struct {

type Direction enums {
'North',
'North',
'East',
'South',
'South',
'West'
}
// enums with specified values
// enums with specified values
type Direction enums {
'North': 0,
'North': 0,
'East': 1,
'South': 2,
'South': 2,
'West': 3

@@ -645,34 +786,4 @@ }

# Articles on tcomb
# License
- [What if your domain model could validate the UI for free?](http://gcanti.github.io/2014/08/12/what-if-your-domain-model-could-validate-the-ui-for-free.html)
- [JSON Deserialization Into An Object Model](http://gcanti.github.io/2014/09/12/json-deserialization-into-an-object-model.html)
- [JSON API Validation In Node.js](http://gcanti.github.io/2014/09/15/json-api-validation-in-node.html)
# Contribution
If you do have a contribution for the package feel free to put up a Pull Request or open an Issue.
# License (MIT)
The MIT License (MIT)
Copyright (c) 2014 Giulio Canti
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@@ -1,6 +0,6 @@

// tcomb 0.2.0
// tcomb 0.2.1
// https://github.com/gcanti/tcomb
// (c) 2014 Giulio Canti <giulio.canti@gmail.com>
// tcomb may be freely distributed under the MIT license.
!function(a,b){"use strict";"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.t=b()}(this,function(){"use strict";function a(a){throw z=!0,new Error(a)}function b(a){A.onFail(a)}function c(a){if(a!==!0){var c=B.call(arguments,1),d=c[0]?f.apply(null,c):"assert failed";b(d)}}function d(a,b,d){if(D.is(b))return a;for(var e in b)b.hasOwnProperty(e)&&(d||c(!a.hasOwnProperty(e),"cannot overwrite property %s",e),a[e]=b[e]);return a}function e(){return Array.prototype.reduce.call(arguments,function(a,b){return d(a,b,!0)},{})}function f(){function a(a,e){if("%%"===a)return"%";if(d>=c)return a;var g=f.formatters[e];return g?g(b[d++]):a}var b=B.call(arguments),c=b.length,d=1,e=b[0],g=e.replace(/%([a-z%])/g,a);return c>d&&(g+=" "+b.slice(d).join(" ")),g}function g(a,b){return"function"==typeof b?f("Func",b.name):b}function h(a){return J.is(a)&&I.is(a.meta)}function i(a){return c(h(a),"Invalid argument `type` of value `%j` supplied to `getName()`, expected a type.",a),a.meta.name}function j(a){console&&console.warn&&console.warn(a)}function k(a){return c(h(a),"Invalid argument `type` of value `%j` supplied to `geKind()`, expected a type.",a),a.meta.kind}function l(a,b){return j("`isKind(type, kind)` is deprecated, use `getKind(type) === kind` instead"),k(a)===b}function m(a,b){c(!(a instanceof b),"Operator `new` is forbidden for `%s`",i(b))}function n(){c(J.is(A.update),"Missing `options.update` implementation");var a=this,b=A.update.apply(a,arguments);return a(b)}function o(a,b){function d(e){return m(this,d),c(b(e),"Invalid `%s` supplied to `%s`",e,a),e}return c("string"==typeof a,"Invalid argument `name` supplied to `irriducible()`"),c("function"==typeof b,"Invalid argument `is` supplied to `irriducible()`"),d.meta={kind:"irriducible",name:a},d.is=b,d}function p(a,b){function d(e,f){if(d.is(e))return e;if(c(I.is(e),"Invalid `%s` supplied to `%s`, expected an `Obj`",e,b),!(this instanceof d))return new d(e,f);for(var g in a)if(a.hasOwnProperty(g)){var h=a[g],i=e[g];this[g]=h(i,f)}f||Object.freeze(this)}return c(w(N).is(a),"Invalid argument `props` supplied to `struct()`"),c(r(E).is(b),"Invalid argument `name` supplied to `struct()`"),b=b||"struct",d.meta={kind:"struct",props:a,name:b},d.is=function(a){return a instanceof d},d.update=n,d}function q(a,b){function d(a,e){m(this,d),c(J.is(d.dispatch),"unimplemented %s.dispatch()",b);var f=d.dispatch(a);return c(h(f),"%s.dispatch() returns no type",b),f(a,e)}c(v(N).is(a),"Invalid argument `types` supplied to `union()`");var e=a.length;return c(e>=2,"Invalid argument `types` supplied to `union()`"),c(r(E).is(b),"Invalid argument `name` supplied to `union()`"),b=b||f("union([%s])",a.map(i).join(", ")),d.meta={kind:"union",types:a,name:b},d.is=function(b){return a.some(function(a){return a.is(b)})},d.dispatch=function(b){for(var c=0,d=a.length;d>c;c++)if(a[c].is(b))return a[c]},d}function r(a,b){function d(b,c){return m(this,d),D.is(b)?null:a(b,c)}return c(h(a),"Invalid argument `type` supplied to `maybe()`"),"maybe"===k(a)?a:(c(D.is(b)||E.is(b),"Invalid argument `name` supplied to `maybe()`"),b=b||f("maybe(%s)",i(a)),d.meta={kind:"maybe",type:a,name:b},d.is=function(b){return D.is(b)||a.is(b)},d)}function s(a,b){function d(a){return m(this,d),c(d.is(a),"Invalid `%s` supplied to `%s`, expected one of %j",a,b,e),a}c(I.is(a),"Invalid argument `map` supplied to `enums()`"),c(r(E).is(b),"Invalid argument `name` supplied to `enums()`"),b=b||"enums";var e=Object.keys(a);return d.meta={kind:"enums",map:a,name:b},d.is=function(b){return E.is(b)&&a.hasOwnProperty(b)},d}function t(a,b){function d(f,g){if(m(this,d),c(H.is(f)&&f.length===e,"Invalid `%s` supplied to `%s`, expected an `Arr` of length `%s`",f,b,e),d.isTuple(f))return f;for(var h=[],i=0;e>i;i++){var j=a[i],k=f[i];h.push(j(k,g))}return g||Object.freeze(h),h}c(v(N).is(a),"Invalid argument `types` supplied to `tuple()`");var e=a.length;return c(e>=2,"Invalid argument `types` supplied to `tuple()`"),c(r(E).is(b),"Invalid argument `name` supplied to `tuple()`"),b=b||f("tuple([%s])",a.map(i).join(", ")),d.meta={kind:"tuple",types:a,name:b},d.isTuple=function(b){return a.every(function(a,c){return a.is(b[c])})},d.is=function(a){return H.is(a)&&a.length===e&&d.isTuple(a)},d.update=n,d}function u(a,b,d){function e(f,h){m(this,e);var i=a(f,h);return c(b(i),"Invalid `%s` supplied to `%s`, %s",f,d,g),i}c(h(a),"Invalid argument `type` supplied to `subtype()`"),c(J.is(b),"Invalid argument `predicate` supplied to `subtype()`"),c(r(E).is(d),"Invalid argument `name` supplied to `subtype()`"),d=d||f("subtype(%s)",i(a));var g=b.__doc__||f("insert a valid value for %s",b.name||"the subtype");return e.meta={kind:"subtype",type:a,predicate:b,name:d},e.is=function(c){return a.is(c)&&b(c)},e}function v(a,b){function d(e,f){if(m(this,d),c(H.is(e),"Invalid `%s` supplied to `%s`, expected an `Arr`",e,b),d.isList(e))return e;for(var g=[],h=0,i=e.length;i>h;h++){var j=e[h];g.push(a(j,f))}return f||Object.freeze(g),g}return c(h(a),"Invalid argument `type` supplied to `list()`"),c(r(E).is(b),"Invalid argument `name` supplied to `list()`"),b=b||f("list(%s)",i(a)),d.meta={kind:"list",type:a,name:b},d.isList=function(b){return b.every(a.is)},d.is=function(a){return H.is(a)&&d.isList(a)},d.update=n,d}function w(a,b){function d(e,f){if(m(this,d),c(I.is(e),"Invalid `%s` supplied to `%s`, expected an `Obj`",e,b),d.isDict(e))return e;var g={};for(var h in e)if(e.hasOwnProperty(h)){var i=e[h];g[h]=a(i,f)}return f||Object.freeze(g),g}return c(h(a),"Invalid argument `type` supplied to `dict()`"),c(r(E).is(b),"Invalid argument `name` supplied to `dict()`"),b=b||f("dict(%s)",i(a)),d.meta={kind:"dict",type:a,name:b},d.isDict=function(b){for(var c in b)if(b.hasOwnProperty(c)&&!a.is(b[c]))return!1;return!0},d.is=function(a){return I.is(a)&&d.isDict(a)},d.update=n,d}function x(a,b,d,e){function f(){var c=B.call(arguments);c.length<b.length&&(c.length=b.length),c=a(c);var e=b.apply(this,c);return d&&(e=d(e)),e}return e=e||"func()",a=H.is(a)?t(a,"Arguments"):a,c(h(a),"Invalid argument `Arguments` supplied to `func()`"),c(J.is(b),"Invalid argument `f` supplied to `func()`"),c(D.is(d)||h(d),"Invalid argument `Return` supplied to `func()`"),c(r(E).is(e),"Invalid argument `name` supplied to `func()`"),e=e||b.name||"func",d=d||null,h(b)&&b.meta.Arguments===a&&b.meta.Return===d?b:(f.is=function(a){return a===f},f.meta={kind:"func",Arguments:a,f:b,Return:d,name:e},f)}function y(a,b){function d(b,c){return a(b,c)}return c(h(a),"Invalid argument `type` supplied to `alias()`"),c(r(E).is(b),"Invalid argument `name` supplied to `alias()`"),b=b||"alias("+i(a)+")",d.is=function(b){return a.is(b)},d.meta=a.meta,d.name=b,d}var z=!1,A={onFail:a,update:null},B=Array.prototype.slice;f.formatters={s:function(a){return String(a)},j:function(a){return JSON.stringify(a,g)}};var C=o("Any",function(){return!0}),D=o("Nil",function(a){return null===a||void 0===a}),E=o("Str",function(a){return"string"==typeof a}),F=o("Num",function(a){return"number"==typeof a&&isFinite(a)&&!isNaN(a)}),G=o("Bool",function(a){return a===!0||a===!1}),H=o("Arr",function(a){return a instanceof Array}),I=o("Obj",function(a){return!D.is(a)&&"object"==typeof a&&!H.is(a)}),J=o("Func",function(a){return"function"==typeof a}),K=o("Err",function(a){return a instanceof Error}),L=o("Re",function(a){return a instanceof RegExp}),M=o("Dat",function(a){return a instanceof Date}),N=o("Type",h);return s.of=function(a,b){a=E.is(a)?a.split(" "):a;var c={};return a.forEach(function(a){c[a]=a}),s(c,b)},{util:{mixin:d,merge:e,format:f,isType:h,getName:i,getKind:k,isKind:l,slice:B},options:A,assert:c,fail:b,Any:C,Nil:D,Str:E,Num:F,Bool:G,Arr:H,Obj:I,Func:J,Err:K,Re:L,Dat:M,Type:N,irriducible:o,struct:p,enums:s,union:q,maybe:r,tuple:t,subtype:u,list:v,dict:w,func:x,alias:y}});
!function(a,b){"use strict";"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.t=b()}(this,function(){"use strict";function a(a){throw w=!0,new Error(a)}function b(a){x.onFail(a)}function c(a){if(a!==!0){var c=y.call(arguments,1),d=c[0]?f.apply(null,c):"assert failed";b(d)}}function d(a,b,d){if(A.is(b))return a;for(var e in b)b.hasOwnProperty(e)&&(d||c(!a.hasOwnProperty(e),"cannot overwrite property %s",e),a[e]=b[e]);return a}function e(){return Array.prototype.reduce.call(arguments,function(a,b){return d(a,b,!0)},{})}function f(){function a(a,e){if("%%"===a)return"%";if(d>=c)return a;var g=f.formatters[e];return g?g(b[d++]):a}var b=y.call(arguments),c=b.length,d=1,e=b[0],g=e.replace(/%([a-z%])/g,a);return c>d&&(g+=" "+b.slice(d).join(" ")),g}function g(a,b){return"function"==typeof b?f("Func",b.name):b}function h(a){return c(K.is(a),"Invalid argument `type` of value `%j` supplied to `getName()`, expected a type.",a),a.meta.name}function i(a){return c(K.is(a),"Invalid argument `type` of value `%j` supplied to `geKind()`, expected a type.",a),a.meta.kind}function j(a,b){c(!(a instanceof b),"Operator `new` is forbidden for `%s`",h(b))}function k(a){return E.is(a)?a.concat():F.is(a)?d({},a):a}function l(a,b){c(!A.is(a)),c(F.is(b));var d=k(a);for(var e in b)if(b.hasOwnProperty(e)){if(l.commands.hasOwnProperty(e))return c(1===Object.keys(b).length),l.commands[e](b[e],d);d[e]=l(d[e],b[e])}return d}function m(a,b){function d(e){return j(this,d),c(b(e),"Invalid `%s` supplied to `%s`",e,a),e}return c("string"==typeof a,"Invalid argument `name` supplied to `irriducible()`"),c("function"==typeof b,"Invalid argument `is` supplied to `irriducible()`"),d.meta={kind:"irriducible",name:a},d.is=b,d}function n(a,b){function e(d,f){if(e.is(d))return d;if(c(F.is(d),"Invalid `%s` supplied to `%s`, expected an `Obj`",d,b),!(this instanceof e))return new e(d,f);for(var g in a)if(a.hasOwnProperty(g)){var h=a[g],i=d[g];this[g]=h(i,f)}f!==!0&&Object.freeze(this)}return c(u(B,K).is(a),"Invalid argument `props` supplied to `struct()`"),c(p(B).is(b),"Invalid argument `name` supplied to `struct()`"),b=b||"struct",e.meta={kind:"struct",props:a,name:b},e.is=function(a){return a instanceof e},e.update=function(a,b,c){return new e(l(a,b,c))},e.extend=function(b,c){return n(d(d({},a),b),c)},e}function o(a,b){function d(a,e){j(this,d),c(G.is(d.dispatch),"unimplemented %s.dispatch()",b);var f=d.dispatch(a);return c(K.is(f),"%s.dispatch() returns no type",b),f(a,e)}c(t(K).is(a),"Invalid argument `types` supplied to `union()`");var e=a.length;return c(e>=2,"Invalid argument `types` supplied to `union()`"),c(p(B).is(b),"Invalid argument `name` supplied to `union()`"),b=b||f("union([%s])",a.map(h).join(", ")),d.meta={kind:"union",types:a,name:b},d.is=function(b){return a.some(function(a){return a.is(b)})},d.dispatch=function(b){for(var c=0,d=a.length;d>c;c++)if(a[c].is(b))return a[c]},d}function p(a,b){function d(b,c){return j(this,d),A.is(b)?null:a(b,c)}return c(K.is(a),"Invalid argument `type` supplied to `maybe()`"),"maybe"===i(a)?a:(c(A.is(b)||B.is(b),"Invalid argument `name` supplied to `maybe()`"),b=b||f("maybe(%s)",h(a)),d.meta={kind:"maybe",type:a,name:b},d.is=function(b){return A.is(b)||a.is(b)},d)}function q(a,b){function d(a){return j(this,d),c(d.is(a),"Invalid `%s` supplied to `%s`, expected one of %j",a,b,e),a}c(F.is(a),"Invalid argument `map` supplied to `enums()`"),c(p(B).is(b),"Invalid argument `name` supplied to `enums()`"),b=b||"enums";var e=Object.keys(a);return d.meta={kind:"enums",map:a,name:b},d.is=function(b){return B.is(b)&&a.hasOwnProperty(b)},d}function r(a,b){function d(f,g){if(c(E.is(f)&&f.length===e,"Invalid `%s` supplied to `%s`, expected an `Arr` of length `%s`",f,b,e),d.isTuple(f))return f;for(var h=[],i=0;e>i;i++){var j=a[i],k=f[i];h.push(j(k,g))}return g!==!0&&Object.freeze(h),h}c(t(K).is(a),"Invalid argument `types` supplied to `tuple()`");var e=a.length;return c(p(B).is(b),"Invalid argument `name` supplied to `tuple()`"),b=b||f("tuple([%s])",a.map(h).join(", ")),d.meta={kind:"tuple",types:a,length:e,name:b},d.isTuple=function(b){return a.every(function(a,c){return a.is(b[c])})},d.is=function(a){return E.is(a)&&a.length===e&&d.isTuple(a)},d.update=function(a,b,c){return d(l(a,b,c))},d}function s(a,b,d){function e(f,h){j(this,e);var i=a(f,h);return c(b(i),"Invalid `%s` supplied to `%s`, %s",f,d,g),i}c(K.is(a),"Invalid argument `type` supplied to `subtype()`"),c(G.is(b),"Invalid argument `predicate` supplied to `subtype()`"),c(p(B).is(d),"Invalid argument `name` supplied to `subtype()`"),d=d||f("subtype(%s)",h(a));var g=b.__doc__||f("insert a valid value for %s",b.name||"the subtype");return e.meta={kind:"subtype",type:a,predicate:b,name:d},e.is=function(c){return a.is(c)&&b(c)},e.update=function(a,b,c){return e(l(a,b,c))},e}function t(a,b){function d(e,f){if(c(E.is(e),"Invalid `%s` supplied to `%s`, expected an `Arr`",e,b),d.isList(e))return e;for(var g=[],h=0,i=e.length;i>h;h++){var j=e[h];g.push(a(j,f))}return f!==!0&&Object.freeze(g),g}return c(K.is(a),"Invalid argument `type` supplied to `list()`"),c(p(B).is(b),"Invalid argument `name` supplied to `list()`"),b=b||f("list(%s)",h(a)),d.meta={kind:"list",type:a,name:b},d.isList=function(b){return b.every(a.is)},d.is=function(a){return E.is(a)&&d.isList(a)},d.update=function(a,b,c){return d(l(a,b,c))},d}function u(a,b,d){function e(f,g){if(c(F.is(f),"Invalid `%s` supplied to `%s`, expected an `Obj`",f,d),e.isDict(f))return f;var h={};for(var i in f)if(f.hasOwnProperty(i)){i=a(i);var j=f[i];h[i]=b(j,g)}return g!==!0&&Object.freeze(h),h}return c(K.is(a),"Invalid argument `domain` supplied to `dict()`"),c(K.is(b),"Invalid argument `codomain` supplied to `dict()`"),c(p(B).is(d),"Invalid argument `name` supplied to `dict()`"),d=d||f("dict(%s, %s)",h(a),h(b)),e.meta={kind:"dict",domain:a,codomain:b,name:d},e.isDict=function(c){for(var d in c)if(c.hasOwnProperty(d)&&(!a.is(d)||!b.is(c[d])))return!1;return!0},e.is=function(a){return F.is(a)&&e.isDict(a)},e.update=function(a,b,c){return e(l(a,b,c))},e}function v(a,b,d){function e(a){return v.is(a)||(a=e.of(a)),c(e.is(a),"Invalid `%s` supplied to `%s`",a,d),a}a=E.is(a)?a:[a],c(t(K).is(a),"Invalid argument `domain` supplied to `func()`"),c(K.is(b),"Invalid argument `codomain` supplied to `func()`"),d=d||f("func([%s], %s)",a.map(h).join(", "),h(b));var g=a.length;return e.meta={kind:"func",domain:a,codomain:b,name:d},e.is=function(c){return v.is(c)&&c.func.domain.length===a.length&&c.func.domain.every(function(b,c){return b===a[c]})&&c.func.codomain===b},e.of=function(d){function f(){var c=y.call(arguments),e=Math.min(c.length,g);if(c=r(a.slice(0,e))(c),e===g){var f=d.apply(this,c);return f=b(f)}var h=Function.prototype.bind.apply(d,[this].concat(c)),i=v(a.slice(e),b);return i.of(h)}return c("function"==typeof d),e.is(d)?d:(f.func={domain:a,codomain:b,f:d},f)},e}var w=!1,x={onFail:a},y=Array.prototype.slice;f.formatters={s:function(a){return String(a)},j:function(a){return JSON.stringify(a,g)}},l.commands={$apply:function(a,b){return c(G.is(a)),a(b)},$push:function(a,b){return c(E.is(a)),c(E.is(b)),b.concat(a)},$remove:function(a,b){c(E.is(a)),c(F.is(b));for(var d=0,e=a.length;e>d;d++)delete b[a[d]];return b},$set:function(a){return a},$splice:function(a,b){return c(t(E).is(a)),c(E.is(b)),a.reduce(function(a,b){return a.splice.apply(a,b),a},b)},$swap:function(a,b){c(F.is(a)),c(C.is(a.from)),c(C.is(a.to)),c(E.is(b));var d=b[a.to];return b[a.to]=b[a.from],b[a.from]=d,b},$unshift:function(a,b){return c(E.is(a)),c(E.is(b)),a.concat(b)}};var z=m("Any",function(){return!0}),A=m("Nil",function(a){return null===a||void 0===a}),B=m("Str",function(a){return"string"==typeof a}),C=m("Num",function(a){return"number"==typeof a&&isFinite(a)&&!isNaN(a)}),D=m("Bool",function(a){return a===!0||a===!1}),E=m("Arr",function(a){return a instanceof Array}),F=m("Obj",function(a){return!A.is(a)&&"object"==typeof a&&!E.is(a)}),G=m("Func",function(a){return"function"==typeof a}),H=m("Err",function(a){return a instanceof Error}),I=m("Re",function(a){return a instanceof RegExp}),J=m("Dat",function(a){return a instanceof Date}),K=m("Type",function(a){return G.is(a)&&F.is(a.meta)});return q.of=function(a,b){a=B.is(a)?a.split(" "):a;var c={};return a.forEach(function(a){c[a]=a}),q(c,b)},v.is=function(a){return G.is(a)&&F.is(a.func)},{util:{mixin:d,merge:e,format:f,getName:h,getKind:i,slice:y,shallowCopy:k,update:l},options:x,assert:c,fail:b,Any:z,Nil:A,Str:B,Num:C,Bool:D,Arr:E,Obj:F,Func:G,Err:H,Re:I,Dat:J,Type:K,irriducible:m,struct:n,enums:q,union:o,maybe:p,tuple:r,subtype:s,list:t,dict:u,func:v}});
//# sourceMappingURL=tcomb.min.js.map

Sorry, the diff of this file is not supported yet

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