-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
115 lines (99 loc) · 3.63 KB
/
index.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const ApiArgumentsLengthError = require('./errors/api/ArgumentsLength')
const ApiLabelTypeError = require('./errors/api/LabelType')
const ApiArgsInstanceError = require('./errors/api/ArgsInstance')
const ApiDescriptionsInstanceError = require('./errors/api/DescriptionsInstance')
const ApiDescriptionError = require('./errors/api/Description')
const UserArgumentsLengthError = require('./errors/user/ArgumentsLength')
const UserArgumentTypeError = require('./errors/user/ArgumentType')
const UserArgumentInstanceError = require('./errors/user/ArgumentInstance')
const Validator = require('./lib/Validator')
const getMessage = require('./lib/getMessage')
function getConstructorName(argument) {
if (argument === undefined) {
return 'undefined'
}
if (!argument.constructor) {
return argument
}
return argument.constructor.name
}
function argumentValidate(label, description, argument) {
if (description === '*') {
return
}
if (description instanceof Validator) {
try {
description.test(argument)
return
} catch (err) {
throw new description.Error(`${label} ${err.message}`)
}
}
const isArray = description.indexOf('[]') === 0
if (isArray) {
if (!(argument instanceof Array)) {
throw new UserArgumentInstanceError(
getMessage(`${label} constructor`, 'Array', getConstructorName(argument))
)
}
argument.forEach((_argument, _index) => {
argumentValidate(`${label}[${_index}]`, description.substr(2), _argument)
})
return
}
// eslint-disable-next-line valid-typeof
const firstLetter = description.charAt(0)
const isLowerCase = firstLetter === firstLetter.toLowerCase()
if (isLowerCase) {
if (typeof argument !== description) {
throw new UserArgumentTypeError(getMessage(`${label} type`, description, typeof argument))
}
return
}
if (argument === undefined || description !== getConstructorName(argument)) {
throw new UserArgumentInstanceError(getMessage(`${label} constructor`, description, getConstructorName(argument)))
}
}
const arguguard = function arguguard(label, descriptions, args) {
if (arguguard.options.disabled === true) {
return
}
apiValidate(...arguments)
if (args.length > descriptions.length) {
throw new UserArgumentsLengthError(getMessage(`${label} arguments.length`, `no more than ${descriptions.length}`, args.length))
}
descriptions.forEach((description, index) => {
argumentValidate(`${label} arguments[${index}]`, description, args[index])
})
}
arguguard.options = {
disabled: false,
allowSynonymousConstructors: true
}
module.exports = arguguard
function apiValidate(label, descriptions, args) {
if (arguments.length !== 3) {
throw new ApiArgumentsLengthError(getMessage('arguguard() arguments.length', 3, arguments.length))
}
if (typeof label !== 'string') {
throw new ApiLabelTypeError(getMessage('arguguard() arguments[0] (label)', 'string', typeof label))
}
if (!(descriptions instanceof Array)) {
throw new ApiDescriptionsInstanceError(getMessage('arguguard() arguments[1] (description)', 'Array', descriptions.constructor.name))
}
descriptions.forEach((description, index) => {
apiDescriptionValidate(`arguguard() descriptions[${index}]`, description)
})
if (!(args instanceof Object)) {
throw new ApiArgsInstanceError(getMessage('arguguard() arguments[2] (args)', 'Object', args.constructor.name))
}
}
function apiDescriptionValidate(label, description) {
if (description instanceof Validator) {
return
}
if (typeof description === 'string') {
return
}
throw new ApiDescriptionError(getMessage(label, 'string/Validator', typeof description))
}