Comparing version 0.4.0 to 0.5.0
@@ -15,2 +15,10 @@ # Changelog | ||
# 0.5.0 | ||
- **Breaking Change** | ||
- `Type` is now an interface | ||
- types no more own a `is` method, use `t.is` instead | ||
- unions no more own a `fold` method | ||
- `Reporter`, `PathReporter`, `ThrowReporter` are now top level modules | ||
# 0.4.0 | ||
@@ -17,0 +25,0 @@ |
@@ -16,10 +16,9 @@ import { Either } from 'fp-ts/lib/Either'; | ||
export declare type Any = Type<any>; | ||
export declare type TypeOf<RT extends Any> = RT['t']; | ||
export declare class Type<A> { | ||
export declare type TypeOf<RT extends Any> = RT['_A']; | ||
export interface Type<A> { | ||
readonly _A: A; | ||
readonly name: string; | ||
readonly validate: Validate<A>; | ||
readonly t: A; | ||
constructor(name: string, validate: Validate<A>); | ||
is(x: any): x is A; | ||
} | ||
export declare const _A: never; | ||
export declare function getFunctionName(f: any): string; | ||
@@ -29,2 +28,3 @@ export declare function failure<T>(value: any, context: Context): Validation<T>; | ||
export declare function validate<T>(value: any, type: Type<T>): Validation<T>; | ||
export declare function is<T>(value: any, type: Type<T>): value is T; | ||
declare module 'fp-ts/lib/HKT' { | ||
@@ -37,53 +37,83 @@ interface HKT<A> { | ||
export declare type URI = typeof URI; | ||
export declare class MapType<RT extends Any, B> extends Type<B> { | ||
export interface MapType<RT extends Any, B> extends Type<B> { | ||
readonly _tag: 'MapType'; | ||
readonly type: RT; | ||
readonly f: (a: TypeOf<RT>) => B; | ||
constructor(name: string, type: RT, f: (a: TypeOf<RT>) => B); | ||
} | ||
export declare function map<RT extends Any, B>(f: (a: TypeOf<RT>) => B, type: RT): MapType<RT, B>; | ||
export declare function mapWithName<RT extends Any, B>(f: (a: TypeOf<RT>) => B, type: RT, name: string): MapType<RT, B>; | ||
export declare type GetOption<S, A> = (s: S) => Option<A>; | ||
export declare class PrismType<RT extends Any, B> extends Type<B> { | ||
readonly type: RT; | ||
readonly getOption: GetOption<TypeOf<RT>, B>; | ||
constructor(name: string, type: RT, getOption: GetOption<TypeOf<RT>, B>); | ||
export interface NullType extends Type<null> { | ||
readonly _tag: 'NullType'; | ||
} | ||
export declare function prism<RT extends Any, B>(type: RT, getOption: GetOption<TypeOf<RT>, B>, name?: string): PrismType<RT, B>; | ||
declare const nullType: Type<null>; | ||
declare const undefinedType: Type<undefined>; | ||
export declare const any: Type<any>; | ||
export declare const never: Type<never>; | ||
export declare const string: Type<string>; | ||
export declare const number: Type<number>; | ||
export declare const boolean: Type<boolean>; | ||
declare const arrayType: Type<Array<any>>; | ||
export declare const Dictionary: Type<{ | ||
declare const nullType: NullType; | ||
export interface UndefinedType extends Type<undefined> { | ||
readonly _tag: 'UndefinedType'; | ||
} | ||
declare const undefinedType: UndefinedType; | ||
export interface AnyType extends Type<any> { | ||
readonly _tag: 'AnyType'; | ||
} | ||
export declare const any: AnyType; | ||
export interface NeverType extends Type<never> { | ||
readonly _tag: 'NeverType'; | ||
} | ||
export declare const never: NeverType; | ||
export interface StringType extends Type<string> { | ||
readonly _tag: 'StringType'; | ||
} | ||
export declare const string: StringType; | ||
export interface NumberType extends Type<number> { | ||
readonly _tag: 'NumberType'; | ||
} | ||
export declare const number: NumberType; | ||
export interface BooleanType extends Type<boolean> { | ||
readonly _tag: 'BooleanType'; | ||
} | ||
export declare const boolean: BooleanType; | ||
export interface AnyArrayType extends Type<Array<any>> { | ||
readonly _tag: 'AnyArrayType'; | ||
} | ||
declare const arrayType: AnyArrayType; | ||
export interface AnyDictionaryType extends Type<{ | ||
[key: string]: any; | ||
}>; | ||
declare const functionType: Type<Function>; | ||
export declare class RefinementType<RT extends Any> extends Type<TypeOf<RT>> { | ||
}> { | ||
readonly _tag: 'AnyDictionaryType'; | ||
} | ||
export declare const Dictionary: AnyDictionaryType; | ||
export interface FunctionType extends Type<Function> { | ||
readonly _tag: 'FunctionType'; | ||
} | ||
declare const functionType: FunctionType; | ||
export interface RefinementType<RT extends Any> extends Type<TypeOf<RT>> { | ||
readonly _tag: 'RefinementType'; | ||
readonly type: RT; | ||
readonly predicate: Predicate<TypeOf<RT>>; | ||
constructor(name: string, validate: Validate<TypeOf<RT>>, type: RT, predicate: Predicate<TypeOf<RT>>); | ||
} | ||
export declare function refinement<RT extends Any>(type: RT, predicate: Predicate<TypeOf<RT>>, name?: string): RefinementType<RT>; | ||
export declare const Integer: RefinementType<Type<number>>; | ||
export declare class LiteralType<T> extends Type<T> { | ||
export declare const Integer: RefinementType<NumberType>; | ||
export declare type GetOption<S, A> = (s: S) => Option<A>; | ||
export interface PrismType<RT extends Any, B> extends Type<B> { | ||
readonly _tag: 'PrismType'; | ||
readonly type: RT; | ||
readonly getOption: GetOption<TypeOf<RT>, B>; | ||
} | ||
export declare function prism<RT extends Any, B>(type: RT, getOption: GetOption<TypeOf<RT>, B>, name?: string): PrismType<RT, B>; | ||
export interface LiteralType<T> extends Type<T> { | ||
readonly _tag: 'LiteralType'; | ||
readonly value: T; | ||
constructor(name: string, validate: Validate<T>, value: T); | ||
} | ||
export declare function literal<T extends string | number | boolean>(value: T): LiteralType<T>; | ||
export declare class KeyofType<D extends { | ||
export interface KeyofType<D extends { | ||
[key: string]: any; | ||
}> extends Type<keyof D> { | ||
readonly _tag: 'KeyofType'; | ||
readonly keys: D; | ||
constructor(name: string, validate: Validate<keyof D>, keys: D); | ||
} | ||
export declare function keyof<D extends { | ||
[key: string]: any; | ||
}>(map: D, name?: string): KeyofType<D>; | ||
}>(keys: D, name?: string): KeyofType<D>; | ||
export declare function recursion<T>(name: string, definition: (self: Any) => Any): Type<T>; | ||
export declare class ArrayType<RT extends Any> extends Type<Array<TypeOf<RT>>> { | ||
export interface ArrayType<RT extends Any> extends Type<Array<TypeOf<RT>>> { | ||
readonly _tag: 'ArrayType'; | ||
readonly type: RT; | ||
constructor(name: string, validate: Validate<Array<TypeOf<RT>>>, type: RT); | ||
} | ||
@@ -97,5 +127,5 @@ export declare function array<RT extends Any>(type: RT, name?: string): ArrayType<RT>; | ||
}; | ||
export declare class InterfaceType<P extends Props> extends Type<InterfaceOf<P>> { | ||
export interface InterfaceType<P extends Props> extends Type<InterfaceOf<P>> { | ||
readonly _tag: 'InterfaceType'; | ||
readonly props: P; | ||
constructor(name: string, validate: Validate<InterfaceOf<P>>, props: P); | ||
} | ||
@@ -109,26 +139,18 @@ declare function interfaceType<P extends Props>(props: P, name?: string): InterfaceType<P>; | ||
}; | ||
export declare class PartialType<P extends Props> extends Type<PartialOf<P>> { | ||
export interface PartialType<P extends Props> extends Type<PartialOf<P>> { | ||
readonly _tag: 'PartialType'; | ||
readonly props: PartialPropsOf<P>; | ||
constructor(name: string, validate: Validate<PartialOf<P>>, props: PartialPropsOf<P>); | ||
} | ||
export declare function partial<P extends Props>(props: P, name?: string): PartialType<P>; | ||
export declare class DictionaryType<D extends Type<string>, C extends Any> extends Type<{ | ||
export interface DictionaryType<D extends Type<string>, C extends Any> extends Type<{ | ||
[key: string]: TypeOf<C>; | ||
}> { | ||
readonly _tag: 'DictionaryType'; | ||
readonly domain: D; | ||
readonly codomain: C; | ||
constructor(name: string, validate: Validate<{ | ||
[key: string]: TypeOf<C>; | ||
}>, domain: D, codomain: C); | ||
} | ||
export declare function dictionary<D extends Type<string>, C extends Any>(domain: D, codomain: C, name?: string): DictionaryType<D, C>; | ||
export declare type Match<RT extends Any, R> = (a: TypeOf<RT>) => R; | ||
export declare class UnionType<RTS extends Array<Any>, U> extends Type<U> { | ||
export interface UnionType<RTS extends Array<Any>, U> extends Type<U> { | ||
readonly _tag: 'UnionType'; | ||
readonly types: RTS; | ||
constructor(name: string, validate: Validate<U>, types: RTS); | ||
fold<R>(a: Match<RTS[0], R>, b: Match<RTS[1], R>, c: Match<RTS[2], R>, d: Match<RTS[3], R>, e: Match<RTS[4], R>): (value: U) => R; | ||
fold<R>(a: Match<RTS[0], R>, b: Match<RTS[1], R>, c: Match<RTS[2], R>, d: Match<RTS[3], R>): (value: U) => R; | ||
fold<R>(a: Match<RTS[0], R>, b: Match<RTS[1], R>, c: Match<RTS[2], R>): (value: U) => R; | ||
fold<R>(a: Match<RTS[0], R>, b: Match<RTS[1], R>): (value: U) => R; | ||
fold<R>(a: Match<RTS[0], R>): (value: U) => R; | ||
} | ||
@@ -140,5 +162,5 @@ export declare function union<A extends Any, B extends Any, C extends Any, D extends Any, E extends Any>(types: [A, B, C, D, E], name?: string): UnionType<[A, B, C, D, E], TypeOf<A> | TypeOf<B> | TypeOf<C> | TypeOf<D> | TypeOf<E>>; | ||
export declare function union<A extends Any>(types: [A], name?: string): UnionType<[A], TypeOf<A>>; | ||
export declare class IntersectionType<RTS, I> extends Type<I> { | ||
export interface IntersectionType<RTS extends Array<Any>, I> extends Type<I> { | ||
readonly _tag: 'IntersectionType'; | ||
readonly types: RTS; | ||
constructor(name: string, validate: Validate<I>, types: RTS); | ||
} | ||
@@ -150,5 +172,5 @@ export declare function intersection<A extends Any, B extends Any, C extends Any, D extends Any, E extends Any>(types: [A, B, C, D, E], name?: string): IntersectionType<[A, B, C, D, E], TypeOf<A> & TypeOf<B> & TypeOf<C> & TypeOf<D> & TypeOf<E>>; | ||
export declare function intersection<A extends Any>(types: [A], name?: string): IntersectionType<[A], TypeOf<A>>; | ||
export declare class TupleType<RTS, T> extends Type<T> { | ||
export interface TupleType<RTS extends Array<Any>, I> extends Type<I> { | ||
readonly _tag: 'TupleType'; | ||
readonly types: RTS; | ||
constructor(name: string, validate: Validate<T>, types: RTS); | ||
} | ||
@@ -160,12 +182,12 @@ export declare function tuple<A extends Any, B extends Any, C extends Any, D extends Any, E extends Any>(types: [A, B, C, D, E], name?: string): TupleType<[A, B, C, D, E], [TypeOf<A>, TypeOf<B>, TypeOf<C>, TypeOf<D>, TypeOf<E>]>; | ||
export declare function tuple<A extends Any>(types: [A], name?: string): TupleType<[A], [TypeOf<A>]>; | ||
export declare class ReadonlyType<RT extends Any> extends Type<Readonly<TypeOf<RT>>> { | ||
export interface ReadonlyType<RT extends Any> extends Type<Readonly<TypeOf<RT>>> { | ||
readonly _tag: 'ReadonlyType'; | ||
readonly type: RT; | ||
constructor(name: string, validate: Validate<Readonly<TypeOf<RT>>>, type: RT); | ||
} | ||
export declare function readonly<RT extends Any>(type: RT, name?: string): ReadonlyType<RT>; | ||
export declare class ReadonlyArrayType<RT extends Any> extends Type<ReadonlyArray<TypeOf<RT>>> { | ||
export interface ReadonlyArrayType<RT extends Any> extends Type<ReadonlyArray<TypeOf<RT>>> { | ||
readonly _tag: 'ReadonlyArrayType'; | ||
readonly type: RT; | ||
constructor(name: string, validate: Validate<ReadonlyArray<TypeOf<RT>>>, type: RT); | ||
} | ||
export declare function readonlyArray<RT extends Any>(type: RT, name?: string): ReadonlyArrayType<RT>; | ||
export { nullType as null, undefinedType as undefined, arrayType as Array, functionType as Function, interfaceType as interface }; |
619
lib/index.js
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __assign = (this && this.__assign) || Object.assign || function(t) { | ||
@@ -22,15 +12,3 @@ for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
var Either_1 = require("fp-ts/lib/Either"); | ||
; | ||
; | ||
var Type = (function () { | ||
function Type(name, validate) { | ||
this.name = name; | ||
this.validate = validate; | ||
} | ||
Type.prototype.is = function (x) { | ||
return Either_1.isRight(validate(x, this)); | ||
}; | ||
return Type; | ||
}()); | ||
exports.Type = Type; | ||
exports._A = null; | ||
function getFunctionName(f) { | ||
@@ -64,14 +42,7 @@ return f.displayName || f.name || "<function" + f.length + ">"; | ||
exports.validate = validate; | ||
function is(value, type) { | ||
return Either_1.isRight(validate(value, type)); | ||
} | ||
exports.is = is; | ||
exports.URI = 'io-ts/Type'; | ||
var MapType = (function (_super) { | ||
__extends(MapType, _super); | ||
function MapType(name, type, f) { | ||
var _this = _super.call(this, name, function (v, c) { return type.validate(v, c).map(f); }) || this; | ||
_this.type = type; | ||
_this.f = f; | ||
return _this; | ||
} | ||
return MapType; | ||
}(Type)); | ||
exports.MapType = MapType; | ||
function map(f, type) { | ||
@@ -82,88 +53,117 @@ return mapWithName(f, type, "(" + type.name + " => ?)"); | ||
function mapWithName(f, type, name) { | ||
return new MapType(name, type, f); | ||
return { | ||
_A: exports._A, | ||
_tag: 'MapType', | ||
name: name, | ||
validate: function (v, c) { return type.validate(v, c).map(f); }, | ||
type: type, | ||
f: f | ||
}; | ||
} | ||
exports.mapWithName = mapWithName; | ||
var PrismType = (function (_super) { | ||
__extends(PrismType, _super); | ||
function PrismType(name, type, getOption) { | ||
var _this = _super.call(this, name, function (v, c) { return type.validate(v, c).chain(function (a) { return getOption(a).fold(function () { return failure(a, c); }, function (b) { return success(b); }); }); }) || this; | ||
_this.type = type; | ||
_this.getOption = getOption; | ||
return _this; | ||
} | ||
return PrismType; | ||
}(Type)); | ||
exports.PrismType = PrismType; | ||
function prism(type, getOption, name) { | ||
return new PrismType(name || "Prism<" + type.name + ", ?>", type, getOption); | ||
} | ||
exports.prism = prism; | ||
// | ||
// default types | ||
// | ||
var nullType = new Type('null', function (v, c) { return v === null ? success(v) : failure(v, c); }); | ||
var nullType = { | ||
_A: exports._A, | ||
_tag: 'NullType', | ||
name: 'null', | ||
validate: function (v, c) { return (v === null ? success(v) : failure(v, c)); } | ||
}; | ||
exports.null = nullType; | ||
var undefinedType = new Type('undefined', function (v, c) { return v === void 0 ? success(v) : failure(v, c); }); | ||
var undefinedType = { | ||
_A: exports._A, | ||
_tag: 'UndefinedType', | ||
name: 'undefined', | ||
validate: function (v, c) { return (v === void 0 ? success(v) : failure(v, c)); } | ||
}; | ||
exports.undefined = undefinedType; | ||
exports.any = new Type('any', function (v, _) { return success(v); }); | ||
exports.never = new Type('never', function (v, c) { return failure(v, c); }); | ||
exports.string = new Type('string', function (v, c) { return typeof v === 'string' ? success(v) : failure(v, c); }); | ||
exports.number = new Type('number', function (v, c) { return typeof v === 'number' ? success(v) : failure(v, c); }); | ||
exports.boolean = new Type('boolean', function (v, c) { return typeof v === 'boolean' ? success(v) : failure(v, c); }); | ||
var arrayType = new Type('Array', function (v, c) { return Array.isArray(v) ? success(v) : failure(v, c); }); | ||
exports.any = { | ||
_A: exports._A, | ||
_tag: 'AnyType', | ||
name: 'any', | ||
validate: function (v, _) { return success(v); } | ||
}; | ||
exports.never = { | ||
_A: exports._A, | ||
_tag: 'NeverType', | ||
name: 'never', | ||
validate: function (v, c) { return failure(v, c); } | ||
}; | ||
exports.string = { | ||
_A: exports._A, | ||
_tag: 'StringType', | ||
name: 'string', | ||
validate: function (v, c) { return (typeof v === 'string' ? success(v) : failure(v, c)); } | ||
}; | ||
exports.number = { | ||
_A: exports._A, | ||
_tag: 'NumberType', | ||
name: 'number', | ||
validate: function (v, c) { return (typeof v === 'number' ? success(v) : failure(v, c)); } | ||
}; | ||
exports.boolean = { | ||
_A: exports._A, | ||
_tag: 'BooleanType', | ||
name: 'boolean', | ||
validate: function (v, c) { return (typeof v === 'boolean' ? success(v) : failure(v, c)); } | ||
}; | ||
var arrayType = { | ||
_A: exports._A, | ||
_tag: 'AnyArrayType', | ||
name: 'Array', | ||
validate: function (v, c) { return (Array.isArray(v) ? success(v) : failure(v, c)); } | ||
}; | ||
exports.Array = arrayType; | ||
exports.Dictionary = new Type('Dictionary', function (v, c) { return v !== null && typeof v === 'object' ? success(v) : failure(v, c); }); | ||
var functionType = new Type('Function', function (v, c) { return typeof v === 'function' ? success(v) : failure(v, c); }); | ||
exports.Dictionary = { | ||
_A: exports._A, | ||
_tag: 'AnyDictionaryType', | ||
name: 'Dictionary', | ||
validate: function (v, c) { return (v !== null && typeof v === 'object' ? success(v) : failure(v, c)); } | ||
}; | ||
var functionType = { | ||
_A: exports._A, | ||
_tag: 'FunctionType', | ||
name: 'Function', | ||
validate: function (v, c) { return (typeof v === 'function' ? success(v) : failure(v, c)); } | ||
}; | ||
exports.Function = functionType; | ||
// | ||
// refinements | ||
// | ||
var RefinementType = (function (_super) { | ||
__extends(RefinementType, _super); | ||
function RefinementType(name, validate, type, predicate) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.type = type; | ||
_this.predicate = predicate; | ||
return _this; | ||
} | ||
return RefinementType; | ||
}(Type)); | ||
exports.RefinementType = RefinementType; | ||
function refinement(type, predicate, name) { | ||
return new RefinementType(name || "(" + type.name + " | " + getFunctionName(predicate) + ")", function (v, c) { return type.validate(v, c).chain(function (t) { return predicate(t) ? success(t) : failure(v, c); }); }, type, predicate); | ||
return { | ||
_A: exports._A, | ||
_tag: 'RefinementType', | ||
name: name || "(" + type.name + " | " + getFunctionName(predicate) + ")", | ||
validate: function (v, c) { return type.validate(v, c).chain(function (t) { return (predicate(t) ? success(t) : failure(v, c)); }); }, | ||
type: type, | ||
predicate: predicate | ||
}; | ||
} | ||
exports.refinement = refinement; | ||
exports.Integer = refinement(exports.number, function (n) { return n % 1 === 0; }, 'Integer'); | ||
// | ||
// literal types | ||
// | ||
var LiteralType = (function (_super) { | ||
__extends(LiteralType, _super); | ||
function LiteralType(name, validate, value) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.value = value; | ||
return _this; | ||
} | ||
return LiteralType; | ||
}(Type)); | ||
exports.LiteralType = LiteralType; | ||
function prism(type, getOption, name) { | ||
return { | ||
_A: exports._A, | ||
_tag: 'PrismType', | ||
name: name || "Prism<" + type.name + ", ?>", | ||
validate: function (v, c) { return type.validate(v, c).chain(function (a) { return getOption(a).fold(function () { return failure(a, c); }, function (b) { return success(b); }); }); }, | ||
type: type, | ||
getOption: getOption | ||
}; | ||
} | ||
exports.prism = prism; | ||
function literal(value) { | ||
return new LiteralType(JSON.stringify(value), function (v, c) { return v === value ? success(value) : failure(v, c); }, value); | ||
return { | ||
_A: exports._A, | ||
_tag: 'LiteralType', | ||
name: JSON.stringify(value), | ||
validate: function (v, c) { return (v === value ? success(value) : failure(v, c)); }, | ||
value: value | ||
}; | ||
} | ||
exports.literal = literal; | ||
// | ||
// keyof types | ||
// | ||
var KeyofType = (function (_super) { | ||
__extends(KeyofType, _super); | ||
function KeyofType(name, validate, keys) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.keys = keys; | ||
return _this; | ||
} | ||
return KeyofType; | ||
}(Type)); | ||
exports.KeyofType = KeyofType; | ||
function keyof(map, name) { | ||
return new KeyofType(name || "(keyof " + JSON.stringify(Object.keys(map)) + ")", function (v, c) { return map.hasOwnProperty(v) ? success(v) : failure(v, c); }, map); | ||
function keyof(keys, name) { | ||
return { | ||
_A: exports._A, | ||
_tag: 'KeyofType', | ||
name: name || "(keyof " + JSON.stringify(Object.keys(keys)) + ")", | ||
validate: function (v, c) { return (keys.hasOwnProperty(v) ? success(v) : failure(v, c)); }, | ||
keys: keys | ||
}; | ||
} | ||
@@ -175,3 +175,3 @@ exports.keyof = keyof; | ||
function recursion(name, definition) { | ||
var Self = new Type(name, function (v, c) { return Result.validate(v, c); }); | ||
var Self = { name: name, validate: function (v, c) { return Result.validate(v, c); } }; | ||
var Result = definition(Self); | ||
@@ -182,76 +182,59 @@ Result.name = name; | ||
exports.recursion = recursion; | ||
// | ||
// arrays | ||
// | ||
var ArrayType = (function (_super) { | ||
__extends(ArrayType, _super); | ||
function ArrayType(name, validate, type) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.type = type; | ||
return _this; | ||
} | ||
return ArrayType; | ||
}(Type)); | ||
exports.ArrayType = ArrayType; | ||
function array(type, name) { | ||
return new ArrayType(name || "Array<" + type.name + ">", function (v, c) { return arrayType.validate(v, c).chain(function (as) { | ||
var t = []; | ||
var errors = []; | ||
var changed = false; | ||
var _loop_1 = function (i, len) { | ||
var a = as[i]; | ||
var validation = type.validate(a, c.concat(getContextEntry(String(i), type))); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (va) { | ||
changed = changed || (va !== a); | ||
t.push(va); | ||
return { | ||
_A: exports._A, | ||
_tag: 'ArrayType', | ||
name: name || "Array<" + type.name + ">", | ||
validate: function (v, c) { | ||
return arrayType.validate(v, c).chain(function (as) { | ||
var t = []; | ||
var errors = []; | ||
var changed = false; | ||
var _loop_1 = function (i) { | ||
var a = as[i]; | ||
var validation = type.validate(a, c.concat(getContextEntry(String(i), type))); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (va) { | ||
changed = changed || va !== a; | ||
t.push(va); | ||
}); | ||
}; | ||
for (var i = 0; i < as.length; i++) { | ||
_loop_1(i); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success(changed ? t : as); | ||
}); | ||
}; | ||
for (var i = 0, len = as.length; i < len; i++) { | ||
_loop_1(i, len); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success(changed ? t : as); | ||
}); }, type); | ||
}, | ||
type: type | ||
}; | ||
} | ||
exports.array = array; | ||
var InterfaceType = (function (_super) { | ||
__extends(InterfaceType, _super); | ||
function InterfaceType(name, validate, props) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.props = props; | ||
return _this; | ||
} | ||
return InterfaceType; | ||
}(Type)); | ||
exports.InterfaceType = InterfaceType; | ||
function interfaceType(props, name) { | ||
return new InterfaceType(name || "{ " + Object.keys(props).map(function (k) { return k + ": " + props[k].name; }).join(', ') + " }", function (v, c) { return exports.Dictionary.validate(v, c).chain(function (o) { | ||
var t = __assign({}, o); | ||
var errors = []; | ||
var changed = false; | ||
var _loop_2 = function (k) { | ||
var ok = o[k]; | ||
var type = props[k]; | ||
var validation = type.validate(ok, c.concat(getContextEntry(k, type))); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (vok) { | ||
changed = changed || (vok !== ok); | ||
t[k] = vok; | ||
return { | ||
_A: exports._A, | ||
_tag: 'InterfaceType', | ||
name: name || "{ " + Object.keys(props).map(function (k) { return k + ": " + props[k].name; }).join(', ') + " }", | ||
validate: function (v, c) { | ||
return exports.Dictionary.validate(v, c).chain(function (o) { | ||
var t = __assign({}, o); | ||
var errors = []; | ||
var changed = false; | ||
var _loop_2 = function (k) { | ||
var ok = o[k]; | ||
var type = props[k]; | ||
var validation = type.validate(ok, c.concat(getContextEntry(k, type))); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (vok) { | ||
changed = changed || vok !== ok; | ||
t[k] = vok; | ||
}); | ||
}; | ||
for (var k in props) { | ||
_loop_2(k); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success((changed ? t : o)); | ||
}); | ||
}; | ||
for (var k in props) { | ||
_loop_2(k); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success((changed ? t : o)); | ||
}); }, props); | ||
}, | ||
props: props | ||
}; | ||
} | ||
exports.interface = interfaceType; | ||
var PartialType = (function (_super) { | ||
__extends(PartialType, _super); | ||
function PartialType(name, validate, props) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.props = props; | ||
return _this; | ||
} | ||
return PartialType; | ||
}(Type)); | ||
exports.PartialType = PartialType; | ||
function partial(props, name) { | ||
@@ -263,192 +246,150 @@ var partials = {}; | ||
var type = interfaceType(partials); | ||
return new PartialType(name || type.name, function (v, c) { return type.validate(v, c); }, partials); | ||
return { | ||
_A: exports._A, | ||
_tag: 'PartialType', | ||
name: name || type.name, | ||
validate: function (v, c) { return type.validate(v, c); }, | ||
props: partials | ||
}; | ||
} | ||
exports.partial = partial; | ||
// | ||
// dictionaries | ||
// | ||
var DictionaryType = (function (_super) { | ||
__extends(DictionaryType, _super); | ||
function DictionaryType(name, validate, domain, codomain) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.domain = domain; | ||
_this.codomain = codomain; | ||
return _this; | ||
} | ||
return DictionaryType; | ||
}(Type)); | ||
exports.DictionaryType = DictionaryType; | ||
function dictionary(domain, codomain, name) { | ||
return new DictionaryType(name || "{ [key: " + domain.name + "]: " + codomain.name + " }", function (v, c) { return exports.Dictionary.validate(v, c).chain(function (o) { | ||
var t = {}; | ||
var errors = []; | ||
var changed = false; | ||
var _loop_3 = function (k) { | ||
var ok = o[k]; | ||
var domainValidation = domain.validate(k, c.concat(getContextEntry(k, domain))); | ||
var codomainValidation = codomain.validate(ok, c.concat(getContextEntry(k, codomain))); | ||
domainValidation.fold(function (error) { return pushAll(errors, error); }, function (vk) { | ||
changed = changed || (vk !== k); | ||
k = vk; | ||
return { | ||
_A: exports._A, | ||
_tag: 'DictionaryType', | ||
name: name || "{ [key: " + domain.name + "]: " + codomain.name + " }", | ||
validate: function (v, c) { | ||
return exports.Dictionary.validate(v, c).chain(function (o) { | ||
var t = {}; | ||
var errors = []; | ||
var changed = false; | ||
var _loop_3 = function (k) { | ||
var ok = o[k]; | ||
var domainValidation = domain.validate(k, c.concat(getContextEntry(k, domain))); | ||
var codomainValidation = codomain.validate(ok, c.concat(getContextEntry(k, codomain))); | ||
domainValidation.fold(function (error) { return pushAll(errors, error); }, function (vk) { | ||
changed = changed || vk !== k; | ||
k = vk; | ||
}); | ||
codomainValidation.fold(function (error) { return pushAll(errors, error); }, function (vok) { | ||
changed = changed || vok !== ok; | ||
t[k] = vok; | ||
}); | ||
}; | ||
for (var k in o) { | ||
_loop_3(k); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success((changed ? t : o)); | ||
}); | ||
codomainValidation.fold(function (error) { return pushAll(errors, error); }, function (vok) { | ||
changed = changed || (vok !== ok); | ||
t[k] = vok; | ||
}); | ||
}; | ||
for (var k in o) { | ||
_loop_3(k); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success((changed ? t : o)); | ||
}); }, domain, codomain); | ||
}, | ||
domain: domain, | ||
codomain: codomain | ||
}; | ||
} | ||
exports.dictionary = dictionary; | ||
var UnionType = (function (_super) { | ||
__extends(UnionType, _super); | ||
function UnionType(name, validate, types) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.types = types; | ||
return _this; | ||
} | ||
UnionType.prototype.fold = function () { | ||
var _this = this; | ||
var matches = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
matches[_i] = arguments[_i]; | ||
} | ||
return function (value) { | ||
for (var i = 0, len = matches.length; i < len; i++) { | ||
var type = _this.types[i]; | ||
var match = matches[i]; | ||
if (type.is(value)) { | ||
return match(value); | ||
function union(types, name) { | ||
return { | ||
_A: exports._A, | ||
_tag: 'UnionType', | ||
name: name || "(" + types.map(function (type) { return type.name; }).join(' | ') + ")", | ||
validate: function (v, c) { | ||
for (var i = 0; i < types.length; i++) { | ||
var validation = types[i].validate(v, c); | ||
if (Either_1.isRight(validation)) { | ||
return validation; | ||
} | ||
} | ||
throw new Error("Invalid value " + JSON.stringify(value) + " supplied to " + _this.name); | ||
}; | ||
return failure(v, c); | ||
}, | ||
types: types | ||
}; | ||
return UnionType; | ||
}(Type)); | ||
exports.UnionType = UnionType; | ||
function union(types, name) { | ||
return new UnionType(name || "(" + types.map(function (type) { return type.name; }).join(' | ') + ")", function (v, c) { | ||
for (var i = 0, len = types.length; i < len; i++) { | ||
var validation = types[i].validate(v, c); | ||
if (Either_1.isRight(validation)) { | ||
return validation; | ||
} | ||
} | ||
return failure(v, c); | ||
}, types); | ||
} | ||
exports.union = union; | ||
// | ||
// intersections | ||
// | ||
var IntersectionType = (function (_super) { | ||
__extends(IntersectionType, _super); | ||
function IntersectionType(name, validate, types) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.types = types; | ||
return _this; | ||
} | ||
return IntersectionType; | ||
}(Type)); | ||
exports.IntersectionType = IntersectionType; | ||
function intersection(types, name) { | ||
return new IntersectionType(name || "(" + types.map(function (type) { return type.name; }).join(' & ') + ")", function (v, c) { | ||
var t = v; | ||
var changed = false; | ||
var errors = []; | ||
for (var i = 0, len = types.length; i < len; i++) { | ||
var type = types[i]; | ||
var validation = type.validate(t, c); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (vv) { | ||
changed = changed || (vv !== t); | ||
t = vv; | ||
}); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success(changed ? t : v); | ||
}, types); | ||
return { | ||
_A: exports._A, | ||
_tag: 'IntersectionType', | ||
name: name || "(" + types.map(function (type) { return type.name; }).join(' & ') + ")", | ||
validate: function (v, c) { | ||
var t = v; | ||
var changed = false; | ||
var errors = []; | ||
for (var i = 0; i < types.length; i++) { | ||
var type = types[i]; | ||
var validation = type.validate(t, c); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (vv) { | ||
changed = changed || vv !== t; | ||
t = vv; | ||
}); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success(changed ? t : v); | ||
}, | ||
types: types | ||
}; | ||
} | ||
exports.intersection = intersection; | ||
// | ||
// tuples | ||
// | ||
var TupleType = (function (_super) { | ||
__extends(TupleType, _super); | ||
function TupleType(name, validate, types) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.types = types; | ||
return _this; | ||
} | ||
return TupleType; | ||
}(Type)); | ||
exports.TupleType = TupleType; | ||
function tuple(types, name) { | ||
return new TupleType(name || "[" + types.map(function (type) { return type.name; }).join(', ') + "]", function (v, c) { return arrayType.validate(v, c).chain(function (as) { | ||
var t = []; | ||
var errors = []; | ||
var changed = false; | ||
var _loop_4 = function (i, len) { | ||
var a = as[i]; | ||
var type = types[i]; | ||
var validation = type.validate(a, c.concat(getContextEntry(String(i), type))); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (va) { | ||
changed = changed || (va !== a); | ||
t.push(va); | ||
return { | ||
_A: exports._A, | ||
_tag: 'TupleType', | ||
name: name || "[" + types.map(function (type) { return type.name; }).join(', ') + "]", | ||
validate: function (v, c) { | ||
return arrayType.validate(v, c).chain(function (as) { | ||
var t = []; | ||
var errors = []; | ||
var changed = false; | ||
var _loop_4 = function (i) { | ||
var a = as[i]; | ||
var type = types[i]; | ||
var validation = type.validate(a, c.concat(getContextEntry(String(i), type))); | ||
validation.fold(function (error) { return pushAll(errors, error); }, function (va) { | ||
changed = changed || va !== a; | ||
t.push(va); | ||
}); | ||
}; | ||
for (var i = 0; i < types.length; i++) { | ||
_loop_4(i); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success(changed ? t : as); | ||
}); | ||
}; | ||
for (var i = 0, len = types.length; i < len; i++) { | ||
_loop_4(i, len); | ||
} | ||
return errors.length ? new Either_1.Left(errors) : success(changed ? t : as); | ||
}); }, types); | ||
}, | ||
types: types | ||
}; | ||
} | ||
exports.tuple = tuple; | ||
// | ||
// readonly | ||
// | ||
var ReadonlyType = (function (_super) { | ||
__extends(ReadonlyType, _super); | ||
function ReadonlyType(name, validate, type) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.type = type; | ||
return _this; | ||
} | ||
return ReadonlyType; | ||
}(Type)); | ||
exports.ReadonlyType = ReadonlyType; | ||
function readonly(type, name) { | ||
return new ReadonlyType(name || "Readonly<" + type.name + ">", function (v, c) { return type.validate(v, c).map(function (x) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
return Object.freeze(x); | ||
} | ||
return x; | ||
}); }, type); | ||
return { | ||
_A: exports._A, | ||
_tag: 'ReadonlyType', | ||
name: name || "Readonly<" + type.name + ">", | ||
validate: function (v, c) { | ||
return type.validate(v, c).map(function (x) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
return Object.freeze(x); | ||
} | ||
return x; | ||
}); | ||
}, | ||
type: type | ||
}; | ||
} | ||
exports.readonly = readonly; | ||
// | ||
// readonlyArray | ||
// | ||
var ReadonlyArrayType = (function (_super) { | ||
__extends(ReadonlyArrayType, _super); | ||
function ReadonlyArrayType(name, validate, type) { | ||
var _this = _super.call(this, name, validate) || this; | ||
_this.type = type; | ||
return _this; | ||
} | ||
return ReadonlyArrayType; | ||
}(Type)); | ||
exports.ReadonlyArrayType = ReadonlyArrayType; | ||
function readonlyArray(type, name) { | ||
var arrayType = array(type); | ||
return new ReadonlyArrayType(name || "ReadonlyArray<" + type.name + ">", function (v, c) { return arrayType.validate(v, c).map(function (x) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
return Object.freeze(x); | ||
} | ||
return x; | ||
}); }, type); | ||
return { | ||
_A: exports._A, | ||
_tag: 'ReadonlyArrayType', | ||
name: name || "ReadonlyArray<" + type.name + ">", | ||
validate: function (v, c) { | ||
return arrayType.validate(v, c).map(function (x) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
return Object.freeze(x); | ||
} | ||
return x; | ||
}); | ||
}, | ||
type: type | ||
}; | ||
} | ||
exports.readonlyArray = readonlyArray; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "io-ts", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "TypeScript compatible runtime type system for IO validation", | ||
@@ -11,5 +11,7 @@ "files": [ | ||
"scripts": { | ||
"lint": "tslint src/**/*.ts test/**/*.ts", | ||
"typings-checker": "typings-checker --allow-expect-error --project typings-checker/tsconfig.json typings-checker/index.ts", | ||
"mocha": "mocha -r ts-node/register test/*.ts", | ||
"test": "npm run typings-checker && npm run mocha", | ||
"prettier": "prettier --no-semi --single-quote --print-width 120 --parser typescript --list-different \"{src,test}/**/*.ts\"", | ||
"test": "npm run prettier && npm run lint && npm run typings-checker && npm run mocha", | ||
"clean": "rm -rf lib/*", | ||
@@ -35,3 +37,6 @@ "build": "npm run clean && tsc" | ||
"mocha": "3.2.0", | ||
"prettier": "^1.4.2", | ||
"ts-node": "2.0.0", | ||
"tslint": "4.4.2", | ||
"tslint-config-standard": "4.0.0", | ||
"typescript": "^2.2.0", | ||
@@ -38,0 +43,0 @@ "typings-checker": "1.1.2" |
@@ -6,5 +6,6 @@ # The idea | ||
```js | ||
class Type<T> { | ||
constructor(public readonly name: string, public readonly validate: Validate<T>) {} | ||
is(x: any): x is T | ||
export interface Type<A> { | ||
readonly _A: A | ||
readonly name: string | ||
readonly validate: Validate<A> | ||
} | ||
@@ -28,8 +29,11 @@ ``` | ||
const string = new t.Type<string>( | ||
'string', | ||
(value, context) => typeof value === 'string' ? t.success(v) : t.failure<string>(v, c) | ||
) | ||
export const string: t.Type<string> = { | ||
_A: t._A, | ||
name: 'string', | ||
validate: (value, context) => (typeof value === 'string' ? t.success(value) : t.failure<string>(value, context)) | ||
} | ||
``` | ||
Note: The `_A` field contains a dummy value and is useful to extract a static type from the runtime type (see the section "TypeScript integration" below) | ||
A runtime type can be used to validate an object in memory (for example an API payload) | ||
@@ -68,3 +72,4 @@ | ||
```js | ||
import { PathReporter, ThrowReporter } from 'io-ts/lib/reporters/default' | ||
import { PathReporter } from 'io-ts/lib/PathReporter' | ||
import { ThrowReporter } from 'io-ts/lib/ThrowReporter' | ||
@@ -117,6 +122,8 @@ const validation = t.validate({"name":"Giulio"}, Person) | ||
const Category = t.recursion<ICategory>('Category', self => t.object({ | ||
name: t.string, | ||
categories: t.array(self) | ||
})) | ||
const Category = t.recursion<ICategory>('Category', self => | ||
t.interface({ | ||
name: t.string, | ||
categories: t.array(self) | ||
}) | ||
) | ||
``` | ||
@@ -192,9 +199,11 @@ | ||
// returns a Date from an ISO string | ||
const DateFromString = new t.Type<Date>( | ||
'DateFromString', | ||
(v, c) => t.string.validate(v, c).chain(s => { | ||
const d = new Date(s) | ||
return isNaN(d.getTime()) ? t.failure<Date>(s, c) : t.success(d) | ||
}) | ||
) | ||
const DateFromString: t.Type<Date> = { | ||
_A: t._A, | ||
name: 'DateFromString', | ||
validate: (v, c) => | ||
t.string.validate(v, c).chain(s => { | ||
const d = new Date(s) | ||
return isNaN(d.getTime()) ? t.failure<Date>(s, c) : t.success(d) | ||
}) | ||
} | ||
@@ -210,3 +219,3 @@ const s = new Date(1973, 10, 30).toISOString() | ||
Note that you can **deserializing** while validating. | ||
Note that you can **deserialize** while validating. | ||
@@ -220,3 +229,6 @@ # Custom combinators | ||
```ts | ||
export function maybe<RT extends t.Any>(type: RT, name?: string): t.UnionType<[RT, typeof t.null], t.TypeOf<RT> | null> { | ||
export function maybe<RT extends t.Any>( | ||
type: RT, | ||
name?: string | ||
): t.UnionType<[RT, typeof t.null], t.TypeOf<RT> | null> { | ||
return t.union([type, t.null], name) | ||
@@ -270,3 +282,3 @@ } | ||
function convertFtoC(fahrenheit: FahrenheitT): CelsiusT { | ||
return (fahrenheit - 32) / 1.8 as CelsiusT; | ||
return ((fahrenheit - 32) / 1.8) as CelsiusT | ||
} | ||
@@ -286,11 +298,9 @@ | ||
import * as t from 'io-ts' | ||
import { pathReporterFailure } from 'io-ts/lib/reporters/default' | ||
import { failure } from 'io-ts/lib/PathReporter' | ||
function unsafeValidate<T>(value: any, type: t.Type<T>): T { | ||
if (process.env.NODE_ENV !== 'production') { | ||
return t.validate(value, type) | ||
.fold( | ||
errors => { throw new Error(pathReporterFailure(errors).join('\n')) }, | ||
x => x | ||
) | ||
return t.validate(value, type).fold(errors => { | ||
throw new Error(failure(errors).join('\n')) | ||
}, x => x) | ||
} | ||
@@ -318,3 +328,3 @@ return value as T | ||
foo: t.InterfaceOf<{ | ||
bar: t.Type<string>; | ||
bar: t.StringType; | ||
}>; | ||
@@ -321,0 +331,0 @@ } |
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
16
332
52803
9
623
1