2018-03-23 14:35:29 +00:00
|
|
|
const Joi = require('joi');
|
|
|
|
Joi.objectId = require('joi-objectid')(Joi);
|
|
|
|
|
2019-02-18 12:43:09 +03:00
|
|
|
const { challengeTypes } = require('../../client/utils/challengeTypes');
|
|
|
|
|
2020-07-01 23:14:46 -07:00
|
|
|
const fileJoi = Joi.object().keys({
|
|
|
|
key: Joi.string(),
|
|
|
|
ext: Joi.string(),
|
|
|
|
name: Joi.string(),
|
2020-06-09 11:41:26 +02:00
|
|
|
editableRegionBoundaries: [Joi.array().items(Joi.number())],
|
|
|
|
path: Joi.string(),
|
|
|
|
error: Joi.empty(),
|
|
|
|
head: Joi.string().allow(''),
|
|
|
|
tail: Joi.string().allow(''),
|
|
|
|
seed: Joi.string().allow(''),
|
|
|
|
contents: Joi.string().allow(''),
|
|
|
|
history: [Joi.array().items(Joi.string().allow('')), Joi.string().allow('')]
|
2020-07-01 23:14:46 -07:00
|
|
|
});
|
|
|
|
|
2020-10-30 20:10:34 +01:00
|
|
|
const schema = Joi.object()
|
|
|
|
.keys({
|
|
|
|
block: Joi.string(),
|
|
|
|
blockId: Joi.objectId(),
|
|
|
|
challengeOrder: Joi.number(),
|
|
|
|
challengeType: Joi.number()
|
|
|
|
.min(0)
|
|
|
|
.max(11)
|
2018-12-05 20:09:18 +03:00
|
|
|
.required(),
|
2020-10-30 20:10:34 +01:00
|
|
|
checksum: Joi.number(),
|
|
|
|
dashedName: Joi.string(),
|
|
|
|
description: Joi.when('challengeType', {
|
|
|
|
is: Joi.only([challengeTypes.step, challengeTypes.video]),
|
|
|
|
then: Joi.string().allow(''),
|
|
|
|
otherwise: Joi.string().required()
|
|
|
|
}),
|
|
|
|
fileName: Joi.string(),
|
|
|
|
files: Joi.object().keys({
|
2020-06-09 11:41:26 +02:00
|
|
|
indexcss: fileJoi,
|
|
|
|
indexhtml: fileJoi,
|
|
|
|
indexjs: fileJoi,
|
2020-10-30 20:10:34 +01:00
|
|
|
indexjsx: fileJoi
|
|
|
|
}),
|
|
|
|
guideUrl: Joi.string().uri({ scheme: 'https' }),
|
|
|
|
helpCategory: Joi.only(['JavaScript', 'HTML-CSS', 'Python']),
|
|
|
|
videoUrl: Joi.string().allow(''),
|
|
|
|
forumTopicId: Joi.number(),
|
|
|
|
helpRoom: Joi.string(),
|
|
|
|
id: Joi.objectId().required(),
|
|
|
|
instructions: Joi.string().allow(''),
|
|
|
|
isComingSoon: Joi.bool(),
|
|
|
|
isLocked: Joi.bool(),
|
|
|
|
isPrivate: Joi.bool(),
|
|
|
|
name: Joi.string(),
|
|
|
|
order: Joi.number(),
|
|
|
|
// video challenges only:
|
|
|
|
videoId: Joi.when('challengeType', {
|
|
|
|
is: challengeTypes.video,
|
|
|
|
then: Joi.string().required()
|
|
|
|
}),
|
|
|
|
question: Joi.object().keys({
|
2020-04-06 14:49:56 -04:00
|
|
|
text: Joi.string().required(),
|
2020-10-30 20:10:34 +01:00
|
|
|
answers: Joi.array()
|
|
|
|
.items(Joi.string())
|
|
|
|
.required(),
|
|
|
|
solution: Joi.number().required()
|
2020-04-06 14:49:56 -04:00
|
|
|
}),
|
2020-10-30 20:10:34 +01:00
|
|
|
required: Joi.array().items(
|
|
|
|
Joi.object().keys({
|
|
|
|
link: Joi.string(),
|
|
|
|
raw: Joi.bool(),
|
|
|
|
src: Joi.string(),
|
|
|
|
crossDomain: Joi.bool()
|
|
|
|
})
|
|
|
|
),
|
|
|
|
solutions: Joi.array().items(
|
|
|
|
Joi.object().keys({
|
|
|
|
indexcss: fileJoi,
|
|
|
|
indexhtml: fileJoi,
|
|
|
|
indexjs: fileJoi,
|
|
|
|
indexjsx: fileJoi,
|
|
|
|
indexpy: fileJoi
|
|
|
|
})
|
|
|
|
),
|
|
|
|
superBlock: Joi.string(),
|
|
|
|
superOrder: Joi.number(),
|
|
|
|
suborder: Joi.number(),
|
|
|
|
tests: Joi.array().items(
|
|
|
|
// public challenges
|
|
|
|
Joi.object().keys({
|
|
|
|
text: Joi.string().required(),
|
|
|
|
testString: Joi.string()
|
|
|
|
.allow('')
|
|
|
|
.required()
|
|
|
|
}),
|
|
|
|
// our tests used in certification verification
|
|
|
|
Joi.object().keys({
|
|
|
|
id: Joi.string().required(),
|
|
|
|
title: Joi.string().required()
|
|
|
|
})
|
|
|
|
),
|
|
|
|
template: Joi.string().allow(''),
|
|
|
|
time: Joi.string().allow(''),
|
|
|
|
title: Joi.string().required()
|
|
|
|
})
|
|
|
|
.xor('helpCategory', 'isPrivate');
|
2018-10-30 18:48:54 +03:00
|
|
|
|
2020-10-01 15:50:43 +02:00
|
|
|
exports.challengeSchemaValidator = () => {
|
2018-12-05 20:09:18 +03:00
|
|
|
return challenge => Joi.validate(challenge, schema);
|
2018-03-23 14:35:29 +00:00
|
|
|
};
|