Comparing version 1.6.3 to 1.6.4
@@ -17,2 +17,10 @@ # Changelog | ||
# 1.6.4 | ||
- **Bug Fix** | ||
- `getIndexRecord`: getIndexRecord: handle conflicting tags in different positions, ref #263 (@gcanti) | ||
- **Experimental** | ||
- added a warning to the console if a tagged union cannot be created (@gcanti) | ||
- revert `union` optimization, needs more work to make it happen (@gcanti) | ||
# 1.6.3 | ||
@@ -19,0 +27,0 @@ |
@@ -583,3 +583,3 @@ import { Either } from 'fp-ts/lib/Either'; | ||
*/ | ||
export declare const union: <CS extends [Mixed, Mixed, ...Mixed[]]>(types: CS, name?: string) => UnionC<CS>; | ||
export declare const union: <CS extends [Mixed, Mixed, ...Mixed[]]>(codecs: CS, name?: string) => UnionC<CS>; | ||
/** | ||
@@ -609,6 +609,6 @@ * @since 1.0.0 | ||
*/ | ||
export declare function intersection<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed, E extends Mixed>(types: [A, B, C, D, E], name?: string): IntersectionC<[A, B, C, D, E]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed>(types: [A, B, C, D], name?: string): IntersectionC<[A, B, C, D]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed, C extends Mixed>(types: [A, B, C], name?: string): IntersectionC<[A, B, C]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed>(types: [A, B], name?: string): IntersectionC<[A, B]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed, E extends Mixed>(codecs: [A, B, C, D, E], name?: string): IntersectionC<[A, B, C, D, E]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed>(codecs: [A, B, C, D], name?: string): IntersectionC<[A, B, C, D]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed, C extends Mixed>(codecs: [A, B, C], name?: string): IntersectionC<[A, B, C]>; | ||
export declare function intersection<A extends Mixed, B extends Mixed>(codecs: [A, B], name?: string): IntersectionC<[A, B]>; | ||
/** | ||
@@ -630,7 +630,7 @@ * @since 1.0.0 | ||
*/ | ||
export declare function tuple<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed, E extends Mixed>(types: [A, B, C, D, E], name?: string): TupleC<[A, B, C, D, E]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed>(types: [A, B, C, D], name?: string): TupleC<[A, B, C, D]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed, C extends Mixed>(types: [A, B, C], name?: string): TupleC<[A, B, C]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed>(types: [A, B], name?: string): TupleC<[A, B]>; | ||
export declare function tuple<A extends Mixed>(types: [A], name?: string): TupleC<[A]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed, E extends Mixed>(codecs: [A, B, C, D, E], name?: string): TupleC<[A, B, C, D, E]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed, C extends Mixed, D extends Mixed>(codecs: [A, B, C, D], name?: string): TupleC<[A, B, C, D]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed, C extends Mixed>(codecs: [A, B, C], name?: string): TupleC<[A, B, C]>; | ||
export declare function tuple<A extends Mixed, B extends Mixed>(codecs: [A, B], name?: string): TupleC<[A, B]>; | ||
export declare function tuple<A extends Mixed>(codecs: [A], name?: string): TupleC<[A]>; | ||
/** | ||
@@ -731,10 +731,13 @@ * @since 1.0.0 | ||
export declare type Tagged<Tag extends string, A = any, O = A> = InterfaceType<TaggedProps<Tag>, A, O> | StrictType<TaggedProps<Tag>, A, O> | TaggedRefinement<Tag, A, O> | TaggedUnion<Tag, A, O> | TaggedIntersection<Tag, A, O> | TaggedExact<Tag, A, O> | RecursiveType<any, A, O>; | ||
interface Index extends Array<[unknown, Mixed]> { | ||
declare type IndexItem = [unknown, Any, Any]; | ||
interface Index extends Array<IndexItem> { | ||
} | ||
interface IndexRecord extends Record<string, Index> { | ||
} | ||
/** @internal */ | ||
export declare const emptyIndexRecord: IndexRecord; | ||
/** | ||
* @internal | ||
*/ | ||
export declare const getIndexRecord: (types: Mixed[]) => IndexRecord; | ||
export declare const getIndexRecord: (codecs: Mixed[]) => IndexRecord; | ||
/** | ||
@@ -745,3 +748,3 @@ * @since 1.3.0 | ||
readonly tag: Tag; | ||
constructor(name: string, is: TaggedUnionType<Tag, CS, A, O, I>['is'], validate: TaggedUnionType<Tag, CS, A, O, I>['validate'], encode: TaggedUnionType<Tag, CS, A, O, I>['encode'], types: CS, tag: Tag); | ||
constructor(name: string, is: TaggedUnionType<Tag, CS, A, O, I>['is'], validate: TaggedUnionType<Tag, CS, A, O, I>['validate'], encode: TaggedUnionType<Tag, CS, A, O, I>['encode'], codecs: CS, tag: Tag); | ||
} | ||
@@ -756,3 +759,3 @@ /** | ||
*/ | ||
export declare const taggedUnion: <Tag extends string, CS extends [Tagged<Tag, any, any>, Tagged<Tag, any, any>, ...Tagged<Tag, any, any>[]]>(tag: Tag, types: CS, name?: string) => TaggedUnionC<Tag, CS>; | ||
export declare const taggedUnion: <Tag extends string, CS extends [Tagged<Tag, any, any>, Tagged<Tag, any, any>, ...Tagged<Tag, any, any>[]]>(tag: Tag, codecs: CS, name?: string) => TaggedUnionC<Tag, CS>; | ||
/** | ||
@@ -759,0 +762,0 @@ * @since 1.1.0 |
207
lib/index.js
@@ -486,3 +486,3 @@ "use strict"; | ||
isRecursiveCodecIndexable = false; | ||
indexRecordCache = getCodecIndexRecord(definition(Self), Self); | ||
indexRecordCache = getCodecIndexRecord(definition(Self), Self, Self); | ||
isRecursiveCodecIndexable = true; | ||
@@ -562,5 +562,5 @@ } | ||
}; | ||
var useIdentity = function (types, len) { | ||
var useIdentity = function (codecs, len) { | ||
for (var i = 0; i < len; i++) { | ||
if (types[i].encode !== exports.identity) { | ||
if (codecs[i].encode !== exports.identity) { | ||
return false; | ||
@@ -818,48 +818,36 @@ } | ||
exports.UnionType = UnionType; | ||
var fst = function (r) { | ||
for (var k in r) { | ||
return [k, r[k]]; | ||
} | ||
return undefined; | ||
var getUnionName = function (codecs) { | ||
return '(' + codecs.map(function (type) { return type.name; }).join(' | ') + ')'; | ||
}; | ||
var getUnionName = function (types) { | ||
return '(' + types.map(function (type) { return type.name; }).join(' | ') + ')'; | ||
}; | ||
/** | ||
* @since 1.0.0 | ||
*/ | ||
exports.union = function (types, name) { | ||
if (name === void 0) { name = getUnionName(types); } | ||
var index = fst(exports.getIndexRecord(types)); | ||
if (index) { | ||
return taggedUnionWithIndex(index[1], index[0], types, name); | ||
} | ||
else { | ||
var len_1 = types.length; | ||
return new UnionType(name, function (u) { return types.some(function (type) { return type.is(u); }); }, function (u, c) { | ||
var errors = []; | ||
for (var i = 0; i < len_1; i++) { | ||
var type_3 = types[i]; | ||
var validation = type_3.validate(u, exports.appendContext(c, String(i), type_3)); | ||
if (validation.isRight()) { | ||
return validation; | ||
exports.union = function (codecs, name) { | ||
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)); | ||
if (validation.isRight()) { | ||
return validation; | ||
} | ||
else { | ||
pushAll(errors, validation.value); | ||
} | ||
} | ||
return errors.length ? exports.failures(errors) : exports.failure(u, c); | ||
}, useIdentity(codecs, len) | ||
? exports.identity | ||
: function (a) { | ||
var i = 0; | ||
for (; i < len - 1; i++) { | ||
var type_4 = codecs[i]; | ||
if (type_4.is(a)) { | ||
return type_4.encode(a); | ||
} | ||
else { | ||
pushAll(errors, validation.value); | ||
} | ||
} | ||
return errors.length ? exports.failures(errors) : exports.failure(u, c); | ||
}, useIdentity(types, len_1) | ||
? exports.identity | ||
: function (a) { | ||
var i = 0; | ||
for (; i < len_1 - 1; i++) { | ||
var type_4 = types[i]; | ||
if (type_4.is(a)) { | ||
return type_4.encode(a); | ||
} | ||
} | ||
return types[i].encode(a); | ||
}, types); | ||
} | ||
return codecs[i].encode(a); | ||
}, codecs); | ||
}; | ||
@@ -880,10 +868,10 @@ /** | ||
exports.IntersectionType = IntersectionType; | ||
function intersection(types, name) { | ||
if (name === void 0) { name = "(" + types.map(function (type) { return type.name; }).join(' & ') + ")"; } | ||
var len = types.length; | ||
return new IntersectionType(name, function (u) { return (len === 0 ? false : types.every(function (type) { return type.is(u); })); }, function (u, c) { | ||
function intersection(codecs, name) { | ||
if (name === void 0) { name = "(" + codecs.map(function (type) { return type.name; }).join(' & ') + ")"; } | ||
var len = codecs.length; | ||
return new IntersectionType(name, function (u) { return (len === 0 ? false : codecs.every(function (type) { return type.is(u); })); }, function (u, c) { | ||
var a = u; | ||
var errors = []; | ||
for (var i = 0; i < len; i++) { | ||
var type_5 = types[i]; | ||
var type_5 = codecs[i]; | ||
var validation = type_5.validate(a, exports.appendContext(c, String(i), type_5)); | ||
@@ -898,3 +886,3 @@ if (validation.isLeft()) { | ||
return errors.length ? exports.failures(errors) : len === 0 ? exports.failure(u, c) : exports.success(a); | ||
}, useIdentity(types, len) | ||
}, useIdentity(codecs, len) | ||
? exports.identity | ||
@@ -904,7 +892,7 @@ : function (a) { | ||
for (var i = 0; i < len; i++) { | ||
var type_6 = types[i]; | ||
var type_6 = codecs[i]; | ||
s = type_6.encode(s); | ||
} | ||
return s; | ||
}, types); | ||
}, codecs); | ||
} | ||
@@ -926,6 +914,6 @@ exports.intersection = intersection; | ||
exports.TupleType = TupleType; | ||
function tuple(types, name) { | ||
if (name === void 0) { name = "[" + types.map(function (type) { return type.name; }).join(', ') + "]"; } | ||
var len = types.length; | ||
return new TupleType(name, function (u) { return arrayType.is(u) && u.length === len && types.every(function (type, i) { return type.is(u[i]); }); }, function (u, c) { | ||
function tuple(codecs, name) { | ||
if (name === void 0) { name = "[" + codecs.map(function (type) { return type.name; }).join(', ') + "]"; } | ||
var len = codecs.length; | ||
return new TupleType(name, function (u) { return arrayType.is(u) && u.length === len && codecs.every(function (type, i) { return type.is(u[i]); }); }, function (u, c) { | ||
var arrayValidation = arrayType.validate(u, c); | ||
@@ -941,3 +929,3 @@ if (arrayValidation.isLeft()) { | ||
var a = as[i]; | ||
var type_7 = types[i]; | ||
var type_7 = codecs[i]; | ||
var validation = type_7.validate(a, exports.appendContext(c, String(i), type_7)); | ||
@@ -963,3 +951,3 @@ if (validation.isLeft()) { | ||
} | ||
}, useIdentity(types, len) ? exports.identity : function (a) { return types.map(function (type, i) { return type.encode(a[i]); }); }, types); | ||
}, useIdentity(codecs, len) ? exports.identity : function (a) { return codecs.map(function (type, i) { return type.encode(a[i]); }); }, codecs); | ||
} | ||
@@ -1050,2 +1038,4 @@ exports.tuple = tuple; | ||
}; | ||
/** @internal */ | ||
exports.emptyIndexRecord = {}; | ||
var monoidIndexRecord = { | ||
@@ -1073,4 +1063,10 @@ concat: function (a, b) { | ||
}, | ||
empty: {} | ||
empty: exports.emptyIndexRecord | ||
}; | ||
var isIndexRecordEmpty = function (a) { | ||
for (var _ in a) { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
var foldMapIndexRecord = function (as, f) { | ||
@@ -1086,4 +1082,13 @@ return as.reduce(function (acc, a) { return monoidIndexRecord.concat(acc, f(a)); }, monoidIndexRecord.empty); | ||
}; | ||
var getCodecIndexRecord = function (codec, override) { | ||
if (override === void 0) { override = codec; } | ||
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)) { | ||
@@ -1095,3 +1100,3 @@ var interfaceIndex = {}; | ||
var value = prop.value; | ||
interfaceIndex[k] = [[value, override]]; | ||
interfaceIndex[k] = [[value, origin, id]]; | ||
} | ||
@@ -1102,12 +1107,16 @@ } | ||
else if (isIntersectionCodec(codec)) { | ||
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, codec); }); | ||
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, origin, codec); }); | ||
} | ||
else if (isUnionCodec(codec)) { | ||
return exports.getIndexRecord(codec.types); | ||
return foldMapIndexRecord(codec.types, function (type) { return getCodecIndexRecord(type, origin, type); }); | ||
} | ||
else if (isExactCodec(codec) || isRefinementCodec(codec)) { | ||
return getCodecIndexRecord(codec.type, codec); | ||
return getCodecIndexRecord(codec.type, origin, codec); | ||
} | ||
else if (isRecursiveCodec(codec)) { | ||
return codec.getIndexRecord(); | ||
var indexRecord = codec.getIndexRecord(); | ||
if (codec !== origin) { | ||
return updateindexRecordOrigin(origin, indexRecord); | ||
} | ||
return indexRecord; | ||
} | ||
@@ -1130,10 +1139,12 @@ else { | ||
*/ | ||
exports.getIndexRecord = function (types) { | ||
var len = types.length; | ||
if (len === 0 || !types.every(isIndexableCodec)) { | ||
return {}; | ||
exports.getIndexRecord = function (codecs) { | ||
var len = codecs.length; | ||
if (len === 0 || !codecs.every(isIndexableCodec)) { | ||
return monoidIndexRecord.empty; | ||
} | ||
var ir = cloneIndexRecord(getCodecIndexRecord(types[0])); | ||
var firstCodec = codecs[0]; | ||
var ir = cloneIndexRecord(getCodecIndexRecord(firstCodec, firstCodec, firstCodec)); | ||
for (var i = 1; i < len; i++) { | ||
var cir = getCodecIndexRecord(types[i]); | ||
var codec = codecs[i]; | ||
var cir = getCodecIndexRecord(codec, codec, codec); | ||
for (var k in ir) { | ||
@@ -1144,11 +1155,11 @@ if (cir.hasOwnProperty(k)) { | ||
var _loop_1 = function (j) { | ||
var pair = cis[j]; | ||
var indexItem = cis[j]; | ||
var index = is.findIndex(function (_a) { | ||
var v = _a[0]; | ||
return v === pair[0]; | ||
return v === indexItem[0]; | ||
}); | ||
if (index === -1) { | ||
is.push(pair); | ||
is.push(indexItem); | ||
} | ||
else if (cis[index][1] !== is[index][1]) { | ||
else if (indexItem[2] !== is[index][2]) { | ||
delete ir[k]; | ||
@@ -1170,11 +1181,18 @@ return "break-loop"; | ||
} | ||
return ir; | ||
return isIndexRecordEmpty(ir) ? monoidIndexRecord.empty : ir; | ||
}; | ||
var taggedUnionWithIndex = function (index, tag, types, name) { | ||
var len = types.length; | ||
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 find = function (tagValue) { | ||
for (var i = 0; i < index.length; i++) { | ||
var pair = index[i]; | ||
if (pair[0] === tagValue) { | ||
return [i, pair[1]]; | ||
for (var i = 0; i < indexWithPosition.length; i++) { | ||
var _a = indexWithPosition[i], value = _a[0], position = _a[1]; | ||
if (value === tagValue) { | ||
return [i, codecs[position]]; | ||
} | ||
@@ -1207,6 +1225,6 @@ } | ||
} | ||
var _a = find(tagValue), typeIndex = _a[0], type_8 = _a[1]; | ||
return type_8.validate(d, exports.appendContext(c, String(typeIndex), type_8)); | ||
var _a = find(tagValue), i = _a[0], type_8 = _a[1]; | ||
return type_8.validate(d, exports.appendContext(c, String(i), type_8)); | ||
} | ||
}, useIdentity(types, len) ? exports.identity : function (a) { return find(a[tag])[1].encode(a); }, types, tag); | ||
}, useIdentity(codecs, len) ? exports.identity : function (a) { return find(a[tag])[1].encode(a); }, codecs, tag); | ||
}; | ||
@@ -1218,4 +1236,4 @@ /** | ||
__extends(TaggedUnionType, _super); | ||
function TaggedUnionType(name, is, validate, encode, types, tag) { | ||
var _this = _super.call(this, name, is, validate, encode, types) /* istanbul ignore next */ // <= workaround for https://github.com/Microsoft/TypeScript/issues/13455 | ||
function TaggedUnionType(name, is, validate, 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 | ||
|| this; | ||
@@ -1231,11 +1249,14 @@ _this.tag = tag; | ||
*/ | ||
exports.taggedUnion = function (tag, types, name) { | ||
if (name === void 0) { name = getUnionName(types); } | ||
var indexRecord = exports.getIndexRecord(types); | ||
exports.taggedUnion = function (tag, codecs, name) { | ||
if (name === void 0) { name = getUnionName(codecs); } | ||
var indexRecord = exports.getIndexRecord(codecs); | ||
if (!indexRecord.hasOwnProperty(tag)) { | ||
var U = exports.union(types, name); | ||
return new TaggedUnionType(name, U.is, U.validate, U.encode, types, tag); | ||
if (isRecursiveCodecIndexable && codecs.length > 0) { | ||
console.warn("[io-ts] Cannot build a tagged union for (B | A), returning a de-optimized union"); | ||
} | ||
var U = exports.union(codecs, name); | ||
return new TaggedUnionType(name, U.is, U.validate, U.encode, codecs, tag); | ||
} | ||
else { | ||
return taggedUnionWithIndex(indexRecord[tag], tag, types, name); | ||
return getTaggedUnion(indexRecord[tag], tag, codecs, name); | ||
} | ||
@@ -1242,0 +1263,0 @@ }; |
{ | ||
"name": "io-ts", | ||
"version": "1.6.3", | ||
"version": "1.6.4", | ||
"description": "TypeScript compatible runtime type system for IO validation", | ||
@@ -5,0 +5,0 @@ "files": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100369
2220