Socket
Socket
Sign inDemoInstall

joi

Package Overview
Dependencies
Maintainers
4
Versions
238
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

joi - npm Package Compare versions

Comparing version 2.9.0 to 3.0.0

lib/language.js

26

lib/alternatives.js
// Load modules
var Hoek = require('hoek');
var Any = require('./any');
var Cast = require('./cast');
var Errors = require('./errors');
var Utils = require('./utils');

@@ -21,6 +21,6 @@

Utils.assert(alternatives && alternatives.length, 'Missing alternatives');
Utils.assert(alternatives.length > 1, 'Alternatives require more than one');
Hoek.assert(alternatives && alternatives.length, 'Missing alternatives');
Hoek.assert(alternatives.length > 1, 'Alternatives require more than one');
this._alternatives = alternatives;
this._inner = alternatives;

@@ -33,3 +33,3 @@ this._base(function (value, state, options) {

Utils.inherits(internals.Alternatives, Any);
Hoek.inherits(internals.Alternatives, Any);

@@ -39,6 +39,6 @@

var alt = new internals.Alternatives(Utils.flatten(Array.prototype.slice.call(arguments)));
var alt = new internals.Alternatives(Hoek.flatten(Array.prototype.slice.call(arguments)));
for (var i = 0, il = alt._alternatives.length; i < il; ++i) {
alt.allow(Cast.schema(alt._alternatives[i])._valids.values());
for (var i = 0, il = alt._inner.length; i < il; ++i) {
alt._allow(Cast.schema(alt._inner[i])._valids.values());
}

@@ -50,3 +50,3 @@

internals.Alternatives._create = function (/* alternatives */) {
internals.Alternatives._create = function (/* alternatives */) { // Used to cast []

@@ -63,4 +63,4 @@ var alt = internals.Alternatives.create.apply(null, arguments);

var errors = [];
for (var i = 0, il = this._alternatives.length; i < il; ++i) {
var err = Cast.schema(this._alternatives[i])._validate(value, state, options);
for (var i = 0, il = this._inner.length; i < il; ++i) {
var err = Cast.schema(this._inner[i])._validate(value, state, options);
if (!err) { // Found a valid match

@@ -80,4 +80,4 @@ return null;

var descriptions = [];
for (var i = 0, il = this._alternatives.length; i < il; ++i) {
descriptions.push(Cast.schema(this._alternatives[i]).describe());
for (var i = 0, il = this._inner.length; i < il; ++i) {
descriptions.push(Cast.schema(this._inner[i]).describe());
}

@@ -84,0 +84,0 @@

@@ -5,4 +5,5 @@ // Load modules

var Path = require('path');
var Hoek = require('hoek');
var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -19,9 +20,6 @@

modify: false,
allowUnknown: false,
skipFunctions: false,
stripUnknown: false,
language: {},
languagePath: Path.join(__dirname, '..', 'languages', 'en-us.json')
language: {}
};

@@ -41,3 +39,4 @@

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
};

@@ -48,2 +47,4 @@

this._tags = [];
this._inner = null; // Immutable
};

@@ -58,2 +59,30 @@

internals.Any.prototype.clone = function () {
var obj = {};
obj.__proto__ = Object.getPrototypeOf(this);
obj._type = this._type;
obj._settings = Hoek.clone(this._settings);
obj._tests = this._tests.slice();
obj._dependencies = this._dependencies.slice();
obj._mutators = this._mutators.slice();
obj._valids = Hoek.clone(this._valids);
obj._invalids = Hoek.clone(this._invalids);
obj._flags = {
insensitive: this._flags.insensitive,
allowOnly: this._flags.allowOnly,
default: this._flags.default
};
obj._description = this._description;
obj._notes = this._notes.slice();
obj._tags = this._tags.slice();
obj._inner = this._inner;
return obj;
};
internals.Any.prototype._base = function (func) {

@@ -67,3 +96,5 @@

this._tests.push({ func: func, name: name, arg: arg });
var obj = this.clone();
obj._tests.push({ func: func, name: name, arg: arg });
return obj;
};

@@ -74,3 +105,5 @@

this._dependencies.push({ func: func, name: name, arg: arg });
var obj = this.clone();
obj._dependencies.push({ func: func, name: name, arg: arg });
return obj;
};

@@ -81,3 +114,5 @@

this._mutators.push(value);
var obj = this.clone();
obj._mutators.push(value);
return obj;
};

@@ -88,4 +123,5 @@

this._settings = Utils.applyToDefaults(this._settings || {}, options);
return this;
var obj = this.clone();
obj._settings = Hoek.applyToDefaults(obj._settings || {}, options);
return obj;
};

@@ -96,13 +132,17 @@

this._settings = this._settings || {};
this._settings.convert = false;
return this;
var obj = this.clone();
obj._settings = obj._settings || {};
obj._settings.convert = false;
return obj;
};
internals.Any.prototype._allow = function (value) {
internals.Any.prototype._allow = function () {
this._invalids.remove(value);
this._valids.add(value);
return this;
var values = Hoek.flatten(Array.prototype.slice.call(arguments));
for (var i = 0, il = values.length; i < il; ++i) {
var value = values[i];
this._invalids.remove(value);
this._valids.add(value);
}
};

@@ -113,8 +153,5 @@

var values = Utils.flatten(Array.prototype.slice.call(arguments));
for (var i = 0, il = values.length; i < il; ++i) {
this._allow(values[i]);
}
return this;
var obj = this.clone();
obj._allow.apply(obj, arguments);
return obj;
};

@@ -125,24 +162,19 @@

this.allow.apply(this, arguments);
this._flags.allowOnly = true;
return this;
var obj = this.allow.apply(this, arguments);
obj._flags.allowOnly = true;
return obj;
};
internals.Any.prototype._deny = function (value) {
internals.Any.prototype.invalid = function (value) {
this._valids.remove(value);
this._invalids.add(value);
return this;
};
internals.Any.prototype.invalid = internals.Any.prototype.deny = function (value) {
var values = Utils.flatten(Array.prototype.slice.call(arguments));
var obj = this.clone();
var values = Hoek.flatten(Array.prototype.slice.call(arguments));
for (var i = 0, il = values.length; i < il; ++i) {
this._deny(values[i]);
var value = values[i];
obj._valids.remove(value);
obj._invalids.add(value);
}
return this;
return obj;
};

@@ -153,4 +185,6 @@

this._deny(undefined);
return this;
var obj = this.clone();
obj._valids.remove(undefined);
obj._invalids.add(undefined);
return obj;
};

@@ -161,23 +195,17 @@

this._invalids.remove(undefined);
this._valids.add(undefined);
return this;
var obj = this.clone();
obj._invalids.remove(undefined);
obj._valids.add(undefined);
return obj;
};
internals.Any.prototype.nullOk = function () {
this._allow(null);
return this;
};
internals.Any.prototype.with = function () {
var peers = Utils.flatten(Array.prototype.slice.call(arguments));
var peers = Hoek.flatten(Array.prototype.slice.call(arguments));
for (var i = 0, li = peers.length; i < li; i++) {
Utils.assert(typeof peers[i] === 'string', 'peers must be a string');
Hoek.assert(typeof peers[i] === 'string', 'peers must be a string');
}
this._dependency('with', peers, function (value, state, options) {
return this._dependency('with', peers, function (value, state, options) {

@@ -202,4 +230,2 @@ if (!state.parent) {

});
return this;
};

@@ -210,8 +236,8 @@

var peers = Utils.flatten(Array.prototype.slice.call(arguments));
var peers = Hoek.flatten(Array.prototype.slice.call(arguments));
for (var i = 0, li = peers.length; i < li; i++) {
Utils.assert(typeof peers[i] === 'string', 'peers must be strings');
Hoek.assert(typeof peers[i] === 'string', 'peers must be strings');
}
this._dependency('without', peers, function (value, state, options) {
return this._dependency('without', peers, function (value, state, options) {

@@ -237,4 +263,2 @@ if (!state.parent) {

});
return this;
};

@@ -245,5 +269,5 @@

var peers = Utils.flatten(Array.prototype.slice.call(arguments));
var peers = Hoek.flatten(Array.prototype.slice.call(arguments));
this._dependency('xor', peers, function (value, state, options) {
return this._dependency('xor', peers, function (value, state, options) {

@@ -275,4 +299,2 @@ if (!state.parent) {

});
return this;
};

@@ -283,8 +305,8 @@

var peers = Utils.flatten(Array.prototype.slice.call(arguments));
var peers = Hoek.flatten(Array.prototype.slice.call(arguments));
for (var i = 0, li = peers.length; i < li; i++) {
Utils.assert(typeof peers[i] === 'string', 'peers must be a string');
Hoek.assert(typeof peers[i] === 'string', 'peers must be a string');
}
this._dependency('or', peers, function (value, state, options) {
return this._dependency('or', peers, function (value, state, options) {

@@ -309,4 +331,2 @@ if (!state.parent) {

});
return this;
};

@@ -323,5 +343,5 @@

renameOptions = Utils.merge(defaults, renameOptions);
renameOptions = Hoek.merge(defaults, renameOptions);
this._mutate(function (value, state, options) {
return this._mutate(function (value, state, options) {

@@ -354,4 +374,2 @@ if (!state.parent) {

});
return this;
};

@@ -362,4 +380,5 @@

this._flags.default = value;
return this;
var obj = this.clone();
obj._flags.default = value;
return obj;
};

@@ -370,5 +389,7 @@

Utils.assert(typeof desc === 'string', 'Description must be a string');
this._description = desc || '';
return this;
Hoek.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');
var obj = this.clone();
obj._description = desc;
return obj;
};

@@ -379,5 +400,7 @@

Utils.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a string or array');
this._notes = this._notes.concat(notes || '');
return this;
Hoek.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');
var obj = this.clone();
obj._notes = obj._notes.concat(notes);
return obj;
};

@@ -388,5 +411,7 @@

Utils.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a string or array');
this._tags = this._tags.concat(tags || '');
return this;
Hoek.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');
var obj = this.clone();
obj._tags = obj._tags.concat(tags);
return obj;
};

@@ -404,3 +429,3 @@

if (this._settings) {
options = Utils.applyToDefaults(options, this._settings);
options = Hoek.applyToDefaults(options, this._settings);
}

@@ -473,3 +498,4 @@

for (i = 0, il = self._tests.length; i < il; ++i) {
var err = self._tests[i].func(value, state, options);
var test = self._tests[i];
var err = test.func(value, state, options);
if (err) {

@@ -483,3 +509,5 @@ if (Array.isArray(err)) {

if (options.abortEarly) {
if (!test.name || // Base test error always stops
options.abortEarly) {
return errors;

@@ -522,5 +550,5 @@ }

var settings = Utils.applyToDefaults(internals.defaults, options || {});
var settings = Hoek.applyToDefaults(internals.defaults, options || {});
Utils.assert(!settings.modify || settings.convert, 'Cannot save and skip conversions at the same time');
Hoek.assert(!settings.modify || settings.convert, 'Cannot save and skip conversions at the same time');

@@ -597,6 +625,4 @@ var errors = this._validate(object, null, settings);

if (values) {
for (var i = 0, il = values.length; i < il; ++i) {
this.add(values[i]);
}
for (var i = 0, il = values.length; i < il; ++i) {
this.add(values[i]);
}

@@ -603,0 +629,0 @@ };

@@ -6,3 +6,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -30,3 +30,3 @@

Utils.inherits(internals.Array, Any);
Hoek.inherits(internals.Array, Any);

@@ -67,5 +67,5 @@

var inclusions = Utils.flatten(Array.prototype.slice.call(arguments));
var inclusions = Hoek.flatten(Array.prototype.slice.call(arguments));
this._test('includes', inclusions, function (value, state, options) {
return this._test('includes', inclusions, function (value, state, options) {

@@ -96,4 +96,2 @@ for (var v = 0, vl = value.length; v < vl; ++v) {

});
return this;
};

@@ -104,5 +102,5 @@

var exclusions = Utils.flatten(Array.prototype.slice.call(arguments));
var exclusions = Hoek.flatten(Array.prototype.slice.call(arguments));
this._test('excludes', exclusions, function (value, state, options) {
return this._test('excludes', exclusions, function (value, state, options) {

@@ -121,4 +119,2 @@ for (var v = 0, vl = value.length; v < vl; ++v) {

});
return this;
};

@@ -129,7 +125,7 @@

Utils.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
Hoek.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
this._test('min', limit, function (value, state, options) {
return this._test('min', limit, function (value, state, options) {
if (value && value.length >= limit) {
if (value.length >= limit) {
return null;

@@ -140,4 +136,2 @@ }

});
return this;
};

@@ -148,7 +142,7 @@

Utils.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
Hoek.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
this._test('max', limit, function (value, state, options) {
return this._test('max', limit, function (value, state, options) {
if (value && value.length <= limit) {
if (value.length <= limit) {
return null;

@@ -159,4 +153,2 @@ }

});
return this;
};

@@ -167,7 +159,7 @@

Utils.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
Hoek.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
this._test('length', limit, function (value, state, options) {
return this._test('length', limit, function (value, state, options) {
if (value && value.length === limit) {
if (value.length === limit) {
return null;

@@ -178,4 +170,2 @@ }

});
return this;
};

@@ -5,3 +5,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -21,3 +21,3 @@

if (value === null || typeof value === 'boolean') {
if (typeof value === 'boolean') {
return null;

@@ -30,3 +30,3 @@ }

Utils.inherits(internals.Boolean, Any);
Hoek.inherits(internals.Boolean, Any);

@@ -33,0 +33,0 @@

// Load modules
var Utils = require('./utils');
var Hoek = require('hoek');
// Object and Alternatives are delayed loaded

@@ -17,3 +17,3 @@

Utils.assert(typeof config === 'object', 'Schema must be an object');
Hoek.assert(typeof config === 'object', 'Schema must be an object');

@@ -20,0 +20,0 @@ internals.Object = internals.Object || require('./object');

@@ -5,3 +5,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -29,3 +29,3 @@

Utils.inherits(internals.Date, Any);
Hoek.inherits(internals.Date, Any);

@@ -64,5 +64,5 @@

date = internals.toDate(date);
Utils.assert(date, 'Invalid date format');
Hoek.assert(date, 'Invalid date format');
this._test('min', date, function (value, state, options) {
return this._test('min', date, function (value, state, options) {

@@ -75,4 +75,2 @@ if (value.getTime() >= date.getTime()) {

});
return this;
};

@@ -84,5 +82,5 @@

date = internals.toDate(date);
Utils.assert(date, 'Invalid date format');
Hoek.assert(date, 'Invalid date format');
this._test('max', date, function (value, state, options) {
return this._test('max', date, function (value, state, options) {

@@ -95,4 +93,2 @@ if (value.getTime() <= date.getTime()) {

});
return this;
};
// Load modules
var Utils = require('./utils');
var Hoek = require('hoek');
var Language = require('./language');

@@ -25,6 +26,4 @@

var localized = this.options.language || {};
var language = require(this.options.languagePath);
var format = Utils.reach(localized, this.type) || Utils.reach(language, this.type);
var localized = this.options.language;
var format = Hoek.reach(localized, this.type) || Hoek.reach(Language.errors, this.type);
if (!format) {

@@ -36,3 +35,3 @@ return this.context.key;

return Utils.reach(self.context, name).toString();
return Hoek.reach(self.context, name).toString();
});

@@ -73,3 +72,3 @@ };

Utils.inherits(internals.ValidationError, Error);
Hoek.inherits(internals.ValidationError, Error);

@@ -93,3 +92,3 @@

var obj = Utils.clone(this._object || {});
var obj = Hoek.clone(this._object || {});

@@ -103,3 +102,6 @@ var el = this.details.length;

var seg = path[i];
if (i + 1 === il) {
if (i + 1 < il) {
ref = ref[seg];
}
else {
var value = ref[seg];

@@ -113,7 +115,3 @@ if (value !== undefined) {

}
break;
}
ref = ref[seg];
}

@@ -120,0 +118,0 @@ }

@@ -5,3 +5,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -29,3 +29,3 @@

Utils.inherits(internals.Function, Any);
Hoek.inherits(internals.Function, Any);

@@ -32,0 +32,0 @@

// Load modules
var Utils = require('./utils');
var Hoek = require('hoek');
var Any = require('./any');

@@ -24,27 +24,2 @@ var Cast = require('./cast');

exports.types = exports.Types = {
any: exports.any,
alternatives: exports.alternatives,
array: exports.array,
boolean: exports.boolean,
date: exports.date,
func: exports.func,
number: exports.number,
object: exports.object,
string: exports.string
};
// Backwards compatibility
exports.types.Any = exports.types.any;
exports.types.Array = exports.types.array;
exports.types.Boolean = exports.types.boolean;
exports.types.Date = exports.types.date;
exports.types.Function = exports.types.func;
exports.types.Number = exports.types.number;
exports.types.Object = exports.types.object;
exports.types.String = exports.types.string;
exports.validate = function (object, schema, options) {

@@ -65,3 +40,3 @@

Utils.assert(typeof schema === 'object', 'Schema must be an object');
Hoek.assert(typeof schema === 'object', 'Schema must be an object');

@@ -68,0 +43,0 @@ if (typeof schema.describe === 'function') {

@@ -5,3 +5,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -21,3 +21,3 @@

if ((typeof value === 'number' || typeof value === 'string') && !isNaN(+value)) {
if (typeof value === 'number' && !isNaN(value)) {
return null;

@@ -30,3 +30,3 @@ }

Utils.inherits(internals.Number, Any);
Hoek.inherits(internals.Number, Any);

@@ -41,2 +41,3 @@

internals.Number.prototype._convert = function (value) {
if (typeof value === 'string') {

@@ -57,7 +58,7 @@ var number = parseFloat(value);

Utils.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
Hoek.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
this._test('min', limit, function (value, state, options) {
return this._test('min', limit, function (value, state, options) {
if (isNaN(value) || value >= limit) {
if (value >= limit) {
return null;

@@ -68,4 +69,2 @@ }

});
return this;
};

@@ -76,5 +75,5 @@

Utils.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
Hoek.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
this._test('max', limit, function (value, state, options) {
return this._test('max', limit, function (value, state, options) {

@@ -87,4 +86,2 @@ if (value <= limit) {

});
return this;
};

@@ -95,5 +92,5 @@

this._test('integer', undefined, function (value, state, options) {
return this._test('integer', undefined, function (value, state, options) {
if (!isNaN(value) && ((value | 0) === parseFloat(value))) {
if ((value | 0) === parseFloat(value)) {
return null;

@@ -104,4 +101,2 @@ }

});
return this;
};

@@ -112,3 +107,3 @@

this._test('negative', undefined, function (value, state, options) {
return this._test('negative', undefined, function (value, state, options) {

@@ -121,4 +116,2 @@ if (value < 0) {

});
return this;
};

@@ -129,3 +122,3 @@

this._test('positive', undefined, function (value, state, options) {
return this._test('positive', undefined, function (value, state, options) {

@@ -138,4 +131,2 @@ if (value > 0) {

});
return this;
};

@@ -6,3 +6,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -21,17 +21,18 @@

this._type = 'object';
this._children = schema;
this._inner = schema;
this._base(function (value, state, options) {
if (typeof value !== 'object' ||
Array.isArray(value)) {
if (value &&
typeof value === 'object' &&
!Array.isArray(value)) {
return Errors.create('object.base', null, state, options);
return self._traverse(value, state, options);
}
return self._traverse(value, state, options);
return Errors.create('object.base', null, state, options);
});
};
Utils.inherits(internals.Object, Any);
Hoek.inherits(internals.Object, Any);

@@ -66,9 +67,9 @@

if (this._children) {
if (this._inner) {
description.children = {};
var children = Object.keys(this._children);
var children = Object.keys(this._inner);
for (var c = 0, cl = children.length; c < cl; ++c) {
var key = children[c];
var child = this._children[key];
var child = this._inner[key];
description.children[key] = Cast.schema(child).describe();

@@ -84,10 +85,7 @@ }

Utils.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
Hoek.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
this._test('length', limit, function (value, state, options) {
return this._test('length', limit, function (value, state, options) {
if (value !== null &&
value !== undefined &&
Object.keys(value).length === limit) {
if (Object.keys(value).length === limit) {
return null;

@@ -98,4 +96,2 @@ }

});
return this;
};

@@ -106,10 +102,7 @@

Utils.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
Hoek.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
this._test('min', limit, function (value, state, options) {
return this._test('min', limit, function (value, state, options) {
if (value !== null &&
value !== undefined &&
Object.keys(value).length >= limit) {
if (Object.keys(value).length >= limit) {
return null;

@@ -120,4 +113,2 @@ }

});
return this;
};

@@ -128,10 +119,7 @@

Utils.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
Hoek.assert((!isNaN(limit) && ((limit | 0) === parseFloat(limit))), 'limit must be an integer');
this._test('max', limit, function (value, state, options) {
return this._test('max', limit, function (value, state, options) {
if (value !== null &&
value !== undefined &&
Object.keys(value).length <= limit) {
if (Object.keys(value).length <= limit) {
return null;

@@ -142,4 +130,2 @@ }

});
return this;
};

@@ -150,8 +136,8 @@

if (!this._children) { // Object() null allows any keys
if (!this._inner) { // Object() null allows any keys
return null;
}
var keys = Object.keys(this._children);
var unprocessed = Utils.mapToObject(Object.keys(value));
var keys = Object.keys(this._inner);
var unprocessed = Hoek.mapToObject(Object.keys(value));
var errors = [];

@@ -162,3 +148,3 @@ var key;

key = keys[i];
var child = this._children[key];
var child = this._inner[key];
var item = value[key];

@@ -165,0 +151,0 @@

@@ -5,3 +5,3 @@ // Load modules

var Errors = require('./errors');
var Utils = require('./utils');
var Hoek = require('hoek');

@@ -22,5 +22,4 @@

if (typeof value === 'string' ||
value === null ||
value === undefined) {
if (value &&
typeof value === 'string') {

@@ -34,3 +33,3 @@ return null;

Utils.inherits(internals.String, Any);
Hoek.inherits(internals.String, Any);

@@ -44,13 +43,7 @@

internals.String.prototype.emptyOk = function () {
this._allow('');
return this;
};
internals.String.prototype.insensitive = function () {
this._flags.insensitive = true;
return this;
var obj = this.clone();
obj._flags.insensitive = true;
return obj;
};

@@ -61,9 +54,7 @@

Utils.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
Hoek.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
this._test('min', limit, function (value, state, options) {
return this._test('min', limit, function (value, state, options) {
if (typeof value === 'string' &&
value.length >= limit) {
if (value.length >= limit) {
return null;

@@ -74,4 +65,2 @@ }

});
return this;
};

@@ -82,9 +71,7 @@

Utils.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
Hoek.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
this._test('max', limit, function (value, state, options) {
return this._test('max', limit, function (value, state, options) {
if (!value ||
value.length <= limit) {
if (value.length <= limit) {
return null;

@@ -95,4 +82,2 @@ }

});
return this;
};

@@ -103,9 +88,7 @@

Utils.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
Hoek.assert(!isNaN(limit) && ((limit | 0) === parseFloat(limit)) && limit >= 0, 'limit must be a positive integer');
this._test('length', limit, function (value, state, options) {
return this._test('length', limit, function (value, state, options) {
if (typeof value === 'string' &&
value.length === limit) {
if (value.length === limit) {
return null;

@@ -116,4 +99,2 @@ }

});
return this;
};

@@ -124,9 +105,7 @@

Utils.assert(pattern instanceof RegExp, 'pattern must be a RegExp');
Hoek.assert(pattern instanceof RegExp, 'pattern must be a RegExp');
this._test('regex', pattern, function (value, state, options) {
return this._test('regex', pattern, function (value, state, options) {
if (typeof value === 'string' &&
value.match(pattern)) {
if (value.match(pattern)) {
return null;

@@ -137,4 +116,2 @@ }

});
return this;
};

@@ -145,7 +122,5 @@

this._test('alphanum', undefined, function (value, state, options) {
return this._test('alphanum', undefined, function (value, state, options) {
if (typeof value === 'string' &&
value.match(/^[a-zA-Z0-9]+$/)) {
if (value.match(/^[a-zA-Z0-9]+$/)) {
return null;

@@ -156,4 +131,2 @@ }

});
return this;
};

@@ -164,7 +137,5 @@

this._test('token', undefined, function (value, state, options) {
return this._test('token', undefined, function (value, state, options) {
if (typeof value === 'string' &&
value.match(/^\w+$/)) {
if (value.match(/^\w+$/)) {
return null;

@@ -175,4 +146,2 @@ }

});
return this;
};

@@ -185,7 +154,5 @@

this._test('email', undefined, function (value, state, options) {
return this._test('email', undefined, function (value, state, options) {
if (typeof value === 'string' &&
value.match(regex)) {
if (value.match(regex)) {
return null;

@@ -196,4 +163,2 @@ }

});
return this;
};

@@ -206,7 +171,5 @@

this._test('isoDate', undefined, function (value, state, options) {
return this._test('isoDate', undefined, function (value, state, options) {
if (typeof value === 'string' &&
value.match(regex)) {
if (value.match(regex)) {
return null;

@@ -217,4 +180,2 @@ }

});
return this;
};

@@ -228,7 +189,5 @@

this._test('guid', undefined, function (value, state, options) {
return this._test('guid', undefined, function (value, state, options) {
if (typeof value === 'string' &&
value.match(regex) || value.match(regex2)) {
if (value.match(regex) || value.match(regex2)) {
return null;

@@ -239,4 +198,2 @@ }

});
return this;
};
{
"name": "joi",
"description": "Object schema validation",
"version": "2.9.0",
"version": "3.0.0",
"repository": "git://github.com/spumko/joi",

@@ -15,6 +15,6 @@ "main": "index",

"dependencies": {
"hoek": "1.x.x"
"hoek": "2.x.x"
},
"devDependencies": {
"lab": "1.x.x"
"lab": "3.x.x"
},

@@ -21,0 +21,0 @@ "scripts": {

@@ -6,3 +6,3 @@ <a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a>

Current version: **2.9.x**
Current version: **3.0.x**

@@ -60,2 +60,4 @@ [![Build Status](https://secure.travis-ci.org/spumko/joi.png)](http://travis-ci.org/spumko/joi)

- [`string.email()`](#stringemail)
- [`string.guid()`](#stringguid)
- [`string.isoDate()`](#stringisodate)
- [`alternatives(types)`](#alternativestypes)

@@ -108,2 +110,5 @@ - [Migration notes](#migration-notes)

Note that **joi** schema objects are immutable which means every additional rule added (e.g. `.min(5)`) will return a
new schema object.
Then the value is validated against the schema:

@@ -143,11 +148,9 @@

- `options` - an optional object with the following optional keys:
- `abortEarly` - when `true`, stops validation on the first error, otherwise returns all the errors found. Defaults to `true`.
- `convert` - when `true`, attempts to cast values to the required types (e.g. a string to a number). Defaults to `true`.
- `modify` - when `true`, converted values are written back to the provided value (only when value is an object). Defaults to `false`.
- `allowUnknown` - when `true`, allows object to contain unknown keys which are ignored. Defaults to `false`.
- `skipFunctions` - when `true`, ignores unknown keys with a function value. Defaults to `false`.
- `stripUnknown` - when `true`, unknown keys are deleted (only when value is an object). Defaults to `false`.
- `language` - a localized langugage object using the format of the `languagePath` file. Error formats are looked up in the `language`
object first, and then in the `languagePath` file. Defaults to no override (`{}`).
- `languagePath` - the location of the language file used to localize error messages. Defaults to `'languages/en-us.json'`.
- `abortEarly` - when `true`, stops validation on the first error, otherwise returns all the errors found. Defaults to `true`.
- `convert` - when `true`, attempts to cast values to the required types (e.g. a string to a number). Defaults to `true`.
- `modify` - when `true`, converted values are written back to the provided value (only when value is an object). Defaults to `false`.
- `allowUnknown` - when `true`, allows object to contain unknown keys which are ignored. Defaults to `false`.
- `skipFunctions` - when `true`, ignores unknown keys with a function value. Defaults to `false`.
- `stripUnknown` - when `true`, unknown keys are deleted (only when value is an object). Defaults to `false`.
- `language` - overrides individual error messages. Defaults to no override (`{}`).

@@ -294,3 +297,3 @@ ```javascript

#### `description(desc)`
#### `any.description(desc)`

@@ -688,34 +691,1 @@ Annotates the key where:

of the provided types while when using the `alternatives()` type, the key is optional by default.
# Migration notes
**joi** 2.0 is a complete rewrite of the previous version. While largely backward compatible, it includes a few changes that are
not as well as a large number of bug fixes that dramatically changes existing behavior. The following is an incomplete list of changes.
Please test your existing validation rules to ensure they behave as expected with this new version.
* `Joi.types` and `Joi.Types` deprecated - use `Joi.string()` etc. instead.
* Uppercase type names deprecated - use lowercase function names instead.
* Top level global config options no longer supported (e.g. `{ languagePath: './file.json' }`). Use the `.options()` method instead.
* `noShortCircuit()` no longer supported - use the `abortEarly` option instead.
* Options renamed:
* `saveConversions` changed to `modify`.
* `skipConversions` changed to `convert` (with reversed meaning).
* `stripExtraKeys` changed to `stripUnknown`.
* `allowExtraKeys` changed to `allowUnknown`.
* In `rename()` options:
* `deleteOrig` changed to `move`.
* `allowMult` changed to `multiple`.
* `allowOverwrite` changed to `override`.
* `nullOk()` and `emptyOk()` are deprecated - use `allow(null)` and `allow('')` instead.
* `number().float()` no longer supported.
* Completely new internal representation of the data. If you were accessing _variables, your code is most likely broken now. Use `describe()` instead.
* `string().alphanum()` no longer allows spaces and underscores and does not take an arguement.
* `string().date()` no longer supported - use new `date()` type.
* `deny()` deprecated - use `invalid()` instead.
* `array().includes()` and `array.excludes()` now validates correctly (not just the base type).
* `allow()`, `valid()`, and `invalid()` values are now compared against the original and converted values (not just after conversion).
* `string().min()` no longer implies `required()`.

@@ -262,2 +262,26 @@ // Load modules

describe('#options', function () {
it('adds to existing options', function (done) {
var a = { b: Joi.number().strict().options({ convert: true, modify: true }) };
var c = { b: '2' };
expect(Joi.validate(c, a)).to.not.exist;
expect(c.b).to.equal(2);
done();
});
});
describe('#strict', function () {
it('adds to existing options', function (done) {
var a = { b: Joi.number().options({ convert: true }).strict() };
var c = { b: '2' };
expect(Joi.validate(c, a)).to.exist;
expect(c.b).to.equal('2');
done();
});
});
describe('#default', function () {

@@ -329,4 +353,3 @@

var b = Joi.any();
b.description('my description');
var b = Joi.any().description('my description');
expect(b._description).to.equal('my description');

@@ -336,2 +359,11 @@

});
it('throws when description is missing', function (done) {
expect(function () {
Joi.any().description();
}).to.throw('Description must be a non-empty string');
done();
});
});

@@ -343,8 +375,25 @@

var b = Joi.any();
b.notes('my notes');
expect(b._notes).to.deep.equal(['my notes']);
var b = Joi.any().notes(['a']).notes('my notes');
expect(b._notes).to.deep.equal(['a', 'my notes']);
done();
});
it('throws when notes are missing', function (done) {
expect(function () {
Joi.any().notes();
}).to.throw('Notes must be a non-empty string or array');
done();
});
it('throws when notes are invalid', function (done) {
expect(function () {
Joi.any().notes(5);
}).to.throw('Notes must be a non-empty string or array');
done();
});
});

@@ -356,11 +405,39 @@

var b = Joi.any();
b.tags(['tag1', 'tag2']);
var b = Joi.any().tags(['tag1', 'tag2']).tags('tag3');
expect(b._tags).to.include('tag1');
expect(b._tags).to.include('tag2');
expect(b._tags).to.include('tag3');
done();
});
it('throws when tags are missing', function (done) {
expect(function () {
Joi.any().tags();
}).to.throw('Tags must be a non-empty string or array');
done();
});
it('throws when tags are invalid', function (done) {
expect(function () {
Joi.any().tags(5);
}).to.throw('Tags must be a non-empty string or array');
done();
});
});
describe('#_validate', function () {
it('checks value after conversion', function (done) {
var a = Joi.number().invalid(2);
expect(Joi.validate('2', a, { abortEarly: false })).to.exist;
done();
});
});
describe('Set', function () {

@@ -367,0 +444,0 @@

@@ -117,2 +117,20 @@ // Load modules

});
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.array().min('a');
}).to.throw('limit must be a positive integer');
done();
});
it('throws when limit is not an integer', function (done) {
expect(function () {
Joi.array().min(1.2);
}).to.throw('limit must be a positive integer');
done();
});
});

@@ -131,2 +149,20 @@

});
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.array().max('a');
}).to.throw('limit must be a positive integer');
done();
});
it('throws when limit is not an integer', function (done) {
expect(function () {
Joi.array().max(1.2);
}).to.throw('limit must be a positive integer');
done();
});
});

@@ -145,2 +181,20 @@

});
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.array().length('a');
}).to.throw('limit must be a positive integer');
done();
});
it('throws when limit is not an integer', function (done) {
expect(function () {
Joi.array().length(1.2);
}).to.throw('limit must be a positive integer');
done();
});
});

@@ -147,0 +201,0 @@

@@ -84,5 +84,5 @@ // Load modules

it('should handle work with deny', function (done) {
it('should handle work with invalid', function (done) {
var rule = Joi.boolean().deny(false);
var rule = Joi.boolean().invalid(false);
Validate(rule, [

@@ -96,5 +96,5 @@ ['1234', false],

it('should handle work with deny and nullOk', function (done) {
it('should handle work with invalid and null allowed', function (done) {
var rule = Joi.boolean().deny(false).nullOk();
var rule = Joi.boolean().invalid(false).allow(null);
Validate(rule, [

@@ -108,5 +108,5 @@ ['1234', false],

it('should handle work with allow and deny', function (done) {
it('should handle work with allow and invalid', function (done) {
var rule = Joi.boolean().deny(true).allow(false);
var rule = Joi.boolean().invalid(true).allow(false);
Validate(rule, [

@@ -120,5 +120,5 @@ ['1234', false],

it('should handle work with allow, deny, and nullOk', function (done) {
it('should handle work with allow, invalid, and null allowed', function (done) {
var rule = Joi.boolean().deny(true).allow(false).nullOk();
var rule = Joi.boolean().invalid(true).allow(false).allow(null);
Validate(rule, [

@@ -125,0 +125,0 @@ ['1234', false],

@@ -65,2 +65,22 @@ // Load modules

it('keeps schema immutable', function (done) {
var a = Joi.string();
var b = a.valid('b');
Validate(a, [
['a', true],
['b', true],
[5, false]
]);
Validate(b, [
['a', false],
['b', true],
[5, false]
]);
done();
});
it('validates null', function (done) {

@@ -70,2 +90,4 @@

expect(err).to.exist;
err.annotated();
expect(err.message).to.equal('{\n \u001b[41m\"<root>\"\u001b[0m\u001b[31m [1]: -- missing --\u001b[0m\n}\n\u001b[31m\n[1] the value of <root> is not allowed to be null\u001b[0m');
done();

@@ -238,4 +260,4 @@ });

Joi.object({
mode: Joi.string().valid('required', 'optional', 'try').nullOk()
}).nullOk(),
mode: Joi.string().valid('required', 'optional', 'try').allow(null)
}).allow(null),
Joi.string(),

@@ -268,3 +290,5 @@ Joi.boolean()

auth: Joi.alternatives(
Joi.object({ mode: Joi.string().valid('required', 'optional', 'try').nullOk() }).nullOk(),
Joi.object({
mode: Joi.string().valid('required', 'optional', 'try').allow(null)
}).allow(null),
Joi.string(),

@@ -369,3 +393,3 @@ Joi.boolean()

expect(Joi.validate(true, Joi.boolean().nullOk())).to.be.null;
expect(Joi.validate(true, Joi.boolean().allow(null))).to.be.null;
expect(Joi.validate({ auth: { mode: 'try' } }, Joi.object())).to.be.null;

@@ -464,4 +488,4 @@

auth: Joi.object({
mode: Joi.string().valid('required', 'optional', 'try').nullOk()
}).nullOk()
mode: Joi.string().valid('required', 'optional', 'try').allow(null)
}).allow(null)
};

@@ -994,65 +1018,28 @@

var err = Joi.validate(input, schema, { abortEarly: false, languagePath: Path.join(__dirname, 'languages', 'en-us.json') });
expect(err).to.exist;
expect(err.message).to.equal('19. 18. 16. 14. 15. 7. 7. 11. 3');
done();
});
it('supports custom errors and localized errors when validating types', function (done) {
var schema = {
email: Joi.string().email(),
date: Joi.date(),
alphanum: Joi.string().alphanum(),
min: Joi.string().min(3),
max: Joi.string().max(3),
required: Joi.string().required().without('xor'),
xor: Joi.string().without('required'),
renamed: Joi.string().rename('required').valid('456'),
notEmpty: Joi.string().required()
};
var input = {
email: 'invalid-email',
date: 'invalid-date',
alphanum: '\b\n\f\r\t',
min: 'ab',
max: 'abcd',
required: 'hello',
xor: '123',
renamed: '456',
notEmpty: ''
};
var options = {
abortEarly: false,
language: {
any: {
empty: 'Custome!'
var lang = {
any: {
empty: '3',
without: {
peer: '7'
},
rename: {
override: '11'
}
},
languagePath: Path.join(__dirname, 'languages', 'en-us.json')
date: {
base: '18'
},
string: {
base: '13',
min: '14',
max: '15',
alphanum: '16',
email: '19'
}
};
var err = Joi.validate(input, schema, options);
expect(err).to.exist;
expect(err.message).to.equal('19. 18. 16. 14. 15. 7. 7. 11. Custome!');
done();
});
var err = Joi.validate(input, schema, { abortEarly: false, language: lang });
it('returns key when language file missing item', function (done) {
var input = {
notEmpty: ''
};
var schema = {
notEmpty: Joi.string().required()
};
var err = Joi.validate(input, schema, { languagePath: Path.join(__dirname, 'languages', 'empty.json') });
expect(err).to.exist;
expect(err.message).to.equal('notEmpty');
expect(err.message).to.equal('19. 18. 16. 14. 15. 7. 7. 11. 3. 13');
done();

@@ -1111,3 +1098,3 @@ });

err.annotated();
expect(err.message).to.equal('{\n \"y\": {\n \"b\" \u001b[31m[5]\u001b[0m: {\n \"c\": 10\n },\n \u001b[41m\"b\"\u001b[0m\u001b[31m [4]: -- missing --\u001b[0m,\n \u001b[41m\"u\"\u001b[0m\u001b[31m [3]: -- missing --\u001b[0m,\n \u001b[41m\"u\"\u001b[0m\u001b[31m [2]: -- missing --\u001b[0m\n },\n \"a\" \u001b[31m[1]\u001b[0m: \"m\"\n}\n\u001b[31m\n[1] the value of a must be one of a, b, c, d\n[2] the value of u is not allowed to be undefined\n[3] the value of u must be one of e, f, g, h\n[4] the value of b must be one of i, j, false\n[5] the value of b must be a string\u001b[0m');
expect(err.message).to.equal('{\n \"y\": {\n \"b\" \u001b[31m[6]\u001b[0m: {\n \"c\": 10\n },\n \u001b[41m\"b\"\u001b[0m\u001b[31m [5]: -- missing --\u001b[0m,\n \u001b[41m\"u\"\u001b[0m\u001b[31m [4]: -- missing --\u001b[0m,\n \u001b[41m\"u\"\u001b[0m\u001b[31m [3]: -- missing --\u001b[0m,\n \u001b[41m\"u\"\u001b[0m\u001b[31m [2]: -- missing --\u001b[0m\n },\n \"a\" \u001b[31m[1]\u001b[0m: \"m\"\n}\n\u001b[31m\n[1] the value of a must be one of a, b, c, d\n[2] the value of u is not allowed to be undefined\n[3] the value of u must be one of e, f, g, h\n[4] the value of u must be a string\n[5] the value of b must be one of i, j, false\n[6] the value of b must be a string\u001b[0m');
done();

@@ -1138,3 +1125,4 @@ });

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1148,3 +1136,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1158,3 +1147,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1169,3 +1159,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1179,3 +1170,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1189,3 +1181,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1205,3 +1198,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1215,3 +1209,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1227,3 +1222,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1238,3 +1234,4 @@ valids: [undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1248,3 +1245,4 @@ invalids: [null, '', undefined],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},

@@ -1259,3 +1257,4 @@ valids: [undefined],

insensitive: false,
allowOnly: true
allowOnly: true,
default: undefined
},

@@ -1269,8 +1268,9 @@ valids: [undefined, '456'],

insensitive: false,
allowOnly: false
allowOnly: false,
default: undefined
},
invalids: [null, '', undefined],
description: 'a',
notes: ['b'],
tags: ['c']
tags: ['c'],
invalids: [null, '', undefined]
}

@@ -1293,3 +1293,10 @@ }

});
it('describes schema without invalids', function (done) {
var description = Joi.describe(Joi.any().allow(null));
expect(description.invalids).to.not.exist;
done();
})
});
});

@@ -44,3 +44,3 @@ // Load modules

var text = Joi.number().deny(50);
var text = Joi.number().invalid(50);
var result = text.validate(50);

@@ -130,5 +130,5 @@ expect(result).to.exist;

it('should handle combination of min, max, and nullOk', function (done) {
it('should handle combination of min, max, and null allowed', function (done) {
var rule = Joi.number().min(8).max(10).nullOk();
var rule = Joi.number().min(8).max(10).allow(null);
Validate(rule, [

@@ -218,5 +218,5 @@ [1, false],

it('should handle combination of positive, allow, and nullOk', function (done) {
it('should handle combination of positive, allow, and null allowed', function (done) {
var rule = Joi.number().positive().allow(-1).nullOk();
var rule = Joi.number().positive().allow(-1).allow(null);
Validate(rule, [

@@ -232,5 +232,5 @@ [1, true],

it('should handle combination of negative, allow, and nullOk', function (done) {
it('should handle combination of negative, allow, and null allowed', function (done) {
var rule = Joi.number().negative().allow(1).nullOk();
var rule = Joi.number().negative().allow(1).allow(null);
Validate(rule, [

@@ -246,5 +246,5 @@ [1, true],

it('should handle combination of positive, allow, nullOk, and deny', function (done) {
it('should handle combination of positive, allow, null allowed, and invalid', function (done) {
var rule = Joi.number().positive().allow(-1).nullOk().deny(1);
var rule = Joi.number().positive().allow(-1).allow(null).invalid(1);
Validate(rule, [

@@ -260,5 +260,5 @@ [1, false],

it('should handle combination of negative, allow, nullOk, and deny', function (done) {
it('should handle combination of negative, allow, null allowed, and invalid', function (done) {
var rule = Joi.number().negative().allow(1).nullOk().deny(-5);
var rule = Joi.number().negative().allow(1).allow(null).invalid(-5);
Validate(rule, [

@@ -288,5 +288,5 @@ [1, true],

it('should handle combination of min, max, allow, and nullOk', function (done) {
it('should handle combination of min, max, allow, and null allowed', function (done) {
var rule = Joi.number().min(8).max(10).allow(1).nullOk();
var rule = Joi.number().min(8).max(10).allow(1).allow(null);
Validate(rule, [

@@ -302,5 +302,5 @@ [1, true],

it('should handle combination of min, max, allow, and deny', function (done) {
it('should handle combination of min, max, allow, and invalid', function (done) {
var rule = Joi.number().min(8).max(10).allow(1).deny(9);
var rule = Joi.number().min(8).max(10).allow(1).invalid(9);
Validate(rule, [

@@ -316,5 +316,5 @@ [1, true],

it('should handle combination of min, max, allow, deny, and nullOk', function (done) {
it('should handle combination of min, max, allow, invalid, and null allowed', function (done) {
var rule = Joi.number().min(8).max(10).allow(1).deny(9).nullOk();
var rule = Joi.number().min(8).max(10).allow(1).invalid(9).allow(null);
Validate(rule, [

@@ -359,5 +359,5 @@ [1, true],

it('should handle combination of min, max, integer, allow, and deny', function (done) {
it('should handle combination of min, max, integer, allow, and invalid', function (done) {
var rule = Joi.number().min(8).max(10).integer().allow(9.1).deny(8);
var rule = Joi.number().min(8).max(10).integer().allow(9.1).invalid(8);
Validate(rule, [

@@ -375,5 +375,5 @@ [1, false],

it('should handle combination of min, max, integer, allow, deny, and nullOk', function (done) {
it('should handle combination of min, max, integer, allow, invalid, and null allowed', function (done) {
var rule = Joi.number().min(8).max(10).integer().allow(9.1).deny(8).nullOk();
var rule = Joi.number().min(8).max(10).integer().allow(9.1).invalid(8).allow(null);
Validate(rule, [

@@ -418,2 +418,26 @@ [1, false],

});
describe('#min', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.number().min('a');
}).to.throw('limit must be an integer');
done();
});
});
describe('#max', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.number().max('a');
}).to.throw('limit must be an integer');
done();
});
});
});

@@ -220,4 +220,68 @@ // Load modules

});
it('errors on unknown keys when functions allows', function (done) {
var schema = { a: Joi.number() };
var obj = { a: 5, b: 'value' };
expect(Joi.validate(obj, schema, { skipFunctions: true })).to.exist;
done();
});
describe('#describe', function () {
it('return empty description when no schema defined', function (done) {
var schema = Joi.object();
var desc = schema.describe();
expect(desc).to.deep.equal({
type: 'object',
flags: {
insensitive: false,
allowOnly: false,
default: undefined
},
valids: [undefined],
invalids: [null]
});
done();
});
});
describe('#length', function () {
it('throws when length is not a number', function (done) {
expect(function () {
Joi.object().length('a');
}).to.throw('limit must be an integer');
done();
});
});
describe('#min', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.object().min('a');
}).to.throw('limit must be an integer');
done();
});
});
describe('#max', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.object().max('a');
}).to.throw('limit must be an integer');
done();
});
});
});
});

@@ -110,2 +110,65 @@ // Load modules

describe('#min', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.string().min('a');
}).to.throw('limit must be a positive integer');
done();
});
it('throws when limit is not an integer', function (done) {
expect(function () {
Joi.string().min(1.2);
}).to.throw('limit must be a positive integer');
done();
});
});
describe('#max', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.string().max('a');
}).to.throw('limit must be a positive integer');
done();
});
it('throws when limit is not an integer', function (done) {
expect(function () {
Joi.string().max(1.2);
}).to.throw('limit must be a positive integer');
done();
});
});
describe('#length', function () {
it('throws when limit is not a number', function (done) {
expect(function () {
Joi.string().length('a');
}).to.throw('limit must be a positive integer');
done();
});
it('throws when limit is not an integer', function (done) {
expect(function () {
Joi.string().length(1.2);
}).to.throw('limit must be a positive integer');
done();
});
});
describe('#validate', function () {

@@ -225,5 +288,5 @@

it('nullOk overrides min length requirement', function (done) {
it('null allowed overrides min length requirement', function (done) {
var schema = Joi.string().min(3).nullOk();
var schema = Joi.string().min(3).allow(null);
Validate(schema, [

@@ -320,3 +383,3 @@ [null, true]

var text = Joi.string().deny('joi');
var text = Joi.string().invalid('joi');
var result = text.validate('joi');

@@ -355,5 +418,5 @@ expect(result).to.exist;

it('should validate null with nullOk()', function (done) {
it('should validate null with allow(null)', function (done) {
Validate(Joi.string().nullOk(), [
Validate(Joi.string().allow(null), [
[null, true]

@@ -364,5 +427,5 @@ ]);

it('should validate "" (empty string) with emptyOk()', function (done) {
it('should validate "" (empty string) with allow(\'\')', function (done) {
Validate(Joi.string().emptyOk(), [
Validate(Joi.string().allow(''), [
['', true],

@@ -399,5 +462,5 @@ ['', true]

it('should handle combination of emptyOk and min', function (done) {
it('should handle combination of allow(\'\') and min', function (done) {
var rule = Joi.string().emptyOk().min(3);
var rule = Joi.string().allow('').min(3);
Validate(rule, [

@@ -413,5 +476,5 @@ ['x', false],

it('should handle combination of emptyOk and max', function (done) {
it('should handle combination of allow(\'\') and max', function (done) {
var rule = Joi.string().emptyOk().max(3);
var rule = Joi.string().allow('').max(3);
Validate(rule, [

@@ -427,4 +490,4 @@ ['x', true],

it('should handle combination of nullOk and max', function (done) {
var rule = Joi.string().nullOk().max(3);
it('should handle combination of null allowed and max', function (done) {
var rule = Joi.string().allow(null).max(3);
Validate(rule, [

@@ -454,5 +517,5 @@ ['x', true],

it('should handle combination of min, max, and emptyOk', function (done) {
it('should handle combination of min, max, and allow(\'\')', function (done) {
var rule = Joi.string().min(2).max(3).emptyOk();
var rule = Joi.string().min(2).max(3).allow('');
Validate(rule, [

@@ -500,5 +563,5 @@ ['x', false],

it('should handle combination of min, max, regex, and emptyOk', function (done) {
it('should handle combination of min, max, regex, and allow(\'\')', function (done) {
var rule = Joi.string().min(2).max(3).regex(/^a/).emptyOk();
var rule = Joi.string().min(2).max(3).regex(/^a/).allow('');
Validate(rule, [

@@ -553,5 +616,5 @@ ['x', false],

it('should handle combination of min, max, alphanum, and emptyOk', function (done) {
it('should handle combination of min, max, alphanum, and allow(\'\')', function (done) {
var rule = Joi.string().min(2).max(3).alphanum().emptyOk();
var rule = Joi.string().min(2).max(3).alphanum().allow('');
Validate(rule, [

@@ -628,5 +691,5 @@ ['x', false],

it('should handle combination of min, max, alphanum, emptyOk, and regex', function (done) {
it('should handle combination of min, max, alphanum, allow(\'\'), and regex', function (done) {
var rule = Joi.string().min(2).max(3).alphanum().emptyOk().regex(/^a/);
var rule = Joi.string().min(2).max(3).alphanum().allow('').regex(/^a/);
Validate(rule, [

@@ -674,5 +737,5 @@ ['x', false],

it('should handle combination of email, min, max, and deny', function (done) {
it('should handle combination of email, min, max, and invalid', function (done) {
var rule = Joi.string().email().min(8).max(10).deny('123@x.com');
var rule = Joi.string().email().min(8).max(10).invalid('123@x.com');
Validate(rule, [

@@ -703,5 +766,5 @@ ['x@x.com', false],

it('should handle combination of email, min, max, allow, and deny', function (done) {
it('should handle combination of email, min, max, allow, and invalid', function (done) {
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').deny('123@x.com');
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com');
Validate(rule, [

@@ -718,5 +781,5 @@ ['x@x.com', true],

it('should handle combination of email, min, max, allow, deny, and emptyOk', function (done) {
it('should handle combination of email, min, max, allow, invalid, and allow(\'\')', function (done) {
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').deny('123@x.com').emptyOk();
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').allow('');
Validate(rule, [

@@ -733,5 +796,5 @@ ['x@x.com', true],

it('should handle combination of email, min, max, allow, and emptyOk', function (done) {
it('should handle combination of email, min, max, allow, and allow(\'\')', function (done) {
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').emptyOk();
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').allow('');
Validate(rule, [

@@ -748,5 +811,5 @@ ['x@x.com', true],

it('should handle combination of email, min, max, allow, deny, and regex', function (done) {
it('should handle combination of email, min, max, allow, invalid, and regex', function (done) {
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').deny('123@x.com').regex(/^1/);
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/);
Validate(rule, [

@@ -763,5 +826,5 @@ ['x@x.com', true],

it('should handle combination of email, min, max, allow, deny, regex, and emptyOk', function (done) {
it('should handle combination of email, min, max, allow, invalid, regex, and allow(\'\')', function (done) {
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').deny('123@x.com').regex(/^1/).emptyOk();
var rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/).allow('');
Validate(rule, [

@@ -778,5 +841,5 @@ ['x@x.com', true],

it('should handle combination of email, min, max, and emptyOk', function (done) {
it('should handle combination of email, min, max, and allow(\'\')', function (done) {
var rule = Joi.string().email().min(8).max(10).emptyOk();
var rule = Joi.string().email().min(8).max(10).allow('');
Validate(rule, [

@@ -807,5 +870,5 @@ ['x@x.com', false],

it('should handle combination of email, min, max, regex, and emptyOk', function (done) {
it('should handle combination of email, min, max, regex, and allow(\'\')', function (done) {
var rule = Joi.string().email().min(8).max(10).regex(/^1234/).emptyOk();
var rule = Joi.string().email().min(8).max(10).regex(/^1234/).allow('');
Validate(rule, [

@@ -926,5 +989,5 @@ ['x@x.com', false],

it('should handle combination of isoDate, min, max and deny', function (done) {
it('should handle combination of isoDate, min, max and invalid', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).deny('2013-06-07T14:21+07:00');
var rule = Joi.string().isoDate().min(17).max(23).invalid('2013-06-07T14:21+07:00');
Validate(rule, [

@@ -969,5 +1032,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max, allow and deny', function (done) {
it('should handle combination of isoDate, min, max, allow and invalid', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').deny('2013-06-07T14:21+07:00');
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21+07:00');
Validate(rule, [

@@ -991,5 +1054,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max, allow, deny and emptyOK', function (done) {
it('should handle combination of isoDate, min, max, allow, invalid and allow(\'\')', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').deny('2013-06-07T14:21+07:00').emptyOk();
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21+07:00').allow('');
Validate(rule, [

@@ -1013,5 +1076,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max, allow, deny and emptyOK', function (done) {
it('should handle combination of isoDate, min, max, allow, invalid and allow(\'\')', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').emptyOk();
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').allow('');
Validate(rule, [

@@ -1035,5 +1098,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max, allow, deny and regex', function (done) {
it('should handle combination of isoDate, min, max, allow, invalid and regex', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').deny('2013-06-07T14:21Z').regex(/Z$/);
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21Z').regex(/Z$/);
Validate(rule, [

@@ -1057,5 +1120,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max, allow, deny, regex and emptyOK', function (done) {
it('should handle combination of isoDate, min, max, allow, invalid, regex and allow(\'\')', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').deny('2013-06-07T14:21Z').regex(/Z$/).emptyOk();
var rule = Joi.string().isoDate().min(17).max(23).allow('2013-06-07T14:21:46.295+07:00').invalid('2013-06-07T14:21Z').regex(/Z$/).allow('');
Validate(rule, [

@@ -1079,5 +1142,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max and emptyOK', function (done) {
it('should handle combination of isoDate, min, max and allow(\'\')', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).emptyOk();
var rule = Joi.string().isoDate().min(17).max(23).allow('');
Validate(rule, [

@@ -1122,5 +1185,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of isoDate, min, max, regex and emptyOK', function (done) {
it('should handle combination of isoDate, min, max, regex and allow(\'\')', function (done) {
var rule = Joi.string().isoDate().min(17).max(23).regex(/Z$/).emptyOk();
var rule = Joi.string().isoDate().min(17).max(23).regex(/Z$/).allow('');
Validate(rule, [

@@ -1234,5 +1297,5 @@ ['2013-06-07T14:21:46.295Z', false],

it('should handle combination of guid, min, max and deny', function (done) {
it('should handle combination of guid, min, max and invalid', function (done) {
var rule = Joi.string().guid().min(32).max(34).deny('b4b2fb69c6244e5eb0698e0c6ec66618');
var rule = Joi.string().guid().min(32).max(34).invalid('b4b2fb69c6244e5eb0698e0c6ec66618');
Validate(rule, [

@@ -1277,5 +1340,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max, allow and deny', function (done) {
it('should handle combination of guid, min, max, allow and invalid', function (done) {
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').deny('b4b2fb69c6244e5eb0698e0c6ec66618');
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').invalid('b4b2fb69c6244e5eb0698e0c6ec66618');
Validate(rule, [

@@ -1299,5 +1362,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max, allow, deny and emptyOK', function (done) {
it('should handle combination of guid, min, max, allow, invalid and allow(\'\')', function (done) {
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').deny('b4b2fb69c6244e5eb0698e0c6ec66618').emptyOk();
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').invalid('b4b2fb69c6244e5eb0698e0c6ec66618').allow('');
Validate(rule, [

@@ -1321,5 +1384,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max, allow and emptyOK', function (done) {
it('should handle combination of guid, min, max, allow and allow(\'\')', function (done) {
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').emptyOk();
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D').allow('');
Validate(rule, [

@@ -1343,5 +1406,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max, allow, deny and regex', function (done) {
it('should handle combination of guid, min, max, allow, invalid and regex', function (done) {
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08').deny('b4b2fb69c6244e5eb0698e0c6ec66618').regex(/^{7e908/);
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08').invalid('b4b2fb69c6244e5eb0698e0c6ec66618').regex(/^{7e908/);
Validate(rule, [

@@ -1365,5 +1428,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max, allow, deny, regex and emptyOK', function (done) {
it('should handle combination of guid, min, max, allow, invalid, regex and allow(\'\')', function (done) {
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08').deny('b4b2fb69c6244e5eb0698e0c6ec66618').regex(/^{7e908/).emptyOk();
var rule = Joi.string().guid().min(32).max(34).allow('{D1A5279D-B27D-4CD4-A05E-EFDD53D08').invalid('b4b2fb69c6244e5eb0698e0c6ec66618').regex(/^{7e908/).allow('');
Validate(rule, [

@@ -1387,5 +1450,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max and emptyOK', function (done) {
it('should handle combination of guid, min, max and allow(\'\')', function (done) {
var rule = Joi.string().guid().min(32).max(34).emptyOk();
var rule = Joi.string().guid().min(32).max(34).allow('');
Validate(rule, [

@@ -1430,5 +1493,5 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

it('should handle combination of guid, min, max, regex and emptyOK', function (done) {
it('should handle combination of guid, min, max, regex and allow(\'\')', function (done) {
var rule = Joi.string().guid().min(32).max(34).regex(/^{7e9081/i).emptyOk();
var rule = Joi.string().guid().min(32).max(34).regex(/^{7e9081/i).allow('');
Validate(rule, [

@@ -1435,0 +1498,0 @@ ['{D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D}', false],

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc