joi 14.2.0 → 17.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +10 -0
- package/README.md +9 -118
- package/dist/joi-browser.min.js +1 -0
- package/lib/annotate.js +175 -0
- package/lib/base.js +1068 -0
- package/lib/cache.js +143 -0
- package/lib/common.js +216 -0
- package/lib/compile.js +283 -0
- package/lib/errors.js +160 -269
- package/lib/extend.js +312 -0
- package/lib/index.d.ts +2200 -0
- package/lib/index.js +179 -347
- package/lib/manifest.js +476 -0
- package/lib/messages.js +178 -0
- package/lib/modify.js +267 -0
- package/lib/ref.js +386 -25
- package/lib/schemas.js +291 -15
- package/lib/state.js +152 -0
- package/lib/template.js +427 -0
- package/lib/trace.js +346 -0
- package/lib/types/alternatives.js +329 -0
- package/lib/types/any.js +174 -0
- package/lib/types/array.js +775 -0
- package/lib/types/binary.js +98 -0
- package/lib/types/boolean.js +150 -0
- package/lib/types/date.js +233 -0
- package/lib/types/function.js +93 -0
- package/lib/types/keys.js +1043 -0
- package/lib/types/link.js +168 -0
- package/lib/types/number.js +335 -0
- package/lib/types/object.js +22 -0
- package/lib/types/string.js +820 -0
- package/lib/types/symbol.js +102 -0
- package/lib/validator.js +650 -0
- package/lib/values.js +263 -0
- package/package.json +34 -29
- package/CHANGELOG.md +0 -3
- package/LICENSE +0 -25
- package/lib/cast.js +0 -64
- package/lib/language.js +0 -166
- package/lib/set.js +0 -191
- package/lib/types/alternatives/index.js +0 -218
- package/lib/types/any/index.js +0 -978
- package/lib/types/any/settings.js +0 -36
- package/lib/types/array/index.js +0 -707
- package/lib/types/binary/index.js +0 -100
- package/lib/types/boolean/index.js +0 -100
- package/lib/types/date/index.js +0 -182
- package/lib/types/func/index.js +0 -90
- package/lib/types/lazy/index.js +0 -82
- package/lib/types/number/index.js +0 -248
- package/lib/types/object/index.js +0 -957
- package/lib/types/state.js +0 -11
- package/lib/types/string/index.js +0 -703
- package/lib/types/string/ip.js +0 -54
- package/lib/types/string/rfc3986.js +0 -219
- package/lib/types/string/uri.js +0 -46
- package/lib/types/symbol/index.js +0 -93
- package/lib/types/symbols.js +0 -5
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Load modules
|
|
4
|
-
|
|
5
|
-
const Any = require('../any');
|
|
6
|
-
const Ref = require('../../ref');
|
|
7
|
-
const Hoek = require('hoek');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// Declare internals
|
|
11
|
-
|
|
12
|
-
const internals = {
|
|
13
|
-
precisionRx: /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,
|
|
14
|
-
normalizeExponent(str) {
|
|
15
|
-
|
|
16
|
-
return str
|
|
17
|
-
.replace(/\.?0+e/, 'e')
|
|
18
|
-
.replace(/e\+/, 'e')
|
|
19
|
-
.replace(/^\+/, '')
|
|
20
|
-
.replace(/^(-?)0+([1-9])/, '$1$2');
|
|
21
|
-
},
|
|
22
|
-
normalizeDecimal(str) {
|
|
23
|
-
|
|
24
|
-
str = str
|
|
25
|
-
.replace(/^\+/, '')
|
|
26
|
-
.replace(/\.0+$/, '')
|
|
27
|
-
.replace(/^(-?)0+([1-9])/, '$1$2');
|
|
28
|
-
|
|
29
|
-
if (str.includes('.') && str.endsWith('0')) {
|
|
30
|
-
str = str.replace(/0+$/, '');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return str;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
internals.Number = class extends Any {
|
|
39
|
-
|
|
40
|
-
constructor() {
|
|
41
|
-
|
|
42
|
-
super();
|
|
43
|
-
this._type = 'number';
|
|
44
|
-
this._flags.unsafe = false;
|
|
45
|
-
this._invalids.add(Infinity);
|
|
46
|
-
this._invalids.add(-Infinity);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
_base(value, state, options) {
|
|
50
|
-
|
|
51
|
-
const result = {
|
|
52
|
-
errors: null,
|
|
53
|
-
value
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
if (typeof value === 'string' &&
|
|
57
|
-
options.convert) {
|
|
58
|
-
|
|
59
|
-
const matches = value.match(/^\s*[+-]?\d+(?:\.\d+)?(?:e([+-]?\d+))?\s*$/i);
|
|
60
|
-
if (matches) {
|
|
61
|
-
|
|
62
|
-
value = value.trim();
|
|
63
|
-
result.value = parseFloat(value);
|
|
64
|
-
|
|
65
|
-
if (!this._flags.unsafe) {
|
|
66
|
-
if (value.includes('e')) {
|
|
67
|
-
if (internals.normalizeExponent(`${result.value / Math.pow(10, matches[1])}e${matches[1]}`) !== internals.normalizeExponent(value)) {
|
|
68
|
-
result.errors = this.createError('number.unsafe', { value }, state, options);
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
if (result.value.toString() !== internals.normalizeDecimal(value)) {
|
|
74
|
-
result.errors = this.createError('number.unsafe', { value }, state, options);
|
|
75
|
-
return result;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const isNumber = typeof result.value === 'number' && !isNaN(result.value);
|
|
83
|
-
|
|
84
|
-
if (options.convert && 'precision' in this._flags && isNumber) {
|
|
85
|
-
|
|
86
|
-
// This is conceptually equivalent to using toFixed but it should be much faster
|
|
87
|
-
const precision = Math.pow(10, this._flags.precision);
|
|
88
|
-
result.value = Math.round(result.value * precision) / precision;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (isNumber) {
|
|
92
|
-
if (!this._flags.unsafe &&
|
|
93
|
-
(value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER)) {
|
|
94
|
-
result.errors = this.createError('number.unsafe', { value }, state, options);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
result.errors = this.createError('number.base', { value }, state, options);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return result;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
multiple(base) {
|
|
105
|
-
|
|
106
|
-
const isRef = Ref.isRef(base);
|
|
107
|
-
|
|
108
|
-
if (!isRef) {
|
|
109
|
-
Hoek.assert(typeof base === 'number' && isFinite(base), 'multiple must be a number');
|
|
110
|
-
Hoek.assert(base > 0, 'multiple must be greater than 0');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return this._test('multiple', base, function (value, state, options) {
|
|
114
|
-
|
|
115
|
-
const divisor = isRef ? base(state.reference || state.parent, options) : base;
|
|
116
|
-
|
|
117
|
-
if (isRef && (typeof divisor !== 'number' || !isFinite(divisor))) {
|
|
118
|
-
return this.createError('number.ref', { ref: base.key }, state, options);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (value % divisor === 0) {
|
|
122
|
-
return value;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return this.createError('number.multiple', { multiple: base, value }, state, options);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
integer() {
|
|
130
|
-
|
|
131
|
-
return this._test('integer', undefined, function (value, state, options) {
|
|
132
|
-
|
|
133
|
-
return Math.trunc(value) - value === 0 ? value : this.createError('number.integer', { value }, state, options);
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
unsafe(enabled = true) {
|
|
138
|
-
|
|
139
|
-
Hoek.assert(typeof enabled === 'boolean', 'enabled must be a boolean');
|
|
140
|
-
|
|
141
|
-
if (this._flags.unsafe === enabled) {
|
|
142
|
-
return this;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const obj = this.clone();
|
|
146
|
-
obj._flags.unsafe = enabled;
|
|
147
|
-
return obj;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
negative() {
|
|
151
|
-
|
|
152
|
-
return this._test('negative', undefined, function (value, state, options) {
|
|
153
|
-
|
|
154
|
-
if (value < 0) {
|
|
155
|
-
return value;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return this.createError('number.negative', { value }, state, options);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
positive() {
|
|
163
|
-
|
|
164
|
-
return this._test('positive', undefined, function (value, state, options) {
|
|
165
|
-
|
|
166
|
-
if (value > 0) {
|
|
167
|
-
return value;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return this.createError('number.positive', { value }, state, options);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
precision(limit) {
|
|
175
|
-
|
|
176
|
-
Hoek.assert(Number.isSafeInteger(limit), 'limit must be an integer');
|
|
177
|
-
Hoek.assert(!('precision' in this._flags), 'precision already set');
|
|
178
|
-
|
|
179
|
-
const obj = this._test('precision', limit, function (value, state, options) {
|
|
180
|
-
|
|
181
|
-
const places = value.toString().match(internals.precisionRx);
|
|
182
|
-
const decimals = Math.max((places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0), 0);
|
|
183
|
-
if (decimals <= limit) {
|
|
184
|
-
return value;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return this.createError('number.precision', { limit, value }, state, options);
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
obj._flags.precision = limit;
|
|
191
|
-
return obj;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
port() {
|
|
195
|
-
|
|
196
|
-
return this._test('port', undefined, function (value, state, options) {
|
|
197
|
-
|
|
198
|
-
if (!Number.isSafeInteger(value) || value < 0 || value > 65535) {
|
|
199
|
-
return this.createError('number.port', { value }, state, options);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return value;
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
internals.compare = function (type, compare) {
|
|
210
|
-
|
|
211
|
-
return function (limit) {
|
|
212
|
-
|
|
213
|
-
const isRef = Ref.isRef(limit);
|
|
214
|
-
const isNumber = typeof limit === 'number' && !isNaN(limit);
|
|
215
|
-
|
|
216
|
-
Hoek.assert(isNumber || isRef, 'limit must be a number or reference');
|
|
217
|
-
|
|
218
|
-
return this._test(type, limit, function (value, state, options) {
|
|
219
|
-
|
|
220
|
-
let compareTo;
|
|
221
|
-
if (isRef) {
|
|
222
|
-
compareTo = limit(state.reference || state.parent, options);
|
|
223
|
-
|
|
224
|
-
if (!(typeof compareTo === 'number' && !isNaN(compareTo))) {
|
|
225
|
-
return this.createError('number.ref', { ref: limit.key }, state, options);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
compareTo = limit;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
if (compare(value, compareTo)) {
|
|
233
|
-
return value;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return this.createError('number.' + type, { limit: compareTo, value }, state, options);
|
|
237
|
-
});
|
|
238
|
-
};
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
internals.Number.prototype.min = internals.compare('min', (value, limit) => value >= limit);
|
|
243
|
-
internals.Number.prototype.max = internals.compare('max', (value, limit) => value <= limit);
|
|
244
|
-
internals.Number.prototype.greater = internals.compare('greater', (value, limit) => value > limit);
|
|
245
|
-
internals.Number.prototype.less = internals.compare('less', (value, limit) => value < limit);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
module.exports = new internals.Number();
|