149 lines
5.1 KiB
JavaScript
149 lines
5.1 KiB
JavaScript
const path = require('path');
|
|
const {
|
|
generateSuperBlockList,
|
|
SuperBlocks
|
|
} = require('../shared/config/curriculum');
|
|
|
|
require('dotenv').config({ path: path.resolve(__dirname, '../.env') });
|
|
|
|
const { availableLangs } = require('../shared/config/i18n');
|
|
const curriculumLangs = availableLangs.curriculum;
|
|
|
|
// checks that the CURRICULUM_LOCALE exists and is an available language
|
|
exports.testedLang = function testedLang() {
|
|
if (process.env.CURRICULUM_LOCALE) {
|
|
if (curriculumLangs.includes(process.env.CURRICULUM_LOCALE)) {
|
|
return process.env.CURRICULUM_LOCALE;
|
|
} else {
|
|
throw Error(`${process.env.CURRICULUM_LOCALE} is not a supported language.
|
|
Before the site can be built, this language needs to be manually approved`);
|
|
}
|
|
} else {
|
|
throw Error('LOCALE must be set for testing');
|
|
}
|
|
};
|
|
|
|
function createSuperOrder(superBlocks) {
|
|
if (!Array.isArray(superBlocks)) {
|
|
throw Error(`superBlocks must be an Array`);
|
|
}
|
|
superBlocks.forEach(superBlock => {
|
|
if (!Object.values(SuperBlocks).includes(superBlock)) {
|
|
throw Error(`Invalid superBlock: ${superBlock}`);
|
|
}
|
|
});
|
|
|
|
const superOrder = {};
|
|
|
|
superBlocks.forEach((superBlock, i) => {
|
|
superOrder[superBlock] = i;
|
|
});
|
|
|
|
return superOrder;
|
|
}
|
|
|
|
const flatSuperBlockMap = generateSuperBlockList({
|
|
showUpcomingChanges: process.env.SHOW_UPCOMING_CHANGES === 'true'
|
|
});
|
|
const superOrder = createSuperOrder(flatSuperBlockMap);
|
|
|
|
// gets the superOrder of a superBlock from the object created above
|
|
function getSuperOrder(superblock) {
|
|
if (typeof superblock !== 'string')
|
|
throw Error(`superblock ${JSON.stringify(superblock)} must be a string`);
|
|
const order = superOrder[superblock];
|
|
if (typeof order === 'undefined')
|
|
throw Error(`${superblock} is not a valid superblock`);
|
|
return order;
|
|
}
|
|
|
|
/**
|
|
* Filters the superblocks array to only include blocks with the specified dashedName (block).
|
|
* If no block is provided, returns the original superblocks array.
|
|
*
|
|
* @param {Array<Object>} superblocks - Array of superblock objects, each containing a blocks array.
|
|
* @param {Object} [options] - Options object
|
|
* @param {string} [options.block] - The dashedName of the block to filter for (in kebab case).
|
|
* @returns {Array<Object>} Filtered array of superblocks containing only the specified block, or the original array if block is not provided.
|
|
*/
|
|
function filterByBlock(superblocks, { block } = {}) {
|
|
if (!block) return superblocks;
|
|
|
|
return superblocks
|
|
.map(superblock => ({
|
|
...superblock,
|
|
blocks: superblock.blocks.filter(({ dashedName }) => dashedName === block)
|
|
}))
|
|
.filter(superblock => superblock.blocks.length > 0);
|
|
}
|
|
|
|
/**
|
|
* Filters the superblocks array to only include the superblock with the specified name.
|
|
* If no superBlock is provided, returns the original superblocks array.
|
|
*
|
|
* @param {Array<Object>} superblocks - Array of superblock objects.
|
|
* @param {Object} [options] - Options object
|
|
* @param {string} [options.superBlock] - The name of the superblock to filter for.
|
|
* @returns {Array<Object>} Filtered array of superblocks containing only the specified superblock, or the original array if superBlock is not provided.
|
|
*/
|
|
function filterBySuperblock(superblocks, { superBlock } = {}) {
|
|
if (!superBlock) return superblocks;
|
|
return superblocks.filter(({ name }) => name === superBlock);
|
|
}
|
|
|
|
/**
|
|
* Filters challenges in superblocks to only include those matching the given challenge id and their solution challenges (i.e. the next challenge, if it exists)
|
|
* @param {Array<Object>} superblocks - Array of superblock objects with blocks containing challenges
|
|
* @param {Object} [options] - Options object
|
|
* @param {string} [options.challengeId] - The specific challenge id to filter for
|
|
* @returns {Array<Object>} Filtered superblocks containing only the matching challenge
|
|
*/
|
|
function filterByChallengeId(superblocks, { challengeId } = {}) {
|
|
if (!challengeId) {
|
|
return superblocks;
|
|
}
|
|
|
|
const findChallengeIndex = (challengeOrder, id) =>
|
|
challengeOrder.findIndex(challenge => challenge.id === id);
|
|
|
|
const filterChallengeOrder = (challengeOrder, id) => {
|
|
const index = findChallengeIndex(challengeOrder, id);
|
|
if (index === -1) return [];
|
|
|
|
return challengeOrder.slice(index, index + 2);
|
|
};
|
|
|
|
return superblocks
|
|
.map(superblock => ({
|
|
...superblock,
|
|
blocks: superblock.blocks
|
|
.map(block => ({
|
|
...block,
|
|
challengeOrder: filterChallengeOrder(
|
|
block.challengeOrder,
|
|
challengeId
|
|
)
|
|
}))
|
|
.filter(
|
|
block => block.challengeOrder && block.challengeOrder.length > 0
|
|
)
|
|
}))
|
|
.filter(superblock => superblock.blocks.length > 0);
|
|
}
|
|
|
|
const createFilterPipeline = filterFunctions => (data, filters) =>
|
|
filterFunctions.reduce((acc, filterFn) => filterFn(acc, filters), data);
|
|
|
|
const applyFilters = createFilterPipeline([
|
|
filterBySuperblock,
|
|
filterByBlock,
|
|
filterByChallengeId
|
|
]);
|
|
|
|
exports.filterByBlock = filterByBlock;
|
|
exports.filterBySuperblock = filterBySuperblock;
|
|
exports.filterByChallengeId = filterByChallengeId;
|
|
exports.createSuperOrder = createSuperOrder;
|
|
exports.getSuperOrder = getSuperOrder;
|
|
exports.applyFilters = applyFilters;
|