Socket
Socket
Sign inDemoInstall

validation.ts

Package Overview
Dependencies
0
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.27 to 0.0.28

118

commonjs/validation.d.ts

@@ -1,5 +0,4 @@

import { Result, Ok, Err, Option, None, Some } from 'space-lift';
export declare abstract class Validator<T> {
export interface Validator<T> {
readonly T: T;
abstract validate(value: Value, config?: Configuration, context?: Context): Validation<T>;
validate(value: Value, config?: Configuration, context?: Context): Validation<T>;
map<B>(fn: (value: T) => B): Validator<B>;

@@ -12,2 +11,20 @@ filter(fn: (value: T) => boolean): Validator<T>;

}
export declare type Ok<VALUE> = {
type: 'ok';
value: VALUE;
};
export declare type Err<ERROR> = {
type: 'error';
errors: ERROR;
};
export declare type Result<ERROR, VALUE> = Err<ERROR> | Ok<VALUE>;
export declare function Ok<VALUE>(value: VALUE): {
readonly type: "ok";
readonly value: VALUE;
};
export declare function Err<ERROR>(errors: ERROR): {
readonly type: "error";
readonly errors: ERROR;
};
export declare function isOk<VALUE>(result: Result<unknown, VALUE>): result is Ok<VALUE>;
export declare type Any = Validator<Value>;

@@ -29,41 +46,18 @@ export declare type TypeOf<V extends Any> = V['T'];

export declare function failure(context: Context, message: string): Validation<never>;
export declare function typeFailure(value: any, context: Context, expectedType: string): Result<{
context: Context;
message: string;
}[], never>;
export declare function typeFailure(value: any, context: Context, expectedType: string): {
readonly type: "error";
readonly errors: {
context: Context;
message: string;
}[];
};
export declare function getContext(name: string, parent?: string): Context;
export declare const snakeCaseTransformation: (key: string) => string;
export declare function is<T>(value: Value, validator: Validator<T>): value is T;
export declare class NullValidator extends Validator<null> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], null>;
}
export declare class UndefinedValidator extends Validator<undefined> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], undefined>;
}
export declare class StringValidator extends Validator<string> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], string>;
}
export declare class NumberValidator extends Validator<number> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], number>;
}
export declare class BooleanValidator extends Validator<boolean> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], boolean>;
}
export declare class TransformValidator<A, B> extends Validator<B> {
private validator;
private f;
constructor(validator: Validator<A>, f: (a: Validation<A>) => Result<string | ValidationError[], B>);
validate(v: Value, config?: Configuration, c?: Context): Result<ValidationError[], B>;
}
export declare class ArrayValidator<A> extends Validator<A[]> {
private validator;
constructor(validator: Validator<A>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], never> | Err<ValidationError[], never> | Ok<never, A[]> | Err<never, A[]>;
}
declare const nullValidator: Validator<null>;
declare const undefinedValidator: Validator<undefined>;
export declare const string: Validator<string>;
export declare const number: Validator<number>;
export declare const boolean: Validator<boolean>;
export declare function array<A>(validator: Validator<A>): Validator<A[]>;
export declare class TupleValidator extends Validator<any> {
private validators;
constructor(validators: Validator<any>[]);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], never> | Err<ValidationError[], never> | Ok<never, any[]> | Err<never, any[]>;
}
export declare function tuple<A = never>(): Validator<A[]>;

@@ -97,20 +91,6 @@ export declare function tuple<A>(a: Validator<A>): Validator<[A]>;

};
export declare class ObjectValidator<P extends Props> extends Validator<ObjectOf<P>> {
export declare function object<P extends Props>(props: P): Validator<ObjectOf<P>> & {
props: P;
constructor(props: P);
validate(v: Value, config?: Configuration, c?: Context): Validation<ObjectOf<P>>;
}
export declare function object<P extends Props>(props: P): ObjectValidator<P>;
export declare class KeyOfValidator<KEYS extends object> extends Validator<keyof KEYS> {
private keys;
constructor(keys: KEYS);
validate(v: Value, _config?: Configuration, c?: Context): Validation<keyof KEYS>;
}
export declare function keyof<KEYS extends object>(keys: KEYS): KeyOfValidator<KEYS>;
export declare class DictionaryValidator<K extends string, V> extends Validator<Record<K, V>> {
private domain;
private codomain;
constructor(domain: Validator<K>, codomain: Validator<V>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], never> | Err<ValidationError[], never> | Ok<never, any> | Err<never, any>;
}
};
export declare function keyof<KEYS extends object>(keys: KEYS): Validator<keyof KEYS>;
export declare function dictionary<K extends string, V>(domain: Validator<K>, codomain: Validator<V>): Validator<Record<K, V>>;

@@ -125,12 +105,2 @@ export declare type Literal = string | number | boolean | null | undefined;

export declare function intersection<A, B, C, D, E, F>(a: Validator<A>, b: Validator<B>, c: Validator<C>, d: Validator<D>, e: Validator<E>, f: Validator<F>): Validator<A & B & C & D & E & F>;
export declare class UnionValidator<A> extends Validator<A> {
private validators;
constructor(validators: Validator<A>[]);
validate(v: Value, config?: Configuration, c?: Context): Err<ValidationError[], never> | Ok<ValidationError[], A>;
}
export declare class LiteralUnionValidator<A extends Literal> extends Validator<A> {
private values;
constructor(values: A[]);
validate(v: Value, config?: Configuration, c?: Context): Err<ValidationError[], never> | Ok<ValidationError[], A>;
}
export declare function union<A, B>(a: Validator<A>, b: Validator<B>): Validator<A | B>;

@@ -154,22 +124,6 @@ export declare function union<A extends Literal, B extends Literal>(a: A, b: B): Validator<A | B>;

export declare function union<A extends Literal, B extends Literal, C extends Literal, D extends Literal, E extends Literal, F extends Literal, G extends Literal, H extends Literal, I extends Literal, J extends Literal>(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J): Validator<A | B | C | D | E | F | G | H | I | J>;
export declare class OptionalValidator<V> extends Validator<V | undefined> {
private validator;
constructor(validator: Validator<V>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], undefined> | Err<ValidationError[], undefined> | Ok<ValidationError[], V> | Err<ValidationError[], V>;
}
export declare function optional<V>(validator: Validator<V>): Validator<V | undefined>;
export declare class OptionValidator<V> extends Validator<Option<V>> {
private validator;
constructor(validator: Validator<V>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], None> | Err<ValidationError[], None> | Ok<ValidationError[], Some<V>> | Err<ValidationError[], Some<V>>;
}
export declare function option<V>(validator: Validator<V>): Validator<Option<V>>;
export declare function recursion<T>(definition: (self: Validator<T>) => Any): Validator<T>;
export declare const isoDate: Validator<Date>;
export declare function errorDebugString(errors: ValidationError[]): string;
declare const nullValidator: NullValidator;
declare const undefinedValidator: UndefinedValidator;
export { nullValidator as null, undefinedValidator as undefined };
export declare const string: StringValidator;
export declare const number: NumberValidator;
export declare const boolean: BooleanValidator;
export declare const isoDate: Validator<Date>;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
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 extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
//--------------------------------------
// Setup
//--------------------------------------
var __assign = (this && this.__assign) || function () {

@@ -26,35 +16,53 @@ __assign = Object.assign || function(t) {

};
exports.__esModule = true;
var space_lift_1 = require("space-lift");
//--------------------------------------
// Setup
//--------------------------------------
var Validator = /** @class */ (function () {
function Validator() {
this.T = null; // Phantom type
Object.defineProperty(exports, "__esModule", { value: true });
exports.undefined = exports.null = exports.errorDebugString = exports.isoDate = exports.recursion = exports.optional = exports.union = exports.intersection = exports.literal = exports.dictionary = exports.keyof = exports.object = exports.tuple = exports.array = exports.boolean = exports.number = exports.string = exports.is = exports.snakeCaseTransformation = exports.getContext = exports.typeFailure = exports.failure = exports.success = exports.isOk = exports.Err = exports.Ok = void 0;
var validatorMethods = {
map: function (fn) {
return this.flatMap(function (v) { return Ok(fn(v)); });
},
filter: function (fn) {
return this.flatMap(function (v) { return fn(v) ? Ok(v) : Err("filter error: " + pretty(v) + "\""); });
},
flatMap: function (fn) {
return this.transform(function (r) { return isOk(r) ? fn(r.value) : r; });
},
transform: function (fn) {
var validator = this;
return Object.assign({}, validatorMethods, {
validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var validated = validator.validate(v, config, c);
var transformed = fn(validated);
if (isOk(transformed))
return success(transformed.value);
var error = transformed.errors;
if (typeof error === 'string')
return failure(c, error);
return Err(error);
}
});
},
tagged: function () {
return this;
}
Validator.prototype.map = function (fn) {
return this.flatMap(function (v) { return space_lift_1.Ok(fn(v)); });
};
Validator.prototype.filter = function (fn) {
return this.flatMap(function (v) { return fn(v) ? space_lift_1.Ok(v) : space_lift_1.Err("The value " + pretty(v) + " failed a predicate\""); });
};
Validator.prototype.flatMap = function (fn) {
return this.transform(function (r) { return r.isOk() ? fn(r.get()) : r; });
};
Validator.prototype.transform = function (fn) {
return new TransformValidator(this, fn);
};
Validator.prototype.tagged = function () {
return this;
};
return Validator;
}());
exports.Validator = Validator;
};
function Ok(value) {
return { type: 'ok', value: value };
}
exports.Ok = Ok;
function Err(errors) {
return { type: 'error', errors: errors };
}
exports.Err = Err;
function isOk(result) {
return result.type === 'ok';
}
exports.isOk = isOk;
function success(value) {
return space_lift_1.Ok(value);
return Ok(value);
}
exports.success = success;
function failure(context, message) {
return space_lift_1.Err([{ context: context, message: message }]);
return Err([{ context: context, message: message }]);
}

@@ -70,4 +78,4 @@ exports.failure = failure;

})();
var message = "Type error: expected " + expectedType + " but got " + valueType;
return space_lift_1.Err([{ context: context, message: message }]);
var message = "Expected " + expectedType + ", got " + valueType;
return Err([{ context: context, message: message }]);
}

@@ -90,3 +98,3 @@ exports.typeFailure = typeFailure;

function is(value, validator) {
return validator.validate(value).isOk();
return isOk(validator.validate(value));
}

@@ -97,163 +105,54 @@ exports.is = is;

//--------------------------------------
var NullValidator = /** @class */ (function (_super) {
__extends(NullValidator, _super);
function NullValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
NullValidator.prototype.validate = function (v, _config, c) {
var nullValidator = __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === null ? success(v) : typeFailure(v, c, 'null');
};
return NullValidator;
}(Validator));
exports.NullValidator = NullValidator;
var UndefinedValidator = /** @class */ (function (_super) {
__extends(UndefinedValidator, _super);
function UndefinedValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
UndefinedValidator.prototype.validate = function (v, _config, c) {
} }, validatorMethods);
exports.null = nullValidator;
var undefinedValidator = __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === void 0 ? success(v) : typeFailure(v, c, 'undefined');
};
return UndefinedValidator;
}(Validator));
exports.UndefinedValidator = UndefinedValidator;
var StringValidator = /** @class */ (function (_super) {
__extends(StringValidator, _super);
function StringValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
StringValidator.prototype.validate = function (v, _config, c) {
} }, validatorMethods);
exports.undefined = undefinedValidator;
exports.string = __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return typeof v === 'string' ? success(v) : typeFailure(v, c, 'string');
};
return StringValidator;
}(Validator));
exports.StringValidator = StringValidator;
var NumberValidator = /** @class */ (function (_super) {
__extends(NumberValidator, _super);
function NumberValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
NumberValidator.prototype.validate = function (v, _config, c) {
} }, validatorMethods);
exports.number = __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return typeof v === 'number' ? success(v) : typeFailure(v, c, 'number');
};
return NumberValidator;
}(Validator));
exports.NumberValidator = NumberValidator;
var BooleanValidator = /** @class */ (function (_super) {
__extends(BooleanValidator, _super);
function BooleanValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
BooleanValidator.prototype.validate = function (v, _config, c) {
} }, validatorMethods);
exports.boolean = __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return typeof v === 'boolean' ? success(v) : typeFailure(v, c, 'boolean');
};
return BooleanValidator;
}(Validator));
exports.BooleanValidator = BooleanValidator;
} }, validatorMethods);
//--------------------------------------
// transform
//--------------------------------------
var TransformValidator = /** @class */ (function (_super) {
__extends(TransformValidator, _super);
function TransformValidator(validator, f) {
var _this = _super.call(this) || this;
_this.validator = validator;
_this.f = f;
return _this;
}
TransformValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var validated = this.validator.validate(v, config, c);
var transformed = this.f(validated);
if (transformed.isOk())
return success(transformed.get());
var error = transformed.get();
if (typeof error === 'string')
return failure(c, error);
return space_lift_1.Err(error);
};
return TransformValidator;
}(Validator));
exports.TransformValidator = TransformValidator;
//--------------------------------------
// array
//--------------------------------------
var ArrayValidator = /** @class */ (function (_super) {
__extends(ArrayValidator, _super);
function ArrayValidator(validator) {
var _this = _super.call(this) || this;
_this.validator = validator;
return _this;
}
ArrayValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (!Array.isArray(v))
return typeFailure(v, c, 'array');
var validatedArray = [];
var errors = [];
for (var i = 0; i < v.length; i++) {
var item = v[i];
var validation = this.validator.validate(item, config, getContext(String(i), c));
if (validation.isOk()) {
validatedArray.push(validation.get());
function array(validator) {
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (!Array.isArray(v))
return typeFailure(v, c, 'array');
var validatedArray = [];
var errors = [];
for (var i = 0; i < v.length; i++) {
var item = v[i];
var validation = validator.validate(item, config, getContext(String(i), c));
if (isOk(validation)) {
validatedArray.push(validation.value);
}
else {
pushAll(errors, validation.errors);
}
}
else {
pushAll(errors, validation.get());
}
}
return errors.length ? space_lift_1.Err(errors) : space_lift_1.Ok(validatedArray);
};
return ArrayValidator;
}(Validator));
exports.ArrayValidator = ArrayValidator;
function array(validator) {
return new ArrayValidator(validator);
return errors.length ? Err(errors) : Ok(validatedArray);
} }, validatorMethods);
}
exports.array = array;
//--------------------------------------
// tuple
//--------------------------------------
var TupleValidator = /** @class */ (function (_super) {
__extends(TupleValidator, _super);
function TupleValidator(validators) {
var _this = _super.call(this) || this;
_this.validators = validators;
return _this;
}
TupleValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (!Array.isArray(v))
return typeFailure(v, c, 'Tuple');
if (v.length !== this.validators.length)
return failure(c, "Expected Tuple" + this.validators.length + ", got Tuple" + v.length);
var validatedArray = [];
var errors = [];
for (var i = 0; i < v.length; i++) {
var item = v[i];
var validation = this.validators[i].validate(item, config, getContext(String(i), c));
if (validation.isOk()) {
validatedArray.push(validation.get());
}
else {
pushAll(errors, validation.get());
}
}
return errors.length ? space_lift_1.Err(errors) : space_lift_1.Ok(validatedArray);
};
return TupleValidator;
}(Validator));
exports.TupleValidator = TupleValidator;
function tuple() {

@@ -264,41 +163,51 @@ var validators = [];

}
return new TupleValidator(validators);
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (!Array.isArray(v))
return typeFailure(v, c, 'Tuple');
if (v.length !== validators.length)
return failure(c, "Expected Tuple" + validators.length + ", got Tuple" + v.length);
var validatedArray = [];
var errors = [];
for (var i = 0; i < v.length; i++) {
var item = v[i];
var validation = validators[i].validate(item, config, getContext(String(i), c));
if (isOk(validation)) {
validatedArray.push(validation.value);
}
else {
pushAll(errors, validation.errors);
}
}
return errors.length ? Err(errors) : Ok(validatedArray);
} }, validatorMethods);
}
exports.tuple = tuple;
var ObjectValidator = /** @class */ (function (_super) {
__extends(ObjectValidator, _super);
function ObjectValidator(props) {
var _this = _super.call(this) || this;
_this.props = props;
return _this;
}
ObjectValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
var validatedObject = {};
var errors = [];
for (var key in this.props) {
var transformedKey = config.transformObjectKeys !== undefined
? config.transformObjectKeys(key)
: key;
var value = v[transformedKey];
var validator = this.props[key];
var validation = validator.validate(value, config, getContext(transformedKey, c));
if (validation.isOk()) {
if (validation.get() !== undefined)
validatedObject[key] = validation.get();
function object(props) {
return __assign({ props: props,
validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
var validatedObject = {};
var errors = [];
for (var key in props) {
var transformedKey = config.transformObjectKeys !== undefined
? config.transformObjectKeys(key)
: key;
var value = v[transformedKey];
var validator = props[key];
var validation = validator.validate(value, config, getContext(transformedKey, c));
if (isOk(validation)) {
if (validation.value !== undefined)
validatedObject[key] = validation.value;
}
else {
pushAll(errors, validation.errors);
}
}
else {
pushAll(errors, validation.get());
}
}
return errors.length ? space_lift_1.Err(errors) : space_lift_1.Ok(validatedObject);
};
return ObjectValidator;
}(Validator));
exports.ObjectValidator = ObjectValidator;
function object(props) {
return new ObjectValidator(props);
return errors.length ? Err(errors) : Ok(validatedObject);
} }, validatorMethods);
}

@@ -309,21 +218,10 @@ exports.object = object;

//--------------------------------------
var KeyOfValidator = /** @class */ (function (_super) {
__extends(KeyOfValidator, _super);
function KeyOfValidator(keys) {
var _this = _super.call(this) || this;
_this.keys = keys;
return _this;
}
KeyOfValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return this.keys.hasOwnProperty(v)
? success(v)
: failure(c, pretty(v) + " is not a key of " + pretty(this.keys));
};
return KeyOfValidator;
}(Validator));
exports.KeyOfValidator = KeyOfValidator;
function keyof(keys) {
return new KeyOfValidator(keys);
return __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return keys.hasOwnProperty(v)
? success(v)
: failure(c, pretty(v) + " is not a key of " + pretty(keys));
} }, validatorMethods);
}

@@ -334,164 +232,104 @@ exports.keyof = keyof;

//--------------------------------------
var DictionaryValidator = /** @class */ (function (_super) {
__extends(DictionaryValidator, _super);
function DictionaryValidator(domain, codomain) {
var _this = _super.call(this) || this;
_this.domain = domain;
_this.codomain = codomain;
return _this;
}
DictionaryValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
var validatedDict = {};
var errors = [];
var _loop_1 = function (key) {
var value = v[key];
var context = getContext(key, c);
var domainValidation = this_1.domain.validate(key, config, context);
var codomainValidation = this_1.codomain.validate(value, config, context);
if (domainValidation.isOk()) {
key = domainValidation.get();
function dictionary(domain, codomain) {
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
var validatedDict = {};
var errors = [];
var _loop_1 = function (key) {
var value = v[key];
var context = getContext(key, c);
var domainValidation = domain.validate(key, config, context);
var codomainValidation = codomain.validate(value, config, context);
if (isOk(domainValidation)) {
key = domainValidation.value;
}
else {
var error = domainValidation.errors;
pushAll(errors, error.map(function (e) { return ({ context: context, message: "key error: " + e.message }); }));
}
if (isOk(codomainValidation)) {
validatedDict[key] = codomainValidation.value;
}
else {
var error = codomainValidation.errors;
pushAll(errors, error.map(function (e) { return ({ context: context, message: "value error: " + e.message }); }));
}
};
for (var key in v) {
_loop_1(key);
}
else {
var error = domainValidation.get();
pushAll(errors, error.map(function (e) { return ({ context: context, message: "key error: " + e.message }); }));
}
if (codomainValidation.isOk()) {
validatedDict[key] = codomainValidation.get();
}
else {
var error = codomainValidation.get();
pushAll(errors, error.map(function (e) { return ({ context: context, message: "value error: " + e.message }); }));
}
};
var this_1 = this;
for (var key in v) {
_loop_1(key);
}
return errors.length ? space_lift_1.Err(errors) : space_lift_1.Ok(validatedDict);
};
return DictionaryValidator;
}(Validator));
exports.DictionaryValidator = DictionaryValidator;
function dictionary(domain, codomain) {
return new DictionaryValidator(domain, codomain);
return errors.length ? Err(errors) : Ok(validatedDict);
} }, validatorMethods);
}
exports.dictionary = dictionary;
var LiteralValidator = /** @class */ (function (_super) {
__extends(LiteralValidator, _super);
function LiteralValidator(value) {
var _this = _super.call(this) || this;
_this.value = value;
return _this;
}
LiteralValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === this.value
? success(v)
: failure(c, "Expected literal " + this.value + " but got " + pretty(v));
};
return LiteralValidator;
}(Validator));
function literal(value) {
return new LiteralValidator(value);
return __assign({ validate: function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === value
? success(v)
: failure(c, "Expected " + pretty(value) + ", got " + pretty(v));
} }, validatorMethods);
}
exports.literal = literal;
//--------------------------------------
// intersection
//--------------------------------------
var IntersectionValidator = /** @class */ (function (_super) {
__extends(IntersectionValidator, _super);
function IntersectionValidator(validators) {
var _this = _super.call(this) || this;
_this.validators = validators;
return _this;
}
IntersectionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var result = {};
for (var i = 0; i < this.validators.length; i++) {
var validation = this.validators[i].validate(v, config, c);
if (validation.isOk()) {
result = __assign(__assign({}, result), validation.get());
}
else {
return validation;
}
}
return success(result);
};
return IntersectionValidator;
}(Validator));
function intersection() {
var values = [];
var validators = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
validators[_i] = arguments[_i];
}
return new IntersectionValidator(values);
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var result = {};
for (var i = 0; i < validators.length; i++) {
var validation = validators[i].validate(v, config, c);
if (isOk(validation)) {
result = __assign(__assign({}, result), validation.value);
}
else {
return validation;
}
}
return success(result);
} }, validatorMethods);
}
exports.intersection = intersection;
//--------------------------------------
// union
//--------------------------------------
var UnionValidator = /** @class */ (function (_super) {
__extends(UnionValidator, _super);
function UnionValidator(validators) {
var _this = _super.call(this) || this;
_this.validators = validators;
return _this;
}
UnionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var errors = [];
for (var i = 0; i < this.validators.length; i++) {
var validation = this.validators[i].validate(v, config, c);
if (validation.isOk())
return validation;
else
errors.push(validation.get());
}
var detailString = errors.map(function (es, index) {
return "Union type #" + index + " => \n " + errorDebugString(es).replace(/\n/g, '\n ');
}).join('\n');
return failure(c, "The value " + pretty(v) + " \nis not part of the union: \n\n" + detailString);
};
return UnionValidator;
}(Validator));
exports.UnionValidator = UnionValidator;
var LiteralUnionValidator = /** @class */ (function (_super) {
__extends(LiteralUnionValidator, _super);
function LiteralUnionValidator(values) {
var _this = _super.call(this) || this;
_this.values = values;
return _this;
}
LiteralUnionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
for (var i = 0; i < this.values.length; i++) {
var validator = literal(this.values[i]);
var validation = validator.validate(v, config, c);
if (validation.isOk())
return validation;
}
return failure(c, "The value " + pretty(v) + " is not part of the union");
};
return LiteralUnionValidator;
}(Validator));
exports.LiteralUnionValidator = LiteralUnionValidator;
function union() {
var values = [];
var validators = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
validators[_i] = arguments[_i];
}
var probe = values[0];
return (probe && typeof probe === 'object')
? new UnionValidator(values)
: new LiteralUnionValidator(values);
var probe = validators[0];
if (probe && typeof probe === 'object') {
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var errors = [];
for (var i = 0; i < validators.length; i++) {
var validation = validators[i].validate(v, config, c);
if (isOk(validation))
return validation;
else
errors.push(validation.errors);
}
var detailString = errors.map(function (es, index) {
return "Union type #" + index + " => \n " + errorDebugString(es).replace(/\n/g, '\n ');
}).join('\n');
return failure(c, "The value " + pretty(v) + " \nis not part of the union: \n\n" + detailString);
} }, validatorMethods);
}
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
for (var i = 0; i < validators.length; i++) {
var validator = literal(validators[i]);
var validation = validator.validate(v, config, c);
if (isOk(validation))
return validation;
}
return failure(c, "The value " + pretty(v) + " is not part of the union");
} }, validatorMethods);
}

@@ -502,57 +340,21 @@ exports.union = union;

//--------------------------------------
var OptionalValidator = /** @class */ (function (_super) {
__extends(OptionalValidator, _super);
function OptionalValidator(validator) {
var _this = _super.call(this) || this;
_this.validator = validator;
return _this;
}
OptionalValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v === undefined)
return success(v);
return this.validator.validate(v, config, c);
};
return OptionalValidator;
}(Validator));
exports.OptionalValidator = OptionalValidator;
function optional(validator) {
return new OptionalValidator(validator);
return __assign({ validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v === undefined)
return success(v);
return validator.validate(v, config, c);
} }, validatorMethods);
}
exports.optional = optional;
//--------------------------------------
// option
//--------------------------------------
var OptionValidator = /** @class */ (function (_super) {
__extends(OptionValidator, _super);
function OptionValidator(validator) {
var _this = _super.call(this) || this;
_this.validator = validator;
return _this;
}
OptionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v === undefined || v === null)
return success(space_lift_1.None);
return this.validator.validate(v, config, c).map(space_lift_1.Some);
};
return OptionValidator;
}(Validator));
exports.OptionValidator = OptionValidator;
function option(validator) {
return new OptionValidator(validator);
}
exports.option = option;
//--------------------------------------
// recursion
//--------------------------------------
function recursion(definition) {
var Self = new Validator();
Self.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return Result.validate(v, config, c);
};
var Self = __assign(__assign({}, validatorMethods), { validate: function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return Result.validate(v, config, c);
} });
var Result = definition(Self);

@@ -563,2 +365,11 @@ return Result;

//--------------------------------------
// isoDate
//--------------------------------------
exports.isoDate = exports.string.flatMap(function (str) {
var date = new Date(str);
return isNaN(date.getTime())
? Err("Expected ISO date, got: " + pretty(str))
: Ok(date);
});
//--------------------------------------
// util

@@ -576,17 +387,1 @@ //--------------------------------------

exports.errorDebugString = errorDebugString;
//--------------------------------------
// Export aliases and singletons
//--------------------------------------
var nullValidator = new NullValidator();
exports["null"] = nullValidator;
var undefinedValidator = new UndefinedValidator();
exports.undefined = undefinedValidator;
exports.string = new StringValidator();
exports.number = new NumberValidator();
exports.boolean = new BooleanValidator();
exports.isoDate = exports.string.flatMap(function (str) {
var date = new Date(str);
return isNaN(date.getTime())
? space_lift_1.Err("Expected an ISO date but got: " + pretty(str))
: space_lift_1.Ok(date);
});

@@ -1,5 +0,4 @@

import { Result, Ok, Err, Option, None, Some } from 'space-lift';
export declare abstract class Validator<T> {
export interface Validator<T> {
readonly T: T;
abstract validate(value: Value, config?: Configuration, context?: Context): Validation<T>;
validate(value: Value, config?: Configuration, context?: Context): Validation<T>;
map<B>(fn: (value: T) => B): Validator<B>;

@@ -12,2 +11,20 @@ filter(fn: (value: T) => boolean): Validator<T>;

}
export declare type Ok<VALUE> = {
type: 'ok';
value: VALUE;
};
export declare type Err<ERROR> = {
type: 'error';
errors: ERROR;
};
export declare type Result<ERROR, VALUE> = Err<ERROR> | Ok<VALUE>;
export declare function Ok<VALUE>(value: VALUE): {
readonly type: "ok";
readonly value: VALUE;
};
export declare function Err<ERROR>(errors: ERROR): {
readonly type: "error";
readonly errors: ERROR;
};
export declare function isOk<VALUE>(result: Result<unknown, VALUE>): result is Ok<VALUE>;
export declare type Any = Validator<Value>;

@@ -29,41 +46,18 @@ export declare type TypeOf<V extends Any> = V['T'];

export declare function failure(context: Context, message: string): Validation<never>;
export declare function typeFailure(value: any, context: Context, expectedType: string): Result<{
context: Context;
message: string;
}[], never>;
export declare function typeFailure(value: any, context: Context, expectedType: string): {
readonly type: "error";
readonly errors: {
context: Context;
message: string;
}[];
};
export declare function getContext(name: string, parent?: string): Context;
export declare const snakeCaseTransformation: (key: string) => string;
export declare function is<T>(value: Value, validator: Validator<T>): value is T;
export declare class NullValidator extends Validator<null> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], null>;
}
export declare class UndefinedValidator extends Validator<undefined> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], undefined>;
}
export declare class StringValidator extends Validator<string> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], string>;
}
export declare class NumberValidator extends Validator<number> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], number>;
}
export declare class BooleanValidator extends Validator<boolean> {
validate(v: Value, _config?: Configuration, c?: Context): Result<ValidationError[], boolean>;
}
export declare class TransformValidator<A, B> extends Validator<B> {
private validator;
private f;
constructor(validator: Validator<A>, f: (a: Validation<A>) => Result<string | ValidationError[], B>);
validate(v: Value, config?: Configuration, c?: Context): Result<ValidationError[], B>;
}
export declare class ArrayValidator<A> extends Validator<A[]> {
private validator;
constructor(validator: Validator<A>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], never> | Err<ValidationError[], never> | Ok<never, A[]> | Err<never, A[]>;
}
declare const nullValidator: Validator<null>;
declare const undefinedValidator: Validator<undefined>;
export declare const string: Validator<string>;
export declare const number: Validator<number>;
export declare const boolean: Validator<boolean>;
export declare function array<A>(validator: Validator<A>): Validator<A[]>;
export declare class TupleValidator extends Validator<any> {
private validators;
constructor(validators: Validator<any>[]);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], never> | Err<ValidationError[], never> | Ok<never, any[]> | Err<never, any[]>;
}
export declare function tuple<A = never>(): Validator<A[]>;

@@ -97,20 +91,6 @@ export declare function tuple<A>(a: Validator<A>): Validator<[A]>;

};
export declare class ObjectValidator<P extends Props> extends Validator<ObjectOf<P>> {
export declare function object<P extends Props>(props: P): Validator<ObjectOf<P>> & {
props: P;
constructor(props: P);
validate(v: Value, config?: Configuration, c?: Context): Validation<ObjectOf<P>>;
}
export declare function object<P extends Props>(props: P): ObjectValidator<P>;
export declare class KeyOfValidator<KEYS extends object> extends Validator<keyof KEYS> {
private keys;
constructor(keys: KEYS);
validate(v: Value, _config?: Configuration, c?: Context): Validation<keyof KEYS>;
}
export declare function keyof<KEYS extends object>(keys: KEYS): KeyOfValidator<KEYS>;
export declare class DictionaryValidator<K extends string, V> extends Validator<Record<K, V>> {
private domain;
private codomain;
constructor(domain: Validator<K>, codomain: Validator<V>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], never> | Err<ValidationError[], never> | Ok<never, any> | Err<never, any>;
}
};
export declare function keyof<KEYS extends object>(keys: KEYS): Validator<keyof KEYS>;
export declare function dictionary<K extends string, V>(domain: Validator<K>, codomain: Validator<V>): Validator<Record<K, V>>;

@@ -125,12 +105,2 @@ export declare type Literal = string | number | boolean | null | undefined;

export declare function intersection<A, B, C, D, E, F>(a: Validator<A>, b: Validator<B>, c: Validator<C>, d: Validator<D>, e: Validator<E>, f: Validator<F>): Validator<A & B & C & D & E & F>;
export declare class UnionValidator<A> extends Validator<A> {
private validators;
constructor(validators: Validator<A>[]);
validate(v: Value, config?: Configuration, c?: Context): Err<ValidationError[], never> | Ok<ValidationError[], A>;
}
export declare class LiteralUnionValidator<A extends Literal> extends Validator<A> {
private values;
constructor(values: A[]);
validate(v: Value, config?: Configuration, c?: Context): Err<ValidationError[], never> | Ok<ValidationError[], A>;
}
export declare function union<A, B>(a: Validator<A>, b: Validator<B>): Validator<A | B>;

@@ -154,22 +124,6 @@ export declare function union<A extends Literal, B extends Literal>(a: A, b: B): Validator<A | B>;

export declare function union<A extends Literal, B extends Literal, C extends Literal, D extends Literal, E extends Literal, F extends Literal, G extends Literal, H extends Literal, I extends Literal, J extends Literal>(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J): Validator<A | B | C | D | E | F | G | H | I | J>;
export declare class OptionalValidator<V> extends Validator<V | undefined> {
private validator;
constructor(validator: Validator<V>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], undefined> | Err<ValidationError[], undefined> | Ok<ValidationError[], V> | Err<ValidationError[], V>;
}
export declare function optional<V>(validator: Validator<V>): Validator<V | undefined>;
export declare class OptionValidator<V> extends Validator<Option<V>> {
private validator;
constructor(validator: Validator<V>);
validate(v: Value, config?: Configuration, c?: Context): Ok<ValidationError[], None> | Err<ValidationError[], None> | Ok<ValidationError[], Some<V>> | Err<ValidationError[], Some<V>>;
}
export declare function option<V>(validator: Validator<V>): Validator<Option<V>>;
export declare function recursion<T>(definition: (self: Validator<T>) => Any): Validator<T>;
export declare const isoDate: Validator<Date>;
export declare function errorDebugString(errors: ValidationError[]): string;
declare const nullValidator: NullValidator;
declare const undefinedValidator: UndefinedValidator;
export { nullValidator as null, undefinedValidator as undefined };
export declare const string: StringValidator;
export declare const number: NumberValidator;
export declare const boolean: BooleanValidator;
export declare const isoDate: Validator<Date>;

@@ -1,51 +0,42 @@

var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
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 extendStatics(d, b);
};
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) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { Ok, Err, None, Some } from 'space-lift';
//--------------------------------------
// Setup
//--------------------------------------
var Validator = /** @class */ (function () {
function Validator() {
this.T = null; // Phantom type
const validatorMethods = {
map(fn) {
return this.flatMap(v => Ok(fn(v)));
},
filter(fn) {
return this.flatMap(v => fn(v) ? Ok(v) : Err(`filter error: ${pretty(v)}"`));
},
flatMap(fn) {
return this.transform(r => isOk(r) ? fn(r.value) : r);
},
transform(fn) {
const validator = this;
return Object.assign({}, validatorMethods, {
validate(v, config = defaultConfig, c = rootContext) {
const validated = validator.validate(v, config, c);
const transformed = fn(validated);
if (isOk(transformed))
return success(transformed.value);
const error = transformed.errors;
if (typeof error === 'string')
return failure(c, error);
return Err(error);
}
});
},
tagged() {
return this;
}
Validator.prototype.map = function (fn) {
return this.flatMap(function (v) { return Ok(fn(v)); });
};
Validator.prototype.filter = function (fn) {
return this.flatMap(function (v) { return fn(v) ? Ok(v) : Err("The value " + pretty(v) + " failed a predicate\""); });
};
Validator.prototype.flatMap = function (fn) {
return this.transform(function (r) { return r.isOk() ? fn(r.get()) : r; });
};
Validator.prototype.transform = function (fn) {
return new TransformValidator(this, fn);
};
Validator.prototype.tagged = function () {
return this;
};
return Validator;
}());
export { Validator };
};
export function Ok(value) {
return { type: 'ok', value };
}
export function Err(errors) {
return { type: 'error', errors };
}
export function isOk(result) {
return result.type === 'ok';
}
export function success(value) {

@@ -55,6 +46,6 @@ return Ok(value);

export function failure(context, message) {
return Err([{ context: context, message: message }]);
return Err([{ context, message }]);
}
export function typeFailure(value, context, expectedType) {
var valueType = (function () {
const valueType = (() => {
if (Array.isArray(value))

@@ -66,20 +57,18 @@ return 'array';

})();
var message = "Type error: expected " + expectedType + " but got " + valueType;
return Err([{ context: context, message: message }]);
const message = `Expected ${expectedType}, got ${valueType}`;
return Err([{ context, message }]);
}
export function getContext(name, parent) {
return (parent ? parent + " / " + name : name);
return (parent ? `${parent} / ${name}` : name);
}
var rootContext = getContext('root');
var defaultConfig = {};
var upperThenLower = /([A-Z]+)([A-Z][a-z])/g;
var lowerThenUpper = /([a-z\\\\d])([A-Z])/g;
export var snakeCaseTransformation = function (key) {
return key
.replace(upperThenLower, '$1_$2')
.replace(lowerThenUpper, '$1_$2')
.toLowerCase();
};
const rootContext = getContext('root');
const defaultConfig = {};
const upperThenLower = /([A-Z]+)([A-Z][a-z])/g;
const lowerThenUpper = /([a-z\\\\d])([A-Z])/g;
export const snakeCaseTransformation = (key) => key
.replace(upperThenLower, '$1_$2')
.replace(lowerThenUpper, '$1_$2')
.toLowerCase();
export function is(value, validator) {
return validator.validate(value).isOk();
return isOk(validator.validate(value));
}

@@ -89,205 +78,73 @@ //--------------------------------------

//--------------------------------------
var NullValidator = /** @class */ (function (_super) {
__extends(NullValidator, _super);
function NullValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
NullValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === null ? success(v) : typeFailure(v, c, 'null');
};
return NullValidator;
}(Validator));
export { NullValidator };
var UndefinedValidator = /** @class */ (function (_super) {
__extends(UndefinedValidator, _super);
function UndefinedValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
UndefinedValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === void 0 ? success(v) : typeFailure(v, c, 'undefined');
};
return UndefinedValidator;
}(Validator));
export { UndefinedValidator };
var StringValidator = /** @class */ (function (_super) {
__extends(StringValidator, _super);
function StringValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
StringValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return typeof v === 'string' ? success(v) : typeFailure(v, c, 'string');
};
return StringValidator;
}(Validator));
export { StringValidator };
var NumberValidator = /** @class */ (function (_super) {
__extends(NumberValidator, _super);
function NumberValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
NumberValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return typeof v === 'number' ? success(v) : typeFailure(v, c, 'number');
};
return NumberValidator;
}(Validator));
export { NumberValidator };
var BooleanValidator = /** @class */ (function (_super) {
__extends(BooleanValidator, _super);
function BooleanValidator() {
return _super !== null && _super.apply(this, arguments) || this;
}
BooleanValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return typeof v === 'boolean' ? success(v) : typeFailure(v, c, 'boolean');
};
return BooleanValidator;
}(Validator));
export { BooleanValidator };
const nullValidator = Object.assign({ validate: (v, _config = defaultConfig, c = rootContext) => v === null ? success(v) : typeFailure(v, c, 'null') }, validatorMethods);
const undefinedValidator = Object.assign({ validate: (v, _config = defaultConfig, c = rootContext) => v === void 0 ? success(v) : typeFailure(v, c, 'undefined') }, validatorMethods);
export const string = Object.assign({ validate: (v, _config = defaultConfig, c = rootContext) => typeof v === 'string' ? success(v) : typeFailure(v, c, 'string') }, validatorMethods);
export const number = Object.assign({ validate: (v, _config = defaultConfig, c = rootContext) => typeof v === 'number' ? success(v) : typeFailure(v, c, 'number') }, validatorMethods);
export const boolean = Object.assign({ validate: (v, _config = defaultConfig, c = rootContext) => typeof v === 'boolean' ? success(v) : typeFailure(v, c, 'boolean') }, validatorMethods);
//--------------------------------------
// transform
//--------------------------------------
var TransformValidator = /** @class */ (function (_super) {
__extends(TransformValidator, _super);
function TransformValidator(validator, f) {
var _this = _super.call(this) || this;
_this.validator = validator;
_this.f = f;
return _this;
}
TransformValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var validated = this.validator.validate(v, config, c);
var transformed = this.f(validated);
if (transformed.isOk())
return success(transformed.get());
var error = transformed.get();
if (typeof error === 'string')
return failure(c, error);
return Err(error);
};
return TransformValidator;
}(Validator));
export { TransformValidator };
//--------------------------------------
// array
//--------------------------------------
var ArrayValidator = /** @class */ (function (_super) {
__extends(ArrayValidator, _super);
function ArrayValidator(validator) {
var _this = _super.call(this) || this;
_this.validator = validator;
return _this;
}
ArrayValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (!Array.isArray(v))
return typeFailure(v, c, 'array');
var validatedArray = [];
var errors = [];
for (var i = 0; i < v.length; i++) {
var item = v[i];
var validation = this.validator.validate(item, config, getContext(String(i), c));
if (validation.isOk()) {
validatedArray.push(validation.get());
export function array(validator) {
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
if (!Array.isArray(v))
return typeFailure(v, c, 'array');
const validatedArray = [];
const errors = [];
for (let i = 0; i < v.length; i++) {
const item = v[i];
const validation = validator.validate(item, config, getContext(String(i), c));
if (isOk(validation)) {
validatedArray.push(validation.value);
}
else {
pushAll(errors, validation.errors);
}
}
else {
pushAll(errors, validation.get());
}
}
return errors.length ? Err(errors) : Ok(validatedArray);
};
return ArrayValidator;
}(Validator));
export { ArrayValidator };
export function array(validator) {
return new ArrayValidator(validator);
return errors.length ? Err(errors) : Ok(validatedArray);
} }, validatorMethods);
}
//--------------------------------------
// tuple
//--------------------------------------
var TupleValidator = /** @class */ (function (_super) {
__extends(TupleValidator, _super);
function TupleValidator(validators) {
var _this = _super.call(this) || this;
_this.validators = validators;
return _this;
}
TupleValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (!Array.isArray(v))
return typeFailure(v, c, 'Tuple');
if (v.length !== this.validators.length)
return failure(c, "Expected Tuple" + this.validators.length + ", got Tuple" + v.length);
var validatedArray = [];
var errors = [];
for (var i = 0; i < v.length; i++) {
var item = v[i];
var validation = this.validators[i].validate(item, config, getContext(String(i), c));
if (validation.isOk()) {
validatedArray.push(validation.get());
export function tuple(...validators) {
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
if (!Array.isArray(v))
return typeFailure(v, c, 'Tuple');
if (v.length !== validators.length)
return failure(c, `Expected Tuple${validators.length}, got Tuple${v.length}`);
const validatedArray = [];
const errors = [];
for (let i = 0; i < v.length; i++) {
const item = v[i];
const validation = validators[i].validate(item, config, getContext(String(i), c));
if (isOk(validation)) {
validatedArray.push(validation.value);
}
else {
pushAll(errors, validation.errors);
}
}
else {
pushAll(errors, validation.get());
}
}
return errors.length ? Err(errors) : Ok(validatedArray);
};
return TupleValidator;
}(Validator));
export { TupleValidator };
export function tuple() {
var validators = [];
for (var _i = 0; _i < arguments.length; _i++) {
validators[_i] = arguments[_i];
}
return new TupleValidator(validators);
return errors.length ? Err(errors) : Ok(validatedArray);
} }, validatorMethods);
}
var ObjectValidator = /** @class */ (function (_super) {
__extends(ObjectValidator, _super);
function ObjectValidator(props) {
var _this = _super.call(this) || this;
_this.props = props;
return _this;
}
ObjectValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
var validatedObject = {};
var errors = [];
for (var key in this.props) {
var transformedKey = config.transformObjectKeys !== undefined
? config.transformObjectKeys(key)
: key;
var value = v[transformedKey];
var validator = this.props[key];
var validation = validator.validate(value, config, getContext(transformedKey, c));
if (validation.isOk()) {
if (validation.get() !== undefined)
validatedObject[key] = validation.get();
export function object(props) {
return Object.assign({ props, validate(v, config = defaultConfig, c = rootContext) {
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
const validatedObject = {};
const errors = [];
for (let key in props) {
const transformedKey = config.transformObjectKeys !== undefined
? config.transformObjectKeys(key)
: key;
const value = v[transformedKey];
const validator = props[key];
const validation = validator.validate(value, config, getContext(transformedKey, c));
if (isOk(validation)) {
if (validation.value !== undefined)
validatedObject[key] = validation.value;
}
else {
pushAll(errors, validation.errors);
}
}
else {
pushAll(errors, validation.get());
}
}
return errors.length ? Err(errors) : Ok(validatedObject);
};
return ObjectValidator;
}(Validator));
export { ObjectValidator };
export function object(props) {
return new ObjectValidator(props);
return errors.length ? Err(errors) : Ok(validatedObject);
} }, validatorMethods);
}

@@ -297,21 +154,8 @@ //--------------------------------------

//--------------------------------------
var KeyOfValidator = /** @class */ (function (_super) {
__extends(KeyOfValidator, _super);
function KeyOfValidator(keys) {
var _this = _super.call(this) || this;
_this.keys = keys;
return _this;
}
KeyOfValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return this.keys.hasOwnProperty(v)
? success(v)
: failure(c, pretty(v) + " is not a key of " + pretty(this.keys));
};
return KeyOfValidator;
}(Validator));
export { KeyOfValidator };
export function keyof(keys) {
return new KeyOfValidator(keys);
return Object.assign({ validate(v, _config = defaultConfig, c = rootContext) {
return keys.hasOwnProperty(v)
? success(v)
: failure(c, `${pretty(v)} is not a key of ${pretty(keys)}`);
} }, validatorMethods);
}

@@ -321,161 +165,78 @@ //--------------------------------------

//--------------------------------------
var DictionaryValidator = /** @class */ (function (_super) {
__extends(DictionaryValidator, _super);
function DictionaryValidator(domain, codomain) {
var _this = _super.call(this) || this;
_this.domain = domain;
_this.codomain = codomain;
return _this;
}
DictionaryValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
var validatedDict = {};
var errors = [];
var _loop_1 = function (key) {
var value = v[key];
var context = getContext(key, c);
var domainValidation = this_1.domain.validate(key, config, context);
var codomainValidation = this_1.codomain.validate(value, config, context);
if (domainValidation.isOk()) {
key = domainValidation.get();
export function dictionary(domain, codomain) {
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
if (v == null || typeof v !== 'object')
return typeFailure(v, c, 'object');
const validatedDict = {};
const errors = [];
for (let key in v) {
const value = v[key];
const context = getContext(key, c);
const domainValidation = domain.validate(key, config, context);
const codomainValidation = codomain.validate(value, config, context);
if (isOk(domainValidation)) {
key = domainValidation.value;
}
else {
const error = domainValidation.errors;
pushAll(errors, error.map(e => ({ context, message: `key error: ${e.message}` })));
}
if (isOk(codomainValidation)) {
validatedDict[key] = codomainValidation.value;
}
else {
const error = codomainValidation.errors;
pushAll(errors, error.map(e => ({ context, message: `value error: ${e.message}` })));
}
}
else {
var error = domainValidation.get();
pushAll(errors, error.map(function (e) { return ({ context: context, message: "key error: " + e.message }); }));
}
if (codomainValidation.isOk()) {
validatedDict[key] = codomainValidation.get();
}
else {
var error = codomainValidation.get();
pushAll(errors, error.map(function (e) { return ({ context: context, message: "value error: " + e.message }); }));
}
};
var this_1 = this;
for (var key in v) {
_loop_1(key);
}
return errors.length ? Err(errors) : Ok(validatedDict);
};
return DictionaryValidator;
}(Validator));
export { DictionaryValidator };
export function dictionary(domain, codomain) {
return new DictionaryValidator(domain, codomain);
return errors.length ? Err(errors) : Ok(validatedDict);
} }, validatorMethods);
}
var LiteralValidator = /** @class */ (function (_super) {
__extends(LiteralValidator, _super);
function LiteralValidator(value) {
var _this = _super.call(this) || this;
_this.value = value;
return _this;
}
LiteralValidator.prototype.validate = function (v, _config, c) {
if (_config === void 0) { _config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return v === this.value
? success(v)
: failure(c, "Expected literal " + this.value + " but got " + pretty(v));
};
return LiteralValidator;
}(Validator));
export function literal(value) {
return new LiteralValidator(value);
return Object.assign({ validate(v, _config = defaultConfig, c = rootContext) {
return v === value
? success(v)
: failure(c, `Expected ${pretty(value)}, got ${pretty(v)}`);
} }, validatorMethods);
}
//--------------------------------------
// intersection
//--------------------------------------
var IntersectionValidator = /** @class */ (function (_super) {
__extends(IntersectionValidator, _super);
function IntersectionValidator(validators) {
var _this = _super.call(this) || this;
_this.validators = validators;
return _this;
}
IntersectionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var result = {};
for (var i = 0; i < this.validators.length; i++) {
var validation = this.validators[i].validate(v, config, c);
if (validation.isOk()) {
result = __assign(__assign({}, result), validation.get());
export function intersection(...validators) {
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
let result = {};
for (let i = 0; i < validators.length; i++) {
const validation = validators[i].validate(v, config, c);
if (isOk(validation)) {
result = Object.assign(Object.assign({}, result), validation.value);
}
else {
return validation;
}
}
else {
return validation;
}
}
return success(result);
};
return IntersectionValidator;
}(Validator));
export function intersection() {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
}
return new IntersectionValidator(values);
return success(result);
} }, validatorMethods);
}
//--------------------------------------
// union
//--------------------------------------
var UnionValidator = /** @class */ (function (_super) {
__extends(UnionValidator, _super);
function UnionValidator(validators) {
var _this = _super.call(this) || this;
_this.validators = validators;
return _this;
export function union(...validators) {
const probe = validators[0];
if (probe && typeof probe === 'object') {
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
const errors = [];
for (let i = 0; i < validators.length; i++) {
const validation = validators[i].validate(v, config, c);
if (isOk(validation))
return validation;
else
errors.push(validation.errors);
}
const detailString = errors.map((es, index) => `Union type #${index} => \n ${errorDebugString(es).replace(/\n/g, '\n ')}`).join('\n');
return failure(c, `The value ${pretty(v)} \nis not part of the union: \n\n${detailString}`);
} }, validatorMethods);
}
UnionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
var errors = [];
for (var i = 0; i < this.validators.length; i++) {
var validation = this.validators[i].validate(v, config, c);
if (validation.isOk())
return validation;
else
errors.push(validation.get());
}
var detailString = errors.map(function (es, index) {
return "Union type #" + index + " => \n " + errorDebugString(es).replace(/\n/g, '\n ');
}).join('\n');
return failure(c, "The value " + pretty(v) + " \nis not part of the union: \n\n" + detailString);
};
return UnionValidator;
}(Validator));
export { UnionValidator };
var LiteralUnionValidator = /** @class */ (function (_super) {
__extends(LiteralUnionValidator, _super);
function LiteralUnionValidator(values) {
var _this = _super.call(this) || this;
_this.values = values;
return _this;
}
LiteralUnionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
for (var i = 0; i < this.values.length; i++) {
var validator = literal(this.values[i]);
var validation = validator.validate(v, config, c);
if (validation.isOk())
return validation;
}
return failure(c, "The value " + pretty(v) + " is not part of the union");
};
return LiteralUnionValidator;
}(Validator));
export { LiteralUnionValidator };
export function union() {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
}
var probe = values[0];
return (probe && typeof probe === 'object')
? new UnionValidator(values)
: new LiteralUnionValidator(values);
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
for (let i = 0; i < validators.length; i++) {
const validator = literal(validators[i]);
const validation = validator.validate(v, config, c);
if (isOk(validation))
return validation;
}
return failure(c, `The value ${pretty(v)} is not part of the union`);
} }, validatorMethods);
}

@@ -485,59 +246,27 @@ //--------------------------------------

//--------------------------------------
var OptionalValidator = /** @class */ (function (_super) {
__extends(OptionalValidator, _super);
function OptionalValidator(validator) {
var _this = _super.call(this) || this;
_this.validator = validator;
return _this;
}
OptionalValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v === undefined)
return success(v);
return this.validator.validate(v, config, c);
};
return OptionalValidator;
}(Validator));
export { OptionalValidator };
export function optional(validator) {
return new OptionalValidator(validator);
return Object.assign({ validate(v, config = defaultConfig, c = rootContext) {
if (v === undefined)
return success(v);
return validator.validate(v, config, c);
} }, validatorMethods);
}
//--------------------------------------
// option
//--------------------------------------
var OptionValidator = /** @class */ (function (_super) {
__extends(OptionValidator, _super);
function OptionValidator(validator) {
var _this = _super.call(this) || this;
_this.validator = validator;
return _this;
}
OptionValidator.prototype.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
if (v === undefined || v === null)
return success(None);
return this.validator.validate(v, config, c).map(Some);
};
return OptionValidator;
}(Validator));
export { OptionValidator };
export function option(validator) {
return new OptionValidator(validator);
}
//--------------------------------------
// recursion
//--------------------------------------
export function recursion(definition) {
var Self = new Validator();
Self.validate = function (v, config, c) {
if (config === void 0) { config = defaultConfig; }
if (c === void 0) { c = rootContext; }
return Result.validate(v, config, c);
};
var Result = definition(Self);
const Self = Object.assign(Object.assign({}, validatorMethods), { validate: (v, config = defaultConfig, c = rootContext) => Result.validate(v, config, c) });
const Result = definition(Self);
return Result;
}
//--------------------------------------
// isoDate
//--------------------------------------
export const isoDate = string.flatMap(str => {
const date = new Date(str);
return isNaN(date.getTime())
? Err(`Expected ISO date, got: ${pretty(str)}`)
: Ok(date);
});
//--------------------------------------
// util

@@ -552,18 +281,7 @@ //--------------------------------------

export function errorDebugString(errors) {
return errors.map(function (e) { return "At [" + e.context + "] " + e.message; }).join('\n');
return errors.map(e => `At [${e.context}] ${e.message}`).join('\n');
}
//--------------------------------------
// Export aliases and singletons
// Export aliases
//--------------------------------------
var nullValidator = new NullValidator();
var undefinedValidator = new UndefinedValidator();
export { nullValidator as null, undefinedValidator as undefined };
export var string = new StringValidator();
export var number = new NumberValidator();
export var boolean = new BooleanValidator();
export var isoDate = string.flatMap(function (str) {
var date = new Date(str);
return isNaN(date.getTime())
? Err("Expected an ISO date but got: " + pretty(str))
: Ok(date);
});
{
"name": "validation.ts",
"version": "0.0.27",
"version": "0.0.28",
"description": "Validation for TypeScript",

@@ -10,6 +10,2 @@ "license": "MIT",

"dependencies": {
"space-lift": ">=0.0.0"
},
"devDependencies": {

@@ -20,3 +16,3 @@ "chalk": "1.1.1",

"mocha": "2.2.5",
"typescript": "3.7.4"
"typescript": "4.0.2"
},

@@ -26,4 +22,4 @@

"build": "npm run build-es && npm run build-commonjs",
"build-es": "tsc validation.ts --outDir es --strict --noUnusedParameters --declaration --lib dom,es5,es6 --module es6 --moduleResolution node",
"build-commonjs": "tsc validation.ts --outDir commonjs --strict --noUnusedParameters --declaration --lib dom,es5,es6",
"build-es": "tsc validation.ts --outDir es --strict --noUnusedParameters --declaration --lib dom,es5,es6 --module es6 --target es6 --moduleResolution node",
"build-commonjs": "tsc validation.ts --outDir commonjs --strict --noUnusedParameters --declaration --lib dom,es5,es6 --target es5",
"pretest": "npm run build && tsc test/mocha.d.ts test/global.d.ts test/expect.d.ts test/test.ts --strict",

@@ -30,0 +26,0 @@ "test": "mocha --recursive && node test/testCompilationErrors.js",

@@ -9,3 +9,3 @@ # validation.ts

Every validator has a `validate` function which returns a [Result](https://github.com/AlexGalays/spacelift#api.result)
Every validator has a `validate` function which returns a Result (either a {type: 'ok', value} or a {type: 'error', errors})

@@ -16,3 +16,3 @@ A validated value can be transformed at any point during the validation process (e.g. `isoDate`).

```ts
import { errorDebugString } from 'validation.ts'
import { errorDebugString, isOk } from 'validation.ts'

@@ -23,6 +23,8 @@ const myValidator = ...

result.fold(
errors => console.error(errorDebugString(errors)),
validatedJson => console.log(validatedJson)
)
if (isOk(result)) {
console.log(result.value)
}
else {
console.error(errorDebugString(result.errors))
}
```

@@ -109,8 +111,2 @@

## option
Whereas `optional` returns an `T | undefined`, `option` return an `Option<T>`
## dictionary

@@ -172,2 +168,5 @@

Instead of using the derived type as your sole interface, use it to compare its compatibility with your
handcrafted interfaces which will always be more readable in IDE's tooltips.
```ts

@@ -181,4 +180,4 @@ import { object, string, number } from 'validation.ts'

type Person = typeof person.T
/*
type PersonFromValidator = typeof person.T
type Person = {

@@ -188,3 +187,2 @@ name: string

}
*/
```

@@ -191,0 +189,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc