joi 4.6.2 → 4.9.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/.c9/.nakignore +17 -0
- package/.c9/metadata/tab0 +1 -0
- package/.c9/metadata/workspace/.c9/project.settings +1 -0
- package/.c9/metadata/workspace/.travis.yml +1 -0
- package/.c9/metadata/workspace/Makefile +1 -0
- package/.c9/metadata/workspace/README.md +1 -0
- package/.c9/metadata/workspace/lib/any.js +1 -0
- package/.c9/metadata/workspace/lib/array.js +1 -0
- package/.c9/metadata/workspace/lib/binary.js +1 -0
- package/.c9/metadata/workspace/lib/boolean.js +1 -0
- package/.c9/metadata/workspace/lib/cast.js +1 -0
- package/.c9/metadata/workspace/lib/date.js +1 -0
- package/.c9/metadata/workspace/lib/errors.js +1 -0
- package/.c9/metadata/workspace/lib/function.js +1 -0
- package/.c9/metadata/workspace/lib/index.js +1 -0
- package/.c9/metadata/workspace/lib/language.js +1 -0
- package/.c9/metadata/workspace/lib/number.js +1 -0
- package/.c9/metadata/workspace/lib/object.js +1 -0
- package/.c9/metadata/workspace/lib/string.js +1 -0
- package/.c9/metadata/workspace/package.json +1 -0
- package/.c9/metadata/workspace/test/alternatives.js +1 -0
- package/.c9/metadata/workspace/test/any.js +1 -0
- package/.c9/metadata/workspace/test/array.js +1 -0
- package/.c9/metadata/workspace/test/binary.js +1 -0
- package/.c9/metadata/workspace/test/boolean.js +1 -0
- package/.c9/metadata/workspace/test/date.js +1 -0
- package/.c9/metadata/workspace/test/errors.js +1 -0
- package/.c9/metadata/workspace/test/function.js +1 -0
- package/.c9/metadata/workspace/test/helper.js +1 -0
- package/.c9/metadata/workspace/test/index.js +1 -0
- package/.c9/metadata/workspace/test/number.js +1 -0
- package/.c9/metadata/workspace/test/object.js +1 -0
- package/.c9/metadata/workspace/test/ref.js +1 -0
- package/.c9/metadata/workspace/test/string.js +1 -0
- package/.c9/project.settings +34 -0
- package/.travis.yml +1 -0
- package/Makefile +3 -3
- package/README.md +162 -31
- package/examples/conditionalRequire.js +43 -0
- package/examples/customMessage.js +22 -0
- package/examples/multipleWhen.js +17 -0
- package/lib/any.js +35 -24
- package/lib/array.js +25 -0
- package/lib/date.js +64 -9
- package/lib/errors.js +18 -2
- package/lib/index.js +3 -2
- package/lib/language.js +17 -6
- package/lib/number.js +50 -0
- package/lib/object.js +69 -5
- package/lib/string.js +27 -6
- package/package.json +5 -3
- package/test/alternatives.js +12 -10
- package/test/any.js +64 -15
- package/test/array.js +55 -16
- package/test/binary.js +13 -11
- package/test/boolean.js +9 -7
- package/test/date.js +143 -20
- package/test/errors.js +26 -15
- package/test/function.js +7 -5
- package/test/helper.js +7 -5
- package/test/index.js +116 -73
- package/test/number.js +125 -12
- package/test/object.js +192 -43
- package/test/ref.js +22 -20
- package/test/string.js +255 -106
- package/AUTHORS +0 -3
package/README.md
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Object schema description language and validator for JavaScript objects.
|
|
4
4
|
|
|
5
|
-
Current version: **4.
|
|
5
|
+
Current version: **4.7.x**
|
|
6
6
|
|
|
7
7
|
[](http://travis-ci.org/hapijs/joi)
|
|
8
8
|
|
|
9
|
-
Lead Maintainer: [
|
|
9
|
+
Lead Maintainer: [Nicolas Morel](https://github.com/marsup)
|
|
10
10
|
|
|
11
11
|
## Table of Contents
|
|
12
12
|
|
|
13
13
|
<img src="https://raw.github.com/hapijs/joi/master/images/validation.png" align="right" />
|
|
14
14
|
- [Example](#example)
|
|
15
15
|
- [Usage](#usage)
|
|
16
|
-
- [`validate(value, schema, [options], callback)`](#validatevalue-schema-options-callback)
|
|
16
|
+
- [`validate(value, schema, [options], [callback])`](#validatevalue-schema-options-callback)
|
|
17
17
|
- [`compile(schema)`](#compileschema)
|
|
18
|
-
- [`assert(value, schema)`](#assertvalue-schema)
|
|
18
|
+
- [`assert(value, schema, [message])`](#assertvalue-schema-message)
|
|
19
19
|
- [`any`](#any)
|
|
20
20
|
- [`any.allow(value)`](#anyallowvalue)
|
|
21
21
|
- [`any.valid(value)`](#anyvalidvalue)
|
|
@@ -34,12 +34,14 @@ Lead Maintainer: [Eran Hammer](https://github.com/hueniverse)
|
|
|
34
34
|
- [`any.default(value)`](#anydefaultvalue)
|
|
35
35
|
- [`any.concat(schema)`](#anyconcatschema)
|
|
36
36
|
- [`any.when(ref, options)`](#anywhenref-options)
|
|
37
|
+
- [`any.label(name)`](#anylabelname)
|
|
37
38
|
- [`array`](#array)
|
|
38
39
|
- [`array.includes(type)`](#arrayincludestype)
|
|
39
40
|
- [`array.excludes(type)`](#arrayexcludestype)
|
|
40
41
|
- [`array.min(limit)`](#arrayminlimit)
|
|
41
42
|
- [`array.max(limit)`](#arraymaxlimit)
|
|
42
43
|
- [`array.length(limit)`](#arraylengthlimit)
|
|
44
|
+
- [`array.unique()`](#arrayunique)
|
|
43
45
|
- [`binary`](#binary)
|
|
44
46
|
- [`binary.encoding(encoding)`](#binaryencodingencoding)
|
|
45
47
|
- [`binary.min(limit)`](#binaryminlimit)
|
|
@@ -49,11 +51,16 @@ Lead Maintainer: [Eran Hammer](https://github.com/hueniverse)
|
|
|
49
51
|
- [`date`](#date)
|
|
50
52
|
- [`date.min(date)`](#datemindate)
|
|
51
53
|
- [`date.max(date)`](#datemaxdate)
|
|
54
|
+
- [`date.format(format)`](#dateformatformat)
|
|
55
|
+
- [`date.iso()`](#dateiso)
|
|
52
56
|
- [`func`](#func)
|
|
53
57
|
- [`number`](#number)
|
|
54
58
|
- [`number.min(limit)`](#numberminlimit)
|
|
55
59
|
- [`number.max(limit)`](#numbermaxlimit)
|
|
60
|
+
- [`number.greater(limit)`](#numbergreaterlimit)
|
|
61
|
+
- [`number.less(limit)`](#numberlesslimit)
|
|
56
62
|
- [`number.integer()`](#numberinteger)
|
|
63
|
+
- [`number.precision(limit)`](#numberprecisionlimit)
|
|
57
64
|
- [`object`](#object)
|
|
58
65
|
- [`object.keys([schema])`](#objectkeysschema)
|
|
59
66
|
- [`object.min(limit)`](#objectminlimit)
|
|
@@ -61,24 +68,26 @@ Lead Maintainer: [Eran Hammer](https://github.com/hueniverse)
|
|
|
61
68
|
- [`object.length(limit)`](#objectlengthlimit)
|
|
62
69
|
- [`object.pattern(regex, schema)`](#objectpatternregex-schema)
|
|
63
70
|
- [`object.and(peers)`](#objectandpeers)
|
|
71
|
+
- [`object.nand(peers)`](#objectnandpeers)
|
|
64
72
|
- [`object.or(peers)`](#objectorpeers)
|
|
65
73
|
- [`object.xor(peers)`](#objectxorpeers)
|
|
66
74
|
- [`object.with(key, peers)`](#objectwithkey-peers)
|
|
67
75
|
- [`object.without(key, peers)`](#objectwithoutkey-peers)
|
|
68
76
|
- [`object.rename(from, to, [options])`](#objectrenamefrom-to-options)
|
|
69
|
-
- [`object.assert(ref, schema, message)`](#objectassertref-schema-message)
|
|
77
|
+
- [`object.assert(ref, schema, [message])`](#objectassertref-schema-message)
|
|
70
78
|
- [`object.unknown([allow])`](#objectunknownallow)
|
|
79
|
+
- [`object.type(constructor, [name])`](#objecttypeconstructorname)
|
|
71
80
|
- [`string`](#string)
|
|
72
81
|
- [`string.insensitive()`](#stringinsensitive)
|
|
73
82
|
- [`string.min(limit, [encoding])`](#stringminlimit-encoding)
|
|
74
83
|
- [`string.max(limit, [encoding])`](#stringmaxlimit-encoding)
|
|
84
|
+
- [`string.creditCard()`](#stringcreditCard)
|
|
75
85
|
- [`string.length(limit, [encoding])`](#stringlengthlimit-encoding)
|
|
76
|
-
- [`string.regex(pattern)`](#stringregexpattern)
|
|
86
|
+
- [`string.regex(pattern, [name])`](#stringregexpattern)
|
|
77
87
|
- [`string.alphanum()`](#stringalphanum)
|
|
78
88
|
- [`string.token()`](#stringtoken)
|
|
79
89
|
- [`string.email()`](#stringemail)
|
|
80
90
|
- [`string.guid()`](#stringguid)
|
|
81
|
-
- [`string.isoDate()`](#stringisodate)
|
|
82
91
|
- [`string.hostname()`](#stringhostname)
|
|
83
92
|
- [`string.lowercase()`](#stringlowercase)
|
|
84
93
|
- [`string.uppercase()`](#stringuppercase)
|
|
@@ -162,7 +171,7 @@ When validating a schema:
|
|
|
162
171
|
* Strings are utf-8 encoded by default.
|
|
163
172
|
* Rules are defined in an additive fashion and evaluated in order after whitelist and blacklist checks.
|
|
164
173
|
|
|
165
|
-
### `validate(value, schema, [options], callback)`
|
|
174
|
+
### `validate(value, schema, [options], [callback])`
|
|
166
175
|
|
|
167
176
|
Validates a value using the given schema and options where:
|
|
168
177
|
- `value` - the value being validated.
|
|
@@ -173,13 +182,16 @@ Validates a value using the given schema and options where:
|
|
|
173
182
|
- `allowUnknown` - when `true`, allows object to contain unknown keys which are ignored. Defaults to `false`.
|
|
174
183
|
- `skipFunctions` - when `true`, ignores unknown keys with a function value. Defaults to `false`.
|
|
175
184
|
- `stripUnknown` - when `true`, unknown keys are deleted (only when value is an object). Defaults to `false`.
|
|
176
|
-
- `language` - overrides individual error messages. Defaults to no override (`{}`).
|
|
185
|
+
- `language` - overrides individual error messages, when `'label'` is set, it overrides the key name in the error message. Defaults to no override (`{}`).
|
|
186
|
+
- `presence` - sets the default presence requirements. Supported modes: `'optional'`, `'required'`, and `'forbidden'`.
|
|
187
|
+
Defaults to `'optional'`.
|
|
177
188
|
- `context` - provides an external data set to be used in [references](#refkey-options). Can only be set as an external option to
|
|
178
189
|
`validate()` and not using `any.options()`.
|
|
179
|
-
- `callback` - the synchronous callback method using the signature `function(err, value)` where:
|
|
190
|
+
- `callback` - the optional synchronous callback method using the signature `function(err, value)` where:
|
|
180
191
|
- `err` - if validation failed, the error reason, otherwise `null`.
|
|
181
192
|
- `value` - the validated value with any type conversions and other modifiers applied (the input is left unchanged). `value` can be
|
|
182
|
-
incomplete if validation failed and `abortEarly` is `true`.
|
|
193
|
+
incomplete if validation failed and `abortEarly` is `true`. If callback is not provided, then returns an object with error
|
|
194
|
+
and value properties.
|
|
183
195
|
|
|
184
196
|
```javascript
|
|
185
197
|
var schema = {
|
|
@@ -193,6 +205,11 @@ var value = {
|
|
|
193
205
|
Joi.validate(value, schema, function (err, value) { });
|
|
194
206
|
// err -> null
|
|
195
207
|
// value.a -> 123 (number, not string)
|
|
208
|
+
|
|
209
|
+
// or
|
|
210
|
+
var result = Joi.validate(value, schema);
|
|
211
|
+
// result.error -> null
|
|
212
|
+
// result.value -> { "a" : 123 }
|
|
196
213
|
```
|
|
197
214
|
|
|
198
215
|
### `compile(schema)`
|
|
@@ -219,11 +236,12 @@ var schema = Joi.alternatives().try([
|
|
|
219
236
|
]);
|
|
220
237
|
```
|
|
221
238
|
|
|
222
|
-
### `assert(value, schema)`
|
|
239
|
+
### `assert(value, schema, [message])`
|
|
223
240
|
|
|
224
241
|
Validates a value against a schema and throws if validation fails where:
|
|
225
242
|
- `value` - the value to validate.
|
|
226
243
|
- `schema` - the schema object.
|
|
244
|
+
- `message` - optional message sting prefix added in front of the error message.
|
|
227
245
|
|
|
228
246
|
```javascript
|
|
229
247
|
Joi.assert('x', Joi.number());
|
|
@@ -302,7 +320,7 @@ Marks a key as forbidden which will not allow any value except `undefined`. Used
|
|
|
302
320
|
|
|
303
321
|
```javascript
|
|
304
322
|
var schema = {
|
|
305
|
-
a: Joi.any.forbidden()
|
|
323
|
+
a: Joi.any().forbidden()
|
|
306
324
|
};
|
|
307
325
|
```
|
|
308
326
|
|
|
@@ -422,6 +440,27 @@ var schema = {
|
|
|
422
440
|
};
|
|
423
441
|
```
|
|
424
442
|
|
|
443
|
+
Alternatively, if you want to specify a specific type such as `string`, `array`, etc, you can do so like this:
|
|
444
|
+
|
|
445
|
+
```javascript
|
|
446
|
+
var schema = {
|
|
447
|
+
a: Joi.valid('a', 'b', 'other'),
|
|
448
|
+
other: Joi.string()
|
|
449
|
+
.when('a', { is: 'other', then: Joi.required() }),
|
|
450
|
+
};
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
#### `any.label(name)`
|
|
454
|
+
|
|
455
|
+
Overrides the key name in error messages.
|
|
456
|
+
- `name` - the name of the key.
|
|
457
|
+
|
|
458
|
+
```javascript
|
|
459
|
+
var schema = {
|
|
460
|
+
first_name: Joi.string().label('First Name')
|
|
461
|
+
};
|
|
462
|
+
```
|
|
463
|
+
|
|
425
464
|
### `array`
|
|
426
465
|
|
|
427
466
|
Generates a schema object that matches an array data type.
|
|
@@ -478,6 +517,14 @@ Specifies the exact number of items in the array where:
|
|
|
478
517
|
var schema = Joi.array().length(5);
|
|
479
518
|
```
|
|
480
519
|
|
|
520
|
+
#### `array.unique()`
|
|
521
|
+
|
|
522
|
+
Requires the array values to be unique. Only works for literals (numbers and strings), all other types are ignored.
|
|
523
|
+
|
|
524
|
+
```javascript
|
|
525
|
+
var schema = Joi.array().unique();
|
|
526
|
+
```
|
|
527
|
+
|
|
481
528
|
### `boolean`
|
|
482
529
|
|
|
483
530
|
Generates a schema object that matches a boolean data type (as well as the strings 'true', 'false', 'yes', and 'no'). Can also be called via `bool()`.
|
|
@@ -555,6 +602,12 @@ Specifies the oldest date allowed where:
|
|
|
555
602
|
var schema = Joi.date().min('1-1-1974');
|
|
556
603
|
```
|
|
557
604
|
|
|
605
|
+
Note: `'now'` can be passed in lieu of `date` so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future.
|
|
606
|
+
|
|
607
|
+
```javascript
|
|
608
|
+
var schema = Joi.date().min('now');
|
|
609
|
+
```
|
|
610
|
+
|
|
558
611
|
#### `date.max(date)`
|
|
559
612
|
|
|
560
613
|
Specifies the latest date allowed where:
|
|
@@ -564,6 +617,29 @@ Specifies the latest date allowed where:
|
|
|
564
617
|
var schema = Joi.date().max('12-31-2020');
|
|
565
618
|
```
|
|
566
619
|
|
|
620
|
+
Note: `'now'` can be passed in lieu of `date` so as to always compare relatively to the current date, allowing to explicitly ensure a date is either in the past or in the future.
|
|
621
|
+
|
|
622
|
+
```javascript
|
|
623
|
+
var schema = Joi.date().max('now');
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
#### `date.format(format)`
|
|
627
|
+
|
|
628
|
+
Specifies the allowed date format:
|
|
629
|
+
- `format` - string or array of strings that follow the `moment.js` [format](http://momentjs.com/docs/#/parsing/string-format/).
|
|
630
|
+
|
|
631
|
+
```javascript
|
|
632
|
+
var schema = Joi.date().format('YYYY/MM/DD');
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
#### `date.iso()`
|
|
636
|
+
|
|
637
|
+
Requires the string value to be in valid ISO 8601 date format.
|
|
638
|
+
|
|
639
|
+
```javascript
|
|
640
|
+
var schema = Joi.date().iso();
|
|
641
|
+
```
|
|
642
|
+
|
|
567
643
|
### `func`
|
|
568
644
|
|
|
569
645
|
Generates a schema object that matches a function type.
|
|
@@ -604,6 +680,22 @@ Specifies the maximum value where:
|
|
|
604
680
|
var schema = Joi.number().max(10);
|
|
605
681
|
```
|
|
606
682
|
|
|
683
|
+
#### `number.greater(limit)`
|
|
684
|
+
|
|
685
|
+
Specifies that the value must be greater than `limit`.
|
|
686
|
+
|
|
687
|
+
```javascript
|
|
688
|
+
var schema = Joi.number().greater(5);
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
#### `number.less(limit)`
|
|
692
|
+
|
|
693
|
+
Specifies that the value must be less than `limit`.
|
|
694
|
+
|
|
695
|
+
```javascript
|
|
696
|
+
var schema = Joi.number().less(10);
|
|
697
|
+
```
|
|
698
|
+
|
|
607
699
|
#### `number.integer()`
|
|
608
700
|
|
|
609
701
|
Requires the number to be an integer (no floating point).
|
|
@@ -612,6 +704,15 @@ Requires the number to be an integer (no floating point).
|
|
|
612
704
|
var schema = Joi.number().integer();
|
|
613
705
|
```
|
|
614
706
|
|
|
707
|
+
#### `number.precision(limit)`
|
|
708
|
+
|
|
709
|
+
Specifies the maximum number of decimal places where:
|
|
710
|
+
- `limit` - the maximum number of decimal places allowed.
|
|
711
|
+
|
|
712
|
+
```javascript
|
|
713
|
+
var schema = Joi.number().precision(2);
|
|
714
|
+
```
|
|
715
|
+
|
|
615
716
|
### `object`
|
|
616
717
|
|
|
617
718
|
Generates a schema object that matches an object data type (as well as JSON strings that parsed into objects). Defaults
|
|
@@ -630,17 +731,21 @@ object.validate({ a: 5 }, function (err, value) { });
|
|
|
630
731
|
|
|
631
732
|
#### `object.keys([schema])`
|
|
632
733
|
|
|
633
|
-
Sets the allowed object keys where:
|
|
634
|
-
- `schema` - optional object where each key is
|
|
734
|
+
Sets or extends the allowed object keys where:
|
|
735
|
+
- `schema` - optional object where each key is assigned a **joi** type object. If `schema` is `{}` no keys allowed.
|
|
635
736
|
If `schema` is `null` or `undefined`, any key allowed. If `schema` is an object with keys, the keys are added to any
|
|
636
737
|
previously defined keys (but narrows the selection if all keys previously allowed). Defaults to 'undefined' which
|
|
637
738
|
allows any child key.
|
|
638
739
|
|
|
639
740
|
```javascript
|
|
640
|
-
var
|
|
641
|
-
a: Joi.number()
|
|
741
|
+
var base = Joi.object().keys({
|
|
742
|
+
a: Joi.number(),
|
|
642
743
|
b: Joi.string()
|
|
643
744
|
});
|
|
745
|
+
// Validate keys a, b and c.
|
|
746
|
+
var extended = base.keys({
|
|
747
|
+
c: Joi.boolean()
|
|
748
|
+
});
|
|
644
749
|
```
|
|
645
750
|
|
|
646
751
|
#### `object.min(limit)`
|
|
@@ -696,6 +801,20 @@ var schema = Joi.object().keys({
|
|
|
696
801
|
}).and('a', 'b');
|
|
697
802
|
```
|
|
698
803
|
|
|
804
|
+
#### `object.nand(peers)`
|
|
805
|
+
|
|
806
|
+
Defines a relationship between keys where not all peers can be present at the
|
|
807
|
+
same time where:
|
|
808
|
+
- `peers` - the key names of which if one present, the others may not all be present. `peers` can be a single string value, an
|
|
809
|
+
array of string values, or each peer provided as an argument.
|
|
810
|
+
|
|
811
|
+
```javascript
|
|
812
|
+
var schema = Joi.object().keys({
|
|
813
|
+
a: Joi.any(),
|
|
814
|
+
b: Joi.any()
|
|
815
|
+
}).nand('a', 'b');
|
|
816
|
+
```
|
|
817
|
+
|
|
699
818
|
#### `object.or(peers)`
|
|
700
819
|
|
|
701
820
|
Defines a relationship between keys where one of the peers is required (and more than one is allowed) where:
|
|
@@ -771,13 +890,13 @@ var object = Joi.object().keys({
|
|
|
771
890
|
object.validate({ b: 5 }, function (err, value) { });
|
|
772
891
|
```
|
|
773
892
|
|
|
774
|
-
#### `object.assert(ref, schema, message)`
|
|
893
|
+
#### `object.assert(ref, schema, [message])`
|
|
775
894
|
|
|
776
895
|
Verifies an assertion where:
|
|
777
896
|
- `ref` - the key name or [reference](#refkey-options).
|
|
778
897
|
- `schema` - the validation rules required to satisfy the assertion. If the `schema` includes references, they are resolved against
|
|
779
898
|
the object value, not the value of the `ref` target.
|
|
780
|
-
- `message` - human-readable message used when the assertion fails.
|
|
899
|
+
- `message` - optional human-readable message used when the assertion fails. Defaults to 'failed to pass the assertion test'.
|
|
781
900
|
|
|
782
901
|
```javascript
|
|
783
902
|
var schema = Joi.object().keys({
|
|
@@ -800,6 +919,16 @@ Overrides the handling of unknown keys for the scope of the current object only
|
|
|
800
919
|
var schema = Joi.object({ a: Joi.any() }).unknown();
|
|
801
920
|
```
|
|
802
921
|
|
|
922
|
+
#### `object.type(constructor, [name])`
|
|
923
|
+
|
|
924
|
+
Requires the object to be an instance of a given constructor where:
|
|
925
|
+
- `constructor` - the constructor function that the object must be an instance of.
|
|
926
|
+
- `name` - an alternate name to use in validation errors. This is useful when the constructor function does not have a name.
|
|
927
|
+
|
|
928
|
+
```javascript
|
|
929
|
+
var schema = Joi.object().type(RegExp);
|
|
930
|
+
```
|
|
931
|
+
|
|
803
932
|
### `string`
|
|
804
933
|
|
|
805
934
|
Generates a schema object that matches a string data type. Note that empty strings are not allowed by default and must be enabled with `allow('')`.
|
|
@@ -839,6 +968,15 @@ Specifies the maximum number of string characters where:
|
|
|
839
968
|
var schema = Joi.string().max(10);
|
|
840
969
|
```
|
|
841
970
|
|
|
971
|
+
#### `string.creditCard()`
|
|
972
|
+
|
|
973
|
+
Requires the number to be a credit card number (Using [Lunh
|
|
974
|
+
Algorithm](http://en.wikipedia.org/wiki/Luhn_algorithm)).
|
|
975
|
+
|
|
976
|
+
```javascript
|
|
977
|
+
var schema = Joi.string().creditCard();
|
|
978
|
+
```
|
|
979
|
+
|
|
842
980
|
#### `string.length(limit, [encoding])`
|
|
843
981
|
|
|
844
982
|
Specifies the exact string length required where:
|
|
@@ -849,10 +987,11 @@ Specifies the exact string length required where:
|
|
|
849
987
|
var schema = Joi.string().length(5);
|
|
850
988
|
```
|
|
851
989
|
|
|
852
|
-
#### `string.regex(pattern)`
|
|
990
|
+
#### `string.regex(pattern, [name])`
|
|
853
991
|
|
|
854
992
|
Defines a regular expression rule where:
|
|
855
993
|
- `pattern` - a regular expression object the string value must match against.
|
|
994
|
+
- `name` - optional name for patterns (useful with multiple patterns). Defaults to 'required'.
|
|
856
995
|
|
|
857
996
|
```javascript
|
|
858
997
|
var schema = Joi.string().regex(/^[abc]+$/);
|
|
@@ -890,14 +1029,6 @@ Requires the string value to be a valid GUID.
|
|
|
890
1029
|
var schema = Joi.string().guid();
|
|
891
1030
|
```
|
|
892
1031
|
|
|
893
|
-
#### `string.isoDate()`
|
|
894
|
-
|
|
895
|
-
Requires the string value to be in valid ISO 8601 date format.
|
|
896
|
-
|
|
897
|
-
```javascript
|
|
898
|
-
var schema = Joi.string().isoDate();
|
|
899
|
-
```
|
|
900
|
-
|
|
901
1032
|
#### `string.hostname()`
|
|
902
1033
|
|
|
903
1034
|
Requires the string value to be a valid hostname as per [RFC1123](http://tools.ietf.org/html/rfc1123).
|
|
@@ -947,7 +1078,7 @@ var alt = Joi.alternatives().try(Joi.number(), Joi.string());
|
|
|
947
1078
|
// Same as [Joi.number(), Joi.string()]
|
|
948
1079
|
```
|
|
949
1080
|
|
|
950
|
-
#### `alternatives.try(schemas)
|
|
1081
|
+
#### `alternatives.try(schemas)`
|
|
951
1082
|
|
|
952
1083
|
Adds an alternative schema type for attempting to match against the validated value where:
|
|
953
1084
|
- `schema` - an array of alternative **joi** types. Also supports providing each type as a separate argument.
|
|
@@ -1003,8 +1134,8 @@ var schema = {
|
|
|
1003
1134
|
Generates a reference to the value of the named key. References are resolved at validation time and in order of dependency
|
|
1004
1135
|
so that if one key validation depends on another, the dependent key is validated second after the reference is validated.
|
|
1005
1136
|
References support the following arguments:
|
|
1006
|
-
- `key` - the reference target. References cannot point up the object tree, only to
|
|
1007
|
-
their
|
|
1137
|
+
- `key` - the reference target. References cannot point up the object tree, only to sibling keys, but they can point to
|
|
1138
|
+
their siblings' children (e.g. 'a.b.c') using the `.` separator. If a `key` starts with `$` is signifies a context reference
|
|
1008
1139
|
which is looked up in the `context` option object.
|
|
1009
1140
|
- `options` - optional settings:
|
|
1010
1141
|
- `separator` - overrides the default `.` hierarchy separator.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// This is an example of a survey to obtain the reputation of Parisians
|
|
2
|
+
// It contains examples of how to conditionally require keys based on values of other keys
|
|
3
|
+
|
|
4
|
+
var Joi = require("../");
|
|
5
|
+
|
|
6
|
+
// This is a valid value for integer rating 1 - 5
|
|
7
|
+
var intRating = Joi.number().integer().min(1).max(5);
|
|
8
|
+
|
|
9
|
+
var schema = Joi.object().keys({
|
|
10
|
+
// Do you know any French people? yes or no (required)
|
|
11
|
+
q1: Joi.boolean().required(),
|
|
12
|
+
// Do you know any Parisians? yes or no (required if answered yes in q1)
|
|
13
|
+
q2: Joi.boolean()
|
|
14
|
+
.when('q1', { is: true, then: Joi.required() }),
|
|
15
|
+
// How many french in paris do you know? 1-6, 6-10, 11-50 or 50+ (required if answered yes in q2)
|
|
16
|
+
q3: Joi.string()
|
|
17
|
+
.when('q2', { is: true, then: Joi.valid('1-5', '6-10', '11-50', '50+').required() }),
|
|
18
|
+
// Rate 20% of most friendly Parisians, from how many people you know answered in q3, individually on 1-5 rating
|
|
19
|
+
q4: Joi.array()
|
|
20
|
+
.when('q3', {is: '1-5', then: Joi.array().min(0).max(1).includes(intRating).required() })
|
|
21
|
+
.when('q3', {is: '6-10', then: Joi.array().min(1).max(2).includes(intRating).required() })
|
|
22
|
+
.when('q3', {is: '11-50', then: Joi.array().min(2).max(10).includes(intRating).required() })
|
|
23
|
+
.when('q3', {is: '50+' , then: Joi.array().min(10).includes(intRating).required() }),
|
|
24
|
+
// Rate remaining 80% of Parisians, from how many people you know answered in q3, individually on 1-5 rating
|
|
25
|
+
q5: Joi.array()
|
|
26
|
+
.when('q3', {is: '1-5', then: Joi.array().min(1).max(4).includes(intRating).required() })
|
|
27
|
+
.when('q3', {is: '6-10', then: Joi.array().min(4).max(8).includes(intRating).required() })
|
|
28
|
+
.when('q3', {is: '11-50', then: Joi.array().min(8).max(40).includes(intRating).required() })
|
|
29
|
+
.when('q3', {is: '50+' , then: Joi.array().min(40).includes(intRating).required().required() }),
|
|
30
|
+
// Rate the reputation of Parisians in general, 1-5 rating
|
|
31
|
+
q6: intRating.required()
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
var response = {
|
|
35
|
+
q1: true,
|
|
36
|
+
q2: true,
|
|
37
|
+
q3: '1-5',
|
|
38
|
+
q4: [5],
|
|
39
|
+
q4: [1],
|
|
40
|
+
q6: 2
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
Joi.assert(response, schema);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var Joi = require('../');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var schema = Joi.object().options({ abortEarly: false }).keys({
|
|
5
|
+
email: Joi.string().email().required().label('User Email'),
|
|
6
|
+
password: Joi.string().min(8).required(),
|
|
7
|
+
password_confirmation: Joi.any().valid(Joi.ref('password')).required().options({ language: { any: { allowOnly: 'must match password' }, label: 'Password Confirmation' } }).label('This label is not used because language.label takes precedence'),
|
|
8
|
+
first_name: Joi.string().required(),
|
|
9
|
+
last_name: Joi.string().required(),
|
|
10
|
+
company: Joi.string().optional()
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
var data = {
|
|
15
|
+
email: 'not_a_valid_email_to_show_custom_label',
|
|
16
|
+
password: 'abcd1234',
|
|
17
|
+
password_confirmation: 'abc1',
|
|
18
|
+
first_name: 'Joe',
|
|
19
|
+
last_name: 'Doe'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Joi.assert(data, schema);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
var Joi = require('../');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var schema = {
|
|
5
|
+
type: Joi.string().required(),
|
|
6
|
+
subtype: Joi.alternatives()
|
|
7
|
+
.when('type', {is: 'video', then: Joi.valid('mp4', 'wav')})
|
|
8
|
+
.when('type', {is: 'audio', then: Joi.valid('mp3')})
|
|
9
|
+
.when('type', {is: 'image', then: Joi.valid('jpg', 'png')})
|
|
10
|
+
.when('type', {is: 'pdf' , then: Joi.valid('document')})
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Joi.assert({ type: 'video', subtype: 'mp4' }, schema); // Pass
|
|
15
|
+
Joi.assert({ type: 'video', subtype: 'wav' }, schema); // Pass
|
|
16
|
+
Joi.assert({ type: 'other', subtype: 'something' }, schema); // Fail
|
|
17
|
+
Joi.assert({ type: 'audio', subtype: 'mp4' }, schema); // Fail
|
package/lib/any.js
CHANGED
|
@@ -19,7 +19,8 @@ internals.defaults = {
|
|
|
19
19
|
allowUnknown: false,
|
|
20
20
|
skipFunctions: false,
|
|
21
21
|
stripUnknown: false,
|
|
22
|
-
language: {}
|
|
22
|
+
language: {},
|
|
23
|
+
presence: 'optional'
|
|
23
24
|
// context: null
|
|
24
25
|
};
|
|
25
26
|
|
|
@@ -43,7 +44,7 @@ module.exports = internals.Any = function () {
|
|
|
43
44
|
insensitive: false,
|
|
44
45
|
trim: false,
|
|
45
46
|
case: undefined // upper, lower
|
|
46
|
-
*/};
|
|
47
|
+
*/ };
|
|
47
48
|
|
|
48
49
|
this._description = null;
|
|
49
50
|
this._unit = null;
|
|
@@ -61,8 +62,7 @@ internals.Any.prototype.isImmutable = true; // Prevents Hoek from deep cloni
|
|
|
61
62
|
|
|
62
63
|
internals.Any.prototype.clone = function () {
|
|
63
64
|
|
|
64
|
-
var obj =
|
|
65
|
-
obj.__proto__ = Object.getPrototypeOf(this);
|
|
65
|
+
var obj = Object.create(Object.getPrototypeOf(this));
|
|
66
66
|
|
|
67
67
|
obj.isJoi = true;
|
|
68
68
|
obj._type = this._type;
|
|
@@ -207,24 +207,24 @@ internals.Any.prototype.required = internals.Any.prototype.exist = function () {
|
|
|
207
207
|
internals.Any.prototype.optional = function () {
|
|
208
208
|
|
|
209
209
|
var obj = this.clone();
|
|
210
|
-
|
|
210
|
+
obj._flags.presence = 'optional';
|
|
211
211
|
return obj;
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
|
|
215
|
-
internals.Any.prototype.
|
|
215
|
+
internals.Any.prototype.forbidden = function () {
|
|
216
216
|
|
|
217
217
|
var obj = this.clone();
|
|
218
|
-
obj._flags.
|
|
219
|
-
Ref.push(obj._refs, value);
|
|
218
|
+
obj._flags.presence = 'forbidden';
|
|
220
219
|
return obj;
|
|
221
220
|
};
|
|
222
221
|
|
|
223
222
|
|
|
224
|
-
internals.Any.prototype.
|
|
223
|
+
internals.Any.prototype.default = function (value) {
|
|
225
224
|
|
|
226
225
|
var obj = this.clone();
|
|
227
|
-
obj._flags.
|
|
226
|
+
obj._flags.default = value;
|
|
227
|
+
Ref.push(obj._refs, value);
|
|
228
228
|
return obj;
|
|
229
229
|
};
|
|
230
230
|
|
|
@@ -329,26 +329,25 @@ internals.Any.prototype._validate = function (value, state, options, reference)
|
|
|
329
329
|
|
|
330
330
|
// Check presence requirements
|
|
331
331
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
errors.push(Errors.create('any.required', null, state, options));
|
|
332
|
+
var presence = this._flags.presence || options.presence;
|
|
333
|
+
if (presence === 'optional') {
|
|
334
|
+
if (value === undefined) {
|
|
337
335
|
return finish();
|
|
338
336
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
337
|
+
}
|
|
338
|
+
else if (presence === 'required' &&
|
|
339
|
+
value === undefined) {
|
|
343
340
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
341
|
+
errors.push(Errors.create('any.required', null, state, options));
|
|
342
|
+
return finish();
|
|
347
343
|
}
|
|
348
|
-
else
|
|
344
|
+
else if (presence === 'forbidden') {
|
|
349
345
|
if (value === undefined) {
|
|
350
346
|
return finish();
|
|
351
347
|
}
|
|
348
|
+
|
|
349
|
+
errors.push(Errors.create('any.unknown', null, state, options));
|
|
350
|
+
return finish();
|
|
352
351
|
}
|
|
353
352
|
|
|
354
353
|
// Check allowed and denied values using the original value
|
|
@@ -496,7 +495,7 @@ internals.Any.prototype.describe = function () {
|
|
|
496
495
|
for (var i = 0, il = this._tests.length; i < il; ++i) {
|
|
497
496
|
var validator = this._tests[i];
|
|
498
497
|
var item = { name: validator.name };
|
|
499
|
-
if (validator.arg) {
|
|
498
|
+
if (validator.arg !== void 0) {
|
|
500
499
|
item.arg = validator.arg;
|
|
501
500
|
}
|
|
502
501
|
description.rules.push(item);
|
|
@@ -509,6 +508,18 @@ internals.Any.prototype.describe = function () {
|
|
|
509
508
|
return description;
|
|
510
509
|
};
|
|
511
510
|
|
|
511
|
+
internals.Any.prototype.label = function (name) {
|
|
512
|
+
|
|
513
|
+
Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string');
|
|
514
|
+
|
|
515
|
+
var obj = this.clone();
|
|
516
|
+
var options = { language: { label: name } };
|
|
517
|
+
|
|
518
|
+
// If language.label is set, it should override this label
|
|
519
|
+
obj._settings = internals.concatSettings(options, obj._settings);
|
|
520
|
+
return obj;
|
|
521
|
+
};
|
|
522
|
+
|
|
512
523
|
|
|
513
524
|
// Set
|
|
514
525
|
|
package/lib/array.js
CHANGED
|
@@ -189,4 +189,29 @@ internals.Array.prototype.length = function (limit) {
|
|
|
189
189
|
};
|
|
190
190
|
|
|
191
191
|
|
|
192
|
+
internals.Array.prototype.unique = function () {
|
|
193
|
+
|
|
194
|
+
return this._test('unique', undefined, function (value, state, options) {
|
|
195
|
+
|
|
196
|
+
var found = {
|
|
197
|
+
string: {},
|
|
198
|
+
number: {}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
for (var i = 0, il = value.length; i < il; ++i) {
|
|
202
|
+
var item = value[i];
|
|
203
|
+
var type = typeof item;
|
|
204
|
+
var records = found[type];
|
|
205
|
+
if (records) {
|
|
206
|
+
if (records[item]) {
|
|
207
|
+
return Errors.create('array.unique', { pos: i }, state, options);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
records[item] = true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
|
|
192
217
|
module.exports = new internals.Array();
|