forked from freeCodeCamp/freeCodeCamp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
getChallenges.js
87 lines (79 loc) · 2.63 KB
/
getChallenges.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const path = require('path');
const { findIndex } = require('lodash');
const readDirP = require('readdirp-walk');
const { parseMarkdown } = require('@freecodecamp/challenge-md-parser');
const challengesDir = path.resolve(__dirname, './challenges');
exports.getChallengesForLang = function getChallengesForLang(lang) {
let curriculum = {};
return new Promise(resolve =>
readDirP({ root: path.resolve(challengesDir, `./${lang}`) })
.on('data', file => buildCurriculum(file, curriculum))
.on('end', () => resolve(curriculum))
);
};
async function buildCurriculum(file, curriculum) {
const { name, depth, path: filePath, 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 blockName = getBlockNameFromPath(filePath);
const metaPath = path.resolve(
__dirname,
`./challenges/_meta/${blockName}/meta.json`
);
const blockMeta = require(metaPath);
const { name: superBlock } = superBlockInfoFromPath(filePath);
const blockInfo = { meta: blockMeta, challenges: [] };
curriculum[superBlock].blocks[name] = blockInfo;
return;
}
if (name === 'meta.json' || name === '.DS_Store') {
return;
}
const block = getBlockNameFromPath(filePath);
const { name: superBlock } = superBlockInfoFromPath(filePath);
const challenge = await parseMarkdown(fullPath);
let challengeBlock;
try {
challengeBlock = curriculum[superBlock].blocks[block];
} catch (e) {
console.log(superBlock, block);
process.exit(0);
}
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);
}
function superBlockInfo(fileName) {
const [maybeOrder, ...superBlock] = fileName.split('-');
let order = parseInt(maybeOrder, 10);
if (isNaN(order)) {
return { order: 0, name: fileName };
} else {
return {
order: order,
name: superBlock.join('-')
};
}
}
function getBlockNameFromPath(filePath) {
const [, block] = filePath.split('/');
return block;
}