joi 17.3.0 → 17.4.3
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/index.d.ts +2242 -2206
- package/lib/types/alternatives.js +11 -7
- package/lib/types/array.js +32 -1
- package/lib/types/keys.js +5 -1
- package/lib/types/string.js +9 -8
- package/lib/validator.js +650 -650
- package/package.json +4 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const Assert = require('@hapi/hoek/lib/assert');
|
|
4
|
+
const Merge = require('@hapi/hoek/lib/merge');
|
|
4
5
|
|
|
5
6
|
const Any = require('./any');
|
|
6
7
|
const Common = require('../common');
|
|
@@ -44,8 +45,7 @@ module.exports = Any.extend({
|
|
|
44
45
|
// Match all or one
|
|
45
46
|
|
|
46
47
|
if (schema._flags.match) {
|
|
47
|
-
|
|
48
|
-
let matched;
|
|
48
|
+
const matched = [];
|
|
49
49
|
|
|
50
50
|
for (let i = 0; i < schema.$_terms.matches.length; ++i) {
|
|
51
51
|
const item = schema.$_terms.matches[i];
|
|
@@ -54,23 +54,27 @@ module.exports = Any.extend({
|
|
|
54
54
|
|
|
55
55
|
const result = item.schema.$_validate(value, localState, prefs);
|
|
56
56
|
if (!result.errors) {
|
|
57
|
-
|
|
58
|
-
matched = result.value;
|
|
57
|
+
matched.push(result.value);
|
|
59
58
|
}
|
|
60
59
|
else {
|
|
61
60
|
localState.restore();
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
if (
|
|
64
|
+
if (matched.length === 0) {
|
|
66
65
|
return { errors: error('alternatives.any') };
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
if (schema._flags.match === 'one') {
|
|
70
|
-
return
|
|
69
|
+
return matched.length === 1 ? { value: matched[0] } : { errors: error('alternatives.one') };
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
if (matched.length !== schema.$_terms.matches.length) {
|
|
73
|
+
return { errors: error('alternatives.all') };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const allobj = schema.$_terms.matches.reduce((acc, v) => acc && v.schema.type === 'object', true);
|
|
77
|
+
return allobj ? { value: matched.reduce((acc, v) => Merge(acc, v, { mergeArrays: false })) } : { value: matched[matched.length - 1] };
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
// Match any
|
package/lib/types/array.js
CHANGED
|
@@ -319,7 +319,7 @@ module.exports = Any.extend({
|
|
|
319
319
|
continue;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
if (schema.$_terms._inclusions.length &&
|
|
322
|
+
if ((schema.$_terms._inclusions.length || schema.$_terms._requireds.length) &&
|
|
323
323
|
!isValid) {
|
|
324
324
|
|
|
325
325
|
if (stripUnknown) {
|
|
@@ -342,6 +342,10 @@ module.exports = Any.extend({
|
|
|
342
342
|
|
|
343
343
|
if (ordereds.length) {
|
|
344
344
|
internals.fillOrderedErrors(schema, errors, ordereds, value, state, prefs);
|
|
345
|
+
|
|
346
|
+
if (!errors.length) {
|
|
347
|
+
internals.fillDefault(ordereds, value, state, prefs);
|
|
348
|
+
}
|
|
345
349
|
}
|
|
346
350
|
|
|
347
351
|
return errors.length ? errors : value;
|
|
@@ -677,6 +681,33 @@ internals.fillOrderedErrors = function (schema, errors, ordereds, value, state,
|
|
|
677
681
|
};
|
|
678
682
|
|
|
679
683
|
|
|
684
|
+
internals.fillDefault = function (ordereds, value, state, prefs) {
|
|
685
|
+
|
|
686
|
+
const overrides = [];
|
|
687
|
+
let trailingUndefined = true;
|
|
688
|
+
|
|
689
|
+
for (let i = ordereds.length - 1; i >= 0; --i) {
|
|
690
|
+
const ordered = ordereds[i];
|
|
691
|
+
const ancestors = [value, ...state.ancestors];
|
|
692
|
+
const override = ordered.$_validate(undefined, state.localize(state.path, ancestors, ordered), prefs).value;
|
|
693
|
+
|
|
694
|
+
if (trailingUndefined) {
|
|
695
|
+
if (override === undefined) {
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
trailingUndefined = false;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
overrides.unshift(override);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
if (overrides.length) {
|
|
706
|
+
value.push(...overrides);
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
|
|
680
711
|
internals.fastSplice = function (arr, i) {
|
|
681
712
|
|
|
682
713
|
let pos = i;
|
package/lib/types/keys.js
CHANGED
|
@@ -112,6 +112,10 @@ module.exports = Any.extend({
|
|
|
112
112
|
return { value, errors: result.errors };
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
if (result.value !== undefined) {
|
|
116
|
+
value[key] = result.value;
|
|
117
|
+
}
|
|
118
|
+
|
|
115
119
|
errors.push(...result.errors);
|
|
116
120
|
}
|
|
117
121
|
else if (child.schema._flags.result === 'strip' ||
|
|
@@ -600,7 +604,7 @@ internals.dependency = function (schema, rel, key, peers, options) {
|
|
|
600
604
|
const separator = Common.default(options.separator, '.');
|
|
601
605
|
const paths = [];
|
|
602
606
|
for (const peer of peers) {
|
|
603
|
-
Assert(typeof peer === 'string', rel, 'peers must be
|
|
607
|
+
Assert(typeof peer === 'string', rel, 'peers must be strings');
|
|
604
608
|
paths.push(Compile.ref(peer, { separator, ancestor: 0, prefix: false }));
|
|
605
609
|
}
|
|
606
610
|
|
package/lib/types/string.js
CHANGED
|
@@ -257,7 +257,7 @@ module.exports = Any.extend({
|
|
|
257
257
|
method(options) {
|
|
258
258
|
|
|
259
259
|
if (options) {
|
|
260
|
-
Common.assertOptions(options, ['allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
260
|
+
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
const address = internals.addressOptions(options);
|
|
@@ -276,7 +276,7 @@ module.exports = Any.extend({
|
|
|
276
276
|
email: {
|
|
277
277
|
method(options = {}) {
|
|
278
278
|
|
|
279
|
-
Common.assertOptions(options, ['allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']);
|
|
279
|
+
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']);
|
|
280
280
|
Assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean');
|
|
281
281
|
|
|
282
282
|
const address = internals.addressOptions(options);
|
|
@@ -632,7 +632,7 @@ module.exports = Any.extend({
|
|
|
632
632
|
Common.assertOptions(options, ['allowRelative', 'allowQuerySquareBrackets', 'domain', 'relativeOnly', 'scheme']);
|
|
633
633
|
|
|
634
634
|
if (options.domain) {
|
|
635
|
-
Common.assertOptions(options.domain, ['allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
635
|
+
Common.assertOptions(options.domain, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
636
636
|
}
|
|
637
637
|
|
|
638
638
|
const { regex, scheme } = Uri.regex(options);
|
|
@@ -647,11 +647,12 @@ module.exports = Any.extend({
|
|
|
647
647
|
|
|
648
648
|
const match = regex.exec(value);
|
|
649
649
|
if (match) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
650
|
+
const matched = match[1] || match[2];
|
|
651
|
+
if (domain &&
|
|
652
|
+
(!options.allowRelative || matched) &&
|
|
653
|
+
!Domain.isValid(matched, domain)) {
|
|
654
|
+
|
|
655
|
+
return helpers.error('string.domain', { value: matched });
|
|
655
656
|
}
|
|
656
657
|
|
|
657
658
|
return value;
|