npm install joi
hapijs / joi Goto Github PK
View Code? Open in Web Editor NEWThe most powerful data validation library for JS
License: Other
The most powerful data validation library for JS
License: Other
npm install joi
If you pass in undefined to validate for a string with a minimum length set, undefined will be considered valid.
Having looked through the README, I was at a loss what to do with my schema once I had defined it. I wanted to validate an object, but nowhere was this shown on the page.
I looked here to find out what to do:
If you think it's a good idea to put this in the readme, then I'd be happy to send a pull request or two. Didn't want to do it without checking with you first. :)
Combinations must always fail on a single rule
I would expect this to succeed, where key foo
is optional by default:
var schema = {
foo: Joi.types.String().max(40)
};
Joi.validate({}, schema);
Instead, it fails with the value of foo must be less than (or equal to) 40 characters long
Bring it up to date and make it complete
Allows a key to have any value. Supports nullOk()
, optional()
, and required()
( and ) are getting encoded and should be removed from language.json
This is different from what hapi expects.
Hi,
As discussed with @hueniverse, describe
should probably be exposed the same way validate
is.
The main goal would be to identify exactly where an error occurs programmatically so we can have more options on how to resolve and/or notify users of the error. My initial, quite possibly overly simplistic thought, was maybe an array of something like this:
{
property: 'name',
path: 'spouse',
message: 'must be a string'
}
The path is particularly important as we can't distinguish between redundant property names throughout an object graph with the current messages.
This may not be appropriate for this particular package, but I wonder if there's a possibility of supporting custom validators by passing a function, and if asynchronous validations would be possible? The use case here is validation against a database, such as seeing whether a username already exists. What do you think?
Set number of allowed keys.
Types.Function was removed for security reasons. However, it may be useful in practice in a few cases.
Either fix by:
adding function support back in
OR
skipping obj keys that are obviously functions
Hi there,
Haven't had a chance to look at the code that is producing this response however it seems that the message returned in response to an integer being above the max() upper bound is returning the inbound parameter not the upper bound.
Examples -
Validation -
maxResults: Hapi.types.Number().integer().min(0).max(30)
Request
http://localhost:8000/jobs?maxResults=50
Result
{"code":400,"error":"Bad Request","message":"the value of maxResults must be less than (or equal to) 50"}
Request
http://localhost:8000/jobs?maxResults=31
Result
{"code":400,"error":"Bad Request","message":"the value of maxResults must be less than (or equal to) 31"}
Request
http://localhost:8000/jobs?maxResults=30
Result
{"code":200,"result":{"totalRecords":159,"startAt":0,"maxResults":30,"resultSet":[{"_id":"a0x90... ... as expected
I believe I am using hapi v 1.9.0 & Joi 3.6.
Regards,
Sean
I suggest to remove Number.float()
because it's not just useless (all numbers are doubles in JavaScript and Joi filters NaN
in any case) and is also bugged.
Currently .float()
does not allow values which have no fractional part (e.g. 3.0
, 6.0
), i.e. integers. But these value are valid doubles.
Fixing that bug essentially makes float()
redundant.
Also .float()
uses .integer()
internally which also breaks it for floats.
var Joi = require('./index');
var T = Joi.types;
var input = { child: { amount: 2 } };
var schema = { child: T.Object({ amount: T.Number().float() }) };
console.log(Joi.validate(input, schema));
{ _errors:
[ { message: 'the value of amount must be a float or double',
path: 'child.amount' } ],
_object: { child: { amount: 2 } },
message: 'the value of amount must be a float or double' }
var Joi = require('./index');
var T = Joi.types;
var input = { child: { amount: 2.5 } };
var schema = { child: T.Object({ amount: T.Number().float() }) };
console.log(Joi.validate(input, schema));
{ _errors:
[ { message: 'the value of amount must be an integer',
path: 'child.amount' } ],
_object: { child: { amount: 2.5 } },
message: 'the value of amount must be an integer' }
Joi should be able to validate an object and any child objects
Instead of always requiring config: { }, allow for config: T.Object() or any other joi type.
Below is a test case that produces the issue. In other words, it only supports homogeneous arrays - not heterogeneous arrays. However, according to the docs, it should be able to support heterogeneous arrays.
describe.only('Joi Array Type', function() {
it('can validate that its elements only include certain types', function() {
var schema = {
array : joi.types.Array().includes(joi.types.String().min(5), joi.types.Number().min(0))
};
var obj = {
array : [ '12345' ]
};
var err = joi.validate(obj, schema);
if (err) {
throw new Error(JSON.stringify(obj) + '\n' + err);
}
obj = {
array : [ '1234' ]
};
err = joi.validate(obj, schema);
if (!err) {
throw new Error(JSON.stringify(obj) + '\n Should be invalid because it contains a String with length < 5');
}
obj = {
array : [ 3 ]
};
err = joi.validate(obj, schema);
if (err) {
throw new Error(JSON.stringify(obj) + '\n' + err);
}
obj = {
array : [ '12345', 3 ]
};
err = joi.validate(obj, schema);
if (err) {
throw new Error(JSON.stringify(obj) + '\n' + err);
}
});
});
Wrap current [] support to apply same common properties:
Joi.alternatives([
string(),
number()
]).required();
This replaces the current need to specify shared properties on each alternative type:
[
string().require(),
number().required()
];
When validating an email address I get:
"[ValidationError]: the value of email
must match the RegExp /^(?:[\\w\\!\\#\\$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\
{|}~]+.)_[\w!#$%&'_+-/=?^`\{\|\}\~]+@(?:(?:(?:a-zA-Z0-9{0,61}[a-zA-Z0-9]?\.)+a-zA-Z0-9{0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/`"
It would be nice if it just said 'Invalid email' ! or some other friendlier message
/lookup?type=username&id=joe
/lookup?type=email&id=[email protected]
Try adding an invalid 'mode' option to the hapi server config settings to observe the following error:
"the value of cache must be a string"
hi...
On hapi 1.14, say I have a response schema like:
response: {
schema: {
data: validate.types.Object({
created: validate.types.String().date(),
updated: validate.types.String().date(),
viewed: validate.types.String(),
timestamp: validate.types.Object()
})
},
failAction: 'log'
},
And response data:
{
"data": {
"created": "2013-10-08T11:26:59.076Z",
"updated": "2013-10-08T11:26:59.000Z",
"viewed": "2013-10-25T09:19:17.427Z",
"timestamp": "2013-10-25T09:19:17.427Z"
}
}
Joi is giving me this validation outcome:
created = passed, no validation issue
updated = error the value of updated must be a string
viewed = error the value of viewed must be a string
timestamp = passed, no validation issue
Question 1: 'created' and 'updated' have the same constraints. Any idea why 'created' passes, but 'updated' fails as an invalid String? (NOTE: 'viewed' without the date() constraint is also failing validation.)
Question 2: why is 'timestamp' being interpreted as an Object?
Thanks
Joi.validate([], Joi.types.Object()); // returns null
Joi.validate([1, 3, 4], Joi.types.Object()); // returns null
Support something like:
{
dontcare: Joi.Types.Any()
}
on a var by var basis (and globally via setting?).
Hi,
I'm on v0.3.6 of Joi...
In the docs, it says: "Use the languagePath option to specify a file path to a JSON file that contains error messages."
I added 'languagePath' to joi options, but I'm getting a Hoek exception loading joi.
Something like: [hapi's joi]../../../messages.json
Would bring me to the root of my project where I have my messages.json.
I added this ("regex": "badstring") directly to joi message file, expecting it to work:
messages.json:
{
"array": {
"base": "the value of {{key}} must be an Array"
},
"string": {
"regex": "bad string"
},
But I continue to get messages like: "the value of 'x' must match the RegExp /[a-zA-Z0-9]{3,30}/"
When validating a datatype like: .types.String().regex(/[a-zA-Z0-9]{3,30}/)
For example, could you set a message for the example you document of a custom user-defined data type? Like:
var PositiveInt = Number().integer().min(0)
messages.json:
{
"array": {
"base": "the value of {{key}} must be an Array"
},
"number": {
"PositiveInt": "bad number!"
},
Is there currently a mechanism where I could pass an optional argument to a validation rule that if the test fails, it would be used as the message
value of the error?
The built in error messages are sometimes not very friendly. Is this something that I can already do and just missed it in the docs?
var Joi = require('joi');
var T = Joi.types;
var schema = {
accepted_payments: T.Array().includes(T.String().valid('amex','visa'))
};
var err1 = Joi.validate({ accepted_payments: ['amex'] }, schema);
var err2 = Joi.validate({ accepted_payments: ['visa','mc'] }, schema);
console.log(err1);
console.log(err2);
err2
should have an error since mc
is not a valid value for the strings defined inside includes()
.
Looking through array.js
, it looks like there are explicit tests for include()
when validation modifiers are used that ultimately call BaseType.prototype.add
(like String().regexp()
or Number().integer()
), but none when using valid()
or allow()
.
In other words, the following behaves as expected:
var Joi = require('joi');
var T = Joi.types;
var schema = {
emails: T.Array().includes(T.String().email())
};
var err1 = Joi.validate({ emails: ['[email protected]'] }, schema);
var err2 = Joi.validate({ emails: ['[email protected]','foobar'] }, schema);
console.log(err1);
console.log(err2); // contains error since `foobar` isn't a valid email.
The validators .with/.without
appear to be broken when testing Hapi 1.0 RC's examples/cache.js.
Is it possible to extend Joi with custom validation functions?
The code below (based on an example in the readme) prints "Fine..." when executed with node v0.10.12 and joi v1.2.1. I expected it to complain about a missing password field.
Is this the correct usage? Are the with/without constraints implemented as documented?
Thanks
var Joi = require('joi');
var schema = {
username: Joi.types.String().with('password'),
password: Joi.types.String().without('access_token')
};
var err = Joi.validate(
{username: 'bob'},
schema
);
if(err){
console.dir(err);
}
else {
console.log('Fine...');
}
Similar to how Object can define what properties are valid, an array should be able to defined what types it can contain along with the structure of those types. This is needed for restricting the pre
route config property: https://github.com/spumko/hapi/blob/master/docs/Reference.md#prerequisites
Hi,
Can you add more constraints on Number type ?
allow
constraint)These constraints can take a String like .with()
or .without()
to compare with the defined attribute value or a number to compare with.
Thank you and sorry for my english ..
Also, null value is not allowed by default (undefined is when optional).
the following test throws:
var schema = {
arr: Joi.types.Array().includes(Joi.types.Number().integer())
};
var input = { arr: [1, 2, 2.1] };
var err = Joi.validate(input, schema);
expect(err).to.exist;
done();
It happens with almost any variation of types with constraints in include (also for excludes)
another example that throws:
var schema = {
arr: Joi.types.Array().includes(Joi.types.String())
};
var input = {arr:["1","2","2.1", 2]};
var err = Joi.validate(input, schema);
expect(err).to.exist;
done();
exception for the first case:
TypeError: Cannot call method 'split' of undefined
at internals.Errors.add (joi/lib/errors.js:20:24)
at Array.1 (/joi/lib/types/number.js:113:20)
at Array.1 (/joi/lib/types/array.js:125:47)
at internals.BaseType.validate (/joi/lib/types/base.js:408:42)
at validateKeyConfig (/joi/lib/index.js:81:39)
at processConfig (/joi/lib/index.js:46:13)
at Object.exports.validate (/joi/lib/index.js:100:5)
at /joi/test/index.js:501:23
at Object._onImmediate (/joi/node_modules/lab/lib/execute.js:238:12)
at processImmediate [as _immediateCallback] (timers.js:330:15)
Use case - query string params: txt=ipad
I tried required().without()
but this resulted in the following...
{"code":400,"error":"Bad Request","message":"[ValidationError]: the value of upc
is not allowed to be undefined"}
validate an object with the provided definition, and allow any key not defined by the schema
See hapijs/hapi#1078
I have a schema with two fields where one or the other is required, but they aren't exclusive. I have been unable to figure out how to express this constraint in joi?
These three cases should work:
{ "A": "foo" }
{ "B": "bar" }
{ "A": "foo", "B": "bar" }
This should fail:
{ "epic": "fail" }
If this is possible in the existing system, please hit me with a cluebat - otherwise, would an or() function make sense here?
Hi,
I just notice that there is no more callback when validating an object but in the documentation we've got this :
Joi.validate(obj, schema, function (err) {
// err will be set if the object failed to validate against the schema
});
Now did I need to catch an error when validating ? try{...}catch(ex){...}
or just assign the returned value in a variable ? var value = Joi.validate(object, schema);
Thank you.
Here is the sample validation snippet from a request config:
validate: {
payload: {
firstName: S.required(),
lastName: S.required(),
location: {
longitude: N.required(),
latitude: N.required()
}
}
}
Removing the "location" object prevents the error. Is there a way to do this without generating the error below? Or is having these types of nested objects not working with the current validation?
Here is the error with the stack trace.
/myApp/node_modules/hapi/node_modules/joi/lib/index.js:76 return converted && keyConfig.validate(converted.value, key, object, e ^ TypeError: Object #<Object> has no method 'validate' at validateKeyConfig (/myApp/node_modules/hapi/node_modules/joi/lib/index.js:76:39) at processConfig (/myApp/node_modules/hapi/node_modules/joi/lib/index.js:41:13) at Object.exports.validate (/myApp/node_modules/hapi/node_modules/joi/lib/index.js:100:5) at exports.payload (/myApp/node_modules/hapi/lib/validation.js:48:21) at /myApp/node_modules/hapi/lib/request.js:321:9 at iterate (/myApp/node_modules/hapi/node_modules/async/lib/async.js:128:13) at /myApp/node_modules/hapi/node_modules/async/lib/async.js:139:25 at exports.query (/myApp/node_modules/hapi/lib/validation.js:25:16) at /myApp/node_modules/hapi/lib/request.js:321:9 at iterate (/myApp/node_modules/hapi/node_modules/async/lib/async.js:128:13)
would be nice to validate dates that are like 11/26/85
or 1-1-2001
using %M/%D/%Y
or whatever format definitions
I made a boo boo and passed an array to these methods instead of calling the method with them as individual parameters, fixed my mistake after realizing I was doing it wrong via the crypt 400 response and second look at the readme, but was wondering if you would be open to that as an acceptable form of input, for example:
validate: {
payload: {
latitude: Hapi.types.Number()
.min(-90).max(90)
.optional()
.with(['longitude','radius'])
longitude: Hapi.types.Number()
.min(-180).max(180)
.optional()
.with(['latitude', 'radius'])
radius: Hapi.types.Number()
.min(0)
.optional()
.with(['latitude', 'longitude'])
}
}
instead of:
validate: {
payload: {
latitude: Hapi.types.Number()
.min(-90).max(90)
.optional()
.with('longitude','radius')
longitude: Hapi.types.Number()
.min(-180).max(180)
.optional()
.with('latitude', 'radius')
radius: Hapi.types.Number()
.min(0)
.optional()
.with('latitude', 'longitude')
}
}
If you don't like the idea then we can close the issue otherwise I'll send a pull request later.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.