/
validators.js
93 lines (76 loc) · 2.11 KB
/
validators.js
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
90
91
92
const EMAIL_REGEX = /^[^@\s]+@[^@\s]+\.[^@\s]+$/ // intentionally non-exhaustive
function EnvError(input) {
this.message = input
this.stack = new Error().stack
}
EnvError.prototype = Object.create(Error.prototype)
EnvError.prototype.name = 'EnvError'
exports.EnvError = EnvError
function EnvMissingError(input) {
this.message = input
this.stack = new Error().stack
}
EnvMissingError.prototype = Object.create(Error.prototype)
EnvMissingError.prototype.name = 'EnvMissingError'
exports.EnvMissingError = EnvMissingError
function makeValidator(parseFn, type = 'unknown') {
return function(spec = {}) {
spec.type = type
spec._parse = parseFn
return spec
}
}
exports.makeValidator = makeValidator
exports.bool = makeValidator(input => {
switch (input) {
case true:
case 'true':
case 't':
case '1':
return true
case false:
case 'false':
case 'f':
case '0':
return false
default:
return null
}
}, 'bool')
exports.num = makeValidator(input => {
const coerced = +input
if (Number.isNaN(coerced)) throw new EnvError(`Invalid number input: "${input}"`)
return coerced
}, 'num')
exports.str = makeValidator(input => {
if (typeof input === 'string') return input
throw new EnvError(`Not a string: "${input}"`)
}, 'str')
exports.email = makeValidator(x => {
if (EMAIL_REGEX.test(x)) return x
throw new EnvError(`Invalid email address: "${x}"`)
}, 'email')
exports.url = makeValidator(x => {
const url = require('url')
let isValid = false
if (url.URL) {
try {
new url.URL(x)
isValid = true
} catch (e) {
isValid = false
}
} else {
const parsed = url.parse(x)
isValid = !!(parsed.protocol && parsed.host && parsed.slashes)
}
if (isValid) return x
throw new EnvError(`Invalid url: "${x}"`)
}, 'url')
exports.json = makeValidator(x => {
try {
return JSON.parse(x)
} catch (e) {
throw new EnvError(`Invalid json: "${x}"`)
}
}, 'json')