joi 17.13.3 → 18.0.1
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 +2627 -2333
- 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 +33 -10
- 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/types/string.js
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const Ip = require('@sideway/address/lib/ip');
|
|
7
|
-
const EscapeRegex = require('@hapi/hoek/lib/escapeRegex');
|
|
8
|
-
const Tlds = require('@sideway/address/lib/tlds');
|
|
9
|
-
const Uri = require('@sideway/address/lib/uri');
|
|
3
|
+
const { assert, escapeRegex } = require('@hapi/hoek');
|
|
4
|
+
const { isDomainValid, isEmailValid, ipRegex, uriRegex } = require('@hapi/address');
|
|
5
|
+
const Tlds = require('@hapi/tlds');
|
|
10
6
|
|
|
11
7
|
const Any = require('./any');
|
|
12
8
|
const Common = require('../common');
|
|
13
9
|
|
|
14
10
|
|
|
15
11
|
const internals = {
|
|
16
|
-
tlds: Tlds instanceof Set ? { tlds: { allow: Tlds, deny: null } } : false, // $lab:coverage:ignore$
|
|
12
|
+
tlds: Tlds.tlds instanceof Set ? { tlds: { allow: Tlds.tlds, deny: null } } : false, // $lab:coverage:ignore$
|
|
17
13
|
base64Regex: {
|
|
18
14
|
// paddingRequired
|
|
19
15
|
true: {
|
|
@@ -32,7 +28,7 @@ const internals = {
|
|
|
32
28
|
withOptionalPrefix: /^(?:0x)?[0-9a-f]+$/i,
|
|
33
29
|
withoutPrefix: /^[0-9a-f]+$/i
|
|
34
30
|
},
|
|
35
|
-
ipRegex:
|
|
31
|
+
ipRegex: ipRegex({ cidr: 'forbidden' }).regex,
|
|
36
32
|
isoDurationRegex: /^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$/,
|
|
37
33
|
|
|
38
34
|
guidBrackets: {
|
|
@@ -171,8 +167,8 @@ module.exports = Any.extend({
|
|
|
171
167
|
Common.assertOptions(options, ['paddingRequired', 'urlSafe']);
|
|
172
168
|
|
|
173
169
|
options = { urlSafe: false, paddingRequired: true, ...options };
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean');
|
|
171
|
+
assert(typeof options.urlSafe === 'boolean', 'urlSafe must be boolean');
|
|
176
172
|
|
|
177
173
|
return this.$_addRule({ name: 'base64', args: { options } });
|
|
178
174
|
},
|
|
@@ -190,7 +186,7 @@ module.exports = Any.extend({
|
|
|
190
186
|
case: {
|
|
191
187
|
method(direction) {
|
|
192
188
|
|
|
193
|
-
|
|
189
|
+
assert(['lower', 'upper'].includes(direction), 'Invalid case:', direction);
|
|
194
190
|
|
|
195
191
|
return this.$_addRule({ name: 'case', args: { direction } });
|
|
196
192
|
},
|
|
@@ -240,7 +236,7 @@ module.exports = Any.extend({
|
|
|
240
236
|
Common.assertOptions(options, ['paddingRequired']);
|
|
241
237
|
|
|
242
238
|
options = { paddingRequired: true, ...options };
|
|
243
|
-
|
|
239
|
+
assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean');
|
|
244
240
|
|
|
245
241
|
return this.$_addRule({ name: 'dataUri', args: { options } });
|
|
246
242
|
},
|
|
@@ -271,7 +267,7 @@ module.exports = Any.extend({
|
|
|
271
267
|
method(options) {
|
|
272
268
|
|
|
273
269
|
if (options) {
|
|
274
|
-
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
270
|
+
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'allowUnderscore', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
275
271
|
}
|
|
276
272
|
|
|
277
273
|
const address = internals.addressOptions(options);
|
|
@@ -279,7 +275,7 @@ module.exports = Any.extend({
|
|
|
279
275
|
},
|
|
280
276
|
validate(value, helpers, args, { address }) {
|
|
281
277
|
|
|
282
|
-
if (
|
|
278
|
+
if (isDomainValid(value, address)) {
|
|
283
279
|
return value;
|
|
284
280
|
}
|
|
285
281
|
|
|
@@ -291,10 +287,10 @@ module.exports = Any.extend({
|
|
|
291
287
|
method(options = {}) {
|
|
292
288
|
|
|
293
289
|
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']);
|
|
294
|
-
|
|
290
|
+
assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean');
|
|
295
291
|
|
|
296
292
|
const address = internals.addressOptions(options);
|
|
297
|
-
const regex = new RegExp(`\\s*[${options.separator ?
|
|
293
|
+
const regex = new RegExp(`\\s*[${options.separator ? escapeRegex(options.separator) : ','}]\\s*`);
|
|
298
294
|
|
|
299
295
|
return this.$_addRule({ name: 'email', args: { options }, regex, address });
|
|
300
296
|
},
|
|
@@ -303,7 +299,7 @@ module.exports = Any.extend({
|
|
|
303
299
|
const emails = options.multiple ? value.split(regex) : [value];
|
|
304
300
|
const invalids = [];
|
|
305
301
|
for (const email of emails) {
|
|
306
|
-
if (!
|
|
302
|
+
if (!isEmailValid(email, address)) {
|
|
307
303
|
invalids.push(email);
|
|
308
304
|
}
|
|
309
305
|
}
|
|
@@ -320,37 +316,72 @@ module.exports = Any.extend({
|
|
|
320
316
|
alias: 'uuid',
|
|
321
317
|
method(options = {}) {
|
|
322
318
|
|
|
323
|
-
Common.assertOptions(options, ['version', 'separator']);
|
|
319
|
+
Common.assertOptions(options, ['version', 'separator', 'wrapper']);
|
|
320
|
+
|
|
321
|
+
assert(
|
|
322
|
+
options.wrapper === undefined ||
|
|
323
|
+
typeof options.wrapper === 'boolean' ||
|
|
324
|
+
(typeof options.wrapper === 'string' && typeof internals.guidBrackets[options.wrapper] === 'string'),
|
|
325
|
+
`"wrapper" must be true, false, or one of "${Object.keys(internals.guidBrackets).filter(Boolean).join('", "')}"`
|
|
326
|
+
);
|
|
324
327
|
|
|
325
328
|
let versionNumbers = '';
|
|
326
329
|
|
|
327
330
|
if (options.version) {
|
|
328
331
|
const versions = [].concat(options.version);
|
|
329
332
|
|
|
330
|
-
|
|
333
|
+
assert(versions.length >= 1, 'version must have at least 1 valid version specified');
|
|
331
334
|
const set = new Set();
|
|
332
335
|
|
|
333
336
|
for (let i = 0; i < versions.length; ++i) {
|
|
334
337
|
const version = versions[i];
|
|
335
|
-
|
|
338
|
+
assert(typeof version === 'string', 'version at position ' + i + ' must be a string');
|
|
336
339
|
const versionNumber = internals.guidVersions[version.toLowerCase()];
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
assert(versionNumber, 'version at position ' + i + ' must be one of ' + Object.keys(internals.guidVersions).join(', '));
|
|
341
|
+
assert(!set.has(versionNumber), 'version at position ' + i + ' must not be a duplicate');
|
|
339
342
|
|
|
340
343
|
versionNumbers += versionNumber;
|
|
341
344
|
set.add(versionNumber);
|
|
342
345
|
}
|
|
343
346
|
}
|
|
344
347
|
|
|
345
|
-
|
|
348
|
+
assert(internals.guidSeparators.has(options.separator), 'separator must be one of true, false, "-", or ":"');
|
|
346
349
|
const separator = options.separator === undefined ? '[:-]?' :
|
|
347
350
|
options.separator === true ? '[:-]' :
|
|
348
351
|
options.separator === false ? '[]?' : `\\${options.separator}`;
|
|
349
352
|
|
|
350
|
-
|
|
353
|
+
let wrapperStart;
|
|
354
|
+
let wrapperEnd;
|
|
355
|
+
|
|
356
|
+
if (options.wrapper === undefined) {
|
|
357
|
+
wrapperStart = '[\\[{\\(]?';
|
|
358
|
+
wrapperEnd = '[\\]}\\)]?';
|
|
359
|
+
}
|
|
360
|
+
else if (options.wrapper === true) {
|
|
361
|
+
wrapperStart = '[\\[{\\(]';
|
|
362
|
+
wrapperEnd = '[\\]}\\)]';
|
|
363
|
+
}
|
|
364
|
+
else if (options.wrapper === false) {
|
|
365
|
+
wrapperStart = '';
|
|
366
|
+
wrapperEnd = '';
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
wrapperStart = escapeRegex(options.wrapper);
|
|
370
|
+
wrapperEnd = escapeRegex(internals.guidBrackets[options.wrapper]);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const regex = new RegExp(
|
|
374
|
+
`^(${wrapperStart})[0-9A-F]{8}(${separator})[0-9A-F]{4}\\2?[${
|
|
375
|
+
versionNumbers || '0-9A-F'
|
|
376
|
+
}][0-9A-F]{3}\\2?[${
|
|
377
|
+
versionNumbers ? '89AB' : '0-9A-F'
|
|
378
|
+
}][0-9A-F]{3}\\2?[0-9A-F]{12}(${wrapperEnd})$`,
|
|
379
|
+
'i'
|
|
380
|
+
);
|
|
351
381
|
|
|
352
382
|
return this.$_addRule({ name: 'guid', args: { options }, regex });
|
|
353
383
|
},
|
|
384
|
+
|
|
354
385
|
validate(value, helpers, args, { regex }) {
|
|
355
386
|
|
|
356
387
|
const results = regex.exec(value);
|
|
@@ -359,9 +390,10 @@ module.exports = Any.extend({
|
|
|
359
390
|
return helpers.error('string.guid');
|
|
360
391
|
}
|
|
361
392
|
|
|
362
|
-
|
|
393
|
+
const open = results[1];
|
|
394
|
+
const close = results[results.length - 1];
|
|
363
395
|
|
|
364
|
-
if (internals.guidBrackets[
|
|
396
|
+
if ((open || close) && internals.guidBrackets[open] !== close) {
|
|
365
397
|
return helpers.error('string.guid');
|
|
366
398
|
}
|
|
367
399
|
|
|
@@ -375,8 +407,8 @@ module.exports = Any.extend({
|
|
|
375
407
|
Common.assertOptions(options, ['byteAligned', 'prefix']);
|
|
376
408
|
|
|
377
409
|
options = { byteAligned: false, prefix: false, ...options };
|
|
378
|
-
|
|
379
|
-
|
|
410
|
+
assert(typeof options.byteAligned === 'boolean', 'byteAligned must be boolean');
|
|
411
|
+
assert(typeof options.prefix === 'boolean' || options.prefix === 'optional', 'prefix must be boolean or "optional"');
|
|
380
412
|
|
|
381
413
|
return this.$_addRule({ name: 'hex', args: { options } });
|
|
382
414
|
},
|
|
@@ -408,7 +440,7 @@ module.exports = Any.extend({
|
|
|
408
440
|
},
|
|
409
441
|
validate(value, helpers) {
|
|
410
442
|
|
|
411
|
-
if (
|
|
443
|
+
if (isDomainValid(value, { minDomainSegments: 1 }) ||
|
|
412
444
|
internals.ipRegex.test(value)) {
|
|
413
445
|
|
|
414
446
|
return value;
|
|
@@ -430,7 +462,7 @@ module.exports = Any.extend({
|
|
|
430
462
|
|
|
431
463
|
Common.assertOptions(options, ['cidr', 'version']);
|
|
432
464
|
|
|
433
|
-
const { cidr, versions, regex } =
|
|
465
|
+
const { cidr, versions, regex } = ipRegex(options);
|
|
434
466
|
const version = options.version ? versions : undefined;
|
|
435
467
|
return this.$_addRule({ name: 'ip', args: { options: { cidr, version } }, regex });
|
|
436
468
|
},
|
|
@@ -529,7 +561,7 @@ module.exports = Any.extend({
|
|
|
529
561
|
normalize: {
|
|
530
562
|
method(form = 'NFC') {
|
|
531
563
|
|
|
532
|
-
|
|
564
|
+
assert(internals.normalizationForms.includes(form), 'normalization form must be one of ' + internals.normalizationForms.join(', '));
|
|
533
565
|
|
|
534
566
|
return this.$_addRule({ name: 'normalize', args: { form } });
|
|
535
567
|
},
|
|
@@ -548,8 +580,8 @@ module.exports = Any.extend({
|
|
|
548
580
|
alias: 'regex',
|
|
549
581
|
method(regex, options = {}) {
|
|
550
582
|
|
|
551
|
-
|
|
552
|
-
|
|
583
|
+
assert(regex instanceof RegExp, 'regex must be a RegExp');
|
|
584
|
+
assert(!regex.flags.includes('g') && !regex.flags.includes('y'), 'regex should not use global or sticky mode');
|
|
553
585
|
|
|
554
586
|
if (typeof options === 'string') {
|
|
555
587
|
options = { name: options };
|
|
@@ -578,11 +610,11 @@ module.exports = Any.extend({
|
|
|
578
610
|
method(pattern, replacement) {
|
|
579
611
|
|
|
580
612
|
if (typeof pattern === 'string') {
|
|
581
|
-
pattern = new RegExp(
|
|
613
|
+
pattern = new RegExp(escapeRegex(pattern), 'g');
|
|
582
614
|
}
|
|
583
615
|
|
|
584
|
-
|
|
585
|
-
|
|
616
|
+
assert(pattern instanceof RegExp, 'pattern must be a RegExp');
|
|
617
|
+
assert(typeof replacement === 'string', 'replacement must be a String');
|
|
586
618
|
|
|
587
619
|
const obj = this.clone();
|
|
588
620
|
|
|
@@ -613,7 +645,7 @@ module.exports = Any.extend({
|
|
|
613
645
|
trim: {
|
|
614
646
|
method(enabled = true) {
|
|
615
647
|
|
|
616
|
-
|
|
648
|
+
assert(typeof enabled === 'boolean', 'enabled must be a boolean');
|
|
617
649
|
|
|
618
650
|
return this.$_addRule({ name: 'trim', args: { enabled } });
|
|
619
651
|
},
|
|
@@ -633,7 +665,7 @@ module.exports = Any.extend({
|
|
|
633
665
|
truncate: {
|
|
634
666
|
method(enabled = true) {
|
|
635
667
|
|
|
636
|
-
|
|
668
|
+
assert(typeof enabled === 'boolean', 'enabled must be a boolean');
|
|
637
669
|
|
|
638
670
|
return this.$_setFlag('truncate', enabled);
|
|
639
671
|
}
|
|
@@ -655,7 +687,7 @@ module.exports = Any.extend({
|
|
|
655
687
|
Common.assertOptions(options.domain, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
|
|
656
688
|
}
|
|
657
689
|
|
|
658
|
-
const { regex, scheme } =
|
|
690
|
+
const { regex, scheme } = uriRegex(options);
|
|
659
691
|
const domain = options.domain ? internals.addressOptions(options.domain) : null;
|
|
660
692
|
return this.$_addRule({ name: 'uri', args: { options }, regex, domain, scheme });
|
|
661
693
|
},
|
|
@@ -679,7 +711,7 @@ module.exports = Any.extend({
|
|
|
679
711
|
const matched = match[1] || match[2];
|
|
680
712
|
if (domain &&
|
|
681
713
|
(!options.allowRelative || matched) &&
|
|
682
|
-
!
|
|
714
|
+
!isDomainValid(matched, domain)) {
|
|
683
715
|
|
|
684
716
|
return helpers.error('string.domain', { value: matched });
|
|
685
717
|
}
|
|
@@ -760,12 +792,12 @@ internals.addressOptions = function (options) {
|
|
|
760
792
|
|
|
761
793
|
// minDomainSegments
|
|
762
794
|
|
|
763
|
-
|
|
795
|
+
assert(options.minDomainSegments === undefined ||
|
|
764
796
|
Number.isSafeInteger(options.minDomainSegments) && options.minDomainSegments > 0, 'minDomainSegments must be a positive integer');
|
|
765
797
|
|
|
766
798
|
// maxDomainSegments
|
|
767
799
|
|
|
768
|
-
|
|
800
|
+
assert(options.maxDomainSegments === undefined ||
|
|
769
801
|
Number.isSafeInteger(options.maxDomainSegments) && options.maxDomainSegments > 0, 'maxDomainSegments must be a positive integer');
|
|
770
802
|
|
|
771
803
|
// tlds
|
|
@@ -777,11 +809,11 @@ internals.addressOptions = function (options) {
|
|
|
777
809
|
if (options.tlds === true ||
|
|
778
810
|
options.tlds === undefined) {
|
|
779
811
|
|
|
780
|
-
|
|
812
|
+
assert(internals.tlds, 'Built-in TLD list disabled');
|
|
781
813
|
return Object.assign({}, options, internals.tlds);
|
|
782
814
|
}
|
|
783
815
|
|
|
784
|
-
|
|
816
|
+
assert(typeof options.tlds === 'object', 'tlds must be true, false, or an object');
|
|
785
817
|
|
|
786
818
|
const deny = options.tlds.deny;
|
|
787
819
|
if (deny) {
|
|
@@ -789,19 +821,19 @@ internals.addressOptions = function (options) {
|
|
|
789
821
|
options = Object.assign({}, options, { tlds: { deny: new Set(deny) } });
|
|
790
822
|
}
|
|
791
823
|
|
|
792
|
-
|
|
793
|
-
|
|
824
|
+
assert(options.tlds.deny instanceof Set, 'tlds.deny must be an array, Set, or boolean');
|
|
825
|
+
assert(!options.tlds.allow, 'Cannot specify both tlds.allow and tlds.deny lists');
|
|
794
826
|
internals.validateTlds(options.tlds.deny, 'tlds.deny');
|
|
795
827
|
return options;
|
|
796
828
|
}
|
|
797
829
|
|
|
798
830
|
const allow = options.tlds.allow;
|
|
799
831
|
if (!allow) {
|
|
800
|
-
return options;
|
|
832
|
+
return { ...options, tlds: false };
|
|
801
833
|
}
|
|
802
834
|
|
|
803
835
|
if (allow === true) {
|
|
804
|
-
|
|
836
|
+
assert(internals.tlds, 'Built-in TLD list disabled');
|
|
805
837
|
return Object.assign({}, options, internals.tlds);
|
|
806
838
|
}
|
|
807
839
|
|
|
@@ -809,7 +841,7 @@ internals.addressOptions = function (options) {
|
|
|
809
841
|
options = Object.assign({}, options, { tlds: { allow: new Set(allow) } });
|
|
810
842
|
}
|
|
811
843
|
|
|
812
|
-
|
|
844
|
+
assert(options.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean');
|
|
813
845
|
internals.validateTlds(options.tlds.allow, 'tlds.allow');
|
|
814
846
|
return options;
|
|
815
847
|
};
|
|
@@ -818,7 +850,7 @@ internals.addressOptions = function (options) {
|
|
|
818
850
|
internals.validateTlds = function (set, source) {
|
|
819
851
|
|
|
820
852
|
for (const tld of set) {
|
|
821
|
-
|
|
853
|
+
assert(isDomainValid(tld, { minDomainSegments: 1, maxDomainSegments: 1 }), `${source} must contain valid top level domain names`);
|
|
822
854
|
}
|
|
823
855
|
};
|
|
824
856
|
|
|
@@ -844,7 +876,7 @@ internals.isoDate = function (value) {
|
|
|
844
876
|
|
|
845
877
|
internals.length = function (schema, name, limit, operator, encoding) {
|
|
846
878
|
|
|
847
|
-
|
|
879
|
+
assert(!encoding || Buffer && Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); // $lab:coverage:ignore$
|
|
848
880
|
|
|
849
881
|
return schema.$_addRule({ name, method: 'length', args: { limit, encoding }, operator });
|
|
850
882
|
};
|
package/lib/types/symbol.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 Any = require('./any');
|
|
6
6
|
|
|
@@ -62,17 +62,17 @@ module.exports = Any.extend({
|
|
|
62
62
|
iterable = Object.entries(iterable);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object');
|
|
66
66
|
|
|
67
67
|
const obj = this.clone();
|
|
68
68
|
|
|
69
69
|
const symbols = [];
|
|
70
70
|
for (const entry of iterable) {
|
|
71
|
-
|
|
71
|
+
assert(entry && entry[Symbol.iterator], 'Entry must be an iterable');
|
|
72
72
|
const [key, value] = entry;
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be of type object, function, or Symbol');
|
|
75
|
+
assert(typeof value === 'symbol', 'Value must be a Symbol');
|
|
76
76
|
|
|
77
77
|
obj.$_terms.map.set(key, value);
|
|
78
78
|
symbols.push(value);
|
package/lib/validator.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const Clone = require('@hapi/hoek/lib/clone');
|
|
5
|
-
const Ignore = require('@hapi/hoek/lib/ignore');
|
|
6
|
-
const Reach = require('@hapi/hoek/lib/reach');
|
|
3
|
+
const { assert, clone, ignore, reach } = require('@hapi/hoek');
|
|
7
4
|
|
|
8
5
|
const Common = require('./common');
|
|
9
6
|
const Errors = require('./errors');
|
|
@@ -19,13 +16,13 @@ exports.entry = function (value, schema, prefs) {
|
|
|
19
16
|
|
|
20
17
|
let settings = Common.defaults;
|
|
21
18
|
if (prefs) {
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
assert(prefs.warnings === undefined, 'Cannot override warnings preference in synchronous validation');
|
|
20
|
+
assert(prefs.artifacts === undefined, 'Cannot override artifacts preference in synchronous validation');
|
|
24
21
|
settings = Common.preferences(Common.defaults, prefs);
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
const result = internals.entry(value, schema, settings);
|
|
28
|
-
|
|
25
|
+
assert(!result.mainstay.externals.length, 'Schema with external rules must use validateAsync()');
|
|
29
26
|
const outcome = { value: result.value };
|
|
30
27
|
|
|
31
28
|
if (result.error) {
|
|
@@ -76,7 +73,7 @@ exports.entryAsync = async function (value, schema, prefs) {
|
|
|
76
73
|
let parent;
|
|
77
74
|
|
|
78
75
|
const ancestors = path.length ? [root] : [];
|
|
79
|
-
const original = path.length ?
|
|
76
|
+
const original = path.length ? reach(value, path) : value;
|
|
80
77
|
|
|
81
78
|
if (path.length) {
|
|
82
79
|
key = path[path.length - 1];
|
|
@@ -189,6 +186,17 @@ exports.entryAsync = async function (value, schema, prefs) {
|
|
|
189
186
|
};
|
|
190
187
|
|
|
191
188
|
|
|
189
|
+
exports.standard = function (value, schema) {
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
if (schema.isAsync()) {
|
|
193
|
+
return exports.entryAsync(value, schema);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return exports.entry(value, schema);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
|
|
192
200
|
internals.Mainstay = class {
|
|
193
201
|
|
|
194
202
|
constructor(tracer, debug, links) {
|
|
@@ -259,7 +267,7 @@ internals.tracer = function (schema, prefs) {
|
|
|
259
267
|
}
|
|
260
268
|
|
|
261
269
|
if (prefs.debug) {
|
|
262
|
-
|
|
270
|
+
assert(schema.$_root.trace, 'Debug mode not supported');
|
|
263
271
|
return { tracer: schema.$_root.trace()._register(schema), cleanup: true };
|
|
264
272
|
}
|
|
265
273
|
|
|
@@ -575,7 +583,7 @@ internals.finalize = function (value, errors, helpers) {
|
|
|
575
583
|
}
|
|
576
584
|
|
|
577
585
|
for (const error of errors) {
|
|
578
|
-
|
|
586
|
+
assert(error instanceof Error || error instanceof Errors.Report, 'error() must return an Error object');
|
|
579
587
|
}
|
|
580
588
|
}
|
|
581
589
|
else {
|
|
@@ -687,7 +695,7 @@ internals.default = function (flag, value, errors, helpers) {
|
|
|
687
695
|
}
|
|
688
696
|
|
|
689
697
|
if (typeof source === 'function') {
|
|
690
|
-
const args = source.length ? [
|
|
698
|
+
const args = source.length ? [clone(state.ancestors[0]), helpers] : [];
|
|
691
699
|
|
|
692
700
|
try {
|
|
693
701
|
return source(...args);
|
|
@@ -710,7 +718,7 @@ internals.default = function (flag, value, errors, helpers) {
|
|
|
710
718
|
return source.resolve(value, state, prefs);
|
|
711
719
|
}
|
|
712
720
|
|
|
713
|
-
return
|
|
721
|
+
return clone(source);
|
|
714
722
|
};
|
|
715
723
|
|
|
716
724
|
|
|
@@ -733,12 +741,12 @@ internals.trim = function (value, schema) {
|
|
|
733
741
|
|
|
734
742
|
internals.ignore = {
|
|
735
743
|
active: false,
|
|
736
|
-
debug:
|
|
737
|
-
entry:
|
|
738
|
-
filter:
|
|
739
|
-
log:
|
|
740
|
-
resolve:
|
|
741
|
-
value:
|
|
744
|
+
debug: ignore,
|
|
745
|
+
entry: ignore,
|
|
746
|
+
filter: ignore,
|
|
747
|
+
log: ignore,
|
|
748
|
+
resolve: ignore,
|
|
749
|
+
value: ignore
|
|
742
750
|
};
|
|
743
751
|
|
|
744
752
|
|
package/lib/values.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const DeepEqual = require('@hapi/hoek/lib/deepEqual');
|
|
3
|
+
const { assert, deepEqual } = require('@hapi/hoek');
|
|
5
4
|
|
|
6
5
|
const Common = require('./common');
|
|
7
6
|
|
|
@@ -132,7 +131,7 @@ module.exports = internals.Values = class {
|
|
|
132
131
|
|
|
133
132
|
if (typeof value === 'object') {
|
|
134
133
|
for (const item of this._values) {
|
|
135
|
-
if (
|
|
134
|
+
if (deepEqual(item, value)) {
|
|
136
135
|
return { value: item };
|
|
137
136
|
}
|
|
138
137
|
}
|
|
@@ -165,7 +164,7 @@ module.exports = internals.Values = class {
|
|
|
165
164
|
}
|
|
166
165
|
}
|
|
167
166
|
else {
|
|
168
|
-
if (
|
|
167
|
+
if (deepEqual(item, value)) {
|
|
169
168
|
return { value: item, ref };
|
|
170
169
|
}
|
|
171
170
|
}
|
|
@@ -209,7 +208,7 @@ module.exports = internals.Values = class {
|
|
|
209
208
|
|
|
210
209
|
concat(source) {
|
|
211
210
|
|
|
212
|
-
|
|
211
|
+
assert(!source._override, 'Cannot concat override set of values');
|
|
213
212
|
|
|
214
213
|
const set = new internals.Values([...this._values, ...source._values], [...this._refs, ...source._refs]);
|
|
215
214
|
set._override = this._override;
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "joi",
|
|
3
3
|
"description": "Object schema validation",
|
|
4
|
-
"version": "
|
|
5
|
-
"repository":
|
|
4
|
+
"version": "18.0.1",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "git://github.com/hapijs/joi",
|
|
7
|
+
"type": "git"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">= 20"
|
|
11
|
+
},
|
|
6
12
|
"main": "lib/index.js",
|
|
7
13
|
"types": "lib/index.d.ts",
|
|
8
14
|
"browser": "dist/joi-browser.min.js",
|
|
@@ -15,19 +21,22 @@
|
|
|
15
21
|
"validation"
|
|
16
22
|
],
|
|
17
23
|
"dependencies": {
|
|
18
|
-
"@hapi/
|
|
19
|
-
"@hapi/
|
|
20
|
-
"@
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
24
|
+
"@hapi/address": "^5.1.1",
|
|
25
|
+
"@hapi/formula": "^3.0.2",
|
|
26
|
+
"@hapi/hoek": "^11.0.7",
|
|
27
|
+
"@hapi/pinpoint": "^2.0.1",
|
|
28
|
+
"@hapi/tlds": "^1.1.1",
|
|
29
|
+
"@hapi/topo": "^6.0.2",
|
|
30
|
+
"@standard-schema/spec": "^1.0.0"
|
|
23
31
|
},
|
|
24
32
|
"devDependencies": {
|
|
25
|
-
"@hapi/bourne": "
|
|
26
|
-
"@hapi/code": "
|
|
33
|
+
"@hapi/bourne": "^3.0.0",
|
|
34
|
+
"@hapi/code": "^9.0.3",
|
|
35
|
+
"@hapi/eslint-plugin": "^7.0.0",
|
|
27
36
|
"@hapi/joi-legacy-test": "npm:@hapi/joi@15.x.x",
|
|
28
|
-
"@hapi/lab": "^
|
|
29
|
-
"@types/node": "^
|
|
30
|
-
"typescript": "
|
|
37
|
+
"@hapi/lab": "^26.0.0",
|
|
38
|
+
"@types/node": "^20.17.47",
|
|
39
|
+
"typescript": "^5.8.3"
|
|
31
40
|
},
|
|
32
41
|
"scripts": {
|
|
33
42
|
"prepublishOnly": "cd browser && npm install && npm run build",
|