mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-28 13:00:31 -04:00
feat(api): add PUT /certificate/verify (#51507)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -34,6 +34,7 @@ export function createUserInput(email: string): Prisma.userCreateInput {
|
||||
isDataAnalysisPyCertV7: false,
|
||||
isDataVisCert: false,
|
||||
isDonating: false,
|
||||
isFoundationalCSharpCertV8: false,
|
||||
isFrontEndCert: false,
|
||||
isFrontEndLibsCert: false,
|
||||
isFullStackCert: false,
|
||||
|
||||
@@ -39,6 +39,7 @@ assert.ok(process.env.FCC_ENABLE_SWAGGER_UI);
|
||||
assert.ok(process.env.FCC_ENABLE_DEV_LOGIN_MODE);
|
||||
assert.ok(process.env.JWT_SECRET);
|
||||
assert.ok(process.env.STRIPE_SECRET_KEY);
|
||||
assert.ok(process.env.SHOW_UPCOMING_CHANGES);
|
||||
|
||||
if (process.env.FREECODECAMP_NODE_ENV !== 'development') {
|
||||
assert.ok(process.env.SES_ID);
|
||||
@@ -109,4 +110,6 @@ export const SES_ID = process.env.SES_ID;
|
||||
export const SES_SECRET = process.env.SES_SECRET;
|
||||
export const SES_REGION = process.env.SES_REGION;
|
||||
export const EMAIL_PROVIDER = process.env.EMAIL_PROVIDER;
|
||||
export const SHOW_UPCOMING_CHANGES =
|
||||
process.env.SHOW_UPCOMING_CHANGES === 'true';
|
||||
export const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||
|
||||
@@ -3,10 +3,15 @@
|
||||
// redirectToCurrentChallenge and, instead, only report the current challenge id
|
||||
// via the user object, then we should *not* store this so it can be garbage
|
||||
// collected.
|
||||
import curriculum from '../../../shared/config/curriculum.json';
|
||||
import { SuperBlocks } from '../../../shared/config/superblocks';
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
type Curriculum = { [keyValue in SuperBlocks]?: CurriculumProps };
|
||||
const CURRICULUM_PATH = '../shared/config/curriculum.json';
|
||||
|
||||
// Curriculum is read using fs, because it is too large for VSCode's LSP to handle type inference which causes anoying behaviour.
|
||||
const curriculum = JSON.parse(
|
||||
readFileSync(join(process.cwd(), CURRICULUM_PATH), 'utf-8')
|
||||
) as Curriculum;
|
||||
|
||||
interface Block {
|
||||
challenges: {
|
||||
@@ -18,25 +23,30 @@ interface Block {
|
||||
}[];
|
||||
}
|
||||
|
||||
interface CurriculumProps {
|
||||
type SuperBlock = {
|
||||
blocks: Record<string, Block>;
|
||||
}
|
||||
};
|
||||
|
||||
type Curriculum = Record<string, SuperBlock>;
|
||||
|
||||
/**
|
||||
* Get all the challenges from the curriculum.
|
||||
* @returns An array of challenges.
|
||||
* Get all challenges including all certifications as "challenges" (ids and tests).
|
||||
* @returns The whole curricula reduced to an array.
|
||||
*/
|
||||
export function getChallenges() {
|
||||
const superBlockKeys = Object.values(SuperBlocks);
|
||||
const typedCurriculum: Curriculum = curriculum as Curriculum;
|
||||
export function getChallenges(): Block['challenges'] {
|
||||
const curricula = Object.values(curriculum);
|
||||
|
||||
return superBlockKeys
|
||||
.map(key => typedCurriculum[key]?.blocks)
|
||||
.reduce((accumulator: Block['challenges'], superBlock) => {
|
||||
const blockKeys = Object.keys(superBlock ?? {});
|
||||
const challengesForBlock = blockKeys.map(
|
||||
key => superBlock?.[key]?.challenges ?? []
|
||||
);
|
||||
return [...accumulator, ...challengesForBlock.flat()];
|
||||
return curricula
|
||||
.map(v => v.blocks)
|
||||
.reduce((acc: Block['challenges'], superBlock) => {
|
||||
const blockKeys = Object.keys(superBlock);
|
||||
const challengesForBlock = blockKeys.map(k => {
|
||||
const block = superBlock[k];
|
||||
if (!block) {
|
||||
return [];
|
||||
}
|
||||
return block.challenges;
|
||||
});
|
||||
return [...acc, ...challengesForBlock.flat()];
|
||||
}, []);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user