119 lines
3.0 KiB
TypeScript
119 lines
3.0 KiB
TypeScript
import type { MarkdownFileType } from './file';
|
|
import slugify from 'slugify';
|
|
|
|
interface RawQuestionGroupFrontmatter {
|
|
order: number;
|
|
briefTitle: string;
|
|
briefDescription: string;
|
|
title: string;
|
|
description: string;
|
|
isNew: boolean;
|
|
seo: {
|
|
title: string;
|
|
description: string;
|
|
ogImageUrl?: string;
|
|
keywords: string[];
|
|
};
|
|
sitemap: {
|
|
priority: number;
|
|
changefreq: string;
|
|
};
|
|
questions: {
|
|
question: string;
|
|
answer: string;
|
|
topics: string[];
|
|
}[];
|
|
}
|
|
|
|
type RawQuestionGroupFileType =
|
|
MarkdownFileType<RawQuestionGroupFrontmatter> & {
|
|
id: string;
|
|
};
|
|
|
|
export type QuestionType = {
|
|
id: string;
|
|
question: string;
|
|
answer: string;
|
|
isLongAnswer: boolean;
|
|
topics?: string[];
|
|
};
|
|
|
|
export type QuestionGroupType = RawQuestionGroupFileType & {
|
|
questions: QuestionType[];
|
|
allTopics: string[];
|
|
};
|
|
|
|
/**
|
|
* Gets all the best practice files
|
|
*
|
|
* @returns Promisified BestPracticeFileType[]
|
|
*/
|
|
export async function getAllQuestionGroups(): Promise<QuestionGroupType[]> {
|
|
const questionGroupFilesMap =
|
|
await import.meta.glob<RawQuestionGroupFileType>(
|
|
`/src/data/question-groups/*/*.md`,
|
|
{
|
|
eager: true,
|
|
}
|
|
);
|
|
|
|
const answerFilesMap = await import.meta.glob<string>(
|
|
// get the files inside /src/data/question-groups/[ignore]/content/*.md
|
|
`/src/data/question-groups/*/content/*.md`,
|
|
{
|
|
eager: true,
|
|
as: 'raw',
|
|
}
|
|
);
|
|
|
|
return Object.values(questionGroupFilesMap)
|
|
.map((questionGroupFile) => {
|
|
const fileParts = questionGroupFile?.file?.split('/');
|
|
const [questionGroupDir, questionGroupFileName] = fileParts?.slice(-2);
|
|
|
|
const questionGroupFileId = questionGroupFileName?.replace('.md', '');
|
|
const formattedAnswers: QuestionType[] =
|
|
questionGroupFile.frontmatter.questions.map((qa) => {
|
|
const questionText = qa.question;
|
|
let answerText = qa.answer;
|
|
let isLongAnswer = false;
|
|
|
|
if (answerText.endsWith('.md')) {
|
|
const answerFilePath = `/src/data/question-groups/${questionGroupDir}/content/${answerText}`;
|
|
answerText =
|
|
answerFilesMap[answerFilePath] ||
|
|
`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[]);
|
|
|
|
return {
|
|
...questionGroupFile,
|
|
id: questionGroupFileId,
|
|
questions: formattedAnswers,
|
|
allTopics: uniqueTopics,
|
|
};
|
|
})
|
|
.sort((a, b) => a.frontmatter.order - b.frontmatter.order);
|
|
}
|