feat(documentation-directory): add typed markdown directory ingestion with author normalization and test coverage
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import * as plugins from './plugins.js';
|
||||
|
||||
export interface IDocumentationDirectoryConstructorOptions {
|
||||
pathArg: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* a documentation directory maps to a directory with markdown documents
|
||||
*/
|
||||
export class DocumentationDirectory {
|
||||
public options: IDocumentationDirectoryConstructorOptions;
|
||||
public smartmarkdownInstance = new plugins.smartmarkdown.SmartMarkdown();
|
||||
public articles: plugins.tsclass.content.IArticle[] = [];
|
||||
|
||||
constructor(optionsArg: IDocumentationDirectoryConstructorOptions) {
|
||||
this.options = optionsArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* reads a directory
|
||||
*/
|
||||
public async readDirectory() {
|
||||
const smartfileFactory = plugins.smartfile.SmartFileFactory.nodeFs();
|
||||
const virtualDirectory = await smartfileFactory.virtualDirectoryFromPath(this.options.pathArg);
|
||||
const fileTreeComplete = virtualDirectory.listFiles();
|
||||
const articles: plugins.tsclass.content.IArticle[] = [];
|
||||
for (const markdownFile of fileTreeComplete.filter(
|
||||
(fileArg) => fileArg.parsedPath.ext === '.md'
|
||||
)) {
|
||||
const parsedMarkdown = await this.smartmarkdownInstance.getMdParsedResultFromMarkdown(
|
||||
markdownFile.contents.toString()
|
||||
);
|
||||
const frontmatterTitle = parsedMarkdown.frontmatterData.title;
|
||||
articles.push({
|
||||
title: typeof frontmatterTitle === 'string' ? frontmatterTitle : markdownFile.parsedPath.name,
|
||||
author: this.normalizeAuthor(parsedMarkdown.frontmatterData.author),
|
||||
content: parsedMarkdown.originalString,
|
||||
timestamp: Date.now(),
|
||||
tags: [`path:${markdownFile.path}`],
|
||||
});
|
||||
}
|
||||
this.articles = articles;
|
||||
}
|
||||
|
||||
private normalizeAuthor(authorArg: unknown): plugins.tsclass.content.IAuthor {
|
||||
if (typeof authorArg === 'object' && authorArg !== null) {
|
||||
const authorCandidate = authorArg as Partial<plugins.tsclass.content.IAuthor>;
|
||||
if (
|
||||
typeof authorCandidate.firstName === 'string' &&
|
||||
typeof authorCandidate.surName === 'string' &&
|
||||
authorCandidate.birthday &&
|
||||
typeof authorCandidate.birthday.day === 'number' &&
|
||||
typeof authorCandidate.birthday.month === 'number' &&
|
||||
typeof authorCandidate.birthday.year === 'number'
|
||||
) {
|
||||
return {
|
||||
firstName: authorCandidate.firstName,
|
||||
surName: authorCandidate.surName,
|
||||
birthday: authorCandidate.birthday,
|
||||
articles: Array.isArray(authorCandidate.articles) ? authorCandidate.articles : [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof authorArg === 'string' && authorArg.trim()) {
|
||||
const [firstName, ...surNameParts] = authorArg.trim().split(/\s+/);
|
||||
return {
|
||||
firstName,
|
||||
surName: surNameParts.join(' '),
|
||||
birthday: {
|
||||
day: 1,
|
||||
month: 1,
|
||||
year: 1970,
|
||||
},
|
||||
articles: [],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
firstName: 'Unknown',
|
||||
surName: 'Author',
|
||||
birthday: {
|
||||
day: 1,
|
||||
month: 1,
|
||||
year: 1970,
|
||||
},
|
||||
articles: [],
|
||||
};
|
||||
}
|
||||
|
||||
public sendAsDocumentationSet(nameArg: string, targetArg: string): void {
|
||||
void nameArg;
|
||||
void targetArg;
|
||||
|
||||
}
|
||||
|
||||
public async processDirectoryForMkdocs() {}
|
||||
}
|
||||
Reference in New Issue
Block a user