computer-scienceangular-roadmapbackend-roadmapblockchain-roadmapdba-roadmapdeveloper-roadmapdevops-roadmapfrontend-roadmapgo-roadmaphactoberfestjava-roadmapjavascript-roadmapnodejs-roadmappython-roadmapqa-roadmapreact-roadmaproadmapstudy-planvue-roadmapweb3-roadmap
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
3.1 KiB
113 lines
3.1 KiB
import slugify from 'slugify'; |
|
import { getAllAuthors, type AuthorFileType } from './author.ts'; |
|
import { getCollection, type CollectionEntry } from 'astro:content'; |
|
|
|
type RawQuestionGroupFileType = CollectionEntry<'question-groups'>; |
|
|
|
export type QuestionType = { |
|
id: string; |
|
question: string; |
|
answer: string; |
|
isLongAnswer: boolean; |
|
topics?: string[]; |
|
}; |
|
|
|
export type QuestionGroupType = RawQuestionGroupFileType & { |
|
questions: QuestionType[]; |
|
allTopics: string[]; |
|
author?: AuthorFileType; |
|
}; |
|
|
|
/** |
|
* Gets all the best practice files |
|
* |
|
* @returns Promisified BestPracticeFileType[] |
|
*/ |
|
export async function getAllQuestionGroups(): Promise<QuestionGroupType[]> { |
|
const questionGroupEntries = await getCollection('question-groups'); |
|
const allAuthors = await getAllAuthors(); |
|
const answerFilesMap = import.meta.glob( |
|
// get the files inside /src/data/question-groups/[ignore]/content/*.md |
|
`/src/data/question-groups/*/content/*.md`, |
|
{ |
|
eager: true, |
|
query: '?raw', |
|
}, |
|
); |
|
|
|
return questionGroupEntries |
|
.map((questionGroupEntry) => { |
|
const formattedAnswers: QuestionType[] = |
|
questionGroupEntry.data.questions.map((qa) => { |
|
const questionText = qa.question; |
|
let answerText = qa.answer; |
|
let isLongAnswer = false; |
|
|
|
if (answerText.endsWith('.md')) { |
|
const answerFilePath = `/src/data/question-groups/${questionGroupEntry.slug}/content/${answerText}`; |
|
answerText = |
|
// @ts-ignore |
|
answerFilesMap[answerFilePath]?.default || |
|
`File missing: ${answerFilePath}`; |
|
|
|
isLongAnswer = true; |
|
} |
|
|
|
return { |
|
id: slugify(questionText, { lower: true }), |
|
question: questionText, |
|
answer: answerText, |
|
topics: qa.topics, |
|
isLongAnswer, |
|
}; |
|
}); |
|
|
|
const uniqueTopics = formattedAnswers |
|
.flatMap((answer) => answer.topics || []) |
|
.filter((topic) => topic) |
|
.reduce((acc, topic) => { |
|
if (!acc.includes(topic)) { |
|
acc.push(topic); |
|
} |
|
|
|
return acc; |
|
}, [] as string[]); |
|
|
|
const author = allAuthors.find( |
|
(author) => author.slug === questionGroupEntry.data.authorId, |
|
); |
|
|
|
return { |
|
...questionGroupEntry, |
|
questions: formattedAnswers, |
|
allTopics: uniqueTopics, |
|
author, |
|
}; |
|
}) |
|
.sort((a, b) => a.data.order - b.data.order); |
|
} |
|
|
|
export async function getQuestionGroupById(slug: string) { |
|
const questionGroups = await getAllQuestionGroups(); |
|
|
|
return questionGroups.find((group) => group.slug === slug); |
|
} |
|
|
|
export async function getQuestionGroupsByIds( |
|
ids: string[], |
|
): Promise<{ id: string; title: string; description: string }[]> { |
|
if (!ids?.length) { |
|
return []; |
|
} |
|
|
|
const questionGroups = await getAllQuestionGroups(); |
|
return questionGroups |
|
.filter((group) => ids.includes(group.slug)) |
|
.map((group) => { |
|
return { |
|
id: group.id, |
|
title: group.data.title, |
|
description: `${group.questions.length} Questions`, |
|
}; |
|
}); |
|
}
|
|
|