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 2.1.0 to 2.2.0

39

CHANGELOG.md

@@ -14,2 +14,22 @@ # Changelog

## v2.2.0
- **New Feature**
- added `intersection` combinator fix #111
**Example**
```js
const Min = t.subtype(t.String, function (s) { return s.length > 2; }, 'Min');
const Max = t.subtype(t.String, function (s) { return s.length < 5; }, 'Max');
const MinMax = t.intersection([Min, Max], 'MinMax');
MinMax.is('abc'); // => true
MinMax.is('a'); // => false
MinMax.is('abcde'); // => false
```
- **Internal**
- optimised the generation of default names for types
## v2.1.0

@@ -46,20 +66,1 @@

* getFunctionName
## v1.0.3
- **Internal**
+ fix tcomb lists don't currently play nice with es6 classes due to inability to invoke classes without new #92
## v1.0.2
- **Internal**
+ Remove `debugger` statement #90
## v1.0.1
- **Internal**
+ Add react-native compatibility #89
## v1.0.0
First release

@@ -433,2 +433,28 @@ # Setup

## The intersection combinator
You can define an intersection of types using the `intersection(types, name)` combinator where:
* `types` is a list of types
* `name` is an optional string useful for debugging purposes
```js
const Min = t.subtype(t.String, function (s) { return s.length > 2; }, 'Min');
const Max = t.subtype(t.String, function (s) { return s.length < 5; }, 'Max');
const MinMax = t.intersection([Min, Max], 'MinMax');
MinMax.is('abc'); // => true
MinMax.is('a'); // => false
MinMax.is('abcde'); // => false
```
Intersections have the following `meta` object:
```js
{
kind: 'intersection',
types: types
}
```
## The maybe combinator

@@ -435,0 +461,0 @@

@@ -89,5 +89,6 @@ 'use strict';

function getTypeName(constructor) {
return isType(constructor) ?
constructor.displayName :
getFunctionName(constructor);
if (isType(constructor)) {
return constructor.displayName;
}
return getFunctionName(constructor);
}

@@ -156,6 +157,7 @@

update.commands = {
'$apply': function (f, value) {
$apply: function (f, value) {
if (process.env.NODE_ENV !== 'production') {
assert(isFunction(f), 'Invalid argument f supplied to immutability helper {"$apply": f}: expected a function');
assert(isFunction(f), 'Invalid argument f supplied to immutability helper { $apply: f }: expected a function');
}

@@ -165,6 +167,7 @@

},
'$push': function (elements, arr) {
$push: function (elements, arr) {
if (process.env.NODE_ENV !== 'production') {
assert(isArray(elements), 'Invalid argument elements supplied to immutability helper {"$push": elements}: expected an array');
assert(isArray(elements), 'Invalid argument elements supplied to immutability helper { $push: elements }: expected an array');
assert(isArray(arr), 'Invalid value supplied to immutability helper "$push": expected an array');

@@ -175,6 +178,7 @@ }

},
'$remove': function (keys, obj) {
$remove: function (keys, obj) {
if (process.env.NODE_ENV !== 'production') {
assert(isArray(keys), 'Invalid argument keys supplied to immutability helper {"$remove": keys}: expected an array');
assert(isArray(keys), 'Invalid argument keys supplied to immutability helper { $remove: keys }: expected an array');
assert(isObject(obj), 'Invalid value supplied to immutability helper $remove: expected an object');

@@ -188,9 +192,11 @@ }

},
'$set': function (value) {
$set: function (value) {
return value;
},
'$splice': function (splices, arr) {
$splice: function (splices, arr) {
if (process.env.NODE_ENV !== 'production') {
assert(list(Arr).is(splices), 'Invalid argument splices supplied to immutability helper {"$splice": splices}: expected an array of arrays');
assert(list(Arr).is(splices), 'Invalid argument splices supplied to immutability helper { $splice: splices }: expected an array of arrays');
assert(isArray(arr), 'Invalid value supplied to immutability helper $splice: expected an array');

@@ -204,8 +210,9 @@ }

},
'$swap': function (config, arr) {
$swap: function (config, arr) {
if (process.env.NODE_ENV !== 'production') {
assert(isObject(config), 'Invalid argument config supplied to immutability helper {"$swap": config}: expected an object');
assert(isNumber(config.from), 'Invalid argument config.from supplied to immutability helper {"$swap": config}: expected a number');
assert(isNumber(config.to), 'Invalid argument config.to supplied to immutability helper {"$swap": config}: expected a number');
assert(isObject(config), 'Invalid argument config supplied to immutability helper { $swap: config }: expected an object');
assert(isNumber(config.from), 'Invalid argument config.from supplied to immutability helper { $swap: config }: expected a number');
assert(isNumber(config.to), 'Invalid argument config.to supplied to immutability helper { $swap: config }: expected a number');
assert(isArray(arr), 'Invalid value supplied to immutability helper $swap');

@@ -219,6 +226,7 @@ }

},
'$unshift': function (elements, arr) {
$unshift: function (elements, arr) {
if (process.env.NODE_ENV !== 'production') {
assert(isArray(elements), 'Invalid argument elements supplied to immutability helper {"$unshift": elements}');
assert(isArray(elements), 'Invalid argument elements supplied to immutability helper {$unshift: elements}');
assert(isArray(arr), 'Invalid value supplied to immutability helper $unshift');

@@ -229,5 +237,7 @@ }

},
'$merge': function (obj, value) {
$merge: function (obj, value) {
return mixin(mixin({}, value), obj, true);
}
};

@@ -294,2 +304,8 @@

function getDefaultStructName(props) {
return '{' + Object.keys(props).map(function (prop) {
return prop + ': ' + getTypeName(props[prop]);
}).join(', ') + '}';
}
function struct(props, name) {

@@ -302,8 +318,4 @@

var defaultName = '{' + Object.keys(props).map(function (prop) {
return prop + ': ' + getTypeName(props[prop]);
}).join(', ') + '}';
var displayName = name || getDefaultStructName(props);
var displayName = name || defaultName;
function Struct(value) {

@@ -372,2 +384,6 @@

function getDefaultUnionName(types) {
return types.map(getTypeName).join(' | ');
}
function union(types, name) {

@@ -380,6 +396,4 @@

var defaultName = types.map(getTypeName).join(' | ');
var displayName = name || getDefaultUnionName(types);
var displayName = name || defaultName;
function Union(value) {

@@ -426,2 +440,53 @@

function getDefaultIntersectionName(types) {
return types.map(getTypeName).join(' & ');
}
function intersection(types, name) {
if (process.env.NODE_ENV !== 'production') {
assert(isArray(types) && types.every(isFunction) && types.length >= 2, 'Invalid argument types = ' + exports.stringify(types) + ' supplied to intersection(types, name): expected an array of at least 2 types');
assert(isTypeName(name), 'Invalid argument name = ' + exports.stringify(name) + ' supplied to intersection(types, name): expected a string');
}
var displayName = name || getDefaultIntersectionName(types);
function Intersection(value) {
if (process.env.NODE_ENV !== 'production') {
forbidNewOperator(this, Intersection);
}
if (process.env.NODE_ENV !== 'production') {
assert(Intersection.is(value), 'Invalid argument value = ' + exports.stringify(value) + ' supplied to intersection ' + displayName);
}
return value;
}
Intersection.meta = {
kind: 'intersection',
types: types,
name: name
};
Intersection.displayName = displayName;
Intersection.is = function (x) {
return types.every(function (type) {
return is(x, type);
});
};
Intersection.update = function (instance, spec) {
return Intersection(exports.update(instance, spec));
};
return Intersection;
}
function getDefaultMaybeName(type) {
return '?' + getTypeName(type);
}
function maybe(type, name) {

@@ -441,3 +506,3 @@

name = name || ('?' + getTypeName(type));
name = name || getDefaultMaybeName(type);

@@ -466,2 +531,6 @@ function Maybe(value) {

function getDefaultEnumsName(map) {
return Object.keys(map).map(function (k) { return exports.stringify(k); }).join(' | ');
}
function enums(map, name) {

@@ -474,6 +543,4 @@

var defaultName = Object.keys(map).map(function (k) { return exports.stringify(k); }).join(' | ');
var displayName = name || getDefaultEnumsName(map);
var displayName = name || defaultName;
function Enums(value) {

@@ -511,2 +578,6 @@ if (process.env.NODE_ENV !== 'production') {

function getDefaultTupleName(types) {
return '[' + types.map(getTypeName).join(', ') + ']';
}
function tuple(types, name) {

@@ -519,6 +590,4 @@

var defaultName = '[' + types.map(getTypeName).join(', ') + ']';
var displayName = name || getDefaultTupleName(types);
var displayName = name || defaultName;
function isTuple(x) {

@@ -560,3 +629,2 @@ return types.every(function (type, i) {

types: types,
length: types.length,
name: name

@@ -580,2 +648,6 @@ };

function getDefaultSubtypeName(type, predicate) {
return '{' + getTypeName(type) + ' | ' + getFunctionName(predicate) + '}';
}
function subtype(type, predicate, name) {

@@ -589,6 +661,4 @@

var defaultName = '{' + getTypeName(type) + ' | ' + getFunctionName(predicate) + '}';
var displayName = name || getDefaultSubtypeName(type, predicate);
var displayName = name || defaultName;
function Subtype(value) {

@@ -629,2 +699,6 @@

function getDefaultListName(type) {
return 'Array<' + getTypeName(type) + '>';
}
function list(type, name) {

@@ -637,6 +711,4 @@

var defaultName = 'Array<' + getTypeName(type) + '>';
var displayName = name || getDefaultListName(type);
var displayName = name || defaultName;
function isList(x) {

@@ -660,2 +732,3 @@ return x.every(function (e) {

}
var arr = [];

@@ -693,2 +766,6 @@ for (var i = 0, len = value.length; i < len; i++ ) {

function getDefaultDictName(domain, codomain) {
return '{[key: ' + getTypeName(domain) + ']: ' + getTypeName(codomain) + '}';
}
function dict(domain, codomain, name) {

@@ -702,6 +779,4 @@

var defaultName = '{[key: ' + getTypeName(domain) + ']: ' + getTypeName(codomain) + '}';
var displayName = name || getDefaultDictName(domain, codomain);
var displayName = name || defaultName;
function isDict(x) {

@@ -771,2 +846,6 @@ for (var k in x) {

function getDefaultFuncName(domain, codomain) {
return '(' + domain.map(getTypeName).join(', ') + ') => ' + getTypeName(codomain);
}
function func(domain, codomain, name) {

@@ -782,6 +861,4 @@

var defaultName = '(' + domain.map(getTypeName).join(', ') + ') => ' + getTypeName(codomain);
var displayName = name || getDefaultFuncName(domain, codomain);
var displayName = name || defaultName;
function FuncType(value, uncurried) {

@@ -839,3 +916,2 @@

if (len === domain.length) {
/* jshint validthis: true */
return create(codomain, f.apply(this, args));

@@ -902,3 +978,4 @@ }

dict: dict,
func: func
func: func,
intersection: intersection
});
{
"name": "tcomb",
"version": "2.1.0",
"version": "2.2.0",
"description": "Type checking and DDD for JavaScript",

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

[![build status](https://img.shields.io/travis/gcanti/tcomb/master.svg?style=flat-square)](https://travis-ci.org/gcanti/tcomb)
[![dependency status](https://img.shields.io/david/gcanti/tcomb.svg?style=flat-square)](https://david-dm.org/gcanti/tcomb)
![npm downloads](https://img.shields.io/npm/dm/tcomb.svg)
[![Join the chat at https://gitter.im/gcanti/tcomb](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/gcanti/tcomb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
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 and concise syntax. It's great for **Domain Driven Design** and for adding safety to your internal code.
> "Si vis pacem, para bellum" - (Vegetius 5th century)
# Code example
```js
import t from 'tcomb';
// a user defined type
const Integer = t.subtype(t.Number, (n) => n % 1 === 0);
// a struct
const Person = t.struct({
name: t.String, // required string
surname: t.maybe(t.String), // optional string
age: Integer, // required integer
tags: t.list(t.String) // a list of strings
});
// methods are defined as usual
Person.prototype.getFullName = function () {
return `${this.name} ${this.surname}`;
};
// an instance of Person (the keyword new is optional)
const person = new Person({
name: 'Giulio',
surname: 'Canti',
age: 41,
tags: ['js developer', 'rock climber']
});
```
# Features

@@ -23,2 +56,3 @@

* unions
* intersections
* the option type

@@ -31,18 +65,38 @@ * tuples

Blog posts:
- [JavaScript, Types and Sets - Part I](https://gcanti.github.io/2014/09/29/javascript-types-and-sets.html)
- [JavaScript, Types and Sets - Part II](https://gcanti.github.io/2014/10/07/javascript-types-and-sets-part-II.html)
## Safety
## Type safety
All models defined by tcomb are type checked (using a built-in `assert(guard, [message])` function).
All models are type checked:
```js
const person = new Person({
name: 'Giulio',
// missing required field "age"
tags: ['js developer', 'rock climber']
});
```
Output to console:
```js
[tcomb] Invalid argument value = undefined supplied to irreducible type Number
```
See "Debugging with Chrome DevTools" section for details.
## Immutability and immutability helpers
Instances are immutables by default using `Object.freeze`. This means you can use standard JavaScript objects and arrays. You don't have to change how you normally code. You can update an immutable instance with the provided `update` function:
Instances are immutables using `Object.freeze`. This means you can use standard JavaScript objects and arrays. You don't have to change how you normally code. You can update an immutable instance with the provided `update(instance, spec)` function:
```js
MyType.update(instance, spec)
const person2 = Person.update(person, {
name: {$set: 'Guido'}
});
```
The following commands are compatible with the [Facebook Immutability Helpers](http://facebook.github.io/react/docs/update.html):
where `spec` is an object contaning *commands*. The following commands are compatible with the [Facebook Immutability Helpers](http://facebook.github.io/react/docs/update.html):

@@ -56,14 +110,14 @@ * `$push`

See [Updating immutable instances](GUIDE.md#updating-immutable-instances) in the docs for details.
## Speed
`Object.freeze` and the asserts are executed only during development and stripped out in production (using `process.env.NODE_ENV = 'production'` tests).
`Object.freeze` calls and asserts are executed only in development and stripped out in production (using `process.env.NODE_ENV = 'production'` tests).
## Debugging with Chrome DevTools
You can customize the behaviour when an assert fails leveraging the power of Chrome DevTools.
You can customize the behavior when an assert fails leveraging the power of Chrome DevTools.
```js
import t from 'tcomb';
// default behaviour
// use the default...
t.fail = function fail(message) {

@@ -73,6 +127,6 @@ throw new TypeError('[tcomb] ' + message); // set "Pause on exceptions" on the "Sources" panel

// .. or define your own handler
// .. or define your own behavior
t.fail = function fail(message) {
debugger; // starts the Chrome DevTools debugger
throw new TypeError('[tcomb] ' + message);
throw new TypeError(message);
};

@@ -83,44 +137,15 @@ ```

Every model is inspectable at runtime. You can read and reuse the informations stored in your types (in a `meta` object). See:
All models are inspectable at runtime. You can read and reuse the informations stored in your types (in a `meta` static property). See [The meta object](GUIDE.md#the-meta-object) in the docs for details.
Libraries exploiting tcomb's RTI:
- [tcomb-validation](https://github.com/gcanti/tcomb-validation)
- [tcomb-form](https://github.com/gcanti/tcomb-form)
- [JSON API Validation In Node.js](https://gcanti.github.io/2014/09/15/json-api-validation-in-node.html)
- Blog post: [JSON API Validation In Node.js](https://gcanti.github.io/2014/09/15/json-api-validation-in-node.html)
## Easy JSON serialization / deseralization
Encodes / decodes your domain models to / from JSON for free. See:
Encodes / decodes your domain models to / from JSON for free.
- Blog post: [JSON Deserialization Into An Object Model](https://gcanti.github.io/2014/09/12/json-deserialization-into-an-object-model.html)
- [JSON Deserialization Into An Object Model](https://gcanti.github.io/2014/09/12/json-deserialization-into-an-object-model.html)
# Code example
```js
import t from 'tcomb';
// a user defined type
const Integer = t.subtype(t.Number, (n) => n % 1 === 0);
// a struct
const Person = t.struct({
name: t.String, // required string
surname: t.maybe(t.String), // optional string
age: Integer, // required integer
tags: t.list(t.String) // a list of strings
});
// methods are defined as usual
Person.prototype.getFullName = function () {
return `${this.name} ${this.surname}`;
};
// an instance of Person (the keyword new is optional)
const person = new Person({
name: 'Giulio',
surname: 'Canti',
age: 41,
tags: ['js developer', 'rock climber']
});
```
# Docs

@@ -127,0 +152,0 @@

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