joi 13.5.0 → 13.7.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/README.md +3 -2
- package/lib/index.js +9 -1
- package/lib/language.js +4 -0
- package/lib/types/alternatives/index.js +1 -1
- package/lib/types/array/index.js +1 -1
- package/lib/types/boolean/index.js +1 -1
- package/lib/types/number/index.js +1 -1
- package/lib/types/object/index.js +1 -1
- package/lib/types/symbol/index.js +93 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Imagine you run facebook and you want visitors to sign up on the website with re
|
|
|
16
16
|
This is joi, joi allows you to create *blueprints* or *schemas* for JavaScript objects (an object that stores information) to ensure *validation* of key information.
|
|
17
17
|
|
|
18
18
|
# API
|
|
19
|
-
See the detailed [API Reference](https://github.com/hapijs/joi/blob/v13.
|
|
19
|
+
See the detailed [API Reference](https://github.com/hapijs/joi/blob/v13.7.0/API.md).
|
|
20
20
|
|
|
21
21
|
# Example
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ const schema = Joi.object().keys({
|
|
|
28
28
|
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
|
|
29
29
|
access_token: [Joi.string(), Joi.number()],
|
|
30
30
|
birthyear: Joi.number().integer().min(1900).max(2013),
|
|
31
|
-
email: Joi.string().email()
|
|
31
|
+
email: Joi.string().email({ minDomainAtoms: 2 })
|
|
32
32
|
}).with('username', 'birthyear').without('password', 'access_token');
|
|
33
33
|
|
|
34
34
|
// Return result.
|
|
@@ -56,6 +56,7 @@ The above schema defines the following constraints:
|
|
|
56
56
|
* an integer between 1900 and 2013
|
|
57
57
|
* `email`
|
|
58
58
|
* a valid email address string
|
|
59
|
+
* must have two domain parts e.g. `example.com`
|
|
59
60
|
|
|
60
61
|
# Usage
|
|
61
62
|
|
package/lib/index.js
CHANGED
|
@@ -22,7 +22,8 @@ const internals = {
|
|
|
22
22
|
func: require('./types/func'),
|
|
23
23
|
number: require('./types/number'),
|
|
24
24
|
object: require('./types/object'),
|
|
25
|
-
string: require('./types/string')
|
|
25
|
+
string: require('./types/string'),
|
|
26
|
+
symbol: require('./types/symbol')
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
internals.callWithDefaults = function (schema, args) {
|
|
@@ -112,6 +113,13 @@ internals.root = function () {
|
|
|
112
113
|
return internals.callWithDefaults.call(this, internals.string, args);
|
|
113
114
|
};
|
|
114
115
|
|
|
116
|
+
root.symbol = function (...args) {
|
|
117
|
+
|
|
118
|
+
Hoek.assert(args.length === 0, 'Joi.symbol() does not allow arguments.');
|
|
119
|
+
|
|
120
|
+
return internals.callWithDefaults.call(this, internals.symbol, args);
|
|
121
|
+
};
|
|
122
|
+
|
|
115
123
|
root.ref = function (...args) {
|
|
116
124
|
|
|
117
125
|
return Ref.create(...args);
|
package/lib/language.js
CHANGED
|
@@ -157,5 +157,9 @@ exports.errors = {
|
|
|
157
157
|
ref: 'references "{{ref}}" which is not a number',
|
|
158
158
|
ip: 'must be a valid ip address with a {{cidr}} CIDR',
|
|
159
159
|
ipVersion: 'must be a valid ip address of one of the following versions {{version}} with a {{cidr}} CIDR'
|
|
160
|
+
},
|
|
161
|
+
symbol: {
|
|
162
|
+
base: 'must be a symbol',
|
|
163
|
+
map: 'must be one of {{map}}'
|
|
160
164
|
}
|
|
161
165
|
};
|
|
@@ -150,7 +150,7 @@ internals.Alternatives = class extends Any {
|
|
|
150
150
|
|
|
151
151
|
describe() {
|
|
152
152
|
|
|
153
|
-
const description =
|
|
153
|
+
const description = super.describe();
|
|
154
154
|
const alternatives = [];
|
|
155
155
|
for (let i = 0; i < this._inner.matches.length; ++i) {
|
|
156
156
|
const item = this._inner.matches[i];
|
package/lib/types/array/index.js
CHANGED
|
@@ -87,7 +87,7 @@ internals.Boolean = class extends Any {
|
|
|
87
87
|
|
|
88
88
|
describe() {
|
|
89
89
|
|
|
90
|
-
const description =
|
|
90
|
+
const description = super.describe();
|
|
91
91
|
description.truthy = [true].concat(this._inner.truthySet.values());
|
|
92
92
|
description.falsy = [false].concat(this._inner.falsySet.values());
|
|
93
93
|
return description;
|
|
@@ -47,7 +47,7 @@ internals.Number = class extends Any {
|
|
|
47
47
|
result.value = Math.round(result.value * precision) / precision;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
result.errors = isNumber ? null : this.createError('number.base',
|
|
50
|
+
result.errors = isNumber ? null : this.createError('number.base', { value }, state, options);
|
|
51
51
|
return result;
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -615,7 +615,7 @@ internals.Object = class extends Any {
|
|
|
615
615
|
|
|
616
616
|
describe(shallow) {
|
|
617
617
|
|
|
618
|
-
const description =
|
|
618
|
+
const description = super.describe();
|
|
619
619
|
|
|
620
620
|
if (description.rules) {
|
|
621
621
|
for (let i = 0; i < description.rules.length; ++i) {
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Load modules
|
|
4
|
+
|
|
5
|
+
const Util = require('util');
|
|
6
|
+
|
|
7
|
+
const Any = require('../any');
|
|
8
|
+
const Hoek = require('hoek');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// Declare internals
|
|
12
|
+
|
|
13
|
+
const internals = {};
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
internals.Map = class extends Map {
|
|
17
|
+
|
|
18
|
+
slice() {
|
|
19
|
+
|
|
20
|
+
return new internals.Map(this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toString() {
|
|
24
|
+
|
|
25
|
+
return Util.inspect(this);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
internals.Symbol = class extends Any {
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
|
|
34
|
+
super();
|
|
35
|
+
this._type = 'symbol';
|
|
36
|
+
this._inner.map = new internals.Map();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_base(value, state, options) {
|
|
40
|
+
|
|
41
|
+
if (options.convert) {
|
|
42
|
+
const lookup = this._inner.map.get(value);
|
|
43
|
+
if (lookup) {
|
|
44
|
+
value = lookup;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (this._flags.allowOnly) {
|
|
48
|
+
return {
|
|
49
|
+
value,
|
|
50
|
+
errors: (typeof value === 'symbol') ? null : this.createError('symbol.map', { map: this._inner.map }, state, options)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
value,
|
|
57
|
+
errors: (typeof value === 'symbol') ? null : this.createError('symbol.base', null, state, options)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
map(iterable) {
|
|
62
|
+
|
|
63
|
+
if (iterable && !iterable[Symbol.iterator] && typeof iterable === 'object') {
|
|
64
|
+
iterable = Object.entries(iterable);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
Hoek.assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object');
|
|
68
|
+
const obj = this.clone();
|
|
69
|
+
|
|
70
|
+
const symbols = [];
|
|
71
|
+
for (const entry of iterable) {
|
|
72
|
+
Hoek.assert(entry && entry[Symbol.iterator], 'Entry must be an iterable');
|
|
73
|
+
const [key, value] = entry;
|
|
74
|
+
|
|
75
|
+
Hoek.assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be an object, function, or Symbol');
|
|
76
|
+
Hoek.assert(typeof value === 'symbol', 'Value must be a Symbol');
|
|
77
|
+
obj._inner.map.set(key, value);
|
|
78
|
+
symbols.push(value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return obj.valid(...symbols);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
describe() {
|
|
85
|
+
|
|
86
|
+
const description = super.describe();
|
|
87
|
+
description.map = new Map(this._inner.map);
|
|
88
|
+
return description;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
module.exports = new internals.Symbol();
|