@valuer/main
Version:
Valuer is an advanced declarative value validator
311 lines (310 loc) • 13.1 kB
JavaScript
;
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 };
},
};