@valuer/main
Version:
Valuer is an advanced declarative value validator
167 lines (166 loc) • 7.08 kB
JavaScript
;
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 is_1 = require("@valuer/is");
var help_1 = require("@valuer/help");
var deepmerge = require("deepmerge");
var constants_1 = require("../constants");
var helpers_1 = require("../helpers");
var errors_1 = require("./errors");
var validators_1 = require("./validators");
var configs_1 = require("./configs");
// ***
/** @private */
var DESCRIPTOR_NAME_PREFIX = ":";
// ***
/** @private */
var DESCRIPTOR_NAME_TO_DESCRIPTOR_MAP = Object.create(null);
// ***
/** @private */
var validateName = function (name) {
var invalid = function (failure) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
return errors_1.Errors.panic.apply(errors_1.Errors, __spreadArrays(["Unexpected error", "descriptor name " + failure], args));
};
if (!is_1.is._string(name))
return invalid("is not a string", help_1.help.getPrintable(name));
// remove heading colon if present
var trimmed = name.trim();
var _name = trimmed.substr(+trimmed.startsWith(DESCRIPTOR_NAME_PREFIX));
if (!_name.length)
return invalid("is empty");
else
return DESCRIPTOR_NAME_PREFIX + _name;
};
/** @private */
var getNamesOf = function (descriptive) {
var isSame = is_1.is.equalTo(exports.Descriptors.create(descriptive));
return Object.keys(exports.Descriptors.defined).filter(function (name) { return isSame(exports.Descriptors.defined[name]); });
};
/** @private */
var warnSimilar = function (descriptor) {
var existing = getNamesOf(descriptor);
if (existing.length <= 1)
return;
var names = existing.map(brackets_1.brackets.surroundBy(brackets_1.brackets.collection.doubleQuotes.tight));
console.warn("Descriptor has been defined as " + help_1.help.getPrintableList(names));
};
/** @private */
var getDefined = function (name) {
if (name in exports.Descriptors.defined)
return exports.Descriptors.defined[name];
else
return errors_1.Errors.panic("Unexpected error", "descriptor \"" + name + "\" is not defined");
};
/** @private */
var addToSet = function (descriptor, values) {
var _a;
if (!(descriptor.set instanceof Array))
descriptor.set = [];
(_a = descriptor.set).push.apply(_a, values);
};
/** @private */
var createFromValidations = function (validations) {
var descriptor = {};
var thunks = [];
for (var _i = 0, _a = help_1.help.getEntries(validations); _i < _a.length; _i++) {
var _b = _a[_i], index = _b[0], validation = _b[1];
if (is_1.is._string(validation))
if (validators_1.Validators.isValidationString(validation))
for (var _c = 0, _d = validators_1.Validators.getFor(validation, index); _c < _d.length; _c++) {
var validator = _d[_c];
descriptor[validator] = validation;
}
else if (validation.startsWith(DESCRIPTOR_NAME_PREFIX))
Object.assign(descriptor, deepmerge(descriptor, getDefined(validation)));
else
return errors_1.Errors.unknown.validation(validation, index);
else if (validation instanceof RegExp)
descriptor.pattern = validation;
else if (helpers_1.isThunk(validation))
thunks.push(validation);
else if (validation instanceof Array)
addToSet(descriptor, validation);
else
return errors_1.Errors.unknown.validation(validation, index);
}
if (thunks.length)
if (thunks.length > 1)
for (var _e = 0, _f = help_1.help.getEntries(thunks); _e < _f.length; _e++) {
var _g = _f[_e], index = _g[0], thunk = _g[1];
descriptor[constants_1.DEFAULT_FAILURE + ' ' + brackets_1.brackets.surround(index, brackets_1.brackets.collection.square.tight)] = thunk;
}
else
descriptor[constants_1.DEFAULT_FAILURE] = thunks[0];
return descriptor;
};
/** @private */
var disclose = function (descriptor) {
if ("composite" in descriptor)
for (var key in descriptor.composite) {
if (!exports.Descriptors.isDescriptorFlow([descriptor.composite[key]]))
descriptor.composite[key] = createFromValidations(descriptor.composite[key]);
descriptor.composite[key] = disclose(descriptor.composite[key]);
}
return descriptor;
};
// ***
/** @internal */
exports.Descriptors = {
get defined() {
return DESCRIPTOR_NAME_TO_DESCRIPTOR_MAP;
},
// ***
isDescriptorFlow: function (args) {
return is_1.is.inRange([1, 2])(args.length) && args.every(is_1.is.directInstanceOf(Object));
},
validate: function (descriptor) {
if (!is_1.is._objectNonNull(descriptor))
return errors_1.Errors.panic("Invalid descriptor", help_1.help.getPrintable(descriptor));
else if (!is_1.is._any(descriptor))
null;
for (var _i = 0, _a = help_1.help.getEntries(descriptor); _i < _a.length; _i++) {
var _b = _a[_i], validator = _b[0], validation = _b[1];
if (validators_1.Validators.isValidator(validator))
validators_1.Validators.validate(validator, validation);
else
validators_1.Validators.validateThunk(validation);
}
return descriptor;
},
create: function (descriptive) {
if (is_1.is.array()(descriptive))
return createFromValidations(descriptive);
else if (exports.Descriptors.isDescriptorFlow([descriptive]))
return disclose(exports.Descriptors.validate(descriptive));
else
return errors_1.Errors.panic("Invalid descriptor", help_1.help.getPrintable(descriptive));
},
/**
* @example
* const number = "integer";
* const spectrum = "positive";
*
* valuer.define(":natural", { number, spectrum });
* valuer.define(":natural", [ number, spectrum ]);
*/
define: function (name, descriptive) {
var _name = validateName(name);
if (_name in exports.Descriptors.defined)
return errors_1.Errors.panic("Unexpected error", "cannot redefine descriptor \"" + _name + "\"");
else
exports.Descriptors.defined[_name] = exports.Descriptors.create(descriptive);
if (configs_1.Configs.current.warnOnMultipleNames)
warnSimilar(exports.Descriptors.defined[_name]);
},
};