refactor: stop curriculum tests depending on client (#65534)

This commit is contained in:
Oliver Eyton-Williams
2026-01-28 15:05:26 +01:00
committed by GitHub
parent 004e126906
commit 14cde3cdea
21 changed files with 141 additions and 99 deletions
@@ -0,0 +1,75 @@
import path from 'node:path';
import fs from 'node:fs';
import { describe, test, expect } from 'vitest';
import { getContentDir } from '@freecodecamp/curriculum/file-handler';
import { buildCertification } from '@freecodecamp/curriculum/build-certification';
import { allCerts } from './cert-and-project-map';
describe('certifications', () => {
const certificationsDir = path.resolve(
getContentDir('english'),
'certifications'
);
const certificationFiles = fs.readdirSync(certificationsDir);
certificationFiles.forEach(filename => {
test(`${filename} should have matching items in cert-and-project-map`, () => {
const filePath = path.join(certificationsDir, filename);
const result = buildCertification(filePath);
const certData = result.challenges[0];
const certTests = certData.tests;
const matchingCert = allCerts.find(cert => cert.id === certData.id);
expect(
matchingCert,
`Cert ID ${certData.id} not found in allCerts.`
).toBeDefined();
expect(
matchingCert,
`Matching cert has no 'projects' property`
).toHaveProperty('projects');
// skip legacy-full-stack as it has no projects
if (filename !== 'legacy-full-stack.yml') {
expect(
Array.isArray(matchingCert?.projects),
`Matching cert 'projects' is not an array`
).toBe(true);
const certProjects = matchingCert?.projects;
expect(
certProjects?.length,
`Project count mismatch: allCerts has ${certProjects?.length} projects, YAML has ${certTests.length} tests`
).toBe(certTests.length);
certTests.forEach((test, i) => {
expect(
test,
`Test at index ${i} in missing id property`
).toHaveProperty('id');
expect(
test,
`Test at index ${i} missing title property`
).toHaveProperty('title');
const matchingProject = certProjects?.[i];
expect(
matchingProject,
`No project found at index ${i} for test ${test.id}`
).toBeDefined();
expect(
matchingProject?.id,
`Project ID mismatch at index ${i}: allCerts has "${matchingProject?.id}", YAML has "${test.id}"`
).toBe(test.id);
});
}
});
});
});
@@ -8,7 +8,7 @@ import {
chapterBasedSuperBlocks chapterBasedSuperBlocks
} from '@freecodecamp/shared/config/curriculum'; } from '@freecodecamp/shared/config/curriculum';
import type { Chapter } from '@freecodecamp/shared/config/chapters'; import type { Chapter } from '@freecodecamp/shared/config/chapters';
import { getSuperblockStructure } from '../../../curriculum/src/file-handler'; import { getSuperblockStructure } from '@freecodecamp/curriculum/file-handler';
import { patchBlock } from './patches'; import { patchBlock } from './patches';
import { import {
availableBackgrounds, availableBackgrounds,
+5 -5
View File
@@ -4,22 +4,22 @@ const _ = require('lodash');
const { const {
getChallengesForLang getChallengesForLang
} = require('../../curriculum/dist/get-challenges.js'); } = require('@freecodecamp/curriculum/get-challenges');
const { const {
getBlockCreator, getBlockCreator,
getSuperblocks, getSuperblocks,
superBlockToFilename superBlockToFilename
} = require('../../curriculum/dist/build-curriculum.js'); } = require('@freecodecamp/curriculum/build-curriculum');
const { const {
getContentDir, getContentDir,
getBlockStructure, getBlockStructure,
getSuperblockStructure getSuperblockStructure
} = require('../../curriculum/dist/file-handler.js'); } = require('@freecodecamp/curriculum/file-handler');
const { const {
transformSuperBlock transformSuperBlock
} = require('../../curriculum/dist/build-superblock.js'); } = require('@freecodecamp/curriculum/build-superblock');
const { getSuperOrder } = require('../../curriculum/dist/super-order.js'); const { getSuperOrder } = require('@freecodecamp/curriculum/super-order');
const curriculumLocale = process.env.CURRICULUM_LOCALE || 'english'; const curriculumLocale = process.env.CURRICULUM_LOCALE || 'english';
+8
View File
@@ -8,6 +8,14 @@
"node": ">=24", "node": ">=24",
"pnpm": ">=10" "pnpm": ">=10"
}, },
"exports": {
"./build-certification": "./dist/build-certification.js",
"./build-curriculum": "./dist/build-curriculum.js",
"./build-superblock": "./dist/build-superblock.js",
"./file-handler": "./dist/file-handler.js",
"./get-challenges": "./dist/get-challenges.js",
"./super-order": "./dist/super-order.js"
},
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/freeCodeCamp/freeCodeCamp.git" "url": "https://github.com/freeCodeCamp/freeCodeCamp.git"
+7 -66
View File
@@ -1,25 +1,19 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { fileURLToPath } from 'url';
import { describe, test, expect } from 'vitest'; import { describe, test, expect } from 'vitest';
import { allCerts } from '../../client/config/cert-and-project-map.js';
import { buildCertification } from './build-certification.js'; import { buildCertification } from './build-certification.js';
import { getContentDir } from './file-handler.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
describe('build-certification', () => { describe('build-certification', () => {
const certificationsDir = path.join( const certificationsDir = path.resolve(
__dirname, getContentDir('english'),
'..', 'certifications'
'challenges/english/certifications'
); );
const yamlFiles = fs
.readdirSync(certificationsDir)
.filter(file => file.endsWith('.yml'));
yamlFiles.forEach(file => { const certificationFiles = fs.readdirSync(certificationsDir);
certificationFiles.forEach(file => {
describe(`${file} file`, () => { describe(`${file} file`, () => {
const filePath = path.join(certificationsDir, file); const filePath = path.join(certificationsDir, file);
const result = buildCertification(filePath); const result = buildCertification(filePath);
@@ -37,59 +31,6 @@ describe('build-certification', () => {
expect(certData).toHaveProperty('tests'); expect(certData).toHaveProperty('tests');
expect(Array.isArray(certData.tests)).toBe(true); expect(Array.isArray(certData.tests)).toBe(true);
}); });
test('Should have matching items in cert-and-project-map', () => {
const certData = result.challenges[0];
const certTests = certData.tests;
const matchingCert = allCerts.find(cert => cert.id === certData.id);
expect(
matchingCert,
`Cert ID ${certData.id} not found in allCerts.`
).toBeDefined();
expect(
matchingCert,
`Matching cert has no 'projects' property`
).toHaveProperty('projects');
// skip legacy-full-stack as it has no projects
if (file !== 'legacy-full-stack.yml') {
expect(
Array.isArray(matchingCert.projects),
`Matching cert 'projects' is not an array`
).toBe(true);
const certProjects = matchingCert.projects;
expect(
certProjects.length,
`Project count mismatch: allCerts has ${certProjects.length} projects, YAML has ${certTests.length} tests`
).toBe(certTests.length);
certTests.forEach((test, i) => {
expect(
test,
`Test at index ${i} in missing id property`
).toHaveProperty('id');
expect(
test,
`Test at index ${i} missing title property`
).toHaveProperty('title');
const matchingProject = certProjects[i];
expect(
matchingProject,
`No project found at index ${i} for test ${test.id}`
).toBeDefined();
expect(
matchingProject.id,
`Project ID mismatch at index ${i}: allCerts has "${matchingProject.id}", YAML has "${test.id}"`
).toBe(test.id);
});
}
});
}); });
}); });
}); });
+14 -2
View File
@@ -1,6 +1,18 @@
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
import { load } from 'js-yaml'; import { load } from 'js-yaml';
export const buildCertification = (filePath: string) => ({ interface CertificationChallenge {
challenges: [load(readFileSync(filePath, 'utf8'))] id: string;
title: string;
certification: string;
challengeType: number;
tests: { id: string; title: string }[];
}
export const buildCertification = (
filePath: string
): {
challenges: CertificationChallenge[];
} => ({
challenges: [load(readFileSync(filePath, 'utf8')) as CertificationChallenge]
}); });
+2 -1
View File
@@ -1,12 +1,13 @@
import { flatten } from 'lodash/fp'; import { flatten } from 'lodash/fp';
import { availableLangs } from '@freecodecamp/shared/config/i18n'; import { availableLangs } from '@freecodecamp/shared/config/i18n';
import { getChallengesForLang } from '../../../curriculum/src/get-challenges';
import { import {
SuperBlocks, SuperBlocks,
getAuditedSuperBlocks getAuditedSuperBlocks
} from '@freecodecamp/shared/config/curriculum'; } from '@freecodecamp/shared/config/curriculum';
import { getChallengesForLang } from '../get-challenges.js';
// TODO: re-organise the types to a common 'types' folder that can be shared // TODO: re-organise the types to a common 'types' folder that can be shared
// between the workspaces so we don't have to declare ChallengeNode here and in // between the workspaces so we don't have to declare ChallengeNode here and in
// the client. // the client.
+1
View File
@@ -3,6 +3,7 @@
"rootDir": "./src", "rootDir": "./src",
"outDir": "./dist", "outDir": "./dist",
"declaration": true, "declaration": true,
"declarationMap": true,
"target": "es2022", "target": "es2022",
"module": "nodenext", "module": "nodenext",
"strict": true, "strict": true,
+9 -6
View File
@@ -927,6 +927,9 @@ importers:
tools/challenge-helper-scripts: tools/challenge-helper-scripts:
devDependencies: devDependencies:
'@freecodecamp/curriculum':
specifier: workspace:*
version: link:../../curriculum
'@freecodecamp/eslint-config': '@freecodecamp/eslint-config':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/eslint-config version: link:../../packages/eslint-config
@@ -21118,7 +21121,7 @@ snapshots:
sirv: 3.0.2 sirv: 3.0.2
tinyglobby: 0.2.15 tinyglobby: 0.2.15
tinyrainbow: 3.0.3 tinyrainbow: 3.0.3
vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.7(@types/node@24.10.9)(typescript@5.9.3))(terser@5.28.1)(tsx@4.21.0)(yaml@2.8.1) vitest: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@24.10.9)(@vitest/ui@4.0.15)(jiti@2.6.1)(jsdom@26.1.0)(msw@2.12.7(@types/node@24.10.9)(typescript@5.9.3))(terser@5.28.1)(tsx@4.19.1)(yaml@2.8.1)
'@vitest/utils@3.2.4': '@vitest/utils@3.2.4':
dependencies: dependencies:
@@ -23720,7 +23723,7 @@ snapshots:
confusing-browser-globals: 1.0.11 confusing-browser-globals: 1.0.11
eslint: 7.32.0 eslint: 7.32.0
eslint-plugin-flowtype: 5.10.0(eslint@7.32.0) eslint-plugin-flowtype: 5.10.0(eslint@7.32.0)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@4.33.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-react: 7.37.4(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react: 7.37.4(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-react-hooks: 4.6.0(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: 4.6.0(eslint@9.39.2(jiti@2.6.1))
@@ -23750,7 +23753,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)): eslint-module-utils@2.12.0(@typescript-eslint/parser@4.33.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)):
dependencies: dependencies:
debug: 3.2.7 debug: 3.2.7
optionalDependencies: optionalDependencies:
@@ -23804,7 +23807,7 @@ snapshots:
- typescript - typescript
- utf-8-validate - utf-8-validate
eslint-plugin-import@2.31.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): eslint-plugin-import@2.31.0(@typescript-eslint/parser@4.33.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)):
dependencies: dependencies:
'@rtsao/scc': 1.1.0 '@rtsao/scc': 1.1.0
array-includes: 3.1.8 array-includes: 3.1.8
@@ -23815,7 +23818,7 @@ snapshots:
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 9.39.2(jiti@2.6.1) eslint: 9.39.2(jiti@2.6.1)
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1)) eslint-module-utils: 2.12.0(@typescript-eslint/parser@4.33.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2(jiti@2.6.1))
hasown: 2.0.2 hasown: 2.0.2
is-core-module: 2.16.1 is-core-module: 2.16.1
is-glob: 4.0.3 is-glob: 4.0.3
@@ -25053,7 +25056,7 @@ snapshots:
eslint-config-react-app: 6.0.0(@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0)(typescript@5.9.3))(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(babel-eslint@10.1.0(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-flowtype@5.10.0(eslint@7.32.0))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@7.32.0))(eslint-plugin-react-hooks@4.6.0(eslint@7.32.0))(eslint-plugin-react@7.37.4(eslint@7.32.0))(eslint@7.32.0)(typescript@5.9.3) eslint-config-react-app: 6.0.0(@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0)(typescript@5.9.3))(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(babel-eslint@10.1.0(eslint@9.39.2(jiti@2.6.1)))(eslint-plugin-flowtype@5.10.0(eslint@7.32.0))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@7.32.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@7.32.0))(eslint-plugin-react-hooks@4.6.0(eslint@7.32.0))(eslint-plugin-react@7.37.4(eslint@7.32.0))(eslint@7.32.0)(typescript@5.9.3)
eslint-plugin-flowtype: 5.10.0(eslint@7.32.0) eslint-plugin-flowtype: 5.10.0(eslint@7.32.0)
eslint-plugin-graphql: 4.0.0(@types/node@24.10.9)(graphql@15.8.0)(typescript@5.9.3) eslint-plugin-graphql: 4.0.0(@types/node@24.10.9)(graphql@15.8.0)(typescript@5.9.3)
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@4.33.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-react: 7.37.4(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react: 7.37.4(eslint@9.39.2(jiti@2.6.1))
eslint-plugin-react-hooks: 4.6.0(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: 4.6.0(eslint@9.39.2(jiti@2.6.1))
@@ -16,8 +16,8 @@ import {
writeBlockStructure, writeBlockStructure,
createBlockFolder, createBlockFolder,
getSuperblockStructure getSuperblockStructure
} from '../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import { superBlockToFilename } from '../../curriculum/src/build-curriculum.js'; import { superBlockToFilename } from '@freecodecamp/curriculum/build-curriculum';
import { getBaseMeta } from './helpers/get-base-meta.js'; import { getBaseMeta } from './helpers/get-base-meta.js';
import { createIntroMD } from './helpers/create-intro.js'; import { createIntroMD } from './helpers/create-intro.js';
import { import {
@@ -12,8 +12,8 @@ import { BlockLayouts, BlockLabel } from '@freecodecamp/shared/config/blocks';
import { import {
createBlockFolder, createBlockFolder,
writeBlockStructure writeBlockStructure
} from '../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import { superBlockToFilename } from '../../curriculum/src/build-curriculum.js'; import { superBlockToFilename } from '@freecodecamp/curriculum/build-curriculum';
import { import {
createQuizFile, createQuizFile,
createStepFile, createStepFile,
@@ -8,8 +8,8 @@ import { SuperBlocks } from '@freecodecamp/shared/config/curriculum';
import { import {
createBlockFolder, createBlockFolder,
writeBlockStructure writeBlockStructure
} from '../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import { superBlockToFilename } from '../../curriculum/src/build-curriculum.js'; import { superBlockToFilename } from '@freecodecamp/curriculum/build-curriculum';
import { createQuizFile, getAllBlocks, validateBlockName } from './utils.js'; import { createQuizFile, getAllBlocks, validateBlockName } from './utils.js';
import { getBaseMeta } from './helpers/get-base-meta.js'; import { getBaseMeta } from './helpers/get-base-meta.js';
import { createIntroMD } from './helpers/create-intro.js'; import { createIntroMD } from './helpers/create-intro.js';
@@ -11,7 +11,7 @@ import { ObjectId } from 'bson';
import { import {
getBlockStructure, getBlockStructure,
writeBlockStructure writeBlockStructure
} from '../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import { createChallengeFile } from './utils.js'; import { createChallengeFile } from './utils.js';
import { getProjectPath } from './helpers/get-project-info.js'; import { getProjectPath } from './helpers/get-project-info.js';
import { getBlock, type Meta } from './helpers/project-metadata.js'; import { getBlock, type Meta } from './helpers/project-metadata.js';
@@ -2,13 +2,13 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
import { import {
getSuperblockStructure, getSuperblockStructure,
writeSuperblockStructure writeSuperblockStructure
} from '../../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import { import {
updateChapterModuleSuperblockStructure, updateChapterModuleSuperblockStructure,
updateSimpleSuperblockStructure updateSimpleSuperblockStructure
} from './create-project.js'; } from './create-project.js';
vi.mock('../../../curriculum/src/file-handler'); vi.mock('@freecodecamp/curriculum/file-handler');
const mockGetSuperblockStructure = vi.mocked(getSuperblockStructure); const mockGetSuperblockStructure = vi.mocked(getSuperblockStructure);
const mockWriteSuperblockStructure = vi.mocked(writeSuperblockStructure); const mockWriteSuperblockStructure = vi.mocked(writeSuperblockStructure);
@@ -3,7 +3,7 @@
import { import {
getSuperblockStructure, getSuperblockStructure,
writeSuperblockStructure writeSuperblockStructure
} from '../../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import { insertInto } from './utils.js'; import { insertInto } from './utils.js';
export async function updateSimpleSuperblockStructure( export async function updateSimpleSuperblockStructure(
@@ -1,9 +1,9 @@
import { join } from 'path'; import { join } from 'path';
import { describe, it, expect, vi } from 'vitest'; import { describe, it, expect, vi } from 'vitest';
import { getBlockStructure } from '../../../curriculum/src/file-handler.js'; import { getBlockStructure } from '@freecodecamp/curriculum/file-handler';
import { getMetaData } from './project-metadata.js'; import { getMetaData } from './project-metadata.js';
vi.mock('../../../curriculum/src/file-handler'); vi.mock('@freecodecamp/curriculum/file-handler');
const commonPath = join('curriculum', 'challenges', 'blocks'); const commonPath = join('curriculum', 'challenges', 'blocks');
const block = 'block-name'; const block = 'block-name';
@@ -2,7 +2,7 @@ import path from 'path';
import { import {
getBlockStructure, getBlockStructure,
writeBlockStructure writeBlockStructure
} from '../../../curriculum/src/file-handler.js'; } from '@freecodecamp/curriculum/file-handler';
import type { BlockLabel } from '@freecodecamp/shared/config/blocks'; import type { BlockLabel } from '@freecodecamp/shared/config/blocks';
import { getProjectPath } from './get-project-info.js'; import { getProjectPath } from './get-project-info.js';
+2 -1
View File
@@ -31,9 +31,10 @@
"type-check": "tsc --noEmit" "type-check": "tsc --noEmit"
}, },
"devDependencies": { "devDependencies": {
"@freecodecamp/curriculum": "workspace:*",
"@freecodecamp/eslint-config": "workspace:*", "@freecodecamp/eslint-config": "workspace:*",
"@total-typescript/ts-reset": "^0.6.1",
"@freecodecamp/shared": "workspace:*", "@freecodecamp/shared": "workspace:*",
"@total-typescript/ts-reset": "^0.6.1",
"@types/glob": "^8.0.1", "@types/glob": "^8.0.1",
"@types/inquirer": "^8.2.5", "@types/inquirer": "^8.2.5",
"@vitest/ui": "^3.2.4", "@vitest/ui": "^3.2.4",
@@ -14,7 +14,7 @@ import {
writeSuperblockStructure, writeSuperblockStructure,
getContentConfig, getContentConfig,
getCurriculumStructure getCurriculumStructure
} from '../../curriculum/src/file-handler'; } from '@freecodecamp/curriculum/file-handler';
import matter from 'gray-matter'; import matter from 'gray-matter';
interface RenameBlockArgs { interface RenameBlockArgs {
+1 -1
View File
@@ -5,7 +5,7 @@ import matter from 'gray-matter';
import { uniq } from 'lodash'; import { uniq } from 'lodash';
import { challengeTypes } from '@freecodecamp/shared/config/challenge-types'; import { challengeTypes } from '@freecodecamp/shared/config/challenge-types';
import { parseCurriculumStructure } from '../../curriculum/src/build-curriculum.js'; import { parseCurriculumStructure } from '@freecodecamp/curriculum/build-curriculum';
import { parseMDSync } from '../challenge-parser/parser/index.js'; import { parseMDSync } from '../challenge-parser/parser/index.js';
import { getMetaData, updateMetaData } from './helpers/project-metadata.js'; import { getMetaData, updateMetaData } from './helpers/project-metadata.js';
import { getProjectPath } from './helpers/get-project-info.js'; import { getProjectPath } from './helpers/get-project-info.js';
@@ -1,10 +1,10 @@
const chokidar = require('chokidar'); const chokidar = require('chokidar');
const { const {
getSuperblockStructure getSuperblockStructure
} = require('@freecodecamp/curriculum/dist/file-handler'); } = require('@freecodecamp/curriculum/file-handler');
const { const {
superBlockToFilename superBlockToFilename
} = require('@freecodecamp/curriculum/dist/build-curriculum'); } = require('@freecodecamp/curriculum/build-curriculum');
const { createChallengeNode } = require('./create-challenge-nodes'); const { createChallengeNode } = require('./create-challenge-nodes');