Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

io-ts

Package Overview
Dependencies
Maintainers
1
Versions
120
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

io-ts - npm Package Compare versions

Comparing version 1.8.6 to 1.9.0

7

CHANGELOG.md

@@ -17,2 +17,9 @@ # Changelog

# 1.9.0
- **New Feature**
- `union` is now able to detect and optimize tagged unions (@gcanti)
- **Deprecation**
- deprecate `taggedUnion` in favour of `union` (@gcanti)
# 1.8.6

@@ -19,0 +26,0 @@

14

es6/index.d.ts

@@ -678,2 +678,3 @@ import { Either } from 'fp-ts/lib/Either';

* @since 1.3.0
* @deprecated
*/

@@ -686,7 +687,12 @@ export declare class TaggedUnionType<Tag extends string, CS extends Array<Mixed>, A = any, O = A, I = unknown> extends UnionType<CS, A, O, I> {

* @since 1.5.3
* @deprecated
*/
export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Array<Mixed>]> extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {
export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Array<Mixed>]>// tslint:disable-next-line: deprecation
extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {
}
/**
* Use `union` instead
*
* @since 1.3.0
* @deprecated
*/

@@ -871,3 +877,4 @@ export declare const taggedUnion: <Tag extends string, CS extends [Mixed, Mixed, ...Mixed[]]>(tag: Tag, codecs: CS, name?: string) => TaggedUnionC<Tag, CS>;

*/
export interface StrictC<P extends Props> extends StrictType<P, {
export interface StrictC<P extends Props>// tslint:disable-next-line: deprecation
extends StrictType<P, {
[K in keyof P]: TypeOf<P[K]>;

@@ -906,3 +913,4 @@ }, {

*/
export interface TaggedIntersection<Tag extends string, A, O = A> extends IntersectionType<TaggedIntersectionArgument<Tag>, A, O> {
export interface TaggedIntersection<Tag extends string, A, O = A>// tslint:disable-next-line: deprecation
extends IntersectionType<TaggedIntersectionArgument<Tag>, A, O> {
}

@@ -909,0 +917,0 @@ /**

@@ -117,12 +117,6 @@ var __extends = (this && this.__extends) || (function () {

var isUnknownCodec = getIsCodec('UnknownType');
// tslint:disable-next-line: deprecation
var isAnyCodec = getIsCodec('AnyType');
var isLiteralCodec = getIsCodec('LiteralType');
var isInterfaceCodec = getIsCodec('InterfaceType');
var isPartialCodec = getIsCodec('PartialType');
var isStrictCodec = getIsCodec('StrictType');
var isIntersectionCodec = getIsCodec('IntersectionType');
var isUnionCodec = getIsCodec('UnionType');
var isExactCodec = getIsCodec('ExactType');
var isRefinementCodec = getIsCodec('RefinementType');
var isRecursiveCodec = getIsCodec('RecursiveType');
//

@@ -303,2 +297,3 @@ // basic types

*/
// tslint:disable-next-line: deprecation
export var Function = new FunctionType();

@@ -324,2 +319,3 @@ /**

export var brand = function (codec, predicate, name) {
// tslint:disable-next-line: deprecation
return refinement(codec, predicate, name);

@@ -413,11 +409,2 @@ };

var Self = new RecursiveType(name, function (u) { return runDefinition().is(u); }, function (u, c) { return runDefinition().validate(u, c); }, function (a) { return runDefinition().encode(a); }, runDefinition);
var indexRecordCache;
Self.getIndexRecord = function () {
if (!indexRecordCache) {
isRecursiveCodecIndexable = false;
indexRecordCache = getCodecIndexRecord(definition(Self), Self, Self);
isRecursiveCodecIndexable = true;
}
return indexRecordCache;
};
return Self;

@@ -491,4 +478,4 @@ };

};
var useIdentity = function (codecs, len) {
for (var i = 0; i < len; i++) {
var useIdentity = function (codecs) {
for (var i = 0; i < codecs.length; i++) {
if (codecs[i].encode !== identity) {

@@ -557,3 +544,3 @@ return false;

return errors.length > 0 ? failures(errors) : success(a);
}, useIdentity(types, len)
}, useIdentity(types)
? identity

@@ -637,3 +624,3 @@ : function (a) {

return errors.length > 0 ? failures(errors) : success(a);
}, useIdentity(types, len)
}, useIdentity(types)
? identity

@@ -753,26 +740,71 @@ : function (a) {

if (name === void 0) { name = getUnionName(codecs); }
var len = codecs.length;
return new UnionType(name, function (u) { return codecs.some(function (type) { return type.is(u); }); }, function (u, c) {
var errors = [];
for (var i = 0; i < len; i++) {
var type_3 = codecs[i];
var validation = type_3.validate(u, appendContext(c, String(i), type_3, u));
if (validation.isRight()) {
return validation;
var index = getIndex(codecs);
if (index !== undefined && codecs.length > 0) {
var tag_1 = index[0], groups_1 = index[1];
var len_1 = groups_1.length;
var find_1 = function (value) {
for (var i = 0; i < len_1; i++) {
if (groups_1[i].indexOf(value) !== -1) {
return i;
}
}
pushAll(errors, validation.value);
}
return errors.length > 0 ? failures(errors) : failure(u, c);
}, useIdentity(codecs, len)
? identity
: function (a) {
for (var i = 0; i < len; i++) {
return undefined;
};
// tslint:disable-next-line: deprecation
return new TaggedUnionType(name, function (u) {
if (!UnknownRecord.is(u)) {
return false;
}
var i = find_1(u[tag_1]);
return i !== undefined ? codecs[i].is(u) : false;
}, function (u, c) {
var dictionaryResult = UnknownRecord.validate(u, c);
if (dictionaryResult.isLeft()) {
return dictionaryResult;
}
var r = dictionaryResult.value;
var i = find_1(r[tag_1]);
if (i === undefined) {
return failure(u, c);
}
var codec = codecs[i];
return codec.validate(r, appendContext(c, String(i), codec, r));
}, useIdentity(codecs)
? identity
: function (a) {
var i = find_1(a[tag_1]);
if (i === undefined) {
// https://github.com/gcanti/io-ts/pull/305
throw new Error("no codec found to encode value in union codec " + name);
}
else {
return codecs[i].encode(a);
}
}, codecs, tag_1);
}
else {
return new UnionType(name, function (u) { return codecs.some(function (type) { return type.is(u); }); }, function (u, c) {
var errors = [];
for (var i = 0; i < codecs.length; i++) {
var codec = codecs[i];
if (codec.is(a)) {
return codec.encode(a);
var validation = codec.validate(u, appendContext(c, String(i), codec, u));
if (validation.isRight()) {
return validation;
}
pushAll(errors, validation.value);
}
// https://github.com/gcanti/io-ts/pull/305
throw new Error("no codec found to encode value in union type " + name);
}, codecs);
return failures(errors);
}, useIdentity(codecs)
? identity
: function (a) {
for (var _i = 0, codecs_1 = codecs; _i < codecs_1.length; _i++) {
var codec = codecs_1[_i];
if (codec.is(a)) {
return codec.encode(a);
}
}
// https://github.com/gcanti/io-ts/pull/305
throw new Error("no codec found to encode value in union type " + name);
}, codecs);
}
};

@@ -860,4 +892,4 @@ /**

var a = us[i];
var type_4 = codecs[i];
var validation = type_4.validate(a, appendContext(c, String(i), type_4, a));
var type_3 = codecs[i];
var validation = type_3.validate(a, appendContext(c, String(i), type_3, a));
if (validation.isLeft()) {

@@ -878,3 +910,3 @@ pushAll(errors, validation.value);

return errors.length > 0 ? failures(errors) : success(as);
}, useIdentity(codecs, len) ? identity : function (a) { return codecs.map(function (type, i) { return type.encode(a[i]); }); }, codecs);
}, useIdentity(codecs) ? identity : function (a) { return codecs.map(function (type, i) { return type.encode(a[i]); }); }, codecs);
}

@@ -945,181 +977,15 @@ /**

};
/** @internal */
export var emptyIndexRecord = {};
var monoidIndexRecord = {
concat: function (a, b) {
var _a;
if (a === monoidIndexRecord.empty) {
return b;
}
if (b === monoidIndexRecord.empty) {
return a;
}
var r = cloneIndexRecord(a);
for (var k in b) {
if (r.hasOwnProperty(k)) {
(_a = r[k]).push.apply(_a, b[k]);
}
else {
r[k] = b[k];
}
}
return r;
},
empty: emptyIndexRecord
};
var isIndexRecordEmpty = function (a) {
for (var _ in a) {
return false;
}
return true;
};
var foldMapIndexRecord = function (as, f) {
return as.reduce(function (acc, a) { return monoidIndexRecord.concat(acc, f(a)); }, monoidIndexRecord.empty);
};
var cloneIndexRecord = function (a) {
var r = {};
for (var k in a) {
r[k] = a[k].slice();
}
return r;
};
var updateindexRecordOrigin = function (origin, indexRecord) {
var r = {};
for (var k in indexRecord) {
r[k] = indexRecord[k].map(function (_a) {
var v = _a[0], _ = _a[1], id = _a[2];
return [v, origin, id];
});
}
return r;
};
var getCodecIndexRecord = function (codec, origin, id) {
if (isInterfaceCodec(codec) || isStrictCodec(codec)) {
var interfaceIndex = {};
for (var k in codec.props) {
var prop = codec.props[k];
if (isLiteralCodec(prop)) {
var value = prop.value;
interfaceIndex[k] = [[value, origin, id]];
}
}
return interfaceIndex;
}
if (isIntersectionCodec(codec)) {
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, origin, codec); });
}
if (isUnionCodec(codec)) {
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, origin, type); });
}
if (isExactCodec(codec) || isRefinementCodec(codec)) {
return getCodecIndexRecord(codec.type, origin, codec);
}
if (isRecursiveCodec(codec)) {
var indexRecord = codec.getIndexRecord();
if (codec !== origin) {
return updateindexRecordOrigin(origin, indexRecord);
}
return indexRecord;
}
return monoidIndexRecord.empty;
};
var isRecursiveCodecIndexable = true;
var isIndexableCodec = function (codec) {
return (((isInterfaceCodec(codec) || isStrictCodec(codec)) &&
Object.keys(codec.props).some(function (key) { return isLiteralCodec(codec.props[key]); })) ||
((isExactCodec(codec) || isRefinementCodec(codec)) && isIndexableCodec(codec.type)) ||
(isIntersectionCodec(codec) && codec.types.some(isIndexableCodec)) ||
(isUnionCodec(codec) && codec.types.every(isIndexableCodec)) ||
(isRecursiveCodecIndexable && isRecursiveCodec(codec)));
};
/**
* @internal
*/
export var getIndexRecord = function (codecs) {
var len = codecs.length;
if (len === 0 || !codecs.every(isIndexableCodec)) {
return monoidIndexRecord.empty;
}
var firstCodec = codecs[0];
var ir = cloneIndexRecord(getCodecIndexRecord(firstCodec, firstCodec, firstCodec));
for (var i = 1; i < len; i++) {
var codec = codecs[i];
var cir = getCodecIndexRecord(codec, codec, codec);
for (var k in ir) {
if (cir.hasOwnProperty(k)) {
var is = ir[k];
var cis = cir[k];
var _loop_1 = function (j) {
var indexItem = cis[j];
var index = is.findIndex(function (_a) {
var v = _a[0];
return v === indexItem[0];
});
if (index === -1) {
is.push(indexItem);
}
else if (indexItem[2] !== is[index][2]) {
delete ir[k];
return "break";
}
};
for (var j = 0; j < cis.length; j++) {
var state_1 = _loop_1(j);
if (state_1 === "break")
break;
}
}
else {
delete ir[k];
}
}
}
return isIndexRecordEmpty(ir) ? monoidIndexRecord.empty : ir;
};
var getTaggedUnion = function (index, tag, codecs, name) {
var len = codecs.length;
var indexWithPosition = index.map(function (_a) {
var v = _a[0], origin = _a[1];
return [
v,
codecs.findIndex(function (codec) { return codec === origin; })
];
});
var findIndex = function (tagValue) {
for (var i = 0; i < indexWithPosition.length; i++) {
var _a = indexWithPosition[i], value = _a[0], position = _a[1];
if (value === tagValue) {
return position;
}
}
};
var isTagValue = function (u) { return findIndex(u) !== undefined; };
return new TaggedUnionType(name, function (u) {
if (!UnknownRecord.is(u)) {
return false;
}
var tagValue = u[tag];
var index = findIndex(tagValue);
return index !== undefined ? codecs[index].is(u) : false;
}, function (u, c) {
var dictionaryResult = UnknownRecord.validate(u, c);
if (dictionaryResult.isLeft()) {
return dictionaryResult;
}
var d = dictionaryResult.value;
var tagValue = d[tag];
if (!isTagValue(tagValue)) {
return failure(u, c);
}
var index = findIndex(tagValue);
var codec = codecs[index];
return codec.validate(d, appendContext(c, String(index), codec, d));
}, useIdentity(codecs, len) ? identity : function (a) { return codecs[findIndex(a[tag])].encode(a); }, codecs, tag);
};
/**
* @since 1.3.0
* @deprecated
*/
var TaggedUnionType = /** @class */ (function (_super) {
__extends(TaggedUnionType, _super);
function TaggedUnionType(name, is, validate, encode, codecs, tag) {
function TaggedUnionType(name,
// tslint:disable-next-line: deprecation
is,
// tslint:disable-next-line: deprecation
validate,
// tslint:disable-next-line: deprecation
encode, codecs, tag) {
var _this = _super.call(this, name, is, validate, encode, codecs) /* istanbul ignore next */ // <= workaround for https://github.com/Microsoft/TypeScript/issues/13455

@@ -1134,15 +1000,21 @@ || this;

/**
* Use `union` instead
*
* @since 1.3.0
* @deprecated
*/
export var taggedUnion = function (tag, codecs, name) {
export var taggedUnion = function (tag, codecs, name
// tslint:disable-next-line: deprecation
) {
if (name === void 0) { name = getUnionName(codecs); }
var indexRecord = getIndexRecord(codecs);
if (!indexRecord.hasOwnProperty(tag)) {
if (isRecursiveCodecIndexable && codecs.length > 0) {
console.warn("[io-ts] Cannot build a tagged union for " + name + ", returning a de-optimized union");
}
var U = union(codecs, name);
var U = union(codecs, name);
// tslint:disable-next-line: deprecation
if (U instanceof TaggedUnionType) {
return U;
}
else {
console.warn("[io-ts] Cannot build a tagged union for " + name + ", returning a de-optimized union");
// tslint:disable-next-line: deprecation
return new TaggedUnionType(name, U.is, U.validate, U.encode, codecs, tag);
}
return getTaggedUnion(indexRecord[tag], tag, codecs, name);
};

@@ -1269,2 +1141,3 @@ /**

*/
// tslint:disable-next-line: deprecation
export var never = new NeverType();

@@ -1290,2 +1163,3 @@ /**

*/
// tslint:disable-next-line: deprecation
export var any = new AnyType();

@@ -1317,2 +1191,3 @@ /**

*/
// tslint:disable-next-line: deprecation
export var object = new ObjectType();

@@ -1340,2 +1215,3 @@ /**

*/
// tslint:disable-next-line: deprecation
export var Integer = refinement(number, Number.isInteger, 'Integer');

@@ -1354,3 +1230,9 @@ /**

__extends(StrictType, _super);
function StrictType(name, is, validate, encode, props) {
function StrictType(name,
// tslint:disable-next-line: deprecation
is,
// tslint:disable-next-line: deprecation
validate,
// tslint:disable-next-line: deprecation
encode, props) {
var _this = _super.call(this, name, is, validate, encode) || this;

@@ -1375,1 +1257,151 @@ _this.props = props;

}
var isNonEmpty = function (as) { return as.length > 0; };
/**
* @internal
*/
export var emptyTags = {};
function intersect(a, b) {
var r = [];
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
var v = a_1[_i];
if (b.indexOf(v) !== -1) {
r.push(v);
}
}
return r;
}
function mergeTags(a, b) {
if (a === emptyTags) {
return b;
}
if (b === emptyTags) {
return a;
}
var r = Object.assign({}, a);
for (var k in b) {
if (a.hasOwnProperty(k)) {
var intersection_1 = intersect(a[k], b[k]);
if (isNonEmpty(intersection_1)) {
r[k] = intersection_1;
}
else {
r = emptyTags;
break;
}
}
else {
r[k] = b[k];
}
}
return r;
}
function intersectTags(a, b) {
if (a === emptyTags || b === emptyTags) {
return emptyTags;
}
var r = emptyTags;
for (var k in a) {
if (b.hasOwnProperty(k)) {
var intersection_2 = intersect(a[k], b[k]);
if (intersection_2.length === 0) {
if (r === emptyTags) {
r = {};
}
r[k] = a[k].concat(b[k]);
}
}
}
return r;
}
function isLiteralC(codec) {
return codec._tag === 'LiteralType';
}
function isTypeC(codec) {
return codec._tag === 'InterfaceType';
}
function isIntersectionC(codec) {
return codec._tag === 'IntersectionType';
}
function isUnionC(codec) {
return codec._tag === 'UnionType';
}
function isRecursiveC(codec) {
return codec._tag === 'RecursiveType';
}
var lazyCodec = null;
/**
* @internal
*/
export function getTags(codec) {
if (codec === lazyCodec) {
return emptyTags;
}
if (isTypeC(codec)) {
var index = emptyTags;
// tslint:disable-next-line: forin
for (var k in codec.props) {
var prop = codec.props[k];
if (isLiteralC(prop)) {
if (index === emptyTags) {
index = {};
}
index[k] = [prop.value];
}
}
return index;
}
else if (isIntersectionC(codec)) {
return codec.types.reduce(function (tags, codec) { return mergeTags(tags, getTags(codec)); }, emptyTags);
}
else if (isUnionC(codec)) {
return codec.types.slice(1).reduce(function (tags, codec) { return intersectTags(tags, getTags(codec)); }, getTags(codec.types[0]));
}
else if (isRecursiveC(codec)) {
lazyCodec = codec;
var tags = getTags(codec.type);
lazyCodec = null;
return tags;
}
return emptyTags;
}
/**
* @internal
*/
export function getIndex(codecs) {
var tags = getTags(codecs[0]);
var keys = Object.keys(tags);
var len = codecs.length;
var _loop_1 = function (k) {
var all = tags[k].slice();
var index = [tags[k]];
for (var i = 1; i < len; i++) {
var codec = codecs[i];
var ctags = getTags(codec);
var values = ctags[k];
// tslint:disable-next-line: strict-type-predicates
if (values === undefined) {
return "continue-keys";
}
else {
if (values.some(function (v) { return all.indexOf(v) !== -1; })) {
return "continue-keys";
}
else {
all.push.apply(all, values);
index.push(values);
}
}
}
return { value: [k, index] };
};
keys: for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var k = keys_1[_i];
var state_1 = _loop_1(k);
if (typeof state_1 === "object")
return state_1.value;
switch (state_1) {
case "continue-keys": continue keys;
}
}
return undefined;
}

@@ -678,2 +678,3 @@ import { Either } from 'fp-ts/lib/Either';

* @since 1.3.0
* @deprecated
*/

@@ -686,7 +687,12 @@ export declare class TaggedUnionType<Tag extends string, CS extends Array<Mixed>, A = any, O = A, I = unknown> extends UnionType<CS, A, O, I> {

* @since 1.5.3
* @deprecated
*/
export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Array<Mixed>]> extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {
export interface TaggedUnionC<Tag extends string, CS extends [Mixed, Mixed, ...Array<Mixed>]>// tslint:disable-next-line: deprecation
extends TaggedUnionType<Tag, CS, TypeOf<CS[number]>, OutputOf<CS[number]>, unknown> {
}
/**
* Use `union` instead
*
* @since 1.3.0
* @deprecated
*/

@@ -871,3 +877,4 @@ export declare const taggedUnion: <Tag extends string, CS extends [Mixed, Mixed, ...Mixed[]]>(tag: Tag, codecs: CS, name?: string) => TaggedUnionC<Tag, CS>;

*/
export interface StrictC<P extends Props> extends StrictType<P, {
export interface StrictC<P extends Props>// tslint:disable-next-line: deprecation
extends StrictType<P, {
[K in keyof P]: TypeOf<P[K]>;

@@ -906,3 +913,4 @@ }, {

*/
export interface TaggedIntersection<Tag extends string, A, O = A> extends IntersectionType<TaggedIntersectionArgument<Tag>, A, O> {
export interface TaggedIntersection<Tag extends string, A, O = A>// tslint:disable-next-line: deprecation
extends IntersectionType<TaggedIntersectionArgument<Tag>, A, O> {
}

@@ -909,0 +917,0 @@ /**

@@ -119,12 +119,6 @@ "use strict";

var isUnknownCodec = getIsCodec('UnknownType');
// tslint:disable-next-line: deprecation
var isAnyCodec = getIsCodec('AnyType');
var isLiteralCodec = getIsCodec('LiteralType');
var isInterfaceCodec = getIsCodec('InterfaceType');
var isPartialCodec = getIsCodec('PartialType');
var isStrictCodec = getIsCodec('StrictType');
var isIntersectionCodec = getIsCodec('IntersectionType');
var isUnionCodec = getIsCodec('UnionType');
var isExactCodec = getIsCodec('ExactType');
var isRefinementCodec = getIsCodec('RefinementType');
var isRecursiveCodec = getIsCodec('RecursiveType');
//

@@ -309,2 +303,3 @@ // basic types

*/
// tslint:disable-next-line: deprecation
exports.Function = new FunctionType();

@@ -330,2 +325,3 @@ /**

exports.brand = function (codec, predicate, name) {
// tslint:disable-next-line: deprecation
return refinement(codec, predicate, name);

@@ -419,11 +415,2 @@ };

var Self = new RecursiveType(name, function (u) { return runDefinition().is(u); }, function (u, c) { return runDefinition().validate(u, c); }, function (a) { return runDefinition().encode(a); }, runDefinition);
var indexRecordCache;
Self.getIndexRecord = function () {
if (!indexRecordCache) {
isRecursiveCodecIndexable = false;
indexRecordCache = getCodecIndexRecord(definition(Self), Self, Self);
isRecursiveCodecIndexable = true;
}
return indexRecordCache;
};
return Self;

@@ -497,4 +484,4 @@ };

};
var useIdentity = function (codecs, len) {
for (var i = 0; i < len; i++) {
var useIdentity = function (codecs) {
for (var i = 0; i < codecs.length; i++) {
if (codecs[i].encode !== exports.identity) {

@@ -563,3 +550,3 @@ return false;

return errors.length > 0 ? exports.failures(errors) : exports.success(a);
}, useIdentity(types, len)
}, useIdentity(types)
? exports.identity

@@ -644,3 +631,3 @@ : function (a) {

return errors.length > 0 ? exports.failures(errors) : exports.success(a);
}, useIdentity(types, len)
}, useIdentity(types)
? exports.identity

@@ -760,26 +747,71 @@ : function (a) {

if (name === void 0) { name = getUnionName(codecs); }
var len = codecs.length;
return new UnionType(name, function (u) { return codecs.some(function (type) { return type.is(u); }); }, function (u, c) {
var errors = [];
for (var i = 0; i < len; i++) {
var type_3 = codecs[i];
var validation = type_3.validate(u, exports.appendContext(c, String(i), type_3, u));
if (validation.isRight()) {
return validation;
var index = getIndex(codecs);
if (index !== undefined && codecs.length > 0) {
var tag_1 = index[0], groups_1 = index[1];
var len_1 = groups_1.length;
var find_1 = function (value) {
for (var i = 0; i < len_1; i++) {
if (groups_1[i].indexOf(value) !== -1) {
return i;
}
}
pushAll(errors, validation.value);
}
return errors.length > 0 ? exports.failures(errors) : exports.failure(u, c);
}, useIdentity(codecs, len)
? exports.identity
: function (a) {
for (var i = 0; i < len; i++) {
return undefined;
};
// tslint:disable-next-line: deprecation
return new TaggedUnionType(name, function (u) {
if (!exports.UnknownRecord.is(u)) {
return false;
}
var i = find_1(u[tag_1]);
return i !== undefined ? codecs[i].is(u) : false;
}, function (u, c) {
var dictionaryResult = exports.UnknownRecord.validate(u, c);
if (dictionaryResult.isLeft()) {
return dictionaryResult;
}
var r = dictionaryResult.value;
var i = find_1(r[tag_1]);
if (i === undefined) {
return exports.failure(u, c);
}
var codec = codecs[i];
return codec.validate(r, exports.appendContext(c, String(i), codec, r));
}, useIdentity(codecs)
? exports.identity
: function (a) {
var i = find_1(a[tag_1]);
if (i === undefined) {
// https://github.com/gcanti/io-ts/pull/305
throw new Error("no codec found to encode value in union codec " + name);
}
else {
return codecs[i].encode(a);
}
}, codecs, tag_1);
}
else {
return new UnionType(name, function (u) { return codecs.some(function (type) { return type.is(u); }); }, function (u, c) {
var errors = [];
for (var i = 0; i < codecs.length; i++) {
var codec = codecs[i];
if (codec.is(a)) {
return codec.encode(a);
var validation = codec.validate(u, exports.appendContext(c, String(i), codec, u));
if (validation.isRight()) {
return validation;
}
pushAll(errors, validation.value);
}
// https://github.com/gcanti/io-ts/pull/305
throw new Error("no codec found to encode value in union type " + name);
}, codecs);
return exports.failures(errors);
}, useIdentity(codecs)
? exports.identity
: function (a) {
for (var _i = 0, codecs_1 = codecs; _i < codecs_1.length; _i++) {
var codec = codecs_1[_i];
if (codec.is(a)) {
return codec.encode(a);
}
}
// https://github.com/gcanti/io-ts/pull/305
throw new Error("no codec found to encode value in union type " + name);
}, codecs);
}
};

@@ -868,4 +900,4 @@ /**

var a = us[i];
var type_4 = codecs[i];
var validation = type_4.validate(a, exports.appendContext(c, String(i), type_4, a));
var type_3 = codecs[i];
var validation = type_3.validate(a, exports.appendContext(c, String(i), type_3, a));
if (validation.isLeft()) {

@@ -886,3 +918,3 @@ pushAll(errors, validation.value);

return errors.length > 0 ? exports.failures(errors) : exports.success(as);
}, useIdentity(codecs, len) ? exports.identity : function (a) { return codecs.map(function (type, i) { return type.encode(a[i]); }); }, codecs);
}, useIdentity(codecs) ? exports.identity : function (a) { return codecs.map(function (type, i) { return type.encode(a[i]); }); }, codecs);
}

@@ -954,181 +986,15 @@ exports.tuple = tuple;

};
/** @internal */
exports.emptyIndexRecord = {};
var monoidIndexRecord = {
concat: function (a, b) {
var _a;
if (a === monoidIndexRecord.empty) {
return b;
}
if (b === monoidIndexRecord.empty) {
return a;
}
var r = cloneIndexRecord(a);
for (var k in b) {
if (r.hasOwnProperty(k)) {
(_a = r[k]).push.apply(_a, b[k]);
}
else {
r[k] = b[k];
}
}
return r;
},
empty: exports.emptyIndexRecord
};
var isIndexRecordEmpty = function (a) {
for (var _ in a) {
return false;
}
return true;
};
var foldMapIndexRecord = function (as, f) {
return as.reduce(function (acc, a) { return monoidIndexRecord.concat(acc, f(a)); }, monoidIndexRecord.empty);
};
var cloneIndexRecord = function (a) {
var r = {};
for (var k in a) {
r[k] = a[k].slice();
}
return r;
};
var updateindexRecordOrigin = function (origin, indexRecord) {
var r = {};
for (var k in indexRecord) {
r[k] = indexRecord[k].map(function (_a) {
var v = _a[0], _ = _a[1], id = _a[2];
return [v, origin, id];
});
}
return r;
};
var getCodecIndexRecord = function (codec, origin, id) {
if (isInterfaceCodec(codec) || isStrictCodec(codec)) {
var interfaceIndex = {};
for (var k in codec.props) {
var prop = codec.props[k];
if (isLiteralCodec(prop)) {
var value = prop.value;
interfaceIndex[k] = [[value, origin, id]];
}
}
return interfaceIndex;
}
if (isIntersectionCodec(codec)) {
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, origin, codec); });
}
if (isUnionCodec(codec)) {
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, origin, type); });
}
if (isExactCodec(codec) || isRefinementCodec(codec)) {
return getCodecIndexRecord(codec.type, origin, codec);
}
if (isRecursiveCodec(codec)) {
var indexRecord = codec.getIndexRecord();
if (codec !== origin) {
return updateindexRecordOrigin(origin, indexRecord);
}
return indexRecord;
}
return monoidIndexRecord.empty;
};
var isRecursiveCodecIndexable = true;
var isIndexableCodec = function (codec) {
return (((isInterfaceCodec(codec) || isStrictCodec(codec)) &&
Object.keys(codec.props).some(function (key) { return isLiteralCodec(codec.props[key]); })) ||
((isExactCodec(codec) || isRefinementCodec(codec)) && isIndexableCodec(codec.type)) ||
(isIntersectionCodec(codec) && codec.types.some(isIndexableCodec)) ||
(isUnionCodec(codec) && codec.types.every(isIndexableCodec)) ||
(isRecursiveCodecIndexable && isRecursiveCodec(codec)));
};
/**
* @internal
*/
exports.getIndexRecord = function (codecs) {
var len = codecs.length;
if (len === 0 || !codecs.every(isIndexableCodec)) {
return monoidIndexRecord.empty;
}
var firstCodec = codecs[0];
var ir = cloneIndexRecord(getCodecIndexRecord(firstCodec, firstCodec, firstCodec));
for (var i = 1; i < len; i++) {
var codec = codecs[i];
var cir = getCodecIndexRecord(codec, codec, codec);
for (var k in ir) {
if (cir.hasOwnProperty(k)) {
var is = ir[k];
var cis = cir[k];
var _loop_1 = function (j) {
var indexItem = cis[j];
var index = is.findIndex(function (_a) {
var v = _a[0];
return v === indexItem[0];
});
if (index === -1) {
is.push(indexItem);
}
else if (indexItem[2] !== is[index][2]) {
delete ir[k];
return "break";
}
};
for (var j = 0; j < cis.length; j++) {
var state_1 = _loop_1(j);
if (state_1 === "break")
break;
}
}
else {
delete ir[k];
}
}
}
return isIndexRecordEmpty(ir) ? monoidIndexRecord.empty : ir;
};
var getTaggedUnion = function (index, tag, codecs, name) {
var len = codecs.length;
var indexWithPosition = index.map(function (_a) {
var v = _a[0], origin = _a[1];
return [
v,
codecs.findIndex(function (codec) { return codec === origin; })
];
});
var findIndex = function (tagValue) {
for (var i = 0; i < indexWithPosition.length; i++) {
var _a = indexWithPosition[i], value = _a[0], position = _a[1];
if (value === tagValue) {
return position;
}
}
};
var isTagValue = function (u) { return findIndex(u) !== undefined; };
return new TaggedUnionType(name, function (u) {
if (!exports.UnknownRecord.is(u)) {
return false;
}
var tagValue = u[tag];
var index = findIndex(tagValue);
return index !== undefined ? codecs[index].is(u) : false;
}, function (u, c) {
var dictionaryResult = exports.UnknownRecord.validate(u, c);
if (dictionaryResult.isLeft()) {
return dictionaryResult;
}
var d = dictionaryResult.value;
var tagValue = d[tag];
if (!isTagValue(tagValue)) {
return exports.failure(u, c);
}
var index = findIndex(tagValue);
var codec = codecs[index];
return codec.validate(d, exports.appendContext(c, String(index), codec, d));
}, useIdentity(codecs, len) ? exports.identity : function (a) { return codecs[findIndex(a[tag])].encode(a); }, codecs, tag);
};
/**
* @since 1.3.0
* @deprecated
*/
var TaggedUnionType = /** @class */ (function (_super) {
__extends(TaggedUnionType, _super);
function TaggedUnionType(name, is, validate, encode, codecs, tag) {
function TaggedUnionType(name,
// tslint:disable-next-line: deprecation
is,
// tslint:disable-next-line: deprecation
validate,
// tslint:disable-next-line: deprecation
encode, codecs, tag) {
var _this = _super.call(this, name, is, validate, encode, codecs) /* istanbul ignore next */ // <= workaround for https://github.com/Microsoft/TypeScript/issues/13455

@@ -1143,15 +1009,21 @@ || this;

/**
* Use `union` instead
*
* @since 1.3.0
* @deprecated
*/
exports.taggedUnion = function (tag, codecs, name) {
exports.taggedUnion = function (tag, codecs, name
// tslint:disable-next-line: deprecation
) {
if (name === void 0) { name = getUnionName(codecs); }
var indexRecord = exports.getIndexRecord(codecs);
if (!indexRecord.hasOwnProperty(tag)) {
if (isRecursiveCodecIndexable && codecs.length > 0) {
console.warn("[io-ts] Cannot build a tagged union for " + name + ", returning a de-optimized union");
}
var U = exports.union(codecs, name);
var U = exports.union(codecs, name);
// tslint:disable-next-line: deprecation
if (U instanceof TaggedUnionType) {
return U;
}
else {
console.warn("[io-ts] Cannot build a tagged union for " + name + ", returning a de-optimized union");
// tslint:disable-next-line: deprecation
return new TaggedUnionType(name, U.is, U.validate, U.encode, codecs, tag);
}
return getTaggedUnion(indexRecord[tag], tag, codecs, name);
};

@@ -1265,2 +1137,3 @@ /**

*/
// tslint:disable-next-line: deprecation
exports.never = new NeverType();

@@ -1286,2 +1159,3 @@ /**

*/
// tslint:disable-next-line: deprecation
exports.any = new AnyType();

@@ -1313,2 +1187,3 @@ /**

*/
// tslint:disable-next-line: deprecation
exports.object = new ObjectType();

@@ -1337,2 +1212,3 @@ /**

*/
// tslint:disable-next-line: deprecation
exports.Integer = refinement(exports.number, Number.isInteger, 'Integer');

@@ -1351,3 +1227,9 @@ /**

__extends(StrictType, _super);
function StrictType(name, is, validate, encode, props) {
function StrictType(name,
// tslint:disable-next-line: deprecation
is,
// tslint:disable-next-line: deprecation
validate,
// tslint:disable-next-line: deprecation
encode, props) {
var _this = _super.call(this, name, is, validate, encode) || this;

@@ -1374,1 +1256,153 @@ _this.props = props;

exports.alias = alias;
var isNonEmpty = function (as) { return as.length > 0; };
/**
* @internal
*/
exports.emptyTags = {};
function intersect(a, b) {
var r = [];
for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
var v = a_1[_i];
if (b.indexOf(v) !== -1) {
r.push(v);
}
}
return r;
}
function mergeTags(a, b) {
if (a === exports.emptyTags) {
return b;
}
if (b === exports.emptyTags) {
return a;
}
var r = Object.assign({}, a);
for (var k in b) {
if (a.hasOwnProperty(k)) {
var intersection_1 = intersect(a[k], b[k]);
if (isNonEmpty(intersection_1)) {
r[k] = intersection_1;
}
else {
r = exports.emptyTags;
break;
}
}
else {
r[k] = b[k];
}
}
return r;
}
function intersectTags(a, b) {
if (a === exports.emptyTags || b === exports.emptyTags) {
return exports.emptyTags;
}
var r = exports.emptyTags;
for (var k in a) {
if (b.hasOwnProperty(k)) {
var intersection_2 = intersect(a[k], b[k]);
if (intersection_2.length === 0) {
if (r === exports.emptyTags) {
r = {};
}
r[k] = a[k].concat(b[k]);
}
}
}
return r;
}
function isLiteralC(codec) {
return codec._tag === 'LiteralType';
}
function isTypeC(codec) {
return codec._tag === 'InterfaceType';
}
function isIntersectionC(codec) {
return codec._tag === 'IntersectionType';
}
function isUnionC(codec) {
return codec._tag === 'UnionType';
}
function isRecursiveC(codec) {
return codec._tag === 'RecursiveType';
}
var lazyCodec = null;
/**
* @internal
*/
function getTags(codec) {
if (codec === lazyCodec) {
return exports.emptyTags;
}
if (isTypeC(codec)) {
var index = exports.emptyTags;
// tslint:disable-next-line: forin
for (var k in codec.props) {
var prop = codec.props[k];
if (isLiteralC(prop)) {
if (index === exports.emptyTags) {
index = {};
}
index[k] = [prop.value];
}
}
return index;
}
else if (isIntersectionC(codec)) {
return codec.types.reduce(function (tags, codec) { return mergeTags(tags, getTags(codec)); }, exports.emptyTags);
}
else if (isUnionC(codec)) {
return codec.types.slice(1).reduce(function (tags, codec) { return intersectTags(tags, getTags(codec)); }, getTags(codec.types[0]));
}
else if (isRecursiveC(codec)) {
lazyCodec = codec;
var tags = getTags(codec.type);
lazyCodec = null;
return tags;
}
return exports.emptyTags;
}
exports.getTags = getTags;
/**
* @internal
*/
function getIndex(codecs) {
var tags = getTags(codecs[0]);
var keys = Object.keys(tags);
var len = codecs.length;
var _loop_1 = function (k) {
var all = tags[k].slice();
var index = [tags[k]];
for (var i = 1; i < len; i++) {
var codec = codecs[i];
var ctags = getTags(codec);
var values = ctags[k];
// tslint:disable-next-line: strict-type-predicates
if (values === undefined) {
return "continue-keys";
}
else {
if (values.some(function (v) { return all.indexOf(v) !== -1; })) {
return "continue-keys";
}
else {
all.push.apply(all, values);
index.push(values);
}
}
}
return { value: [k, index] };
};
keys: for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
var k = keys_1[_i];
var state_1 = _loop_1(k);
if (typeof state_1 === "object")
return state_1.value;
switch (state_1) {
case "continue-keys": continue keys;
}
}
return undefined;
}
exports.getIndex = getIndex;
{
"name": "io-ts",
"version": "1.8.6",
"version": "1.9.0",
"description": "TypeScript compatible runtime type system for IO validation",

@@ -14,7 +14,7 @@ "files": [

"scripts": {
"lint": "tslint -p tsconfig.json src/**/*.ts test/**/*.ts",
"lint": "tslint -p tsconfig.tslint.json src/**/*.ts test/**/*.ts",
"jest": "jest",
"prettier": "prettier --no-semi --single-quote --print-width 120 --parser typescript --list-different \"{src,test}/**/*.ts\"",
"fix-prettier": "prettier --no-semi --single-quote --print-width 120 --parser typescript --write \"{src,test,examples,exercises}/**/*.ts\"",
"test": "npm run prettier && npm run lint && npm run dtslint && npm run declaration && npm run jest",
"test": "npm run prettier && npm run lint && npm run dtslint && npm run declaration && npm run jest && npm run docs",
"clean": "rimraf lib/* es6/*",

@@ -48,3 +48,3 @@ "build": "npm run clean && tsc && tsc -p tsconfig.es6.json",

"benchmark": "2.1.4",
"docs-ts": "0.0.1",
"docs-ts": "0.0.3",
"doctoc": "^1.4.0",

@@ -51,0 +51,0 @@ "dtslint": "github:gcanti/dtslint",

@@ -20,3 +20,2 @@ [![build status](https://img.shields.io/travis/gcanti/io-ts/master.svg?style=flat-square)](https://travis-ci.org/gcanti/io-ts)

- [Mutually recursive types](#mutually-recursive-types)
- [Tagged unions](#tagged-unions)
- [Branded types / Refinements](#branded-types--refinements)

@@ -254,3 +253,3 @@ - [Exact types](#exact-types)

| tuple | `[ A, B ]` | `t.tuple([ A, B ])` |
| union | `A \| B` | `t.union([ A, B ])` or `t.taggedUnion(tag, [ A, B ])` |
| union | `A \| B` | `t.union([ A, B ])` |
| intersection | `A & B` | `t.intersection([ A, B ])` |

@@ -310,22 +309,2 @@ | keyof | `keyof M` | `t.keyof(M)` (**only supports string keys**) |

# Tagged unions
If you are encoding tagged unions, instead of the general purpose `union` combinator, you may want to use the
`taggedUnion` combinator in order to get better performances
```ts
const A = t.type({
tag: t.literal('A'),
foo: t.string
})
const B = t.type({
tag: t.literal('B'),
bar: t.number
})
// the actual presence of the tag is statically checked
const U = t.taggedUnion('tag', [A, B])
```
# Branded types / Refinements

@@ -332,0 +311,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