UNPKG

narrows

Version:

Super lean and simple object validation with TypeScript support.

143 lines 5.53 kB
"use strict"; var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.report = exports.nullable = exports.optional = exports.all = exports.any = exports.tuple = exports.record = exports.instance = exports.array = exports.object = exports.literal = exports.nil = exports.empty = exports.number = exports.string = exports.boolean = void 0; var isObject = function (x) { return typeof x === "object" && x !== null; }; // -------------------------------- // // - - - PRIMITIVE VALIDATORS - - - // // -------------------------------- // /** Returns true if and only if x is a boolean. */ var boolean = function (x) { return typeof x === "boolean"; }; exports.boolean = boolean; /** Returns true if and only if x is a string. */ var string = function (x) { return typeof x === "string"; }; exports.string = string; /** Returns true if and only if x is a number. */ var number = function (x) { return typeof x === "number"; }; exports.number = number; /** Returns true if and only if x is undefined. */ var empty = function (x) { return x === undefined; }; exports.empty = empty; /** Returns true if and only if x is null. */ var nil = function (x) { return x === null; }; exports.nil = nil; /** Returns true if and only if x is strictly equal to y. */ var literal = function (y) { return function (x) { return x === y; }; }; exports.literal = literal; // ------------------------------ // // - - - COMPLEX VALIDATORS - - - // // ------------------------------ // /** Returns true if and only if x is an object where each value matches the given validator. */ var object = function (validator) { return function (x) { return isObject(x) && Object.values(x).every(validator); }; }; exports.object = object; /** Returns true if and only if x is an array where each element matches the given validator. */ var array = function (validator) { return function (x) { return Array.isArray(x) && x.every(validator); }; }; exports.array = array; /** Returns true if and only if x is an instance of the given type. */ var instance = function (base) { return function (x) { return x instanceof base; }; }; exports.instance = instance; // ------------------------------// // - - - SCHEMA VALIDATORS - - - // // ------------------------------// /** Returns true if and only if x is an object where each value matches the validator at the corresponding key in the schema. */ var record = function (schema) { return function (x) { return isObject(x) && Object.entries(schema).every(function (_a) { var key = _a[0], validate = _a[1]; return validate(x[key]); }); }; }; exports.record = record; /** Returns true if and only if x is an array where each element matches the validator at the corresponding index in the schema. */ var tuple = function () { var schema = []; for (var _i = 0; _i < arguments.length; _i++) { schema[_i] = arguments[_i]; } return function (x) { return Array.isArray(x) && schema.every(function (validator, i) { return validator(x[i]); }); }; }; exports.tuple = tuple; // ----------------------- // // - - - COMBINATORS - - - // // ----------------------- // /** Returns true if and only if x matches any of the given validators. */ var any = function () { var validators = []; for (var _i = 0; _i < arguments.length; _i++) { validators[_i] = arguments[_i]; } return function (x) { return validators.some(function (validator) { return validator(x); }); }; }; exports.any = any; /** Returns true if and only if x matches all of the given validators. */ var all = function () { var validators = []; for (var _i = 0; _i < arguments.length; _i++) { validators[_i] = arguments[_i]; } return function (x) { return validators.every(function (validator) { return validator(x); }); }; }; exports.all = all; /** Returns true if and only if x matches the given validator or is undefined. */ var optional = function (validator) { return exports.any(exports.empty, validator); }; exports.optional = optional; /** Returns true if and only if x matches the given validator or is null. */ var nullable = function (validator) { return exports.any(exports.nil, validator); }; exports.nullable = nullable; // --------------------- // // - - - REPORTING - - - // // --------------------- // var canProxy = function (x) { return x !== null && (typeof x === "object" || typeof x === "function"); }; function spy(source, report, path) { if (path === void 0) { path = []; } if (!canProxy(source)) return source; return new Proxy(source, { get: function (target, property) { var value = target[property]; var next = __spreadArray(__spreadArray([], path), [property]); report(next); return canProxy(value) ? spy(value, report, next) : value; } }); } /** Takes a validator and an object to be validated. Returns null if the object is valid, or the path to the invalid property. */ function report(validate, object) { var path = []; var passed = validate(spy(object, function (current) { return (path = current); })); return passed ? null : path; } exports.report = report; //# sourceMappingURL=index.js.map