aboutsummaryrefslogtreecommitdiff
path: root/src/lib/data-validator.js
blob: 6d1d8f04c86f625003a8d618b927f9bf3dcc190d (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
 * @throws Error
 */
function validateObjectSchema(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)
        }
    }
}

function validateTargetsList(targets) {
    if (!Array.isArray(targets))
        throw new Error('targets must be array')

    if (!targets.length)
        throw new Error('targets are empty')

    for (const t of targets) {
        const type = typeof t
        if (type !== 'string')
            throw new Error(`all targets must be strings, ${type} given`)
    }
}

module.exports = {
    validateObjectSchema,
    validateTargetsList
}