UNPKG

@valuer/main

Version:

Valuer is an advanced declarative value validator

311 lines (310 loc) 13.1 kB
"use strict"; 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); }; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); var brackets_1 = require("@valuer/brackets"); var help_1 = require("@valuer/help"); var is_1 = require("@valuer/is"); var fn_1 = require("@valuer/fn"); var constants_1 = require("../constants"); var descriptors_1 = require("./descriptors"); var errors_1 = require("./errors"); var validators_1 = require("./validators"); // *** /** @private */ var DEFAULT_PROP_SEPARATOR = "."; /** @private */ var DEFAULT_NAME_SEPARATOR = "@"; /** @private */ var PROPS_PREPOSITION = " in "; // *** /** @private */ var VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_FAILURE_MAP_MAP = { kind: { "any": null, "void": "is not a void", "defined": "is undefined", "non-null": "is null", "non-void": "is a void", "primitive": "is not a primitive", "primitive-defined": "is not a defined primitive", "primitive-non-null": "should be a primitive and not null", "primitive-non-void": "should be a primitive and not a void", "composite": "is not a composite", "composite-defined": "is not a defined composite", "composite-non-null": "should be a composite and not null", "composite-non-void": "should be a composite and not a void", }, number: { "any": null, "number": "is not a number", "numeric": "is NaN", "finite": "is not a finite number", "non-integer": "should not be an integer", "non-integer-finite": "should be a finite non-integer number", "integer": "is not an integer", "integer-even": "is not an even integer", "integer-odd": "is not an odd integer", "integer-safe": "is not a safe integer", "integer-even-safe": "is not a safe even integer", "integer-odd-safe": "is not a safe odd integer", }, spectrum: { "any": null, "number": "is not a number", "negative": "is not a negative number", "positive": "is not a positive number", "non-positive": "should not be a positive number", "non-negative": "should not be a negative number", "non-zero": "should not be zero", }, }; /** @private */ var VALIDATOR_TO_FAILURE_FACTORY_MAP = { value: function (value, config) { return "is not " + help_1.help.getPrintable(value); }, equals: function (equals, config) { return "is not equal to " + help_1.help.getPrintable(equals); }, set: function (set, config) { return "was not found in the set"; }, kind: function (kind, config) { return VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_FAILURE_MAP_MAP.kind[kind]; }, composite: function (map, config) { return "is not a composite value"; }, // *** typeOf: function (type, config) { return "is not of type \"" + type + "\""; }, instanceOf: function (klass, config) { return "is not an instance of " + klass.name; }, // *** number: function (number, config) { return VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_FAILURE_MAP_MAP.number[number]; }, spectrum: function (spectrum, config) { return VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_FAILURE_MAP_MAP.spectrum[spectrum]; }, range: function (range, _a) { var rangeInclusiveness = _a.rangeInclusiveness; return "is out of bounds \"" + help_1.help.getPrintableRange(range, rangeInclusiveness) + "\""; }, // *** pattern: function (pattern, config) { return "does not match the pattern \"" + pattern + "\""; }, length: function (length, config) { return "is not " + length + " element" + (length === 1 ? '' : 's') + " long"; }, lengthRange: function (lengthRange, _a) { var lengthRangeInclusiveness = _a.lengthRangeInclusiveness; return "is not " + help_1.help.getPrintableRange(lengthRange, lengthRangeInclusiveness) + " elements long"; }, }; /** @private */ var VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_THUNK_MAP_MAP = { kind: { "any": is_1.is._any, "void": is_1.is._void, "defined": fn_1.fn.not(is_1.is._undefined), "non-null": fn_1.fn.not(is_1.is._null), "non-void": is_1.is._nonVoid, "primitive": is_1.is._primitive, "primitive-defined": fn_1.fn.any(is_1.is._nonVoidPrimitive, is_1.is._null), "primitive-non-null": fn_1.fn.any(is_1.is._nonVoidPrimitive, is_1.is._undefined), "primitive-non-void": is_1.is._nonVoidPrimitive, "composite": is_1.is._composite, "composite-defined": fn_1.fn.any(is_1.is._nonVoidComposite, is_1.is._null), "composite-non-null": fn_1.fn.any(is_1.is._nonVoidComposite, is_1.is._undefined), "composite-non-void": is_1.is._nonVoidComposite, }, number: { "any": is_1.is._any, "number": is_1.is._number, "numeric": fn_1.fn.all(is_1.is._number, is_1.is.numeric()), "finite": fn_1.fn.all(is_1.is._number, Number.isFinite), "non-integer": fn_1.fn.all(is_1.is._number, is_1.is.float()), "non-integer-finite": fn_1.fn.all(is_1.is._number, Number.isFinite, is_1.is.float()), "integer": Number.isInteger, "integer-even": is_1.is.integer("even"), "integer-odd": is_1.is.integer("odd"), "integer-safe": Number.isSafeInteger, "integer-even-safe": fn_1.fn.all(Number.isSafeInteger, is_1.is.integer("even")), "integer-odd-safe": fn_1.fn.all(Number.isSafeInteger, is_1.is.integer("odd")), }, spectrum: { "any": is_1.is._any, "number": is_1.is._number, "negative": fn_1.fn.all(is_1.is.numeric(), function (value) { return value < 0; }), "positive": fn_1.fn.all(is_1.is.numeric(), function (value) { return value > 0; }), "non-positive": fn_1.fn.all(is_1.is.numeric(), function (value) { return value <= 0; }), "non-negative": fn_1.fn.all(is_1.is.numeric(), function (value) { return value >= 0; }), "non-zero": fn_1.fn.all(is_1.is._number, function (value) { return value !== 0; }), }, }; /** @private */ var _isStringOrArray = fn_1.fn.any(is_1.is._string, is_1.is.array()); /** @private */ var VALIDATOR_TO_THUNK_FACTORY_MAP = { value: function (expected, config) { return function (actual) { return actual === expected; }; }, equals: function (expected, config) { return function (actual) { return is_1.is.equalTo(expected)(actual); }; }, set: function (array, config) { return function (item) { return is_1.is.inArray(array)(item); }; }, kind: function (kind, config) { return VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_THUNK_MAP_MAP.kind[kind]; }, composite: function (map, config) { return function (object) { return is_1.is._composite(object); }; }, // *** typeOf: function (type, config) { return function (value) { return is_1.is.ofType(type)(value); }; }, instanceOf: function (klass, config) { return function (instance) { return is_1.is.instanceOf(klass)(instance); }; }, // *** number: function (number, config) { return VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_THUNK_MAP_MAP.number[number]; }, spectrum: function (spectrum, config) { return VALIDATOR_STRING_CUSTOM_TO_VALIDATION_STRING_TO_THUNK_MAP_MAP.spectrum[spectrum]; }, range: function (bounds, _a) { var rangeInclusiveness = _a.rangeInclusiveness; return function (value) { return is_1.is.inRange(bounds, rangeInclusiveness)(value); }; }, // *** pattern: function (pattern, config) { return fn_1.fn.all(is_1.is._string, pattern.test.bind(pattern)); }, length: function (length, config) { return function (value) { return _isStringOrArray(value) && value.length === length; }; }, lengthRange: function (lengthRange, _a) { var lengthRangeInclusiveness = _a.lengthRangeInclusiveness; return function (value) { return _isStringOrArray(value) && is_1.is.inRange(lengthRange, lengthRangeInclusiveness)(value.length); }; }, }; // *** /** @private */ var getThunk = function (validator, validation, config) { var thunkFactory = VALIDATOR_TO_THUNK_FACTORY_MAP[validator]; return thunkFactory(validation, config); }; /** @private */ var getFailure = function (validator, validation, config) { if (validator === "custom") return constants_1.DEFAULT_FAILURE; else if (!validators_1.Validators.isValidator(validator)) return String(validator); return VALIDATOR_TO_FAILURE_FACTORY_MAP[validator](validation, config); }; /** @private */ var forComposite = function (validation, config, path) { if (path === void 0) { path = []; } var processors = [{ key: "composite", path: __spreadArrays(path), thunk: getThunk("composite", null, config), failure: getFailure("composite", null, config), validator: "composite", validation: is_1.is._composite, }]; for (var key in validation) { var descriptor = descriptors_1.Descriptors.create(validation[key]); processors.push.apply(processors, exports.Processors.create([descriptor], true, config, __spreadArrays(path, [key]))); } return processors; }; /** @private */ var pathToProps = function (path) { if (!path.length) return ""; var _in_ = PROPS_PREPOSITION; return path.reverse().map(brackets_1.brackets.surroundBy(brackets_1.brackets.collection.singleQuotes.tight)).join(_in_) + _in_; }; // *** /** @internal */ exports.Processors = { getKey: function (_a) { var path = _a.path, key = _a.key; if (!path.length) return key; else return DEFAULT_PROP_SEPARATOR + path.join(DEFAULT_PROP_SEPARATOR) + DEFAULT_NAME_SEPARATOR + key; }, getMessageTextPart: function (processor, role) { return pathToProps(processor.path) + role + " " + processor.failure; }, getPanicArgs: function (processor, value, role) { return [ "Validation failed", exports.Processors.getMessageTextPart(processor, role), "value " + help_1.help.getPrintable(value), "validator " + processor.validator, "validation " + help_1.help.getPrintable(processor.validation), ]; }, getMessage: function (processor, value, role) { return errors_1.Errors.composeMessage.apply(errors_1.Errors, exports.Processors.getPanicArgs(processor, value, role)); }, create: function (args, usingDescriptor, config, path) { if (path === void 0) { path = []; } var descriptive = usingDescriptor ? args[0] : args; var descriptor = descriptors_1.Descriptors.create(descriptive); var processors = []; for (var _i = 0, _a = help_1.help.getEntries(descriptor); _i < _a.length; _i++) { var _b = _a[_i], validator = _b[0], validation = _b[1]; var _path = __spreadArrays(path); if (validator === "composite") { processors.push.apply(processors, forComposite(validation, config, _path)); continue; } var mixin = validators_1.Validators.isValidator(validator) ? { validator: validator, thunk: getThunk(validator, validation, config), } : { validator: "(custom)", thunk: validation, }; processors.push(__assign(__assign({}, mixin), { key: validator, path: _path, failure: getFailure(validator, validation, config), validation: validation })); } return processors; }, apply: function (processor, source) { var value = help_1.help.get(source)(processor.path); var result = processor.thunk(value); return { value: value, result: result, processor: processor }; }, };