chain-able
Version:
interfaces that describe their intentions.
136 lines (126 loc) • 10.4 kB
JavaScript
var ENV_DEVELOPMENT = require('../env/dev')
var dotPropPaths = require('../dot/paths')
var dotGet = require('../dot/get')
var isStringOrNumber = require('../is/stringOrNumber')
var isReal = require('../is/real')
var isBoolean = require('../is/boolean')
var isRegExp = require('../is/regexp')
var isError = require('../is/error')
var validationBuilder = require('./validatorBuilder')
var isNotNested = function (x) { return isStringOrNumber(x) ||
isBoolean(x) ||
!isReal(x) ||
isError(x) ||
isRegExp(x); }
var validateType = function (type, value, nestedSchema) {
var validator = nestedSchema || validationBuilder(type)
return validator(value)
}
/**
* @desc pass the property & schema in, get a nestable typeValidator out
* @since 4.0.0-alpha.1
* @category types
* @category schema
*
* @param {Primitive} property property name of the currently nested schema
* @param {Schema | Type} nestedSchema a nested schema with Type validators, or a Type validator
* @return {Function} typeValidator
*
* @example
*
* // property name here is `dates`, then `created`, then `at`
* nestedSchema = {
* dates: {
* created: {
* at: 'date'
* }
* }
* }
*
* input = {
* dates: {
* created: {
* at: new Date()
* }
* }
* }
*
* input = new Date()
* input = {
* dates: {
* mismatch: true
* }
* }
*
*/
var schemaFactory = function (property, nestedSchema) {
/**
* @desc build a recursive schema for all around runtime type safety
* @category types
* @category schema
* @memberOf schema
* @symb 🛂
* @since 4.0.0-beta.1
*
* @param {any} input the input to validate
* @return {boolean} valid
*
* @see is
*
* @example
*
* const typeValidator = schemaFactory('eh', x => typeof x === 'string')
*
* var isValid = typeValidator('stringy')
* //=> true
*
* var isValid = typeValidator(Number)
* //=> false
*
* @example
*
* const isNumber = x => typeof x === 'number'
* const typeValidator = schemaFactory('eh', {canada: 'number'})
*
* var isValid = typeValidator({canada: 1})
* //=> true
*
* var isValid = typeValidator({})
* //=> false
*
* var isValid = typeValidator({canada: false})
* //=> false
*
* var isValid = typeValidator(1)
* //=> false
*
*/
function typeValidator(input) {
if (isNotNested(input)) {
// @@DEBUGGER
return validateType(property, input, nestedSchema)
}
var longestPaths = dotPropPaths(false, input, true)
// @@DEBUGGER
for (var l = 0; l < longestPaths.length; l++) {
var fullPath = longestPaths[l] || property
var type = dotGet(nestedSchema, fullPath)
var value = dotGet(input, fullPath.split('.'))
// @@DEBUGGER
if (!validateType(type, value)) {
// @@DEBUGGER
return false
}
// @@DEBUGGER
}
return true
}
/* istanbul ignore next: devs */
if (ENV_DEVELOPMENT) {
typeValidator.inspect = function () { return ({property: property, nestedSchema: nestedSchema}); }
typeValidator.toString = function () { return JSON.stringify(typeValidator.inspect(), null, 2); }
}
return typeValidator
}
module.exports = schemaFactory
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hQnVpbGRlci5qcyIsInNvdXJjZXMiOlsic2NoZW1hQnVpbGRlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBFTlZfREVWRUxPUE1FTlQgPSByZXF1aXJlKCcuLi9lbnYvZGV2JylcbmNvbnN0IGRvdFByb3BQYXRocyA9IHJlcXVpcmUoJy4uL2RvdC9wYXRocycpXG5jb25zdCBkb3RHZXQgPSByZXF1aXJlKCcuLi9kb3QvZ2V0JylcbmNvbnN0IGlzU3RyaW5nT3JOdW1iZXIgPSByZXF1aXJlKCcuLi9pcy9zdHJpbmdPck51bWJlcicpXG5jb25zdCBpc1JlYWwgPSByZXF1aXJlKCcuLi9pcy9yZWFsJylcbmNvbnN0IGlzQm9vbGVhbiA9IHJlcXVpcmUoJy4uL2lzL2Jvb2xlYW4nKVxuY29uc3QgaXNSZWdFeHAgPSByZXF1aXJlKCcuLi9pcy9yZWdleHAnKVxuY29uc3QgaXNFcnJvciA9IHJlcXVpcmUoJy4uL2lzL2Vycm9yJylcbmNvbnN0IHZhbGlkYXRpb25CdWlsZGVyID0gcmVxdWlyZSgnLi92YWxpZGF0b3JCdWlsZGVyJylcblxuY29uc3QgaXNOb3ROZXN0ZWQgPSB4ID0+XG4gIGlzU3RyaW5nT3JOdW1iZXIoeCkgfHxcbiAgaXNCb29sZWFuKHgpIHx8XG4gICFpc1JlYWwoeCkgfHxcbiAgaXNFcnJvcih4KSB8fFxuICBpc1JlZ0V4cCh4KVxuXG5jb25zdCB2YWxpZGF0ZVR5cGUgPSAodHlwZSwgdmFsdWUsIG5lc3RlZFNjaGVtYSkgPT4ge1xuICBjb25zdCB2YWxpZGF0b3IgPSBuZXN0ZWRTY2hlbWEgfHwgdmFsaWRhdGlvbkJ1aWxkZXIodHlwZSlcbiAgcmV0dXJuIHZhbGlkYXRvcih2YWx1ZSlcbn1cblxuLyoqXG4gKiBAZGVzYyBwYXNzIHRoZSBwcm9wZXJ0eSAmIHNjaGVtYSBpbiwgZ2V0IGEgbmVzdGFibGUgdHlwZVZhbGlkYXRvciBvdXRcbiAqIEBzaW5jZSA0LjAuMC1hbHBoYS4xXG4gKiBAY2F0ZWdvcnkgdHlwZXNcbiAqIEBjYXRlZ29yeSBzY2hlbWFcbiAqXG4gKiBAcGFyYW0ge1ByaW1pdGl2ZX0gcHJvcGVydHkgcHJvcGVydHkgbmFtZSBvZiB0aGUgY3VycmVudGx5IG5lc3RlZCBzY2hlbWFcbiAqIEBwYXJhbSB7U2NoZW1hIHwgVHlwZX0gbmVzdGVkU2NoZW1hIGEgbmVzdGVkIHNjaGVtYSB3aXRoIFR5cGUgdmFsaWRhdG9ycywgb3IgYSBUeXBlIHZhbGlkYXRvclxuICogQHJldHVybiB7RnVuY3Rpb259IHR5cGVWYWxpZGF0b3JcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHByb3BlcnR5IG5hbWUgaGVyZSBpcyBgZGF0ZXNgLCB0aGVuIGBjcmVhdGVkYCwgdGhlbiBgYXRgXG4gKiBuZXN0ZWRTY2hlbWEgPSB7XG4gKiAgIGRhdGVzOiB7XG4gKiAgICAgIGNyZWF0ZWQ6IHtcbiAqICAgICAgICAgYXQ6ICdkYXRlJ1xuICogICAgICB9XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBpbnB1dCA9IHtcbiAqICAgIGRhdGVzOiB7XG4gKiAgICAgIGNyZWF0ZWQ6IHtcbiAqICAgICAgICBhdDogbmV3IERhdGUoKVxuICogICAgICB9XG4gKiAgICB9XG4gKiB9XG4gKlxuICogaW5wdXQgPSBuZXcgRGF0ZSgpXG4gKiBpbnB1dCA9IHtcbiAqICAgIGRhdGVzOiB7XG4gKiAgICAgIG1pc21hdGNoOiB0cnVlXG4gKiAgICB9XG4gKiB9XG4gKlxuICovXG5jb25zdCBzY2hlbWFGYWN0b3J5ID0gKHByb3BlcnR5LCBuZXN0ZWRTY2hlbWEpID0+IHtcbiAgLyoqXG4gICAqIEBkZXNjIGJ1aWxkIGEgcmVjdXJzaXZlIHNjaGVtYSBmb3IgYWxsIGFyb3VuZCBydW50aW1lIHR5cGUgc2FmZXR5XG4gICAqIEBjYXRlZ29yeSB0eXBlc1xuICAgKiBAY2F0ZWdvcnkgc2NoZW1hXG4gICAqIEBtZW1iZXJPZiBzY2hlbWFcbiAgICogQHN5bWIg8J+bglxuICAgKiBAc2luY2UgNC4wLjAtYmV0YS4xXG4gICAqXG4gICAqIEBwYXJhbSAge2FueX0gaW5wdXQgdGhlIGlucHV0IHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IHZhbGlkXG4gICAqXG4gICAqIEBzZWUgaXNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICBjb25zdCB0eXBlVmFsaWRhdG9yID0gc2NoZW1hRmFjdG9yeSgnZWgnLCB4ID0+IHR5cGVvZiB4ID09PSAnc3RyaW5nJylcbiAgICpcbiAgICogICB2YXIgaXNWYWxpZCA9IHR5cGVWYWxpZGF0b3IoJ3N0cmluZ3knKVxuICAgKiAgIC8vPT4gdHJ1ZVxuICAgKlxuICAgKiAgIHZhciBpc1ZhbGlkID0gdHlwZVZhbGlkYXRvcihOdW1iZXIpXG4gICAqICAgLy89PiBmYWxzZVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgIGNvbnN0IGlzTnVtYmVyID0geCA9PiB0eXBlb2YgeCA9PT0gJ251bWJlcidcbiAgICogICBjb25zdCB0eXBlVmFsaWRhdG9yID0gc2NoZW1hRmFjdG9yeSgnZWgnLCB7Y2FuYWRhOiAnbnVtYmVyJ30pXG4gICAqXG4gICAqICAgdmFyIGlzVmFsaWQgPSB0eXBlVmFsaWRhdG9yKHtjYW5hZGE6IDF9KVxuICAgKiAgIC8vPT4gdHJ1ZVxuICAgKlxuICAgKiAgIHZhciBpc1ZhbGlkID0gdHlwZVZhbGlkYXRvcih7fSlcbiAgICogICAvLz0+IGZhbHNlXG4gICAqXG4gICAqICAgdmFyIGlzVmFsaWQgPSB0eXBlVmFsaWRhdG9yKHtjYW5hZGE6IGZhbHNlfSlcbiAgICogICAvLz0+IGZhbHNlXG4gICAqXG4gICAqICAgdmFyIGlzVmFsaWQgPSB0eXBlVmFsaWRhdG9yKDEpXG4gICAqICAgLy89PiBmYWxzZVxuICAgKlxuICAgKi9cbiAgZnVuY3Rpb24gdHlwZVZhbGlkYXRvcihpbnB1dCkge1xuICAgIGlmIChpc05vdE5lc3RlZChpbnB1dCkpIHtcbiAgICAgIC8vIEBAREVCVUdHRVJcbiAgICAgIHJldHVybiB2YWxpZGF0ZVR5cGUocHJvcGVydHksIGlucHV0LCBuZXN0ZWRTY2hlbWEpXG4gICAgfVxuICAgIGxldCBsb25nZXN0UGF0aHMgPSBkb3RQcm9wUGF0aHMoZmFsc2UsIGlucHV0LCB0cnVlKVxuXG4gICAgLy8gQEBERUJVR0dFUlxuXG4gICAgZm9yIChsZXQgbCA9IDA7IGwgPCBsb25nZXN0UGF0aHMubGVuZ3RoOyBsKyspIHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gbG9uZ2VzdFBhdGhzW2xdIHx8IHByb3BlcnR5XG4gICAgICBjb25zdCB0eXBlID0gZG90R2V0KG5lc3RlZFNjaGVtYSwgZnVsbFBhdGgpXG4gICAgICBjb25zdCB2YWx1ZSA9IGRvdEdldChpbnB1dCwgZnVsbFBhdGguc3BsaXQoJy4nKSlcblxuICAgICAgLy8gQEBERUJVR0dFUlxuXG4gICAgICBpZiAoIXZhbGlkYXRlVHlwZSh0eXBlLCB2YWx1ZSkpIHtcbiAgICAgICAgLy8gQEBERUJVR0dFUlxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cblxuICAgICAgLy8gQEBERUJVR0dFUlxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldnMgKi9cbiAgaWYgKEVOVl9ERVZFTE9QTUVOVCkge1xuICAgIHR5cGVWYWxpZGF0b3IuaW5zcGVjdCA9ICgpID0+ICh7cHJvcGVydHksIG5lc3RlZFNjaGVtYX0pXG4gICAgdHlwZVZhbGlkYXRvci50b1N0cmluZyA9ICgpID0+XG4gICAgICBKU09OLnN0cmluZ2lmeSh0eXBlVmFsaWRhdG9yLmluc3BlY3QoKSwgbnVsbCwgMilcbiAgfVxuICByZXR1cm4gdHlwZVZhbGlkYXRvclxufVxubW9kdWxlLmV4cG9ydHMgPSBzY2hlbWFGYWN0b3J5XG4iXSwibmFtZXMiOlsiY29uc3QiLCJsZXQiXSwibWFwcGluZ3MiOiJBQUFBQSxHQUFLLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7QUFDN0NBLEdBQUssQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztBQUM1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