joi 17.3.0 → 17.4.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.
@@ -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
- let hits = 0;
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
- ++hits;
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 (!hits) {
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 hits === 1 ? { value: matched } : { errors: error('alternatives.one') };
69
+ return matched.length === 1 ? { value: matched[0] } : { errors: error('alternatives.one') };
71
70
  }
72
71
 
73
- return hits === schema.$_terms.matches.length ? { value } : { errors: error('alternatives.all') };
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
@@ -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 a string or a reference');
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
 
@@ -647,11 +647,12 @@ module.exports = Any.extend({
647
647
 
648
648
  const match = regex.exec(value);
649
649
  if (match) {
650
- if (domain) {
651
- const matched = match[1] || match[2];
652
- if (!Domain.isValid(matched, domain)) {
653
- return helpers.error('string.domain', { value: matched });
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;