@polyn/blueprint
Version:
An easy to use, flexible, and powerful validation library for nodejs and browsers
1,041 lines (1,005 loc) • 37.8 kB
JavaScript
;
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Node, or global
;
(function (root) {
// eslint-disable-line no-extra-semi
'use strict';
var module = {
factories: {}
};
Object.defineProperty(module, 'exports', {
get: function get() {
return null;
},
set: function set(val) {
module.factories[val.name] = val.factory;
},
// this property should show up when this object's property names are enumerated
enumerable: true,
// this property may not be deleted
configurable: false
});
module.exports = {
name: 'blueprint',
factory: function factory(is) {
'use strict';
var validators = {};
var ValueOrError = /*#__PURE__*/_createClass(function ValueOrError(input) {
_classCallCheck(this, ValueOrError);
this.err = input.err || null;
this.value = is.defined(input.value) ? input.value : null;
if (is.array(input.messages)) {
this.messages = input.messages;
} else if (input.err) {
this.messages = [input.err.message];
} else {
this.messages = null;
}
Object.freeze(this);
});
var ValidationContext = /*#__PURE__*/_createClass(function ValidationContext(input) {
_classCallCheck(this, ValidationContext);
this.key = input.key;
this.value = input.value;
this.input = input.input;
this.root = input.root;
this.output = input.output;
this.schema = input.schema;
});
var Blueprint = /*#__PURE__*/_createClass(function Blueprint(input) {
_classCallCheck(this, Blueprint);
this.name = input.name;
this.schema = input.schema;
this.validate = input.validate;
Object.freeze(this);
});
/**
* Makes a message factory that produces an error message on demand
* @param {string} options.key - the property name
* @param {any} options.value - the value being validated
* @param {any} options.input - the object being validated
* @param {any?} options.schema - the type definitions
* @param {string?} options.type - the type this key should be
*/
var makeDefaultErrorMessage = function makeDefaultErrorMessage(options) {
return function () {
options = options || {};
var key = options.key;
var value = Object.keys(options).includes('value') ? options.value : options.input && options.input[key];
var actualType = is.getType(value);
var expectedType = options.type || options.schema && options.schema[key];
return "expected `".concat(key, "` {").concat(actualType, "} to be {").concat(expectedType, "}");
};
};
/**
* Support for ad-hoc polymorphism for `isValid` functions: they can throw,
* return boolean, or return { isValid: 'boolean', value: 'any', message: 'string[]' }.
* @curried
* @param {function} isValid - the validation function
* @param {ValidationContext} context - the validation context
* @param {function} defaultMessageFactory - the default error message
*/
var normalIsValid = function normalIsValid(isValid) {
return function (context, defaultMessageFactory) {
try {
var result = isValid(context);
if (is.boolean(result)) {
return result ? new ValueOrError({
value: context.value
}) : new ValueOrError({
err: new Error(defaultMessageFactory())
});
} else if (result) {
return {
err: result.err,
value: result.value
};
} else {
return new ValueOrError({
err: new Error("ValidationError: the validator for `".concat(context.key, "` didn't return a value"))
});
}
} catch (err) {
return new ValueOrError({
err: err
});
}
};
};
/**
* If the caller passes in an instance of a class, or a function that
* has prototype values, we shouldn't strip those away. Try to create
* an object from the input's prototype, and return a plain object if
* that fails
* @param {any} input - the input that was passed to `validate`
*/
var tryMakeFromProto = function tryMakeFromProto(input) {
try {
return Object.create(Object.getPrototypeOf(input));
} catch (e) {
return {};
}
};
/**
* Validates the input values against the schema expectations
* @curried
* @param {string} name - the name of the model being validated
* @param {object} schema - the type definitions
* @param {object} input - the values being validated
*/
var validate = function validate(name, schema) {
return function (input, root) {
var outcomes = Object.keys(schema).reduce(function (output, key) {
var keyName = root ? "".concat(name, ".").concat(key) : key;
if (is.object(schema[key])) {
var child = validate("".concat(keyName), schema[key])(input[key], root || input);
if (child.err) {
output.validationErrors = output.validationErrors.concat(child.messages);
}
output.value[key] = child.value;
return output;
}
var validator;
if (is.function(schema[key])) {
validator = normalIsValid(schema[key]);
} else if (is.regexp(schema[key])) {
validator = normalIsValid(validators.expression(schema[key]));
} else {
validator = validators[schema[key]];
}
if (is.not.function(validator)) {
output.validationErrors.push("I don't know how to validate ".concat(schema[key]));
return output;
}
var context = new ValidationContext({
key: "".concat(keyName),
value: input && input[key],
input: input,
root: root || input,
output: output.value,
schema: schema
});
var result = validator(context, makeDefaultErrorMessage(context));
if (result && result.err) {
output.validationErrors.push(result.err.message);
return output;
}
output.value[key] = result ? result.value : input[key];
return output;
}, {
/* output */
validationErrors: [],
value: tryMakeFromProto(input)
}); // /reduce
if (outcomes.validationErrors.length) {
return new ValueOrError({
err: new Error("Invalid ".concat(name, ": ").concat(outcomes.validationErrors.join(', '))),
messages: outcomes.validationErrors
});
}
return new ValueOrError({
value: outcomes.value
});
};
}; // /validate
/**
* Returns a validator (fluent interface) for validating the input values
* against the schema expectations
* @param {string} name - the name of the model being validated
* @param {object} schema - the type definitions
* @param {object} validate.input - the values being validated
*/
var blueprint = function blueprint(name, schema) {
if (is.not.string(name) || is.not.object(schema)) {
throw new Error('blueprint requires a name {string}, and a schema {object}');
}
return new Blueprint({
name: name,
schema: schema,
validate: validate(name, schema)
});
};
/**
* Registers a validator by name, so it can be used in blueprints
* @param {string} name - the name of the validator
* @param {function} validator - the validator
*/
var registerValidator = function registerValidator(name, validator) {
if (is.not.string(name) || is.not.function(validator)) {
throw new Error('registerValidator requires a name {string}, and a validator {function}');
}
if (name === 'expression') {
validators[name] = validator;
} else {
validators[name] = normalIsValid(validator);
}
return validator;
}; // /registerValidator
/**
* Registers a validator, and a nullable validator by the given name, using
* the given isValid function
* @param {string} name - the name of the type
* @param {function} isValid - the validator for testing one instance of this type (must return truthy/falsey)
*/
var registerInstanceOfType = function registerInstanceOfType(name, isValid) {
var test = normalIsValid(isValid);
return [
// required
registerValidator(name, function (context) {
var key = context.key;
return test(context, makeDefaultErrorMessage({
key: key,
value: context.value,
type: name
}));
}),
// nullable
registerValidator("".concat(name, "?"), function (context) {
var key = context.key,
value = context.value;
if (is.nullOrUndefined(value)) {
return {
err: null,
value: value
};
} else {
return test(context, makeDefaultErrorMessage({
key: key,
value: context.value,
type: name
}));
}
})];
};
/**
* Registers an array validator, and a nullable array validator by the given
* name, using the given isValid function
* @param {string} name - the name of the type
* @param {function} isValid - the validator for testing one instance of this type (must return truthy/falsey)
*/
var registerArrayOfType = function registerArrayOfType(instanceName, arrayName, isValid) {
var test = normalIsValid(isValid);
var validateMany = function validateMany(context, errorMessageFactory) {
if (is.not.array(context.value)) {
return {
err: new Error(errorMessageFactory()),
value: null
};
}
var errors = [];
var values = [];
context.value.forEach(function (value, index) {
var key = "".concat(context.key, "[").concat(index, "]");
var result = test({
key: key,
value: value,
input: context.input,
root: context.root
}, makeDefaultErrorMessage({
key: key,
value: value,
type: instanceName
}));
if (result.err) {
// make sure the array key[index] is in the error message
var message = result.err.message.indexOf("[".concat(index, "]")) > -1 ? result.err.message : "(`".concat(key, "`) ").concat(result.err.message);
return errors.push(message);
}
return values.push(result.value);
});
if (errors.length) {
return {
err: new Error(errors.join(', ')),
value: null
};
}
return {
err: null,
value: values
};
};
return [
// required
registerValidator(arrayName, function (context) {
var key = context.key;
return validateMany(context, makeDefaultErrorMessage({
key: key,
value: context.value,
type: arrayName
}));
}),
// nullable
registerValidator("".concat(arrayName, "?"), function (context) {
var key = context.key,
value = context.value;
if (is.nullOrUndefined(value)) {
return {
err: null,
value: value
};
} else {
return validateMany(context, makeDefaultErrorMessage({
key: key,
value: context.value,
type: arrayName
}));
}
})];
};
/**
* Registers a validator, a nullable validator, an array validator, and
* a nullable array validator based on the given name, using the
* given validator function
* @param {string} name - the name of the type
* @param {function} validator - the validator for testing one instance of this type (must return truthy/falsey)
*/
var registerType = function registerType(name, validator) {
if (is.not.string(name) || is.not.function(validator)) {
throw new Error('registerType requires a name {string}, and a validator {function}');
}
registerInstanceOfType(name, validator);
registerArrayOfType(name, "".concat(name, "[]"), validator);
var output = {};
output[name] = validators[name];
output["".concat(name, "?")] = validators["".concat(name, "?")];
output["".concat(name, "[]")] = validators["".concat(name, "[]")];
output["".concat(name, "[]?")] = validators["".concat(name, "[]?")];
return output;
};
/**
* Registers a blueprint that can be used as a validator
* @param {string} name - the name of the model being validated
* @param {object} schema - the type definitions
*/
var registerBlueprint = function registerBlueprint(name, schema) {
var bp;
if (schema && schema.schema) {
// this must be an instance of a blueprint
bp = blueprint(name, schema.schema);
} else {
bp = blueprint(name, schema);
}
var cleanMessage = function cleanMessage(key, message) {
return message.replace("Invalid ".concat(bp.name, ": "), '').replace(/expected `/g, "expected `".concat(key, "."));
};
registerType(bp.name, function (_ref) {
var key = _ref.key,
value = _ref.value;
var result = bp.validate(value);
if (result.err) {
result.err.message = cleanMessage(key, result.err.message);
}
return result;
});
return bp;
};
/**
* Registers a regular expression validator by name, so it can be used in blueprints
* @param {string} name - the name of the validator
* @param {string|RegExp} expression - the expression that will be used to validate the values
*/
var registerExpression = function registerExpression(name, expression) {
if (is.not.string(name) || is.not.regexp(expression) && is.not.string(expression)) {
throw new Error('registerExpression requires a name {string}, and an expression {expression}');
}
var regex = is.string(expression) ? new RegExp(expression) : expression;
return registerType(name, function (_ref2) {
var key = _ref2.key,
value = _ref2.value;
return regex.test(value) === true ? new ValueOrError({
value: value
}) : new ValueOrError({
err: new Error("expected `".concat(key, "` to match ").concat(regex.toString()))
});
});
};
var getValidators = function getValidators() {
return _objectSpread({}, validators);
};
var getValidator = function getValidator(name) {
if (!validators[name]) {
return;
}
return _objectSpread({}, validators[name]);
};
var comparatorToValidator = function comparatorToValidator(comparator) {
var validator;
if (is.function(comparator)) {
validator = normalIsValid(comparator);
} else if (is.regexp(comparator)) {
validator = normalIsValid(validators.expression(comparator));
} else {
validator = validators[comparator];
}
return validator;
};
/**
* Fluent interface to support optional function based validators
* (i.e. like gt, lt, range, custom), and to use default values when
* the value presented is null, or undefined.
* @param {any} comparator - the name of the validator, or a function that performs validation
*/
var optional = function optional(comparator) {
var defaultVal;
var from;
var validator = comparatorToValidator(comparator);
var valueOrDefaultValue = function valueOrDefaultValue(value) {
if (is.function(defaultVal)) {
return {
value: defaultVal()
};
} else if (is.defined(defaultVal)) {
return {
value: defaultVal
};
} else {
return {
value: value
};
}
};
var output = function output(ctx) {
var context;
if (from) {
context = _objectSpread(_objectSpread({}, ctx), {
value: from(ctx)
});
} else {
context = ctx;
}
var _context = context,
value = _context.value;
if (is.nullOrUndefined(value)) {
return valueOrDefaultValue(value);
} else {
return validator(context);
}
};
/**
* A value factory for producing a value, given the constructor context
* @param {function} callback - a callback function that accepts IValidationContext and produces a value
*/
output.from = function (callback) {
if (is.function(callback)) {
from = callback;
}
return output;
};
/**
* Sets a default value to be used when a value is not given for this property
* @param {any} defaultValue - the value to use when this property is null or undefined
*/
output.withDefault = function (defaultValue) {
defaultVal = defaultValue;
return output;
};
return output;
};
/**
* Fluent interface to support optional function based validators
* (i.e. like gt, lt, range, custom), and to use default values when
* the value presented is null, or undefined.
* @param {any} comparator - the name of the validator, or a function that performs validation
*/
var required = function required(comparator) {
var from;
var validator = comparatorToValidator(comparator);
var output = function output(ctx) {
var context;
if (from) {
context = _objectSpread(_objectSpread({}, ctx), {
value: from(ctx)
});
} else {
context = ctx;
}
return validator(context);
};
/**
* A value factory for producing a value, given the constructor context
* @param {function} callback - a callback function that accepts IValidationContext and produces a value
*/
output.from = function (callback) {
if (is.function(callback)) {
from = callback;
}
return output;
};
return output;
};
return {
blueprint: blueprint,
registerValidator: registerValidator,
registerType: registerType,
registerBlueprint: registerBlueprint,
registerExpression: registerExpression,
optional: optional,
required: required,
// below are undocumented / subject to breaking changes
registerInstanceOfType: registerInstanceOfType,
registerArrayOfType: registerArrayOfType,
getValidators: getValidators,
getValidator: getValidator
};
}
};
module.exports = {
name: 'is',
factory: function factory() {
'use strict';
var is = {
getType: undefined,
defined: undefined,
nullOrUndefined: undefined,
function: undefined,
func: undefined,
promise: undefined,
asyncFunction: undefined,
asyncFunc: undefined,
object: undefined,
array: undefined,
string: undefined,
boolean: undefined,
date: undefined,
regexp: undefined,
number: undefined,
nullOrWhitespace: undefined,
decimal: undefined,
primitive: undefined,
arrayOf: undefined,
not: {
defined: undefined,
nullOrUndefined: undefined,
function: undefined,
func: undefined,
promise: undefined,
asyncFunction: undefined,
asyncFunc: undefined,
object: undefined,
array: undefined,
string: undefined,
boolean: undefined,
date: undefined,
regexp: undefined,
number: undefined,
nullOrWhitespace: undefined,
decimal: undefined,
primitive: undefined,
arrayOf: undefined
}
};
var primitives = ['boolean', 'null', 'undefined', 'number', 'bigint', 'string', 'symbol'];
/**
* Produces the printed type (i.e. [object Object], [object Function]),
* removes everything except for the type, and returns the lowered form.
* (i.e. boolean, number, string, function, asyncfunction, promise, array,
* date, regexp, object)
*/
is.getType = function (obj) {
return Object.prototype.toString.call(obj).replace(/(^\[object )|(\]$)/g, '').toLowerCase();
};
is.defined = function (obj) {
return is.getType(obj) !== 'undefined';
};
is.not.defined = function (obj) {
return is.defined(obj) === false;
};
is.nullOrUndefined = function (obj) {
return is.not.defined(obj) || obj === null;
};
is.not.nullOrUndefined = function (obj) {
return is.nullOrUndefined(obj) === false;
};
is.not.nullOrWhitespace = function (str) {
if (typeof str === 'undefined' || str === null) {
return false;
} else if (Array.isArray(str)) {
return true;
}
// ([^\s]*) = is not whitespace
// /^$|\s+/ = is empty or whitespace
return /([^\s])/.test(str);
};
is.nullOrWhitespace = function (str) {
return is.not.nullOrWhitespace(str) === false;
};
is.function = function (obj) {
var type = is.getType(obj);
return type === 'function' || type === 'asyncfunction' || type === 'promise';
};
is.func = is.function; // typescript support
is.not.function = function (obj) {
return is.function(obj) === false;
};
is.not.func = is.not.function; // typescript support
is.promise = function (obj) {
var type = is.getType(obj);
return type === 'asyncfunction' || type === 'promise';
};
is.not.promise = function (obj) {
return is.promise(obj) === false;
};
is.asyncFunction = function (obj) {
return is.promise(obj);
};
is.asyncFunc = is.asyncFunction; // consistency for typescript
is.not.asyncFunction = function (obj) {
return is.asyncFunction(obj) === false;
};
is.not.asyncFunc = is.not.asyncFunction; // consistency for typescript
is.object = function (obj) {
return is.getType(obj) === 'object';
};
is.not.object = function (obj) {
return is.object(obj) === false;
};
is.array = function (obj) {
return is.getType(obj) === 'array';
};
is.not.array = function (obj) {
return is.array(obj) === false;
};
is.string = function (obj) {
return is.getType(obj) === 'string';
};
is.not.string = function (obj) {
return is.string(obj) === false;
};
is.boolean = function (obj) {
return is.getType(obj) === 'boolean';
};
is.not.boolean = function (obj) {
return is.boolean(obj) === false;
};
is.date = function (obj) {
return is.getType(obj) === 'date' && is.function(obj.getTime) && !isNaN(obj.getTime());
};
is.not.date = function (obj) {
return is.date(obj) === false;
};
is.regexp = function (obj) {
return is.getType(obj) === 'regexp';
};
is.not.regexp = function (obj) {
return is.regexp(obj) === false;
};
is.number = function (obj) {
return is.getType(obj) === 'number';
};
is.not.number = function (obj) {
return is.number(obj) === false;
};
is.decimal = function (num, places) {
if (is.not.number(num)) {
return false;
}
if (!places && is.number(num)) {
return true;
}
var padded = +(+num || 0).toFixed(20); // pad to the right for whole numbers
return padded.toFixed(places) === "".concat(+num);
};
is.not.decimal = function (val, places) {
return is.decimal(val, places) === false;
};
is.primitive = function (input) {
return primitives.indexOf(is.getType(input)) > -1;
};
is.not.primitive = function (input) {
return is.primitive(input) === false;
};
is.arrayOf = function (type) {
if (!is[type]) {
throw new Error("is does not support evaluation of {".concat(type, "}"));
}
return function (input) {
return input.find(function (v) {
return is.not[type](v);
}) === undefined;
};
};
is.not.arrayOf = function (type) {
if (!is[type]) {
throw new Error("is does not support evaluation of {".concat(type, "}"));
}
return function (input) {
return is.arrayOf(type)(input) === false;
};
};
return is;
}
};
module.exports = {
name: 'numberValidators',
factory: function factory(is) {
'use strict';
var makeErrorMessage = function makeErrorMessage(options) {
return "expected `".concat(options.key, "` to be ").concat(options.comparator, " ").concat(options.boundary);
};
var gt = function gt(min) {
if (is.not.number(min)) {
throw new Error('gt requires a minimum number to compare values to');
}
return function (_ref3) {
var key = _ref3.key,
value = _ref3.value;
if (is.number(value) && value > min) {
return {
err: null,
value: value
};
}
return {
err: new Error(makeErrorMessage({
key: key,
comparator: 'greater than',
boundary: min
})),
value: null
};
};
};
var gte = function gte(min) {
if (is.not.number(min)) {
throw new Error('gte requires a minimum number to compare values to');
}
return function (_ref4) {
var key = _ref4.key,
value = _ref4.value;
if (is.number(value) && value >= min) {
return {
err: null,
value: value
};
}
return {
err: new Error(makeErrorMessage({
key: key,
comparator: 'greater than, or equal to',
boundary: min
})),
value: null
};
};
};
var lt = function lt(max) {
if (is.not.number(max)) {
throw new Error('lt requires a maximum number to compare values to');
}
return function (_ref5) {
var key = _ref5.key,
value = _ref5.value;
if (is.number(value) && value < max) {
return {
err: null,
value: value
};
}
return {
err: new Error(makeErrorMessage({
key: key,
comparator: 'less than',
boundary: max
})),
value: null
};
};
};
var lte = function lte(max) {
if (is.not.number(max)) {
throw new Error('lte requires a maximum number to compare values to');
}
return function (_ref6) {
var key = _ref6.key,
value = _ref6.value;
if (is.number(value) && value <= max) {
return {
err: null,
value: value
};
}
return {
err: new Error(makeErrorMessage({
key: key,
comparator: 'less than, or equal to',
boundary: max
})),
value: null
};
};
};
var range = function range(options) {
if (!options) {
throw new Error('You must specify a range');
} else if (is.not.number(options.gt) && is.not.number(options.gte)) {
throw new Error('You must specify `gt`, or `gte` {number} when defining a range');
} else if (is.not.number(options.lt) && is.not.number(options.lte)) {
throw new Error('You must specify `lt`, or `lte` {number} when defining a range');
}
var gtExpression = options.gt ? gt(options.gt) : gte(options.gte);
var ltExpression = options.lt ? lt(options.lt) : lte(options.lte);
return function (input) {
var ltOutcome = ltExpression(input);
if (ltOutcome.err) {
return ltOutcome;
}
return gtExpression(input);
};
};
var optional = function optional(comparator) {
return function (input) {
var validator = comparator(input);
return function (context) {
var value = context.value;
if (is.nullOrUndefined(value)) {
return {
value: value
};
} else {
return validator(context);
}
};
};
};
return {
gt: gt,
gte: gte,
lt: lt,
lte: lte,
range: range,
// backward compatibility - can be removed in v3
__optional: {
gt: optional(gt),
gte: optional(gte),
lt: optional(lt),
lte: optional(lte),
range: optional(range)
}
};
}
};
module.exports = {
name: 'registerCommonTypes',
factory: function factory(is, Blueprint) {
'use strict';
var registerType = Blueprint.registerType;
var types = ['function', 'asyncFunction', 'promise', 'object', 'array', 'boolean', 'date', 'number', 'decimal', 'regexp', 'primitive'
// 'string' registered separately, below
];
var errorMessage = function errorMessage(type) {
return function (key, value) {
return "expected `".concat(key, "` {").concat(is.getType(value), "} to be {").concat(type, "}");
};
};
types.forEach(function (type) {
registerType(type, function (_ref7) {
var key = _ref7.key,
value = _ref7.value;
return is[type](value) ? {
err: null,
value: value
} : {
err: new Error(errorMessage(type)(key, value))
};
});
});
registerType('string', function (_ref8) {
var key = _ref8.key,
value = _ref8.value;
if (is.string(value)) {
var trimmed = value.trim();
if (trimmed.length) {
return {
value: trimmed
};
}
return {
err: new Error("expected `".concat(key, "` {").concat(is.getType(value), "} to not be an empty string"))
};
} else {
return {
err: new Error(errorMessage('string')(key, value))
};
}
});
registerType('any', function (_ref9) {
var key = _ref9.key,
value = _ref9.value;
return is.not.nullOrUndefined(value) ? {
err: null,
value: value
} : {
err: new Error(errorMessage('any')(key, value))
};
});
}
};
module.exports = {
name: 'registerDecimals',
factory: function factory(is, Blueprint) {
'use strict';
var registerValidator = Blueprint.registerValidator;
// support up to 15 decimal places for decimal precision
var _loop = function _loop(i) {
registerValidator("decimal:".concat(i), function (_ref10) {
var key = _ref10.key,
value = _ref10.value;
return is.decimal(value, i) ? {
err: null,
value: value
} : {
err: new Error("expected `".concat(key, "` to be a {decimal} with ").concat(i, " places")),
value: null
};
});
registerValidator("decimal:".concat(i, "?"), function (_ref11) {
var key = _ref11.key,
value = _ref11.value;
if (is.nullOrUndefined(value)) {
return {
err: null,
value: value
};
} else if (is.decimal(value, i)) {
return {
err: null,
value: value
};
} else {
return {
err: new Error("expected `".concat(key, "` to be a {decimal} with ").concat(i, " places")),
value: null
};
}
});
};
for (var i = 1; i <= 15; i += 1) {
_loop(i);
}
}
};
module.exports = {
name: 'registerExpressions',
factory: function factory(Blueprint) {
'use strict';
var registerValidator = Blueprint.registerValidator;
registerValidator('expression', function (regex) {
return function (_ref12) {
var key = _ref12.key,
value = _ref12.value;
return regex.test(value) === true ? {
value: value
} : {
err: new Error("expected `".concat(key, "` to match ").concat(regex.toString()))
};
};
});
}
};
var is = module.factories.is();
var numberValidators = module.factories.numberValidators(is);
var blueprint = module.factories.blueprint(is);
// backward compatibility - can be removed in v3
Object.keys(numberValidators.__optional).forEach(function (key) {
blueprint.optional[key] = numberValidators.__optional[key];
});
delete numberValidators.__optional;
root.polyn = root.polyn || {};
root.polyn.blueprint = Object.freeze(Object.assign({
is: is
}, numberValidators, blueprint));
module.factories.registerCommonTypes(is, root.polyn.blueprint);
module.factories.registerDecimals(is, root.polyn.blueprint);
module.factories.registerExpressions(root.polyn.blueprint);
// we don't need these anymore
delete module.factories;
})(window);