2017-01-18 23:16:23 +00:00
|
|
|
const path = require('path');
|
2018-10-04 13:45:22 +00:00
|
|
|
const { findIndex } = require('lodash');
|
|
|
|
const readDirP = require('readdirp-walk');
|
2015-11-02 01:20:03 +00:00
|
|
|
|
2018-10-04 17:25:49 +00:00
|
|
|
const { parseMarkdown } = require('@freecodecamp/challenge-md-parser');
|
2018-01-19 19:03:17 +00:00
|
|
|
|
2018-10-04 13:45:22 +00:00
|
|
|
exports.getChallengesForLang = function getChallengesForLang(lang) {
|
|
|
|
let curriculum = {};
|
|
|
|
return new Promise(resolve =>
|
|
|
|
readDirP({ root: path.resolve(__dirname, `./challenges/${lang}`) })
|
|
|
|
.on('data', file => buildCurriculum(file, curriculum))
|
|
|
|
.on('end', () => resolve(curriculum))
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
async function buildCurriculum(file, curriculum) {
|
|
|
|
const { name, depth, path, fullPath, stat } = file;
|
|
|
|
if (depth === 1 && stat.isDirectory()) {
|
|
|
|
// extract the superBlock info
|
|
|
|
const { order, name: superBlock } = superBlockInfo(name);
|
|
|
|
curriculum[superBlock] = { superBlock, order, blocks: {} };
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (depth === 2 && stat.isDirectory()) {
|
|
|
|
const blockMeta = require(`${fullPath}/meta.json`);
|
|
|
|
const { name: superBlock } = superBlockInfoFromPath(path);
|
|
|
|
const blockInfo = { meta: blockMeta, challenges: [] };
|
|
|
|
curriculum[superBlock].blocks[name] = blockInfo;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (name === 'meta.json') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const block = getBlockNameFromPath(path);
|
|
|
|
const { name: superBlock } = superBlockInfoFromPath(path);
|
|
|
|
const challenge = await parseMarkdown(fullPath);
|
|
|
|
const challengeBlock = curriculum[superBlock].blocks[block];
|
|
|
|
const { meta } = challengeBlock;
|
|
|
|
const challengeOrder = findIndex(
|
|
|
|
meta.challengeOrder,
|
|
|
|
([id]) => id === challenge.id
|
|
|
|
);
|
|
|
|
const { name: blockName, order, superOrder } = meta;
|
|
|
|
challenge.block = blockName;
|
|
|
|
challenge.order = order;
|
|
|
|
challenge.superOrder = superOrder;
|
|
|
|
challenge.superBlock = superBlock;
|
|
|
|
challenge.challengeOrder = challengeOrder;
|
|
|
|
challengeBlock.challenges = [...challengeBlock.challenges, challenge];
|
|
|
|
}
|
|
|
|
|
|
|
|
function superBlockInfoFromPath(filePath) {
|
|
|
|
const [maybeSuper] = filePath.split('/');
|
|
|
|
return superBlockInfo(maybeSuper);
|
2015-11-02 01:20:03 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 13:45:22 +00:00
|
|
|
function superBlockInfo(fileName) {
|
|
|
|
const [maybeOrder, ...superBlock] = fileName.split('-');
|
|
|
|
let order = parseInt(maybeOrder, 10);
|
2018-01-19 19:03:17 +00:00
|
|
|
if (isNaN(order)) {
|
2018-10-04 13:45:22 +00:00
|
|
|
return { order: 0, name: fileName };
|
2018-01-19 19:03:17 +00:00
|
|
|
} else {
|
|
|
|
return {
|
|
|
|
order: order,
|
2018-10-04 13:45:22 +00:00
|
|
|
name: superBlock.join('-')
|
2018-01-19 19:03:17 +00:00
|
|
|
};
|
2015-12-07 05:44:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-04 13:45:22 +00:00
|
|
|
function getBlockNameFromPath(filePath) {
|
|
|
|
const [, block] = filePath.split('/');
|
|
|
|
return block;
|
|
|
|
}
|