UNPKG

obey

Version:

Data modelling and validation library

71 lines (65 loc) 2.31 kB
const _ = require('lodash') const Promise = require('bluebird') let rules const loadRules = () => { if (!rules) rules = require('../rules') } /** * Validates an object using the definition's `keys` property * @param {Object} context An Obey type context * @param {string} keyPrefix A prefix to include before the key in an error message * @returns {Promise.<Object>} Resolves with the final object */ const validateByKeys = (context, keyPrefix) => { // Build validation checks const missingKeys = [] const promises = {} _.forOwn(context.def.keys, (keyDef, key) => { promises[key] = rules.validate(keyDef, context.value[key], context.def.opts, `${keyPrefix}${key}`, context.errors, false, context.initData) .then(val => { if (!context.value.hasOwnProperty(key) && val === undefined) missingKeys.push(key) return val }) }) // Check undefined keys const strictMode = !context.def.hasOwnProperty('strict') || context.def.strict _.forOwn(context.value, (val, key) => { if (!context.def.keys[key]) { if (strictMode) { context.fail(`'${key}' is not an allowed property`) } else { promises[key] = val } } }) return Promise.props(promises).then(obj => { missingKeys.forEach(key => delete obj[key]) return obj }) } /** * Validates an object using the definition's `values` property * @param {Object} context An Obey type context * @param {string} keyPrefix A prefix to include before the key in an error message * @returns {Promise.<Object>} Resolves with the final object */ const validateByValues = (context, keyPrefix) => { const promises = {} _.forOwn(context.value, (val, key) => { promises[key] = rules.validate(context.def.values, val, context.def.opts, `${keyPrefix}${key}`, context.errors, false, context.initData) }) return Promise.props(promises) } const object = { default: context => { if (!_.isObject(context.value) || context.value === null) { return context.fail('Value must be an object') } loadRules() const prefix = context.key ? `${context.key}.` : '' if (context.def.keys) return validateByKeys(context, prefix) if (context.def.values) return validateByValues(context, prefix) return context.value } } module.exports = object