Reputation: 2700
i am trying to validate the string using the JOI package available in npm, i checked this documentation which has many useful string formats e.g. date, IP, base64 but i need to validate the following JSON which contains a stringified JSON as a value, and there is no example in the documentation for such case
{
"id": 232,
"name": "Trojan Horse",
"file": "download.exe",
"infected": true,
"engines": "['Norton', 'AVG', 'NOD32']"
}
So for example what if i want to check engines
have valid JSON value and have at-least one engine defined if infected
key is set to true
The following schema works only if the engines
value is written as parsed JSON
Joi.object().keys({
id: Joi.number().required(),
name: Joi.string().min(5).required(),
file: Joi.string().min(3).required(),
infected: Joi.boolean().required(),
engines: Joi.array().when('infected', {
is: Joi.exists().valid(true),
then: Joi.min(1).required()
})
});
Upvotes: 0
Views: 5483
Reputation: 180
What you need to do is to create a custom JOI validator by extending the array validator of the JOI package and using that custom validator for the engines property.
const custom = Joi.extend({
type: 'array',
base: Joi.array(),
coerce: {
from: 'string',
method(value, helpers) {
if (typeof value !== 'string' ||
value[0] !== '[' && !/^\s*\[/.test(value)) {
return;
}
try {
return { value: JSON.parse(value) };
}
catch (ignoreErr) { }
}
}
});
const schema = Joi.object({
id: Joi.number().required(),
name: Joi.string().min(5).required(),
file: Joi.string().min(3).required(),
infected: Joi.boolean().required(),
engines: custom.array().when('infected', {
is: true,
then: custom.array().min(1).required()
})
})
const validateTest = async (joiSchema, testObject) => {
try {
const value = await joiSchema.validateAsync(testObject);
console.log(value);
}
catch (err) {
console.error(err)
}
};
validateTest(schema, {
"id": 232,
"name": "Trojan Horse",
"file": "download.exe",
"infected": true,
"engines": `["Norton", "AVG", "NOD32"]`
})
You can see more examples like that here
Upvotes: 3