joi 17.13.2 → 18.0.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/dist/joi-browser.min.js +1 -1
- package/lib/annotate.js +2 -2
- package/lib/base.js +151 -74
- package/lib/cache.js +3 -4
- package/lib/common.js +1 -2
- package/lib/compile.js +23 -23
- package/lib/extend.js +10 -11
- package/lib/index.d.ts +78 -20
- package/lib/index.js +9 -10
- package/lib/manifest.js +15 -16
- package/lib/messages.js +10 -11
- package/lib/modify.js +10 -10
- package/lib/ref.js +15 -17
- package/lib/state.js +4 -5
- package/lib/template.js +8 -10
- package/lib/trace.js +4 -4
- package/lib/types/alternatives.js +39 -13
- package/lib/types/any.js +5 -5
- package/lib/types/array.js +32 -10
- package/lib/types/binary.js +3 -3
- package/lib/types/boolean.js +3 -3
- package/lib/types/date.js +3 -3
- package/lib/types/function.js +4 -4
- package/lib/types/keys.js +39 -16
- package/lib/types/link.js +11 -11
- package/lib/types/number.js +4 -4
- package/lib/types/string.js +84 -52
- package/lib/types/symbol.js +5 -5
- package/lib/validator.js +26 -18
- package/lib/values.js +4 -5
- package/package.json +21 -12
package/lib/compile.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const { assert } = require('@hapi/hoek');
|
|
4
4
|
|
|
5
5
|
const Common = require('./common');
|
|
6
6
|
const Ref = require('./ref');
|
|
@@ -30,10 +30,10 @@ exports.schema = function (Joi, config, options = {}) {
|
|
|
30
30
|
|
|
31
31
|
internals.schema = function (Joi, config, options) {
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
assert(config !== undefined, 'Invalid undefined schema');
|
|
34
34
|
|
|
35
35
|
if (Array.isArray(config)) {
|
|
36
|
-
|
|
36
|
+
assert(config.length, 'Invalid empty array schema');
|
|
37
37
|
|
|
38
38
|
if (config.length === 1) {
|
|
39
39
|
config = config[0];
|
|
@@ -57,7 +57,7 @@ internals.schema = function (Joi, config, options) {
|
|
|
57
57
|
return Joi.custom(config);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
assert(typeof config === 'object', 'Invalid schema content:', typeof config);
|
|
61
61
|
|
|
62
62
|
if (Common.isResolvable(config)) {
|
|
63
63
|
return valid(Joi, config);
|
|
@@ -85,7 +85,7 @@ internals.schema = function (Joi, config, options) {
|
|
|
85
85
|
return valid(Joi.date(), config);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
assert(Object.getPrototypeOf(config) === Object.getPrototypeOf({}), 'Schema can only contain plain objects');
|
|
89
89
|
|
|
90
90
|
return Joi.object().keys(config);
|
|
91
91
|
};
|
|
@@ -105,7 +105,7 @@ exports.compile = function (root, schema, options = {}) {
|
|
|
105
105
|
|
|
106
106
|
const any = schema && schema[Common.symbols.any];
|
|
107
107
|
if (any) {
|
|
108
|
-
|
|
108
|
+
assert(options.legacy || any.version === Common.version, 'Cannot mix different versions of joi schemas:', any.version, Common.version);
|
|
109
109
|
return schema;
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -150,7 +150,7 @@ internals.walk = function (schema) {
|
|
|
150
150
|
return { root: schema[any.root], compile: any.compile };
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
assert(Object.getPrototypeOf(schema) === Object.getPrototypeOf({}), 'Schema can only contain plain objects');
|
|
154
154
|
|
|
155
155
|
for (const key in schema) {
|
|
156
156
|
const compiler = internals.walk(schema[key]);
|
|
@@ -172,7 +172,7 @@ internals.simple = function (value) {
|
|
|
172
172
|
exports.when = function (schema, condition, options) {
|
|
173
173
|
|
|
174
174
|
if (options === undefined) {
|
|
175
|
-
|
|
175
|
+
assert(condition && typeof condition === 'object', 'Missing options');
|
|
176
176
|
|
|
177
177
|
options = condition;
|
|
178
178
|
condition = Ref.create('.');
|
|
@@ -187,17 +187,17 @@ exports.when = function (schema, condition, options) {
|
|
|
187
187
|
// Schema condition
|
|
188
188
|
|
|
189
189
|
if (Common.isSchema(condition)) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
assert(options.is === undefined, '"is" can not be used with a schema condition');
|
|
191
|
+
assert(options.not === undefined, '"not" can not be used with a schema condition');
|
|
192
|
+
assert(options.switch === undefined, '"switch" can not be used with a schema condition');
|
|
193
193
|
|
|
194
194
|
return internals.condition(schema, { is: condition, then: options.then, otherwise: options.otherwise, break: options.break });
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
// Single condition
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
assert(Ref.isRef(condition) || typeof condition === 'string', 'Invalid condition:', condition);
|
|
200
|
+
assert(options.not === undefined || options.is === undefined, 'Cannot combine "is" with "not"');
|
|
201
201
|
|
|
202
202
|
if (options.switch === undefined) {
|
|
203
203
|
let rule = options;
|
|
@@ -206,8 +206,8 @@ exports.when = function (schema, condition, options) {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
let is = rule.is !== undefined ? schema.$_compile(rule.is) : schema.$_root.invalid(null, false, 0, '').required();
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
assert(rule.then !== undefined || rule.otherwise !== undefined, 'options must have at least one of "then", "otherwise", or "switch"');
|
|
210
|
+
assert(rule.break === undefined || rule.then === undefined || rule.otherwise === undefined, 'Cannot specify then, otherwise, and break all together');
|
|
211
211
|
|
|
212
212
|
if (options.is !== undefined &&
|
|
213
213
|
!Ref.isRef(options.is) &&
|
|
@@ -221,10 +221,10 @@ exports.when = function (schema, condition, options) {
|
|
|
221
221
|
|
|
222
222
|
// Switch statement
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
assert(Array.isArray(options.switch), '"switch" must be an array');
|
|
225
|
+
assert(options.is === undefined, 'Cannot combine "switch" with "is"');
|
|
226
|
+
assert(options.not === undefined, 'Cannot combine "switch" with "not"');
|
|
227
|
+
assert(options.then === undefined, 'Cannot combine "switch" with "then"');
|
|
228
228
|
|
|
229
229
|
const rule = {
|
|
230
230
|
ref: exports.ref(condition),
|
|
@@ -238,8 +238,8 @@ exports.when = function (schema, condition, options) {
|
|
|
238
238
|
|
|
239
239
|
Common.assertOptions(test, last ? ['is', 'then', 'otherwise'] : ['is', 'then']);
|
|
240
240
|
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
assert(test.is !== undefined, 'Switch statement missing "is"');
|
|
242
|
+
assert(test.then !== undefined, 'Switch statement missing "then"');
|
|
243
243
|
|
|
244
244
|
const item = {
|
|
245
245
|
is: schema.$_compile(test.is),
|
|
@@ -253,10 +253,10 @@ exports.when = function (schema, condition, options) {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
if (last) {
|
|
256
|
-
|
|
256
|
+
assert(options.otherwise === undefined || test.otherwise === undefined, 'Cannot specify "otherwise" inside and outside a "switch"');
|
|
257
257
|
const otherwise = options.otherwise !== undefined ? options.otherwise : test.otherwise;
|
|
258
258
|
if (otherwise !== undefined) {
|
|
259
|
-
|
|
259
|
+
assert(rule.break === undefined, 'Cannot specify both otherwise and break');
|
|
260
260
|
item.otherwise = schema.$_compile(otherwise);
|
|
261
261
|
}
|
|
262
262
|
}
|
package/lib/extend.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const Clone = require('@hapi/hoek/lib/clone');
|
|
3
|
+
const { assert, clone } = require('@hapi/hoek');
|
|
5
4
|
|
|
6
5
|
const Common = require('./common');
|
|
7
6
|
const Messages = require('./messages');
|
|
@@ -13,7 +12,7 @@ const internals = {};
|
|
|
13
12
|
exports.type = function (from, options) {
|
|
14
13
|
|
|
15
14
|
const base = Object.getPrototypeOf(from);
|
|
16
|
-
const prototype =
|
|
15
|
+
const prototype = clone(base);
|
|
17
16
|
const schema = from._assign(Object.create(prototype));
|
|
18
17
|
const def = Object.assign({}, options); // Shallow cloned
|
|
19
18
|
delete def.base;
|
|
@@ -38,7 +37,7 @@ exports.type = function (from, options) {
|
|
|
38
37
|
if (def.terms) {
|
|
39
38
|
for (const name in def.terms) { // Only apply own terms
|
|
40
39
|
const term = def.terms[name];
|
|
41
|
-
|
|
40
|
+
assert(schema.$_terms[name] === undefined, 'Invalid term override for', def.type, name);
|
|
42
41
|
schema.$_terms[name] = term.init;
|
|
43
42
|
terms[name] = term;
|
|
44
43
|
}
|
|
@@ -82,7 +81,7 @@ exports.type = function (from, options) {
|
|
|
82
81
|
if (def.rules) {
|
|
83
82
|
for (const name in def.rules) {
|
|
84
83
|
const rule = def.rules[name];
|
|
85
|
-
|
|
84
|
+
assert(typeof rule === 'object', 'Invalid rule definition for', def.type, name);
|
|
86
85
|
|
|
87
86
|
let method = rule.method;
|
|
88
87
|
if (method === undefined) {
|
|
@@ -93,11 +92,11 @@ exports.type = function (from, options) {
|
|
|
93
92
|
}
|
|
94
93
|
|
|
95
94
|
if (method) {
|
|
96
|
-
|
|
95
|
+
assert(!prototype[name], 'Rule conflict in', def.type, name);
|
|
97
96
|
prototype[name] = method;
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
assert(!rules[name], 'Rule conflict in', def.type, name);
|
|
101
100
|
rules[name] = rule;
|
|
102
101
|
|
|
103
102
|
if (rule.alias) {
|
|
@@ -115,7 +114,7 @@ exports.type = function (from, options) {
|
|
|
115
114
|
arg = { name: arg };
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
|
|
117
|
+
assert(!rule.argsByName.has(arg.name), 'Duplicated argument name', arg.name);
|
|
119
118
|
|
|
120
119
|
if (Common.isSchema(arg.assert)) {
|
|
121
120
|
arg.assert = arg.assert.strict().label(arg.name);
|
|
@@ -135,10 +134,10 @@ exports.type = function (from, options) {
|
|
|
135
134
|
const modifiers = Object.assign({}, parent.modifiers);
|
|
136
135
|
if (def.modifiers) {
|
|
137
136
|
for (const name in def.modifiers) {
|
|
138
|
-
|
|
137
|
+
assert(!prototype[name], 'Rule conflict in', def.type, name);
|
|
139
138
|
|
|
140
139
|
const modifier = def.modifiers[name];
|
|
141
|
-
|
|
140
|
+
assert(typeof modifier === 'function', 'Invalid modifier definition for', def.type, name);
|
|
142
141
|
|
|
143
142
|
const method = function (arg) {
|
|
144
143
|
|
|
@@ -158,7 +157,7 @@ exports.type = function (from, options) {
|
|
|
158
157
|
prototype._super = base;
|
|
159
158
|
schema.$_super = {}; // Backwards compatibility
|
|
160
159
|
for (const override in def.overrides) {
|
|
161
|
-
|
|
160
|
+
assert(base[override], 'Cannot override missing', override);
|
|
162
161
|
def.overrides[override][Common.symbols.parent] = base[override];
|
|
163
162
|
schema.$_super[override] = base[override].bind(schema); // Backwards compatibility
|
|
164
163
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// TypeScript Version: 2.8
|
|
9
9
|
|
|
10
10
|
// TODO express type of Schema in a type-parameter (.default, .valid, .example etc)
|
|
11
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
11
12
|
|
|
12
13
|
declare namespace Joi {
|
|
13
14
|
type Types =
|
|
@@ -290,6 +291,12 @@ declare namespace Joi {
|
|
|
290
291
|
* @default true
|
|
291
292
|
*/
|
|
292
293
|
allowUnicode?: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* If `true`, underscores (`_`) are allowed in the domain name
|
|
296
|
+
*
|
|
297
|
+
* @default false
|
|
298
|
+
*/
|
|
299
|
+
allowUnderscore?: boolean;
|
|
293
300
|
/**
|
|
294
301
|
* if `true`, ignore invalid email length errors.
|
|
295
302
|
*
|
|
@@ -341,7 +348,12 @@ declare namespace Joi {
|
|
|
341
348
|
* @default true
|
|
342
349
|
*/
|
|
343
350
|
allowUnicode?: boolean;
|
|
344
|
-
|
|
351
|
+
/**
|
|
352
|
+
* If `true`, underscores (`_`) are allowed in the domain name
|
|
353
|
+
*
|
|
354
|
+
* @default false
|
|
355
|
+
*/
|
|
356
|
+
allowUnderscore?: boolean;
|
|
345
357
|
/**
|
|
346
358
|
* Options for TLD (top level domain) validation. By default, the TLD must be a valid name listed on the [IANA registry](http://data.iana.org/TLD/tlds-alpha-by-domain.txt)
|
|
347
359
|
*
|
|
@@ -395,6 +407,14 @@ declare namespace Joi {
|
|
|
395
407
|
interface GuidOptions {
|
|
396
408
|
version?: GuidVersions[] | GuidVersions;
|
|
397
409
|
separator?: boolean | '-' | ':';
|
|
410
|
+
/**
|
|
411
|
+
* Defines the allowed or required GUID wrapper characters where:
|
|
412
|
+
* - `undefined` - (default) the GUID can be optionally wrapped with `{}`, `[]`, or `()`. The opening and closing characters must be a matching pair.
|
|
413
|
+
* - `true` - the GUID must be wrapped with `{}`, `[]`, or `()`. The opening and closing characters must be a matching pair.
|
|
414
|
+
* - `false` - wrapper characters are not allowed.
|
|
415
|
+
* - `'['`, `'{'`, or `'('` - a specific wrapper is required (e.g., if `wrapper` is `'['`, the GUID must be enclosed in square brackets).
|
|
416
|
+
*/
|
|
417
|
+
wrapper?: true | false | '[' | '{' | '(' | undefined;
|
|
398
418
|
}
|
|
399
419
|
|
|
400
420
|
interface UriOptions {
|
|
@@ -428,7 +448,7 @@ declare namespace Joi {
|
|
|
428
448
|
domain?: DomainOptions;
|
|
429
449
|
/**
|
|
430
450
|
* Encode URI before validation.
|
|
431
|
-
*
|
|
451
|
+
*
|
|
432
452
|
* @default false
|
|
433
453
|
*/
|
|
434
454
|
encodeUri?: boolean;
|
|
@@ -471,7 +491,7 @@ declare namespace Joi {
|
|
|
471
491
|
otherwise: SchemaLike;
|
|
472
492
|
}
|
|
473
493
|
|
|
474
|
-
interface WhenOptions {
|
|
494
|
+
interface WhenOptions<ThenSchema = any, OtherwiseSchema = any> {
|
|
475
495
|
/**
|
|
476
496
|
* the required condition joi type.
|
|
477
497
|
*/
|
|
@@ -486,12 +506,12 @@ declare namespace Joi {
|
|
|
486
506
|
/**
|
|
487
507
|
* the alternative schema type if the condition is true. Required if otherwise or switch are missing.
|
|
488
508
|
*/
|
|
489
|
-
then?: SchemaLike
|
|
509
|
+
then?: SchemaLike<ThenSchema>;
|
|
490
510
|
|
|
491
511
|
/**
|
|
492
512
|
* the alternative schema type if the condition is false. Required if then or switch are missing.
|
|
493
513
|
*/
|
|
494
|
-
otherwise?: SchemaLike
|
|
514
|
+
otherwise?: SchemaLike<OtherwiseSchema>;
|
|
495
515
|
|
|
496
516
|
/**
|
|
497
517
|
* the list of cases. Required if then is missing. Required if then or otherwise are missing.
|
|
@@ -504,15 +524,15 @@ declare namespace Joi {
|
|
|
504
524
|
break?: boolean;
|
|
505
525
|
}
|
|
506
526
|
|
|
507
|
-
interface WhenSchemaOptions {
|
|
527
|
+
interface WhenSchemaOptions<ThenSchema = any, OtherwiseSchema = any> {
|
|
508
528
|
/**
|
|
509
529
|
* the alternative schema type if the condition is true. Required if otherwise is missing.
|
|
510
530
|
*/
|
|
511
|
-
then?: SchemaLike
|
|
531
|
+
then?: SchemaLike<ThenSchema>;
|
|
512
532
|
/**
|
|
513
533
|
* the alternative schema type if the condition is false. Required if then is missing.
|
|
514
534
|
*/
|
|
515
|
-
otherwise?: SchemaLike
|
|
535
|
+
otherwise?: SchemaLike<OtherwiseSchema>;
|
|
516
536
|
}
|
|
517
537
|
|
|
518
538
|
interface Cache {
|
|
@@ -772,8 +792,13 @@ declare namespace Joi {
|
|
|
772
792
|
|
|
773
793
|
type ExternalValidationFunction<V = any, R = V> = (value: V, helpers: ExternalHelpers<R>) => R | undefined;
|
|
774
794
|
|
|
775
|
-
type
|
|
776
|
-
|
|
795
|
+
type Primitives = string | number | boolean | bigint | symbol | null;
|
|
796
|
+
|
|
797
|
+
type SchemaLikeWithoutArray<TSchema = any> = Exclude<
|
|
798
|
+
(Primitives | Schema<TSchema> | SchemaMap<TSchema>),
|
|
799
|
+
any[]
|
|
800
|
+
>;
|
|
801
|
+
type SchemaLike<TSchema = any> = SchemaLikeWithoutArray<TSchema> | object;
|
|
777
802
|
|
|
778
803
|
type NullableType<T> = undefined | null | T
|
|
779
804
|
|
|
@@ -945,7 +970,7 @@ declare namespace Joi {
|
|
|
945
970
|
$_validate(value: any, state: State, prefs: ValidationOptions): ValidationResult;
|
|
946
971
|
}
|
|
947
972
|
|
|
948
|
-
interface AnySchema<TSchema = any> extends SchemaInternals {
|
|
973
|
+
interface AnySchema<TSchema = any> extends SchemaInternals, StandardSchemaV1<TSchema> {
|
|
949
974
|
/**
|
|
950
975
|
* Flags of current schema.
|
|
951
976
|
*/
|
|
@@ -1043,8 +1068,8 @@ declare namespace Joi {
|
|
|
1043
1068
|
disallow(...values: any[]): this;
|
|
1044
1069
|
|
|
1045
1070
|
/**
|
|
1046
|
-
* Considers anything that matches the schema to be empty (undefined).
|
|
1047
|
-
* @param schema -
|
|
1071
|
+
* Considers anything that matches the schema to be empty (undefined). Overrides any previous calls to empty.
|
|
1072
|
+
* @param schema - an object, value, or joi schema to match or an array of objects, values, and joi schemas to match. An undefined schema unsets that rule.
|
|
1048
1073
|
*/
|
|
1049
1074
|
empty(schema?: SchemaLike): this;
|
|
1050
1075
|
|
|
@@ -1137,6 +1162,11 @@ declare namespace Joi {
|
|
|
1137
1162
|
*/
|
|
1138
1163
|
invalid(...values: any[]): this;
|
|
1139
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* Returns a boolean indicating whether this schema contains a rule that requires asynchronous validation.
|
|
1167
|
+
*/
|
|
1168
|
+
isAsync(): boolean;
|
|
1169
|
+
|
|
1140
1170
|
/**
|
|
1141
1171
|
* Same as `rule({ keep: true })`.
|
|
1142
1172
|
*
|
|
@@ -1648,7 +1678,13 @@ declare namespace Joi {
|
|
|
1648
1678
|
*
|
|
1649
1679
|
* @param type - a joi schema object to validate each array item against.
|
|
1650
1680
|
*/
|
|
1651
|
-
items(
|
|
1681
|
+
items<A>(a: SchemaLikeWithoutArray<A>): ArraySchema<A[]>;
|
|
1682
|
+
items<A, B>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>): ArraySchema<(A | B)[]>;
|
|
1683
|
+
items<A, B, C>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>): ArraySchema<(A | B | C)[]>;
|
|
1684
|
+
items<A, B, C, D>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>, d: SchemaLikeWithoutArray<D>): ArraySchema<(A | B | C| D)[]>;
|
|
1685
|
+
items<A, B, C, D, E>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>, d: SchemaLikeWithoutArray<D>, e: SchemaLikeWithoutArray<E>): ArraySchema<(A | B | C| D | E)[]>;
|
|
1686
|
+
items<A, B, C, D, E , F>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>, d: SchemaLikeWithoutArray<D>, e: SchemaLikeWithoutArray<E>, f: SchemaLikeWithoutArray<F>): ArraySchema<(A | B | C| D | E |F)[]>;
|
|
1687
|
+
items<TItems>(...types: SchemaLikeWithoutArray<TItems>[]): this;
|
|
1652
1688
|
|
|
1653
1689
|
/**
|
|
1654
1690
|
* Specifies the exact number of items in the array.
|
|
@@ -1922,8 +1958,8 @@ declare namespace Joi {
|
|
|
1922
1958
|
/**
|
|
1923
1959
|
* Adds a conditional alternative schema type, either based on another key value, or a schema peeking into the current value.
|
|
1924
1960
|
*/
|
|
1925
|
-
conditional(ref: string | Reference, options: WhenOptions | WhenOptions[]):
|
|
1926
|
-
conditional(ref: Schema, options: WhenSchemaOptions):
|
|
1961
|
+
conditional<ThenSchema, OtherwiseSchema>(ref: string | Reference, options: WhenOptions | WhenOptions[]): AlternativesSchema<ThenSchema | OtherwiseSchema>;
|
|
1962
|
+
conditional<ThenSchema, OtherwiseSchema>(ref: Schema, options: WhenSchemaOptions<ThenSchema, OtherwiseSchema>): AlternativesSchema<ThenSchema | OtherwiseSchema>;
|
|
1927
1963
|
|
|
1928
1964
|
/**
|
|
1929
1965
|
* Requires the validated value to match a specific set of the provided alternative.try() schemas.
|
|
@@ -1934,6 +1970,12 @@ declare namespace Joi {
|
|
|
1934
1970
|
/**
|
|
1935
1971
|
* Adds an alternative schema type for attempting to match against the validated value.
|
|
1936
1972
|
*/
|
|
1973
|
+
try<A>(a: SchemaLikeWithoutArray<A>): AlternativesSchema<A>;
|
|
1974
|
+
try<A, B>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>): AlternativesSchema<A | B>;
|
|
1975
|
+
try<A, B, C>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>): AlternativesSchema<A | B | C>;
|
|
1976
|
+
try<A, B, C, D>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>, d: SchemaLikeWithoutArray<D>): AlternativesSchema<A | B | C| D>;
|
|
1977
|
+
try<A, B, C, D, E>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>, d: SchemaLikeWithoutArray<D>, e: SchemaLikeWithoutArray<E>): AlternativesSchema<A | B | C| D | E>;
|
|
1978
|
+
try<A, B, C, D, E , F>(a: SchemaLikeWithoutArray<A>, b: SchemaLikeWithoutArray<B>, c: SchemaLikeWithoutArray<C>, d: SchemaLikeWithoutArray<D>, e: SchemaLikeWithoutArray<E>, f: SchemaLikeWithoutArray<F>): AlternativesSchema<A | B | C| D | E |F>;
|
|
1937
1979
|
try(...types: SchemaLikeWithoutArray[]): this;
|
|
1938
1980
|
}
|
|
1939
1981
|
|
|
@@ -2092,12 +2134,12 @@ declare namespace Joi {
|
|
|
2092
2134
|
array<TSchema = any[]>(): ArraySchema<TSchema>;
|
|
2093
2135
|
|
|
2094
2136
|
/**
|
|
2095
|
-
* Generates a schema object that matches a boolean data type (as well as the strings 'true'
|
|
2137
|
+
* Generates a schema object that matches a boolean data type (as well as the strings 'true' and 'false'). Can also be called via boolean().
|
|
2096
2138
|
*/
|
|
2097
2139
|
bool<TSchema = boolean>(): BooleanSchema<TSchema>;
|
|
2098
2140
|
|
|
2099
2141
|
/**
|
|
2100
|
-
* Generates a schema object that matches a boolean data type (as well as the strings 'true'
|
|
2142
|
+
* Generates a schema object that matches a boolean data type (as well as the strings 'true' and 'false'). Can also be called via bool().
|
|
2101
2143
|
*/
|
|
2102
2144
|
boolean<TSchema = boolean>(): BooleanSchema<TSchema>;
|
|
2103
2145
|
|
|
@@ -2145,12 +2187,28 @@ declare namespace Joi {
|
|
|
2145
2187
|
/**
|
|
2146
2188
|
* Generates a type that will match one of the provided alternative schemas
|
|
2147
2189
|
*/
|
|
2148
|
-
alternatives<
|
|
2149
|
-
alternatives<
|
|
2190
|
+
alternatives<A,B>(params: [SchemaLike<A>,SchemaLike<B>]): AlternativesSchema<A | B>;
|
|
2191
|
+
alternatives<A,B,C>(params: [SchemaLike<A>, SchemaLike<B>, SchemaLike<C>]): AlternativesSchema<A | B | C>;
|
|
2192
|
+
alternatives<A,B,C,D>(params: [SchemaLike<A>, SchemaLike<B>, SchemaLike<C>, SchemaLike<D>]): AlternativesSchema<A | B | C | D>;
|
|
2193
|
+
alternatives<A,B,C,D, E>(params: [SchemaLike<A>,SchemaLike<B>, SchemaLike<C>, SchemaLike<D>, SchemaLike<E>]): AlternativesSchema<A | B | C | D|E>;
|
|
2194
|
+
alternatives<A,B>(a: SchemaLike<A>,b: SchemaLike<B>): AlternativesSchema<A | B>;
|
|
2195
|
+
alternatives<A,B,C>(a: SchemaLike<A>,b: SchemaLike<B>, c:SchemaLike<C>): AlternativesSchema<A | B | C>;
|
|
2196
|
+
alternatives<A,B,C,D>(a: SchemaLike<A>,b: SchemaLike<B>, c:SchemaLike<C>, d: SchemaLike<D>): AlternativesSchema<A | B | C | D>;
|
|
2197
|
+
alternatives<A,B,C,D, E>(a: SchemaLike<A>,b: SchemaLike<B>, c:SchemaLike<C>, d: SchemaLike<D>, e: SchemaLike<E>): AlternativesSchema<A | B | C | D|E>;
|
|
2198
|
+
alternatives<TSchema = any>(types: SchemaLike<TSchema>[]): AlternativesSchema<TSchema>;
|
|
2199
|
+
alternatives<TSchema = any>(...types: SchemaLike<TSchema>[]): AlternativesSchema<TSchema>;
|
|
2150
2200
|
|
|
2151
2201
|
/**
|
|
2152
2202
|
* Alias for `alternatives`
|
|
2153
2203
|
*/
|
|
2204
|
+
alt<A,B>(params: [SchemaLike<A>,SchemaLike<B>]): AlternativesSchema<A | B>;
|
|
2205
|
+
alt<A,B,C>(params: [SchemaLike<A>, SchemaLike<B>, SchemaLike<C>]): AlternativesSchema<A | B | C>;
|
|
2206
|
+
alt<A,B,C,D>(params: [SchemaLike<A>, SchemaLike<B>, SchemaLike<C>, SchemaLike<D>]): AlternativesSchema<A | B | C | D>;
|
|
2207
|
+
alt<A,B,C,D, E>(params: [SchemaLike<A>,SchemaLike<B>, SchemaLike<C>, SchemaLike<D>, SchemaLike<E>]): AlternativesSchema<A | B | C | D|E>;
|
|
2208
|
+
alt<A,B>(a: SchemaLike<A>,b: SchemaLike<B>): AlternativesSchema<A | B>;
|
|
2209
|
+
alt<A,B,C>(a: SchemaLike<A>,b: SchemaLike<B>, c:SchemaLike<C>): AlternativesSchema<A | B | C>;
|
|
2210
|
+
alt<A,B,C,D>(a: SchemaLike<A>,b: SchemaLike<B>, c:SchemaLike<C>, d: SchemaLike<D>): AlternativesSchema<A | B | C | D>;
|
|
2211
|
+
alt<A,B,C,D, E>(a: SchemaLike<A>,b: SchemaLike<B>, c:SchemaLike<C>, d: SchemaLike<D>, e: SchemaLike<E>): AlternativesSchema<A | B | C | D|E>;
|
|
2154
2212
|
alt<TSchema = any>(types: SchemaLike[]): AlternativesSchema<TSchema>;
|
|
2155
2213
|
alt<TSchema = any>(...types: SchemaLike[]): AlternativesSchema<TSchema>;
|
|
2156
2214
|
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const Clone = require('@hapi/hoek/lib/clone');
|
|
3
|
+
const { assert, clone } = require('@hapi/hoek');
|
|
5
4
|
|
|
6
5
|
const Cache = require('./cache');
|
|
7
6
|
const Common = require('./common');
|
|
@@ -54,7 +53,7 @@ internals.root = function () {
|
|
|
54
53
|
for (const type of root._types) {
|
|
55
54
|
root[type] = function (...args) {
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');
|
|
58
57
|
return internals.generate(this, internals.types[type], args);
|
|
59
58
|
};
|
|
60
59
|
}
|
|
@@ -109,7 +108,7 @@ internals.methods = {
|
|
|
109
108
|
|
|
110
109
|
build(desc) {
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
assert(typeof Manifest.build === 'function', 'Manifest functionality disabled');
|
|
113
112
|
return Manifest.build(this, desc);
|
|
114
113
|
},
|
|
115
114
|
|
|
@@ -125,12 +124,12 @@ internals.methods = {
|
|
|
125
124
|
|
|
126
125
|
defaults(modifier) {
|
|
127
126
|
|
|
128
|
-
|
|
127
|
+
assert(typeof modifier === 'function', 'modifier must be a function');
|
|
129
128
|
|
|
130
129
|
const joi = Object.assign({}, this);
|
|
131
130
|
for (const type of joi._types) {
|
|
132
131
|
const schema = modifier(joi[type]());
|
|
133
|
-
|
|
132
|
+
assert(Common.isSchema(schema), 'modifier must return a valid schema object');
|
|
134
133
|
|
|
135
134
|
joi[type] = function (...args) {
|
|
136
135
|
|
|
@@ -152,7 +151,7 @@ internals.methods = {
|
|
|
152
151
|
|
|
153
152
|
Schemas = Schemas || require('./schemas');
|
|
154
153
|
|
|
155
|
-
|
|
154
|
+
assert(extensions.length, 'You need to provide at least one extension');
|
|
156
155
|
this.assert(extensions, Schemas.extensions);
|
|
157
156
|
|
|
158
157
|
const joi = Object.assign({}, this);
|
|
@@ -167,7 +166,7 @@ internals.methods = {
|
|
|
167
166
|
|
|
168
167
|
const expanded = internals.expandExtension(extension, joi);
|
|
169
168
|
for (const item of expanded) {
|
|
170
|
-
|
|
169
|
+
assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type);
|
|
171
170
|
|
|
172
171
|
const base = item.base || this.any();
|
|
173
172
|
const schema = Extend.type(base, item);
|
|
@@ -236,7 +235,7 @@ internals.assert = function (value, schema, annotate, args /* [message], [option
|
|
|
236
235
|
const display = annotate && typeof error.annotate === 'function' ? error.annotate() : error.message;
|
|
237
236
|
|
|
238
237
|
if (error instanceof Errors.ValidationError === false) {
|
|
239
|
-
error =
|
|
238
|
+
error = clone(error);
|
|
240
239
|
}
|
|
241
240
|
|
|
242
241
|
error.message = message ? `${message} ${display}` : display;
|
|
@@ -246,7 +245,7 @@ internals.assert = function (value, schema, annotate, args /* [message], [option
|
|
|
246
245
|
|
|
247
246
|
internals.generate = function (root, schema, args) {
|
|
248
247
|
|
|
249
|
-
|
|
248
|
+
assert(root, 'Must be invoked on a Joi instance.');
|
|
250
249
|
|
|
251
250
|
schema.$_root = root;
|
|
252
251
|
|
package/lib/manifest.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const Clone = require('@hapi/hoek/lib/clone');
|
|
3
|
+
const { assert, clone } = require('@hapi/hoek');
|
|
5
4
|
|
|
6
5
|
const Common = require('./common');
|
|
7
6
|
const Messages = require('./messages');
|
|
@@ -41,7 +40,7 @@ exports.describe = function (schema) {
|
|
|
41
40
|
// Preferences
|
|
42
41
|
|
|
43
42
|
if (schema._preferences) {
|
|
44
|
-
desc.preferences =
|
|
43
|
+
desc.preferences = clone(schema._preferences, { shallow: ['messages'] });
|
|
45
44
|
delete desc.preferences[Common.symbols.prefs];
|
|
46
45
|
if (desc.preferences.messages) {
|
|
47
46
|
desc.preferences.messages = Messages.decompile(desc.preferences.messages);
|
|
@@ -106,7 +105,7 @@ exports.describe = function (schema) {
|
|
|
106
105
|
continue;
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
|
|
108
|
+
assert(!desc[term], 'Cannot describe schema due to internal name conflict with', term);
|
|
110
109
|
|
|
111
110
|
const items = schema.$_terms[term];
|
|
112
111
|
if (!items) {
|
|
@@ -126,7 +125,7 @@ exports.describe = function (schema) {
|
|
|
126
125
|
continue;
|
|
127
126
|
}
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
assert(def.terms[term], 'Term', term, 'missing configuration');
|
|
130
129
|
const manifest = def.terms[term].manifest;
|
|
131
130
|
const mapped = typeof manifest === 'object';
|
|
132
131
|
if (!items.length &&
|
|
@@ -155,7 +154,7 @@ exports.describe = function (schema) {
|
|
|
155
154
|
// Single
|
|
156
155
|
|
|
157
156
|
if (manifest === 'single') {
|
|
158
|
-
|
|
157
|
+
assert(normalized.length === 1, 'Term', term, 'contains more than one item');
|
|
159
158
|
desc[term] = normalized[0];
|
|
160
159
|
continue;
|
|
161
160
|
}
|
|
@@ -187,7 +186,7 @@ internals.describe = function (item, options = {}) {
|
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
if (options.assign === 'options') {
|
|
190
|
-
return
|
|
189
|
+
return clone(item);
|
|
191
190
|
}
|
|
192
191
|
|
|
193
192
|
if (Buffer && Buffer.isBuffer(item)) { // $lab:coverage:ignore$
|
|
@@ -264,7 +263,7 @@ internals.Builder = class {
|
|
|
264
263
|
if (desc.flags) {
|
|
265
264
|
for (const flag in desc.flags) {
|
|
266
265
|
const setter = def.flags[flag] && def.flags[flag].setter || flag;
|
|
267
|
-
|
|
266
|
+
assert(typeof schema[setter] === 'function', 'Invalid flag', flag, 'for type', desc.type);
|
|
268
267
|
schema = schema[setter](this.build(desc.flags[flag]));
|
|
269
268
|
}
|
|
270
269
|
}
|
|
@@ -289,7 +288,7 @@ internals.Builder = class {
|
|
|
289
288
|
|
|
290
289
|
if (desc.rules) {
|
|
291
290
|
for (const rule of desc.rules) {
|
|
292
|
-
|
|
291
|
+
assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type);
|
|
293
292
|
|
|
294
293
|
const args = [];
|
|
295
294
|
if (rule.args) {
|
|
@@ -301,13 +300,13 @@ internals.Builder = class {
|
|
|
301
300
|
const keys = Object.keys(built);
|
|
302
301
|
const definition = def.rules[rule.name].args;
|
|
303
302
|
if (definition) {
|
|
304
|
-
|
|
303
|
+
assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length, ', found', keys.length, ')');
|
|
305
304
|
for (const { name } of definition) {
|
|
306
305
|
args.push(built[name]);
|
|
307
306
|
}
|
|
308
307
|
}
|
|
309
308
|
else {
|
|
310
|
-
|
|
309
|
+
assert(keys.length === 1, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to 1, found', keys.length, ')');
|
|
311
310
|
args.push(built[keys[0]]);
|
|
312
311
|
}
|
|
313
312
|
}
|
|
@@ -339,7 +338,7 @@ internals.Builder = class {
|
|
|
339
338
|
continue;
|
|
340
339
|
}
|
|
341
340
|
|
|
342
|
-
|
|
341
|
+
assert(def.terms[key], 'Term', key, 'missing configuration');
|
|
343
342
|
const manifest = def.terms[key].manifest;
|
|
344
343
|
|
|
345
344
|
if (manifest === 'schema') {
|
|
@@ -394,7 +393,7 @@ internals.Builder = class {
|
|
|
394
393
|
}
|
|
395
394
|
|
|
396
395
|
if (options.assign === 'options') {
|
|
397
|
-
return
|
|
396
|
+
return clone(desc);
|
|
398
397
|
}
|
|
399
398
|
|
|
400
399
|
if (options.assign === 'regex') {
|
|
@@ -411,7 +410,7 @@ internals.Builder = class {
|
|
|
411
410
|
|
|
412
411
|
if (Object.keys(desc).length === 1) {
|
|
413
412
|
if (desc.buffer) {
|
|
414
|
-
|
|
413
|
+
assert(Buffer, 'Buffers are not supported');
|
|
415
414
|
return Buffer && Buffer.from(desc.buffer, 'binary'); // $lab:coverage:ignore$
|
|
416
415
|
}
|
|
417
416
|
|
|
@@ -432,12 +431,12 @@ internals.Builder = class {
|
|
|
432
431
|
}
|
|
433
432
|
|
|
434
433
|
if (desc.special) {
|
|
435
|
-
|
|
434
|
+
assert(['deep'].includes(desc.special), 'Unknown special value', desc.special);
|
|
436
435
|
return Common.symbols.deepDefault;
|
|
437
436
|
}
|
|
438
437
|
|
|
439
438
|
if (desc.value) {
|
|
440
|
-
return
|
|
439
|
+
return clone(desc.value);
|
|
441
440
|
}
|
|
442
441
|
}
|
|
443
442
|
|