Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions scripts/build-challenge-map-graphql.mjs
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
import { writeFile, mkdir } from 'fs/promises';
import { dirname } from 'path';
import { fileURLToPath } from 'url';

/**
* Build challenge map from freeCodeCamp GraphQL Curriculum Database
*
* This script fetches the complete curriculum structure from the GraphQL API
* and generates a flat lookup map for challenge resolution.
*
* Output format: { challengeId: { certification, block, name } }
* Output format:
* {
* "challengeId": {
* "superblocks": ["superblock-dashed-name", ...],
* "blocks": ["block-dashed-name", ...],
* "name": "Challenge Title"
* }
* }
*
* Notes:
* - Challenges may appear in multiple superblocks/blocks; the script records
* all occurrences as arrays. Consumers that need a single canonical
* superblock/block (e.g., dashboard grouping) should use the first array
* element as the canonical value.
*/

const GRAPHQL_ENDPOINT = 'https://curriculum-db.freecodecamp.org/graphql';
const OUTPUT_PATH = new URL('../data/challengeMap.json', import.meta.url);
const OUTPUT_PATH = fileURLToPath(
new URL('../data/challengeMap.json', import.meta.url)
);

const CHALLENGE_MAP_QUERY = `
query GetChallengeMap {
Expand Down Expand Up @@ -158,14 +174,14 @@ async function buildChallengeMapFromGraphQL() {
const challengeMap = buildChallengeMap(data);

// Ensure output directory exists
await mkdir(dirname(OUTPUT_PATH.pathname), { recursive: true });
await mkdir(dirname(OUTPUT_PATH), { recursive: true });

// Write to file
console.log(`\n💾 Writing challenge map to ${OUTPUT_PATH.pathname}...`);
console.log(`\n💾 Writing challenge map to ${OUTPUT_PATH}...`);
await writeFile(OUTPUT_PATH, JSON.stringify(challengeMap, null, 2));

console.log('✅ Challenge map successfully generated!\n');
console.log(` File: ${OUTPUT_PATH.pathname}`);
console.log(` File: ${OUTPUT_PATH}`);
console.log(` Size: ${Object.keys(challengeMap).length} challenges`);
} catch (err) {
console.error('❌ Error building challenge map:', err);
Expand Down