diff options
Diffstat (limited to 'src/lib/data-validator.js')
-rw-r--r-- | src/lib/data-validator.js | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/lib/data-validator.js b/src/lib/data-validator.js new file mode 100644 index 0000000..276ea9b --- /dev/null +++ b/src/lib/data-validator.js @@ -0,0 +1,71 @@ +const {isInteger, isObject} = require('lodash') +const {getLogger} = require('./logger') + +const typeNames = { + 'i': 'integer', + 'n': 'number', + 's': 'string', + 'o': 'object', + 'a': 'array', +} + +const logger = getLogger('data-validator') + +/** + * @param {string} expectedType + * @param value + */ +function checkType(expectedType, value) { + switch (expectedType) { + case 'i': + return isInteger(value) + case 'n': + return typeof value === 'number' + case 's': + return typeof value === 'string' + case 'o': + return typeof value === 'object' + case 'a': + return Array.isArray(value) + default: + logger.error(`checkType: unknown type ${expectedType}`) + return false + } +} + +/** + * @param {object} data + * @param {array} schema + */ +function validateMessageData(data, schema) { + if (!isObject(data)) + throw new Error(`data is not an object`) + + for (const field of schema) { + let [name, types, required] = field + if (!(name in data)) { + if (required) + throw new Error(`missing required field ${name}`) + + continue + } + + types = types.split('') + + if (!types + .map(type => checkType(type, data[name])) + .some(result => result === true)) { + + let error = `'${name}' must be ` + if (types.length === 1) { + error += typeNames[types[0]] + } else { + error += 'any of: ' + types.map(t => typeNames[t]).join(', ') + } + + throw new Error(error) + } + } +} + +module.exports = {validateMessageData}
\ No newline at end of file |