2018-03-26 12:01:24 +00:00
|
|
|
const crypto = require('crypto');
|
2021-12-14 18:11:20 +00:00
|
|
|
const { blockNameify } = require('../../../utils/block-nameify');
|
2018-03-26 12:01:24 +00:00
|
|
|
|
2022-01-10 09:03:20 +00:00
|
|
|
const createdIds = new Set();
|
|
|
|
|
|
|
|
function createChallengeNode(
|
|
|
|
challenge,
|
|
|
|
reporter,
|
|
|
|
{ isReloading } = { isReloading: false }
|
|
|
|
) {
|
2020-09-24 10:34:35 +00:00
|
|
|
// challengeType 11 is for video challenges (they only have instructions)
|
|
|
|
// challengeType 7 is for certificates (they only have tests)
|
2021-06-15 15:37:13 +00:00
|
|
|
// challengeType 12 is for CodeAlly/CodeRoad challenge
|
2020-11-27 18:02:05 +00:00
|
|
|
|
|
|
|
// TODO: either handle empty descriptions inside Gatsby OR ensure that
|
|
|
|
// description defaults to '' when creating challenges.
|
|
|
|
// ditto for seeds and instructions.
|
|
|
|
// create-md should, then, not create empty seed, description or instruction
|
|
|
|
// sections.
|
2020-04-21 22:19:22 +00:00
|
|
|
if (
|
2020-11-27 18:02:05 +00:00
|
|
|
typeof challenge.description !== 'string' &&
|
2021-03-10 19:01:46 +00:00
|
|
|
challenge.challengeType !== 11 &&
|
2021-06-15 15:37:13 +00:00
|
|
|
challenge.challengeType !== 7 &&
|
|
|
|
challenge.challengeType !== 12
|
2020-04-21 22:19:22 +00:00
|
|
|
) {
|
2018-04-16 11:04:25 +00:00
|
|
|
reporter.warn(`
|
2018-03-26 12:01:24 +00:00
|
|
|
|
2018-04-06 13:51:52 +00:00
|
|
|
${challenge.title} has a description that will break things!
|
|
|
|
|
|
|
|
`);
|
2018-03-26 12:01:24 +00:00
|
|
|
}
|
2018-04-06 13:51:52 +00:00
|
|
|
const contentDigest = crypto
|
|
|
|
.createHash('md5')
|
|
|
|
.update(JSON.stringify(challenge))
|
|
|
|
.digest('hex');
|
|
|
|
const internal = {
|
|
|
|
contentDigest,
|
2020-09-24 10:34:35 +00:00
|
|
|
type: challenge.challengeType === 7 ? 'CertificateNode' : 'ChallengeNode'
|
2018-04-06 13:51:52 +00:00
|
|
|
};
|
|
|
|
|
2021-12-14 18:11:20 +00:00
|
|
|
if (internal.type === 'ChallengeNode') {
|
|
|
|
const { tests = [], block, dashedName, superBlock } = challenge;
|
|
|
|
const slug = `/learn/${superBlock}/${block}/${dashedName}`;
|
|
|
|
|
|
|
|
challenge.fields = {
|
|
|
|
slug,
|
|
|
|
blockName: blockNameify(block),
|
|
|
|
tests
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-01-10 09:03:20 +00:00
|
|
|
// Challenge id should be unique for CertificateNodes, but not for
|
|
|
|
// ChallengeNodes
|
|
|
|
const id =
|
|
|
|
internal.type === 'ChallengeNode' ? challenge.fields.slug : challenge.id;
|
|
|
|
|
|
|
|
if (createdIds.has(id) && !isReloading) {
|
|
|
|
throw Error(`
|
|
|
|
Challenge slugs must be unique, but ${id} already exists.
|
|
|
|
`);
|
|
|
|
}
|
|
|
|
createdIds.add(id);
|
|
|
|
|
2018-04-06 13:51:52 +00:00
|
|
|
return JSON.parse(
|
|
|
|
JSON.stringify(
|
|
|
|
Object.assign(
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
children: [],
|
|
|
|
parent: null,
|
|
|
|
internal,
|
|
|
|
sourceInstanceName: 'challenge'
|
|
|
|
},
|
2021-12-14 18:11:20 +00:00
|
|
|
{ challenge },
|
2022-01-10 09:03:20 +00:00
|
|
|
{
|
|
|
|
id
|
|
|
|
}
|
2018-04-06 13:51:52 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2018-03-26 12:01:24 +00:00
|
|
|
|
2018-11-16 18:22:52 +00:00
|
|
|
exports.createChallengeNode = createChallengeNode;
|