aboutsummaryrefslogtreecommitdiff
path: root/src/lib/data-validator.js
blob: 276ea9b1e2020bc08a064654163a8c067495bcf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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}