From f4121968e4d2d4e94baf7a8416748a989eaddf4c Mon Sep 17 00:00:00 2001
From: Tom <20648924+moT01@users.noreply.github.com>
Date: Sun, 8 Jun 2025 09:01:16 -0500
Subject: [PATCH] refactor: move superblock folder maps to config (#60714)
---
curriculum/utils.js | 33 ++---------------
shared/config/curriculum.ts | 37 +++++++++++++++++++
tools/challenge-auditor/index.ts | 37 ++-----------------
.../client/src/components/editor/editor.tsx | 4 +-
.../client/src/utils/block-name-translator.ts | 28 --------------
tools/challenge-helper-scripts/fs-utils.ts | 37 +++----------------
6 files changed, 50 insertions(+), 126 deletions(-)
delete mode 100644 tools/challenge-editor/client/src/utils/block-name-translator.ts
diff --git a/curriculum/utils.js b/curriculum/utils.js
index 0ac19749e34..c757c873c4f 100644
--- a/curriculum/utils.js
+++ b/curriculum/utils.js
@@ -1,7 +1,8 @@
const path = require('path');
const {
generateSuperBlockList,
- SuperBlocks
+ SuperBlocks,
+ folderToSuperBlockMap
} = require('../shared/config/curriculum');
require('dotenv').config({ path: path.resolve(__dirname, '../.env') });
@@ -59,35 +60,7 @@ function getSuperOrder(superblock) {
const directoryToSuperblock = {
'00-certifications': 'certifications', // treating certifications as a superblock for simplicity
- '01-responsive-web-design': 'responsive-web-design',
- '02-javascript-algorithms-and-data-structures':
- 'javascript-algorithms-and-data-structures',
- '03-front-end-development-libraries': 'front-end-development-libraries',
- '04-data-visualization': 'data-visualization',
- '05-back-end-development-and-apis': 'back-end-development-and-apis',
- '06-quality-assurance': 'quality-assurance',
- '07-scientific-computing-with-python': 'scientific-computing-with-python',
- '08-data-analysis-with-python': 'data-analysis-with-python',
- '09-information-security': 'information-security',
- '10-coding-interview-prep': 'coding-interview-prep',
- '11-machine-learning-with-python': 'machine-learning-with-python',
- '13-relational-databases': 'relational-database',
- '14-responsive-web-design-22': '2022/responsive-web-design',
- '15-javascript-algorithms-and-data-structures-22':
- 'javascript-algorithms-and-data-structures-v8',
- '16-the-odin-project': 'the-odin-project',
- '17-college-algebra-with-python': 'college-algebra-with-python',
- '18-project-euler': 'project-euler',
- '19-foundational-c-sharp-with-microsoft':
- 'foundational-c-sharp-with-microsoft',
- '21-a2-english-for-developers': 'a2-english-for-developers',
- '22-rosetta-code': 'rosetta-code',
- '23-python-for-everybody': 'python-for-everybody',
- '24-b1-english-for-developers': 'b1-english-for-developers',
- '25-front-end-development': 'full-stack-developer',
- '26-a2-professional-spanish': 'a2-professional-spanish',
- '27-a2-professional-chinese': 'a2-professional-chinese',
- '99-dev-playground': 'dev-playground'
+ ...folderToSuperBlockMap
};
function getSuperBlockFromDir(dir) {
diff --git a/shared/config/curriculum.ts b/shared/config/curriculum.ts
index 35371517b53..38f33061f02 100644
--- a/shared/config/curriculum.ts
+++ b/shared/config/curriculum.ts
@@ -32,6 +32,43 @@ export enum SuperBlocks {
DevPlayground = 'dev-playground'
}
+// Note that this object is used to create folderToSuperBlockMap object
+export const superBlockToFolderMap = {
+ [SuperBlocks.RespWebDesign]: '01-responsive-web-design',
+ [SuperBlocks.JsAlgoDataStruct]:
+ '02-javascript-algorithms-and-data-structures',
+ [SuperBlocks.FrontEndDevLibs]: '03-front-end-development-libraries',
+ [SuperBlocks.DataVis]: '04-data-visualization',
+ [SuperBlocks.BackEndDevApis]: '05-back-end-development-and-apis',
+ [SuperBlocks.QualityAssurance]: '06-quality-assurance',
+ [SuperBlocks.SciCompPy]: '07-scientific-computing-with-python',
+ [SuperBlocks.DataAnalysisPy]: '08-data-analysis-with-python',
+ [SuperBlocks.InfoSec]: '09-information-security',
+ [SuperBlocks.CodingInterviewPrep]: '10-coding-interview-prep',
+ [SuperBlocks.MachineLearningPy]: '11-machine-learning-with-python',
+ [SuperBlocks.RelationalDb]: '13-relational-databases',
+ [SuperBlocks.RespWebDesignNew]: '14-responsive-web-design-22',
+ [SuperBlocks.JsAlgoDataStructNew]:
+ '15-javascript-algorithms-and-data-structures-22',
+ [SuperBlocks.TheOdinProject]: '16-the-odin-project',
+ [SuperBlocks.CollegeAlgebraPy]: '17-college-algebra-with-python',
+ [SuperBlocks.ProjectEuler]: '18-project-euler',
+ [SuperBlocks.FoundationalCSharp]: '19-foundational-c-sharp-with-microsoft',
+ [SuperBlocks.A2English]: '21-a2-english-for-developers',
+ [SuperBlocks.RosettaCode]: '22-rosetta-code',
+ [SuperBlocks.PythonForEverybody]: '23-python-for-everybody',
+ [SuperBlocks.B1English]: '24-b1-english-for-developers',
+ [SuperBlocks.FullStackDeveloper]: '25-front-end-development',
+ [SuperBlocks.A2Spanish]: '26-a2-professional-spanish',
+ [SuperBlocks.A2Chinese]: '27-a2-professional-chinese',
+ [SuperBlocks.DevPlayground]: '99-dev-playground'
+};
+
+// Same as superBlockToFolderMap but with the keys and values reversed
+export const folderToSuperBlockMap = Object.fromEntries(
+ Object.entries(superBlockToFolderMap).map(([key, value]) => [value, key])
+);
+
/*
* SuperBlockStages.Upcoming = SHOW_UPCOMING_CHANGES === 'true'
* 'Upcoming' is for development -> not shown on stag or prod anywhere
diff --git a/tools/challenge-auditor/index.ts b/tools/challenge-auditor/index.ts
index 2b21d1ed7c8..87e9311dea5 100644
--- a/tools/challenge-auditor/index.ts
+++ b/tools/challenge-auditor/index.ts
@@ -11,7 +11,8 @@ import { availableLangs } from '../../shared/config/i18n';
import { getChallengesForLang } from '../../curriculum/get-challenges';
import {
SuperBlocks,
- getAuditedSuperBlocks
+ getAuditedSuperBlocks,
+ superBlockToFolderMap
} from '../../shared/config/curriculum';
// TODO: re-organise the types to a common 'types' folder that can be shared
@@ -28,38 +29,6 @@ type ChallengeNode = {
challengeType: number;
};
-const superBlockFolderMap = {
- 'responsive-web-design': '01-responsive-web-design',
- 'javascript-algorithms-and-data-structures':
- '02-javascript-algorithms-and-data-structures',
- 'front-end-development-libraries': '03-front-end-development-libraries',
- 'data-visualization': '04-data-visualization',
- 'back-end-development-and-apis': '05-back-end-development-and-apis',
- 'quality-assurance': '06-quality-assurance',
- 'scientific-computing-with-python': '07-scientific-computing-with-python',
- 'data-analysis-with-python': '08-data-analysis-with-python',
- 'information-security': '09-information-security',
- 'machine-learning-with-python': '10-machine-learning-with-python',
- 'coding-interview-prep': '11-coding-interview-prep',
- 'relational-database': '13-relational-database',
- '2022/responsive-web-design': '14-responsive-web-design-22',
- 'javascript-algorithms-and-data-structures-v8':
- '15-javascript-algorithms-and-data-structures-22',
- 'the-odin-project': '16-the-odin-project',
- 'college-algebra-with-python': '17-college-algebra-with-python',
- 'project-euler': '18-project-euler',
- 'foundational-c-sharp-with-microsoft':
- '19-foundational-c-sharp-with-microsoft',
- 'a2-english-for-developers': '21-a2-english-for-developers',
- 'rosetta-code': '22-rosetta-code',
- 'python-for-everybody': '23-python-for-everybody',
- 'b1-english-for-developers': '24-b1-english-for-developers',
- 'full-stack-developer': '25-front-end-development',
- 'a2-professional-spanish': '26-a2-professional-spanish',
- 'a2-professional-chinese': '27-a2-professional-chinese',
- 'dev-playground': '99-dev-playground'
-};
-
// Adding types for getChallengesForLang is possible, but not worth the effort
// at this time.
/* eslint-disable @typescript-eslint/no-unsafe-return */
@@ -132,7 +101,7 @@ void (async () => {
// we're not ready to audit the new curriculum yet
(cert !== SuperBlocks.JsAlgoDataStructNew ||
process.env.SHOW_UPCOMING_CHANGES === 'true') &&
- file.startsWith(superBlockFolderMap[cert])
+ file.startsWith(superBlockToFolderMap[cert])
)
);
const noMissingFiles = await auditChallengeFiles(auditedFiles, {
diff --git a/tools/challenge-editor/client/src/components/editor/editor.tsx b/tools/challenge-editor/client/src/components/editor/editor.tsx
index e9d14c90f0a..567342e8c21 100644
--- a/tools/challenge-editor/client/src/components/editor/editor.tsx
+++ b/tools/challenge-editor/client/src/components/editor/editor.tsx
@@ -13,7 +13,7 @@ import { ChallengeContent } from '../../../interfaces/challenge-content';
import SaveChallenge from '../buttons/save-challenge';
import './editor.css';
import { API_LOCATION } from '../../utils/handle-request';
-import { superBlockNameMap } from '../../utils/block-name-translator';
+import { folderToSuperBlockMap } from '../../../../../../shared/config/curriculum';
const Editor = () => {
const [error, setError] = useState