Skip to content

Commit a646761

Browse files
committed
Allow all return values in custom validators
Fixes #899.
1 parent 9ed1e43 commit a646761

File tree

13 files changed

+69
-68
lines changed

13 files changed

+69
-68
lines changed

API.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ const customJoi = Joi.extend({
311311
return Math.round(value); // Change the value
312312
}
313313

314-
return null; // Keep the value as it was
314+
return value; // Keep the value as it was
315315
},
316316
rules: [
317317
{
@@ -327,7 +327,7 @@ const customJoi = Joi.extend({
327327
return this.createError('number.round', { v: value }, state, options);
328328
}
329329

330-
return null; // Everything is OK
330+
return value; // Everything is OK
331331
}
332332
},
333333
{
@@ -342,7 +342,7 @@ const customJoi = Joi.extend({
342342
return this.createError('number.dividable', { v: value, q: params.q }, state, options);
343343
}
344344

345-
return null; // Everything is OK
345+
return value; // Everything is OK
346346
}
347347
}
348348
]

lib/alternatives.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ internals.Alternatives = class extends Any {
9090
const obj = this.clone();
9191
let is = Cast.schema(options.is);
9292

93-
if (options.is === null || !options.is.isJoi) {
93+
if (options.is === null || !(Ref.isRef(options.is) || options.is instanceof Any)) {
9494

95-
// Only apply required if this wasn't already a schema, we'll suppose people know what they're doing
95+
// Only apply required if this wasn't already a schema or a ref, we'll suppose people know what they're doing
9696
is = is.required();
9797
}
9898

lib/any.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ module.exports = internals.Any = class {
115115

116116
concat(schema) {
117117

118-
Hoek.assert(schema && schema.isJoi, 'Invalid schema object');
118+
Hoek.assert(schema instanceof internals.Any, 'Invalid schema object');
119119
Hoek.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);
120120

121121
let obj = this.clone();
@@ -566,13 +566,13 @@ module.exports = internals.Any = class {
566566
for (let i = 0; i < this._tests.length; ++i) {
567567
const test = this._tests[i];
568568
const ret = test.func.call(this, value, state, options);
569-
if (ret && ret.isJoi) {
569+
if (ret instanceof Errors.Err) {
570570
errors.push(ret);
571571
if (options.abortEarly) {
572572
return finish();
573573
}
574574
}
575-
else if (ret !== null) {
575+
else {
576576
value = ret;
577577
}
578578
}

lib/array.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ internals.Array = class extends Any {
395395
return this._test('min', limit, function (value, state, options) {
396396

397397
if (value.length >= limit) {
398-
return null;
398+
return value;
399399
}
400400

401401
return this.createError('array.min', { limit, value }, state, options);
@@ -409,7 +409,7 @@ internals.Array = class extends Any {
409409
return this._test('max', limit, function (value, state, options) {
410410

411411
if (value.length <= limit) {
412-
return null;
412+
return value;
413413
}
414414

415415
return this.createError('array.max', { limit, value }, state, options);
@@ -423,7 +423,7 @@ internals.Array = class extends Any {
423423
return this._test('length', limit, function (value, state, options) {
424424

425425
if (value.length === limit) {
426-
return null;
426+
return value;
427427
}
428428

429429
return this.createError('array.length', { limit, value }, state, options);
@@ -475,7 +475,7 @@ internals.Array = class extends Any {
475475
}
476476
}
477477

478-
return null;
478+
return value;
479479
});
480480
}
481481

lib/binary.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ internals.Binary = class extends Any {
5555
return this._test('min', limit, function (value, state, options) {
5656

5757
if (value.length >= limit) {
58-
return null;
58+
return value;
5959
}
6060

6161
return this.createError('binary.min', { limit, value }, state, options);
@@ -69,7 +69,7 @@ internals.Binary = class extends Any {
6969
return this._test('max', limit, function (value, state, options) {
7070

7171
if (value.length <= limit) {
72-
return null;
72+
return value;
7373
}
7474

7575
return this.createError('binary.max', { limit, value }, state, options);
@@ -83,7 +83,7 @@ internals.Binary = class extends Any {
8383
return this._test('length', limit, function (value, state, options) {
8484

8585
if (value.length === limit) {
86-
return null;
86+
return value;
8787
}
8888

8989
return this.createError('binary.length', { limit, value }, state, options);

lib/date.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ internals.compare = function (type, compare) {
176176
}
177177

178178
if (compare(value.getTime(), compareTo)) {
179-
return null;
179+
return value;
180180
}
181181

182182
return this.createError('date.' + type, { limit: new Date(compareTo) }, state, options);

lib/errors.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ internals.stringify = function (value, wrapArrays) {
2222
return value;
2323
}
2424

25-
if (value instanceof internals.Err || type === 'function') {
25+
if (value instanceof exports.Err || type === 'function') {
2626
return value.toString();
2727
}
2828

@@ -43,7 +43,7 @@ internals.stringify = function (value, wrapArrays) {
4343
return JSON.stringify(value);
4444
};
4545

46-
internals.Err = class {
46+
exports.Err = class {
4747

4848
constructor(type, context, state, options, flags) {
4949

@@ -97,7 +97,7 @@ internals.Err = class {
9797

9898
exports.create = function (type, context, state, options, flags) {
9999

100-
return new internals.Err(type, context, state, options, flags);
100+
return new exports.Err(type, context, state, options, flags);
101101
};
102102

103103

lib/index.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
const Hoek = require('hoek');
66
const Any = require('./any');
77
const Cast = require('./cast');
8+
const Errors = require('./errors');
89
const Lazy = require('./lazy');
910
const Ref = require('./ref');
1011

@@ -151,7 +152,7 @@ internals.root = function () {
151152

152153
root.reach = function (schema, path) {
153154

154-
Hoek.assert(schema && schema.isJoi, 'you must provide a joi schema');
155+
Hoek.assert(schema && schema instanceof Any, 'you must provide a joi schema');
155156
Hoek.assert(typeof path === 'string', 'path must be a string');
156157

157158
if (path === '') {
@@ -218,12 +219,11 @@ internals.root = function () {
218219
let ret;
219220
if (extension.coerce) {
220221
ret = extension.coerce.call(this, value, state, options);
221-
if (ret && ret.isJoi) {
222+
if (ret instanceof Errors.Err) {
222223
return { value, errors: ret };
223224
}
224-
else if (ret !== null) {
225-
value = ret;
226-
}
225+
226+
value = ret;
227227
}
228228

229229
if (ctor.prototype._base) {
@@ -238,12 +238,11 @@ internals.root = function () {
238238

239239
if (extension.pre) {
240240
ret = extension.pre.call(this, value, state, options);
241-
if (ret && ret.isJoi) {
241+
if (ret instanceof Errors.Err) {
242242
return { value, errors: ret };
243243
}
244-
else if (ret !== null) {
245-
return { value: ret };
246-
}
244+
245+
return { value: ret };
247246
}
248247

249248
return { value };

lib/number.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ internals.Number = class extends Any {
6969
}
7070

7171
if (value % divisor === 0) {
72-
return null;
72+
return value;
7373
}
7474

7575
return this.createError('number.multiple', { multiple: base, value }, state, options);
@@ -80,7 +80,7 @@ internals.Number = class extends Any {
8080

8181
return this._test('integer', undefined, function (value, state, options) {
8282

83-
return Hoek.isInteger(value) ? null : this.createError('number.integer', { value }, state, options);
83+
return Hoek.isInteger(value) ? value : this.createError('number.integer', { value }, state, options);
8484
});
8585
}
8686

@@ -89,7 +89,7 @@ internals.Number = class extends Any {
8989
return this._test('negative', undefined, function (value, state, options) {
9090

9191
if (value < 0) {
92-
return null;
92+
return value;
9393
}
9494

9595
return this.createError('number.negative', { value }, state, options);
@@ -101,7 +101,7 @@ internals.Number = class extends Any {
101101
return this._test('positive', undefined, function (value, state, options) {
102102

103103
if (value > 0) {
104-
return null;
104+
return value;
105105
}
106106

107107
return this.createError('number.positive', { value }, state, options);
@@ -118,7 +118,7 @@ internals.Number = class extends Any {
118118
const places = value.toString().match(internals.precisionRx);
119119
const decimals = Math.max((places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0), 0);
120120
if (decimals <= limit) {
121-
return null;
121+
return value;
122122
}
123123

124124
return this.createError('number.precision', { limit, value }, state, options);
@@ -155,7 +155,7 @@ internals.compare = function (type, compare) {
155155
}
156156

157157
if (compare(value, compareTo)) {
158-
return null;
158+
return value;
159159
}
160160

161161
return this.createError('number.' + type, { limit: compareTo, value }, state, options);

0 commit comments

Comments
 (0)